roma 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/LICENSE.rdoc +675 -0
  2. data/README.rdoc +0 -0
  3. data/Rakefile +70 -0
  4. data/bin/mkrecent +7 -0
  5. data/bin/mkroute +7 -0
  6. data/bin/recoverlost +8 -0
  7. data/bin/recoverlost_alist +8 -0
  8. data/bin/romad +7 -0
  9. data/bin/sample_watcher +8 -0
  10. data/bin/sample_watcher2 +8 -0
  11. data/bin/simple_bench +8 -0
  12. data/bin/ssroute +7 -0
  13. data/bin/tribunus +7 -0
  14. data/lib/roma/async_process.rb +696 -0
  15. data/lib/roma/command/bg_command_receiver.rb +188 -0
  16. data/lib/roma/command/mh_command_receiver.rb +117 -0
  17. data/lib/roma/command/receiver.rb +287 -0
  18. data/lib/roma/command/rt_command_receiver.rb +147 -0
  19. data/lib/roma/command/st_command_receiver.rb +564 -0
  20. data/lib/roma/command/util_command_receiver.rb +67 -0
  21. data/lib/roma/command/vn_command_receiver.rb +143 -0
  22. data/lib/roma/command_plugin.rb +11 -0
  23. data/lib/roma/config.rb +64 -0
  24. data/lib/roma/event/con_pool.rb +140 -0
  25. data/lib/roma/event/handler.rb +159 -0
  26. data/lib/roma/plugin/plugin_alist.rb +1572 -0
  27. data/lib/roma/plugin/plugin_debug.rb +19 -0
  28. data/lib/roma/plugin/plugin_test.rb +14 -0
  29. data/lib/roma/romad.rb +582 -0
  30. data/lib/roma/routing/cb_rttable.rb +326 -0
  31. data/lib/roma/routing/merkle_tree.rb +54 -0
  32. data/lib/roma/routing/rttable.rb +148 -0
  33. data/lib/roma/stats.rb +112 -0
  34. data/lib/roma/storage/basic_storage.rb +510 -0
  35. data/lib/roma/storage/dbm_storage.rb +80 -0
  36. data/lib/roma/storage/dummy_storage.rb +44 -0
  37. data/lib/roma/storage/rh_storage.rb +35 -0
  38. data/lib/roma/storage/sqlite3_storage.rb +73 -0
  39. data/lib/roma/storage/tc_storage.rb +133 -0
  40. data/lib/roma/tools/mkrecent.rb +138 -0
  41. data/lib/roma/tools/mkroute.rb +52 -0
  42. data/lib/roma/tools/recoverlost.rb +9 -0
  43. data/lib/roma/tools/recoverlost_alist.rb +9 -0
  44. data/lib/roma/tools/recoverlost_lib.rb +217 -0
  45. data/lib/roma/tools/sample_watcher.rb +38 -0
  46. data/lib/roma/tools/sample_watcher2.rb +38 -0
  47. data/lib/roma/tools/simple_bench.rb +57 -0
  48. data/lib/roma/tools/ssroute.rb +23 -0
  49. data/lib/roma/tools/tribunus.rb +299 -0
  50. data/lib/roma/version.rb +4 -0
  51. data/lib/roma/write_behind.rb +179 -0
  52. data/test/rcirb.rb +16 -0
  53. data/test/roma-test-utils.rb +65 -0
  54. data/test/run-test.rb +16 -0
  55. data/test/t_cpdata.rb +277 -0
  56. data/test/t_listplugin.rb +592 -0
  57. data/test/t_rclient.rb +318 -0
  58. data/test/t_routing_data.rb +100 -0
  59. data/test/t_storage.rb +644 -0
  60. data/test/t_writebehind.rb +200 -0
  61. metadata +134 -0
