archipelago 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,71 @@
1
+
2
+ require File.join(File.dirname(__FILE__), 'test_helper')
3
+
4
+ class DumpTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @c = Archipelago::Sanitation::Officer.new(:initial_lookup_timeout => 0)
8
+ @d = Archipelago::Dump::Site.new(:officer => @c,
9
+ :persistence_directory => Pathname.new(__FILE__).parent.join("site.db"))
10
+ end
11
+
12
+ def teardown
13
+ @d.instance_eval do @persistence_provider.unlink! end
14
+ @c.stop!
15
+ end
16
+
17
+ def test_insert_fetch
18
+ @d.insert!("key", ["value", "value1"])
19
+
20
+ assert_equal(["value", "value1"].sort,
21
+ @d.fetch("key").collect do |e| e.last end.sort)
22
+
23
+ @d.insert!("key2", ["value2"])
24
+ @d.insert!("key2", ["value3"])
25
+ assert_equal(["value2"],
26
+ @d.fetch("key2").collect do |e| e.last end.sort)
27
+
28
+ @d.insert!("key2", ["value3"], "hehu")
29
+ assert_equal(["value3"],
30
+ @d.fetch("key2").collect do |e| e.last end.sort)
31
+
32
+ @d.insert!("key", ["value2", "value3"], "apap")
33
+ assert_equal(["value2", "value3"].sort,
34
+ @d.fetch("key").collect do |e| e.last end.sort)
35
+
36
+ @d.delete!("key")
37
+ @d.delete!("key2")
38
+ assert_equal([],
39
+ @d.fetch("key").collect do |e| e.last end)
40
+ assert_equal([],
41
+ @d.fetch("key2").collect do |e| e.last end)
42
+ end
43
+
44
+ def test_too_few
45
+ @d.insert!("a", ["b","c"])
46
+ assert_equal(["b","c"].sort,
47
+ @d.fetch("a").collect do |e| e.last end.sort)
48
+ @d.insert!("a", ["d","c","b"])
49
+ assert_equal(["b","c","d"].sort,
50
+ @d.fetch("a").collect do |e| e.last end.sort)
51
+ end
52
+
53
+ def test_too_many
54
+ @d.insert!("a", ["b","c"])
55
+ assert_equal(["b","c"].sort,
56
+ @d.fetch("a").collect do |e| e.last end.sort)
57
+ @d.insert!("a", ["d"])
58
+ assert_equal(["d"],
59
+ @d.fetch("a").collect do |e| e.last end)
60
+ end
61
+
62
+ def test_wrong_timestamp
63
+ @d.insert!("a", ["b","c"], "epap")
64
+ assert_equal(["b","c"].sort,
65
+ @d.fetch("a").collect do |e| e.last end.sort)
66
+ @d.insert!("a", ["x", "y"], "epao")
67
+ assert_equal(["x","y"].sort,
68
+ @d.fetch("a").collect do |e| e.last end.sort)
69
+ end
70
+
71
+ end
data/tests/pirate_test.rb CHANGED
@@ -4,33 +4,72 @@ require File.join(File.dirname(__FILE__), 'test_helper')
4
4
  class PirateTest < Test::Unit::TestCase
5
5
 
6
6
  def setup
7
- DRb.start_service("druby://localhost:#{rand(1000) + 5000}")
7
+ @j = Archipelago::Disco::Jockey.new
8
8
  @p = Archipelago::Pirate::Captain.new(:chest_description => {:class => "TestChest"},
9
- :tranny_description => {:class => "TestManager"})
10
- @c = TestChest.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("chest.db")))
11
- @c.publish!
12
- @c2 = TestChest.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("chest2.db")))
13
- @c2.publish!
14
- @tm = TestManager.new(:persistence_provider => Archipelago::Hashish::BerkeleyHashishProvider.new(Pathname.new(__FILE__).parent.join("tranny.db")))
9
+ :tranny_description => {:class => "TestManager"},
10
+ :jockey => @j,
11
+ :initial_lookup_timeout => 0)
12
+ @c = TestChest.new(:captain => @p,
13
+ :persistence_directory => Pathname.new(__FILE__).parent.join("chest.db"))
14
+ @c.publish!(:jockey => @j)
15
+ assert(@j.instance_eval do
16
+ @service_change_subscribers_by_event_type
17
+ end[:lost].include?([@p.instance_eval do
18
+ @service_descriptions
19
+ end[:chests], @c.service_id]))
20
+ assert(@j.instance_eval do
21
+ @service_change_subscribers_by_event_type
22
+ end[:found].include?([@p.instance_eval do
23
+ @service_descriptions
24
+ end[:chests], @c.service_id]))
25
+ assert_within(10) do
26
+ @p.update_services!
27
+ @p.chests.keys.include?(@c.service_id)
28
+ end
29
+ assert_equal(@c.service_id, @c.instance_eval do @predecessor_id end)
30
+
31
+ @c2 = TestChest.new(:captain => @p,
32
+ :persistence_directory => Pathname.new(__FILE__).parent.join("chest2.db"))
33
+ @c2.publish!(:jockey => @j)
34
+ assert_within(10) do
35
+ @p.update_services!
36
+ @p.chests.keys.include?(@c2.service_id)
37
+ end
38
+ assert_within(10) do
39
+ @c2.service_id == @c.instance_eval do @predecessor_id end
40
+ end
41
+ assert_within(10) do
42
+ @c.service_id == @c2.instance_eval do @predecessor_id end
43
+ end
44
+
45
+ @tm = TestManager.new(:captain => @p,
46
+ :persistence_directory => Pathname.new(__FILE__).parent.join("tranny.db"))
15
47
  @tm.publish!
16
- @p.update_services!
17
48
  assert_within(10) do
49
+ @p.update_services!
50
+ @p.trannies.keys.include?(@tm.service_id)
51
+ end
52
+
53
+
54
+ assert_within(10) do
55
+ @p.update_services!
18
56
  @p.chests.keys.sort == [@c.service_id, @c2.service_id].sort
19
57
  end
20
58
  assert_within(10) do
59
+ @p.update_services!
21
60
  @p.trannies.keys == [@tm.service_id]
22
61
  end
23
62
  end
24
63
 
25
64
  def teardown
26
- @p.stop!
27
- @c.stop!
65
+ @c.close!
28
66
  @c.persistence_provider.unlink!
29
- @c2.stop!
67
+ @c2.close!
30
68
  @c2.persistence_provider.unlink!
31
- @tm.stop!
69
+ @tm.close!
32
70
  @tm.persistence_provider.unlink!
33
- DRb.stop_service
71
+ @p.stop!
72
+ @j.stop!
34
73
  end
35
74
 
36
75
  def test_include
@@ -122,18 +161,18 @@ class PirateTest < Test::Unit::TestCase
122
161
  end
123
162
  trans = nil
124
163
  assert_raise(Archipelago::Pirate::CommitFailedException) do
125
- @p.transaction do |trans|
126
- assert_equal(trans.transaction_id, @p.active_transaction.transaction_id)
127
- @p["hehu"] = "haha"
164
+ @p.transaction do |copy|
165
+ trans = copy.active_transaction
166
+ copy["hehu"] = "haha"
128
167
  assert(!p2.include?("hehu"))
129
168
  assert(!p2.include?("hehu", nil))
130
169
  assert_equal(nil, p2.active_transaction)
131
170
  trans2 = nil
132
- p2.transaction do |trans2|
133
- assert_equal(trans2.transaction_id, p2.active_transaction.transaction_id)
134
- p2["hehu"] = "hoj"
135
- assert_equal("haha", @p["hehu"])
136
- assert_equal("hoj", @p["hehu", trans2])
171
+ p2.transaction do |copy2|
172
+ trans2 = copy2.active_transaction
173
+ copy2["hehu"] = "hoj"
174
+ assert_equal("haha", copy["hehu"])
175
+ assert_equal("hoj", copy["hehu", trans2])
137
176
  end
138
177
  assert_equal(:commited, trans2.state)
139
178
  assert_equal(:active, trans.state)
@@ -145,6 +184,20 @@ class PirateTest < Test::Unit::TestCase
145
184
  assert_equal("hoj", @p["hehu"])