data/test/t_rclient.rb ADDED
@@ -0,0 +1,318 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'roma/client/rclient'
5
+
6
+ Roma::Client::RomaClient.class_eval{
7
+ def init_sync_routing_proc
8
+ end
9
+ }
10
+
11
+ class RClientTest < Test::Unit::TestCase
12
+ include RomaTestUtils
13
+
14
+ def setup
15
+ start_roma
16
+ @rc=Roma::Client::RomaClient.new(["localhost_11211","localhost_11212"])
17
+ end
18
+
19
+ def teardown
20
+ stop_roma
21
+ Roma::Messaging::ConPool::instance.close_all
22
+ end
23
+
24
+ def test_set_get_delete
25
+ @rc.delete("abc")
26
+ assert_nil( @rc.get("abc") )
27
+ assert_equal("STORED", @rc.set("abc","value abc"))
28
+ assert_equal("value abc", @rc.get("abc"))
29
+ assert_equal("STORED", @rc.set("abc","value abc")) # 上書きは成功する
30
+ assert_equal("DELETED", @rc.delete("abc"))
31
+ assert_nil( @rc.get("abc"))
32
+ assert_equal("NOT_FOUND", @rc.delete("abc"))
33
+ end
34
+
35
+ def test_set_get
36
+ 10.times{|i|
37
+ s = i.to_s * 1024000
38
+ assert_equal("STORED", @rc.set("abc", s))
39
+ assert(s == @rc.get("abc"))
40
+ }
41
+ end
42
+
43
+ def test_set_gets
44
+ keys = []
45
+ assert_equal(@rc.gets(["key-1","key-2"]).length,0)
46
+ 10.times{|i|
47
+ assert_equal("STORED", @rc.set("key-#{i}", "value-#{i}"))
48
+ keys << "key-#{i}"
49
+ }
50
+ ret = @rc.gets(keys)
51
+ assert_equal(ret.length,10)
52
+ ret.each_pair{|k,v|
53
+ assert_equal(k[-1],v[-1])
54
+ assert_equal(k[0..3],"key-")
55
+ assert_equal(v[0..5],"value-")
56
+ }
57
+ keys << "key-99"
58
+ ret = @rc.gets(keys)
59
+ assert_equal(ret.length,10)
60
+
61
+ assert_equal("DELETED", @rc.delete("key-5"))
62
+ ret = @rc.gets(keys)
63
+ assert_equal(ret.length,9)
64
+ end
65
+
66
+ def test_out
67
+ # 本当に消す
68
+ @rc.out("key-out")
69
+ # 本当にない場合は NOT_DELETED
70
+ assert_equal("NOT_DELETED", @rc.out("key-out"))
71
+ assert_equal("STORED", @rc.set("key-out","value out"))
72
+ assert_equal("DELETED", @rc.out("key-out"))
73
+ assert_equal("STORED", @rc.set("key-out","value out"))
74
+ # 削除マークをつける
75
+ assert_equal("DELETED", @rc.delete("key-out"))
76
+ # delete してもマークを消すので DELETED
77
+ assert_equal("DELETED", @rc.out("key-out"))
78
+ end
79
+
80
+ def test_add
81
+ assert_nil( @rc.get("add") )
82
+ assert_equal("STORED", @rc.add("add","value add"))
83
+ assert_equal("NOT_STORED", @rc.add("add","value add")) # 上書きは失敗する
84
+ assert_equal("DELETED", @rc.delete("add"))
85
+ assert_equal("STORED", @rc.add("add","value add")) # delete 後の add の成功を確認
86
+ assert_equal("DELETED", @rc.delete("add"))
87
+ end
88
+
89
+ def test_replace
90
+ assert_nil( @rc.get("replace") )
91
+ assert_equal("NOT_STORED", @rc.replace("replace","value replace"))
92
+ assert_nil( @rc.get("replace") )
93
+ assert_equal("STORED", @rc.add("replace","value add"))
94
+ assert_equal("STORED", @rc.replace("replace","value replace"))
95
+ assert_equal("DELETED", @rc.delete("replace"))
96
+ end
97
+
98
+ def test_append
99
+ assert_nil( @rc.get("append") )
100
+ assert_equal("NOT_STORED", @rc.append("append","append"))
101
+ assert_equal("STORED", @rc.set("append","set"))
102
+ assert_equal("set", @rc.get("append"))
103
+ assert_equal("STORED", @rc.append("append","append"))
104
+ assert_equal("setappend", @rc.get("append"))
105
+ assert_equal("DELETED", @rc.delete("append"))
106
+ end
107
+
108
+ def test_prepend
109
+ assert_nil( @rc.get("prepend"))
110
+ assert_equal("NOT_STORED", @rc.prepend("prepend","prepend"))
111
+ assert_equal("STORED", @rc.set("prepend","set"))
112
+ assert_equal("set", @rc.get("prepend"))
113
+ assert_equal("STORED", @rc.prepend("prepend","prepend"))
114
+ assert_equal("prependset", @rc.get("prepend"))
115
+ assert_equal("DELETED", @rc.delete("prepend"))
116
+ end
117
+
118
+ def test_incr
119
+ assert_nil( @rc.get("incr"))
120
+ assert_equal("NOT_FOUND", @rc.incr("incr"))
121
+ assert_equal("STORED", @rc.set("incr","100"))
122
+ assert_equal(101, @rc.incr("incr"))
123
+ assert_equal(102, @rc.incr("incr"))
124
+ assert_equal("DELETED", @rc.delete("incr"))
125
+ end
126
+
127
+ def test_decr
128
+ assert_nil( @rc.get("decr") )
129
+ assert_equal("NOT_FOUND", @rc.decr("decr"))
130
+ assert_equal("STORED", @rc.set("decr","100"))
131
+ assert_equal(99, @rc.decr("decr"))
132
+ assert_equal(98, @rc.decr("decr"))
133
+ assert_equal("DELETED", @rc.delete("decr"))
134
+ end
135
+
136
+ def test_createhash
137
+ con = Roma::Messaging::ConPool.instance.get_connection("localhost_11211")
138
+ con.write("hashlist\r\n")
139
+ ret = con.gets
140
+ assert_equal("roma", ret.chomp )
141
+
142
+ con.write("createhash test\r\n")
143
+ ret = con.gets
144
+ assert_equal("{\"localhost_11212\"=>\"CREATED\", \"localhost_11211\"=>\"CREATED\"}", ret.chomp )
145
+
146
+ con.write("hashlist\r\n")
147
+ ret = con.gets
148
+ assert_equal("roma test", ret.chomp )
149
+
150
+ assert_equal("STORED", @rc.set("roma","hname=roma"))
151
+ assert_equal("hname=roma", @rc.get("roma"))
152
+ @rc.default_hash_name='test'
153
+ assert_nil( @rc.get("roma") )
154
+ assert_equal("STORED", @rc.set("roma","hname=test"))
155
+ assert_equal("hname=test", @rc.get("roma"))
156
+ @rc.default_hash_name='roma'
157
+ assert_equal("hname=roma", @rc.get("roma"))
158
+ assert_equal("DELETED", @rc.delete("roma"))
159
+
160
+ @rc.default_hash_name='not_exist_hash' # 存在しないハッシュへのアクセス
161
+ begin
162
+ @rc.get("roma")
163
+ assert(false)
164
+ rescue =>e
165
+ assert_equal('SERVER_ERROR not_exist_hash dose not exists.',e.message)
166
+ end
167
+
168
+ begin
169
+ @rc.set("roma","hname=roma")
170
+ assert(false)
171
+ rescue =>e
172
+ assert_equal('SERVER_ERROR not_exist_hash dose not exists.',e.message)
173
+ end
174
+
175
+ begin
176
+ @rc.delete("roma")
177
+ assert(false)
178
+ rescue =>e
179
+ assert_equal('SERVER_ERROR not_exist_hash dose not exists.',e.message)
180
+ end
181
+
182
+ begin
183
+ @rc.add("add","value add")
184
+ assert(false)
185
+ rescue =>e
186
+ assert_equal('SERVER_ERROR not_exist_hash dose not exists.',e.message)
187
+ end
188
+
189
+ begin
190
+ @rc.replace("replace","value replace")
191
+ assert(false)
192
+ rescue =>e
193
+ assert_equal('SERVER_ERROR not_exist_hash dose not exists.',e.message)
194
+ end
195
+
196
+ begin
197
+ @rc.append("append","append")
198
+ assert(false)
199
+ rescue =>e
200
+ assert_equal('SERVER_ERROR not_exist_hash dose not exists.', e.message)
201
+ end
202
+
203
+ begin
204
+ @rc.prepend("prepend","prepend")
205
+ assert(false)
206
+ rescue =>e
207
+ assert_equal('SERVER_ERROR not_exist_hash dose not exists.',e.message)
208
+ end
209
+
210
+ begin
211
+ @rc.incr("incr")
212
+ assert(false)
213
+ rescue =>e
214
+ assert_equal('SERVER_ERROR not_exist_hash dose not exists.',e.message)
215
+ end
216
+
217
+ begin
218
+ @rc.decr("decr")
219
+ assert(false)
220
+ rescue =>e
221
+ assert_equal('SERVER_ERROR not_exist_hash dose not exists.',e.message)
222
+ end
223
+
224
+ con.write("deletehash test\r\n")
225
+ ret = con.gets
226
+ assert_equal( "{\"localhost_11212\"=>\"DELETED\", \"localhost_11211\"=>\"DELETED\"}", ret.chomp )
227
+
228
+ con.close
229
+ end
230
+
231
+ def test_createhash2
232
+ # test ハッシュを追加し終了する
233
+ con = Roma::Messaging::ConPool.instance.get_connection("localhost_11211")
234
+ con.write("hashlist\r\n")
235
+ ret = con.gets
236
+ assert_equal("roma", ret.chomp)
237
+
238
+ con.write("createhash test\r\n")
239
+ ret = con.gets
240
+ assert_equal("{\"localhost_11212\"=>\"CREATED\", \"localhost_11211\"=>\"CREATED\"}", ret.chomp )
241
+
242
+ assert_equal("STORED", @rc.set("roma","hname=roma"))
243
+ assert_equal("hname=roma", @rc.get("roma"))
244
+ @rc.default_hash_name='test'
245
+ assert_equal("STORED", @rc.set("roma","hname=test"))
246
+ assert_equal("hname=test", @rc.get("roma"))
247
+ con.write("balse\r\n")
248
+ con.gets
249
+ con.write "yes\r\n"
250
+ ret = con.gets
251
+ con.close
252
+
253
+
254
+ # 再起動
255
+ ruby_path = File.join(RbConfig::CONFIG["bindir"],
256
+ RbConfig::CONFIG["ruby_install_name"])
257
+ path = File.dirname(File.expand_path($PROGRAM_NAME))
258
+ sh = Shell.new
259
+ sh.system(ruby_path,"#{path}/../bin/romad","localhost","-p","11211","-d","--verbose")
260
+ sh.system(ruby_path,"#{path}/../bin/romad","localhost","-p","11212","-d","--verbose")
261
+ sleep 2
262
+ Roma::Messaging::ConPool.instance.close_all
263
+
264
+ @rc=Roma::Client::RomaClient.new(["localhost_11211","localhost_11212"])
265
+ @rc.default_hash_name='test'
266
+ con = Roma::Messaging::ConPool.instance.get_connection("localhost_11211")
267
+ con.write("hashlist\r\n")
268
+ ret = con.gets
269
+
270
+ #
271
+ # for file storage
272
+ #
273
+
274
+ # 停止前のデータが残っていることを確認
275
+ #assert_equal("hname=test", @rc.get("roma"))
276
+
277
+ # test ハッシュを削除
278
+ #con.write("deletehash test\r\n")
279
+ #ret = con.gets
280
+ #assert_equal("{\"localhost_11212\"=>\"DELETED\", \"localhost_11211\"=>\"DELETED\"}", ret.chomp )
281
+
282
+ # デフォルトハッシュに残ったテストデータを削除
283
+ #@rc.default_hash_name='roma'
284
+ #assert_equal('DELETED', @rc.delete("roma"))
285
+
286
+ end
287
+
288
+ def test_createhash3
289
+ con = Roma::Messaging::ConPool.instance.get_connection("localhost_11211")
290
+
291
+ # 存在しないハッシュを削除
292
+ con.write("deletehash test\r\n")
293
+ ret = con.gets
294
+ assert_equal("{\"localhost_11212\"=>\"SERVER_ERROR test dose not exists.\", \"localhost_11211\"=>\"SERVER_ERROR test dose not exists.\"}", ret.chomp )
295
+
296
+ # デフォルトハッシュを削除
297
+ con.write("deletehash roma\r\n")
298
+ ret = con.gets
299
+ assert_equal("{\"localhost_11212\"=>\"SERVER_ERROR the hash name of 'roma' can't delete.\", \"localhost_11211\"=>\"SERVER_ERROR the hash name of 'roma' can't delete.\"}", ret.chomp )
300
+ end
301
+ end
302
+
303
+ class RClientTestForceForward < RClientTest
304
+ def setup
305
+ super
306
+ @rc.rttable.instance_eval{
307
+ undef search_node
308
+
309
+ def search_node(key); search_node2(key); end
310
+
311
+ def search_node2(key)
312
+ d = Digest::SHA1.hexdigest(key).hex % @hbits
313
+ @rd.v_idx[d & @search_mask][1]
314
+ end
315
+ }
316
+ end
317
+
318
+ end
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require 'roma/routing/routing_data'
5
+ require 'yaml'
6
+
7
+ class RoutingDataTest < Test::Unit::TestCase
8
+ def setup
9
+ end
10
+
11
+ def teardown
12
+ end
13
+
14
+ def cnt_obj
15
+ GC.start
16
+ n=0
17
+ ObjectSpace.each_object{|o| n+=1 }
18
+ n
19
+ end
20
+
21
+ def test_object_count
22
+ c1=cnt_obj
23
+ rd=Roma::Routing::RoutingData.create(32,9,2,['roma0_11211','roma0_11212'])
24
+ c2=cnt_obj
25
+ puts
26
+ puts "RoutingData.create #{c2-c1} objects"
27
+ c1=c2
28
+ rd.save("routing_data.test.route")
29
+ rd2=Roma::Routing::RoutingData.load("routing_data.test.route")
30
+ c2=cnt_obj
31
+ puts "RoutingData.load #{c2-c1} objects"
32
+ File::unlink("routing_data.test.route")
33
+ end
34
+
35
+ def test_save_load
36
+ rd=Roma::Routing::RoutingData.create(32,8,1,['roma0_3300'])
37
+ rd.save("routing_data.test.route")
38
+ rd2=Roma::Routing::RoutingData.load("routing_data.test.route")
39
+ assert( YAML.dump(rd) == YAML.dump(rd2) )
40
+ File::unlink("routing_data.test.route")
41
+ end
42
+
43
+ def test_next_vnode
44
+ rd=Roma::Routing::RoutingData.create(32,8,1,['roma0_3300'])
45
+ assert( 0x01000000 == rd.next_vnode(0x00000000) )
46
+ assert( 0x00000000 == rd.next_vnode(0xff000000) )
47
+ assert( 0x56000000 == rd.next_vnode(0x55000000) )
48
+ end
49
+
50
+ def test_create_nodes_from_v_idx
51
+ rd=Roma::Routing::RoutingData.create(32,8,1,['roma0','roma1','roma2'])
52
+ rd.nodes.clear
53
+ rd.create_nodes_from_v_idx
54
+ assert( rd.nodes == ['roma0','roma1','roma2'] )
55
+ end
56
+
57
+ def test_create
58
+ # ダイジェストの総ビット数 32
59
+ # バーチャルノードのビット数 8
60
+ # 冗長度 1
61
+ # ノードIDの配列 [roma0_3300]
62
+ rd=Roma::Routing::RoutingData.create(32,8,1,['roma0_3300'])
63
+
64
+ assert( rd.v_idx.length==256 )
65
+ assert( rd.nodes.length==1 )
66
+ assert( rd.search_mask==0xff000000 )
67
+ assert( rd.dgst_bits==32 )
68
+ assert( rd.div_bits==8 )
69
+ assert( rd.rn==1 )
70
+
71
+ # ダイジェストの総ビット数 32
72
+ # バーチャルノードのビット数 16
73
+ # 冗長度 2
74
+ # ノードIDの配列 ['roma0_3300','roma1_3300','roma2_3300']
75
+ rd=Roma::Routing::RoutingData.create(32,16,2,['roma0_3300','roma1_3300','roma2_3300'])
76
+
77
+ assert( rd.v_idx.length==65536 )
78
+ assert( rd.nodes.length==3 )
79
+ assert( rd.search_mask==0xffff0000 )
80
+ assert( rd.dgst_bits==32 )
81
+ assert( rd.div_bits==16 )
82
+ assert( rd.rn==2 )
83
+
84
+ c0=c1=c2=0
85
+ rd.v_idx.each_value{|v|
86
+ case v[0]
87
+ when 'roma0_3300'
88
+ c0+=1
89
+ when 'roma1_3300'
90
+ c1+=1
91
+ when 'roma2_3300'
92
+ c2+=1
93
+ end
94
+ }
95
+ # バラつきは10%より小さいでしょ
96
+ assert( (c0-c1).abs < rd.v_idx.length/10 )
97
+ assert( (c1-c2).abs < rd.v_idx.length/10 )
98
+ end
99
+
100
+ end