146
185
  end
147
186
 
187
+ def test_wrong_chest_exception
188
+ chests = [@c, @c2].sort do |a,b|
189
+ a.service_id <=> b.service_id
190
+ end
191
+ begin
192
+ $DO_ASSERT_MINE = true
193
+ assert_raise(Archipelago::Treasure::WrongChestException) do
194
+ chests.last.call_instance_method(chests.last.service_id.next, :bruhuf, nil)
195
+ end
196
+ ensure
197
+ $DO_ASSERT_MINE = false
198
+ end
199
+ end
200
+
148
201
  def test_write_read_transaction
149
202
  $T = true
150
203
  @p["hej"] = "haha"
@@ -0,0 +1,50 @@
1
+
2
+ require File.join(File.dirname(__FILE__), 'test_helper')
3
+
4
+ class SanitationBenchmark < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @d = Archipelago::Dump::Site.new(:persistence_directory => Pathname.new(__FILE__).parent.join("site.db"))
8
+ @d.publish!
9
+ @c = Archipelago::Sanitation::Officer.new
10
+ assert_within(10) do
11
+ @c.update_services!
12
+ @c.sites.keys == [@d.service_id]
13
+ end
14
+ end
15
+
16
+ def teardown
17
+ @d.close!
18
+ @d.instance_eval do @persistence_provider.unlink! end
19
+ @c.stop!
20
+ end
21
+
22
+ def test_set_get
23
+ do_set_get(8)
24
+ do_set_get(128)
25
+ do_set_get(512)
26
+ do_set_get(1024)
27
+ end
28
+
29
+ private
30
+
31
+ def do_set_get(size)
32
+ k = "apa"
33
+ v = " " * size
34
+ bm("Sanitation#[]= (#{size})", :n => 100) do
35
+ @c[k] = v
36
+ k = k.next
37
+ end
38
+ k = "apa"
39
+ bm("Sanitation#[] (#{size})", :n => 100) do
40
+ t = @c[k]
41
+ k = k.next
42
+ end
43
+ k = "apa"
44
+ bm("Sanitation#delete", :n => 100) do
45
+ t = @c.delete!(k)
46
+ k = k.next
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,219 @@
1
+
2
+ require File.join(File.dirname(__FILE__), 'test_helper')
3
+
4
+ class SanitationTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @c = Archipelago::Sanitation::Officer.new(:initial_lookup_timeout => 0)
8
+ @d = Archipelago::Dump::Site.new(:officer => @c,
9
+ :persistence_directory => Pathname.new(__FILE__).parent.join("site.db"))
10
+ @d.publish!
11
+ begin
12
+ assert_within(10) do
13
+ @c.update_services!
14
+ @c.sites.keys == [@d.service_id]
15
+ end
16
+ rescue Test::Unit::AssertionFailedError => e
17
+ puts "#{@c.sites.keys.inspect} != #{[@d.service_id].inspect}"
18
+ raise e
19
+ end
20
+ end
21
+
22
+ def teardown
23
+ @d.close!
24
+ @d.instance_eval do @persistence_provider.unlink! end
25
+ @c.stop!
26
+ end
27
+
28
+ def test_sanitation_backed_chest
29
+ chest = Archipelago::Treasure::Chest.new(:persistence_directory => Pathname.new(__FILE__).parent.join("site_chest.db"),
30
+ :officer => @c)
31
+ chest.publish!
32
+ begin
33
+ assert_equal(nil, chest["klibb"])
34
+ assert_equal("kladd", chest["klibb"] = "kladd")
35
+ assert_equal("kladd", chest["klibb"])
36
+ assert_equal("KLADD", chest["klibb"].upcase!)
37
+ klibb = chest["klibb"]
38
+ assert_equal("kladd", klibb.downcase)
39
+ assert_equal("kladd", klibb.downcase!)
40
+ assert_equal("KLADD", klibb.upcase)
41
+ assert_equal("kladd", klibb)
42
+ @d.close!
43
+ @c.update_services!(:validate => true)
44
+ assert_raise(Archipelago::Sanitation::NoRemoteDatabaseAvailableException) do
45
+ klibb.upcase!
46
+ end
47
+ ensure
48
+ chest.close!
49
+ chest.instance_eval do @persistence_provider.unlink! end
50
+ end
51
+ end
52
+
53
+ def test_missing_bits
54
+ s1 = Oneliner::SuperString.new("brappa")
55
+ @d.insert!("a", [s1.encode(9)], "abab")
56
+ assert_raise(Archipelago::Sanitation::NotEnoughDataException) do
57
+ @c["a"]
58
+ end
59
+ end
60
+
61
+
62
+ def test_get_set
63
+ @c["hej"] = "hoho"
64
+ assert_equal("hoho", @c["hej"])
65
+ @c.delete!("hej")
66
+ assert_equal(@c["hej"], nil)
67
+ end
68
+
69
+ def test_multi
70
+ #
71
+ # Setup the network
72
+ #
73
+ @d.close!
74
+ dumps = []
75
+ cleaner2 = Archipelago::Sanitation::Officer.new(:minimum_nr_of_chunks => 3,
76
+ :initial_lookup_timeout => 0)
77
+ begin
78
+ 10.times do |n|
79
+ dumps[n] = Archipelago::Dump::Site.new(:officer => cleaner2,
80
+ :service_description => {:service_id => n.to_s},
81
+ :persistence_directory => Pathname.new(__FILE__).parent.join("master_test_#{n}.db"))
82
+ dumps[n].publish!
83
+ end
84
+ #
85
+ # Wait until it is alive
86
+ #
87
+ assert_within(30) do
88
+ cleaner2.update_services!
89
+ dumps.collect do |d| d.service_id end.sort == cleaner2.sites.keys.sort
90
+ end
91
+ #
92
+ # Perform checks on all dumps
93
+ #
94
+ 10.times do |n|
95
+ if n < 9
96
+ assert(dumps[n].instance_eval do right_before?(dumps[n+1].service_id) end,
97
+ "#{dumps[n].service_id} is supposed to be right_before? #{dumps[n+1].service_id}, but isnt. services are #{cleaner2.sites.keys.inspect}")
98
+ assert(dumps[n+1].instance_eval do right_after?(dumps[n].service_id) end,
99
+ "#{dumps[n+1].service_id} is supposed to be right_after? #{dumps[n].service_id}, but isnt. services are #{cleaner2.sites.keys.inspect}")
100
+ else
101
+ assert(dumps[n].instance_eval do right_before?(dumps[0].service_id) end,
102
+ "#{dumps[n].service_id} is supposed to be right_before? #{dumps[0].service_id}, but isnt. services are #{cleaner2.sites.keys.inspect}")
103
+ assert(dumps[0].instance_eval do right_after?(dumps[n].service_id) end,
104
+ "#{dumps[0].service_id} is supposed to be right_after? #{dumps[n].service_id}, but isnt. services are #{cleaner2.sites.keys.inspect}")
105
+ end
106
+ if n > 0
107
+ assert_equal(dumps[n - 1].service_id, cleaner2.predecessor(dumps[n].service_id))
108
+ else
109
+ assert_equal(dumps[9].service_id, cleaner2.predecessor(dumps[0].service_id))
110
+ end
111
+ end
112
+ #
113
+ # Check that only fresh data is returned
114
+ #
115
+ s1 = Oneliner::SuperString.new("brappa")
116
+ s2 = Oneliner::SuperString.new("brappa2")
117
+ assert_equal(0, dumps[0].db.size)
118
+ assert_equal(0, dumps[0].db.size)
119
+ dumps[0].insert!("a", [s1.encode(20)], "aaaa")
120
+ dumps[1].insert!("a", [s2.encode(200)], "aaab")
121
+ assert(cleaner2.responsible_sites("a").include?(dumps[0].service_id))
122
+ assert(cleaner2.responsible_sites("a").include?(dumps[1].service_id))
123
+ assert_equal(s2.to_s, cleaner2["a"])
124
+ #
125
+ # Check the utility methods of sanitation
126
+ #
127
+ assert_equal([dumps[9].service_id, dumps[0].service_id, dumps[1].service_id].sort,
128
+ cleaner2.instance_eval do
129
+ get_greatest_less_than(:sites, dumps[2].service_id, 3)
130
+ end.collect do |d| d[:service_id] end.sort)
131
+ assert_equal([dumps[8].service_id, dumps[9].service_id, dumps[0].service_id].sort,
132
+ cleaner2.instance_eval do
133
+ get_least_greater_than(:sites, dumps[7].service_id, 3)
134
+ end.collect do |d| d[:service_id] end.sort)
135
+ assert_equal(dumps[3].service_id,
136
+ cleaner2.second_master_to(dumps[4].service_id))
137
+ assert_equal(dumps[9].service_id,
138
+ cleaner2.second_master_to(dumps[0].service_id))
139
+ #
140
+ # Check the recovery methods
141
+ #
142
+ assert_equal({
143
+ "6"=>0,
144
+ "7"=>0,
145
+ "8"=>0,
146
+ "9"=>0,
147
+ "0"=>1,
148
+ "1"=>1,
149
+ "2"=>0,
150
+ "3"=>0,
151
+ "4"=>0,
152
+ "5"=>0
153
+ },
154
+ chunks_by_id(cleaner2, "a"))
155
+ cleaner2.redistribute("a")
156
+ healthy_chunks = {
157
+ "6"=>0,
158
+ "7"=>0,
159
+ "8"=>0,
160
+ "9"=>0,
161
+ "0"=>1,
162
+ "1"=>1,
163
+ "2"=>1,
164
+ "3"=>0,
165
+ "4"=>0,
166
+ "5"=>0
167
+ }
168
+ assert_equal(healthy_chunks,
169
+ chunks_by_id(cleaner2, "a"))
170
+ dumps[1].close!
171
+ cleaner2.update_services!(:validate => true)
172
+ dumps[0].instance_eval do lost_peer({:service_id => dumps[1].service_id}) end
173
+ dumps[2].instance_eval do lost_peer({:service_id => dumps[1].service_id}) end
174
+ assert_equal({"6"=>0, "7"=>0, "8"=>0, "9"=>0, "0"=>1, "2"=>1, "3"=>1, "4"=>0, "5"=>0},
175
+ chunks_by_id(cleaner2, "a"))
176
+
177
+ dumps[1] = Archipelago::Dump::Site.new(:officer => cleaner2,
178
+ :service_description => {:service_id => "1"},
179
+ :persistence_directory => Pathname.new(__FILE__).parent.join("master_test_1.db"))
180
+ dumps[1].publish!
181
+ begin
182
+ assert_within(20) do
183
+ cleaner2.update_services!
184
+ ["0","1","2","3","4","5","6","7","8","9"].sort == cleaner2.sites.keys.sort
185
+ end
186
+ rescue Test::Unit::AssertionFailedError => e
187
+ pp chunks_by_id(cleaner2, "a")
188
+ raise e
189
+ end
190
+ assert_equal({"0"=>1, "1"=>1, "2"=>1},
191
+ cleaner2.responsible_sites("a"))
192
+ dumps[3].instance_eval do @edge_check_thread.wakeup end
193
+ cleaner2.update_services!(:validate => true)
194
+ begin
195
+ assert_within(20) do
196
+ chunks_by_id(cleaner2, "a") == healthy_chunks
197
+ end
198
+ rescue Test::Unit::AssertionFailedError => e
199
+ pp chunks_by_id(cleaner2, "a")
200
+ raise e
201
+ end
202
+ ensure
203
+ dumps.extend(Archipelago::Current::ThreadedCollection)
204
+ dumps.t_each do |dump|
205
+ dump.close!
206
+ dump.instance_eval do @persistence_provider.unlink! end
207
+ end
208
+ end
209
+ end
210
+
211
+ private
212
+
213
+ def chunks_by_id(officer, key)
214
+ officer.sites.values.inject({}) do |result, service_desc|
215
+ result.merge({service_desc[:service_id] => service_desc[:service].fetch(key).size})
216
+ end
217
+ end
218
+
219
+ end