roma 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +44 -1
  3. data/Gemfile.lock +18 -15
  4. data/README.md +15 -1
  5. data/bin/consistency_test +10 -0
  6. data/bin/data_accumulation +11 -0
  7. data/lib/roma/async_process.rb +39 -2
  8. data/lib/roma/command/sys_command_receiver.rb +80 -0
  9. data/lib/roma/command/vn_command_receiver.rb +1 -1
  10. data/lib/roma/config.rb +1 -1
  11. data/lib/roma/plugin/plugin_storage.rb +105 -1
  12. data/lib/roma/romad.rb +13 -1
  13. data/lib/roma/routing/cb_rttable.rb +1 -1
  14. data/lib/roma/tools/consistency_test.rb +77 -0
  15. data/lib/roma/tools/data_accumulation.rb +64 -0
  16. data/lib/roma/version.rb +1 -1
  17. data/lib/roma/write_behind.rb +138 -1
  18. data/test/config4mhash.rb +1 -1
  19. data/test/config4storage_error.rb +1 -1
  20. data/test/config4test.rb +1 -1
  21. data/test/cpdbtest/config4cpdb_base.rb +1 -1
  22. data/test/optional_test/t_mkroute_rich.rb +44 -0
  23. data/test/optional_test/t_other_cpdb.rb +45 -0
  24. data/test/optional_test/t_other_database.rb +59 -0
  25. data/test/{t_routing_logic.rb → optional_test/t_routing_logic.rb} +1 -0
  26. data/test/roma-test-storage.rb +685 -0
  27. data/test/roma-test-utils.rb +24 -0
  28. data/test/run-test.rb +9 -0
  29. data/test/t_command_definition.rb +2 -0
  30. data/test/t_cpdata.rb +1 -0
  31. data/test/t_cpdb.rb +22 -34
  32. data/test/t_eventmachine.rb +1 -0
  33. data/test/t_listplugin.rb +2 -0
  34. data/test/t_logshift.rb +2 -4
  35. data/test/t_mapcountplugin.rb +48 -37
  36. data/test/t_mapplugin.rb +2 -0
  37. data/test/t_mhash.rb +2 -1
  38. data/test/t_new_func.rb +386 -0
  39. data/test/t_protocol.rb +66 -1
  40. data/test/t_rclient.rb +2 -0
  41. data/test/t_replication.rb +299 -0
  42. data/test/t_routing_data.rb +6 -5
  43. data/test/t_storage.rb +5 -740
  44. data/test/t_storage_error.rb +1 -0
  45. data/test/t_writebehind.rb +11 -2
  46. metadata +31 -19
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+ require 'roma/client/rclient'
3
+ require 'roma/messaging/con_pool'
4
+ require 'roma/config'
5
+ require 'pathname'
6
+
7
+ class CpdbBaseTest < Test::Unit::TestCase
8
+ self.test_order = :defined
9
+ include RomaTestUtils
10
+
11
+ def teardown
12
+ stop_roma
13
+ rescue => e
14
+ puts "#{e} #{$@}"
15
+ end
16
+
17
+ end
18
+
19
+ # Dbm Storage Test
20
+ class DbmTest < CpdbBaseTest
21
+ def setup
22
+ start_roma 'cpdbtest/config4cpdb_dbm.rb'
23
+ @rc=Roma::Client::RomaClient.new(["localhost_11211","localhost_11212"])
24
+ @sock = TCPSocket.new("localhost", 11211)
25
+ end
26
+ def test_st_class_dbm
27
+ @sock.write("stat st_class\r\n")
28
+ assert_equal('storages[roma].storage.st_class DbmStorage', @sock.gets.chomp)
29
+ assert_equal('END', @sock.gets.chomp)
30
+ end
31
+ end
32
+
33
+ # Sqlite3 Storage Test
34
+ class Sqlite3Test < CpdbBaseTest
35
+ def setup
36
+ start_roma 'cpdbtest/config4cpdb_sqlite3.rb'
37
+ @rc=Roma::Client::RomaClient.new(["localhost_11211","localhost_11212"])
38
+ @sock = TCPSocket.new("localhost", 11211)
39
+ end
40
+ def test_st_class_sqlite3
41
+ @sock.write("stat st_class\r\n")
42
+ assert_equal('storages[roma].storage.st_class SQLite3Storage', @sock.gets.chomp)
43
+ assert_equal('END', @sock.gets.chomp)
44
+ end
45
+ end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../roma-test-storage'
4
+ require 'roma/storage/dbm_storage'
5
+ require 'roma/storage/sqlite3_storage'
6
+
7
+ class DbmStorageTest < Test::Unit::TestCase
8
+ include StorageTests
9
+
10
+ def setup
11
+ rmtestdir('storage_test')
12
+ @st=Roma::Storage::DbmStorage.new
13
+ @st.vn_list = [0,1,2,3,4,5,6,7,8,9]
14
+ @st.storage_path = 'storage_test'
15
+ @st.opendb
16
+ end
17
+
18
+ def test_close_after_each_clean_up
19
+ h={}
20
+ 1000.times{|i|
21
+ h[i.to_s]=[i%10,Time.now.to_i,0,Time.now.to_i].pack('NNNN')+'old data'
22
+ }
23
+ dmp=Marshal.dump(h)
24
+ @st.load(dmp)
25
+
26
+ assert_raise RuntimeError do
27
+ @st.each_clean_up(Time.now.to_i-100, Hash.new(:primary) ){|k,vn|
28
+ @st.closedb
29
+ }
30
+ end
31
+ end
32
+ end
33
+
34
+ class SQLite3StorageTest < Test::Unit::TestCase
35
+ include StorageTests
36
+
37
+ def setup
38
+ rmtestdir('storage_test')
39
+ @st=Roma::Storage::SQLite3Storage.new
40
+ @st.vn_list = [0,1,2,3,4,5,6,7,8,9]
41
+ @st.storage_path = 'storage_test'
42
+ @st.opendb
43
+ end
44
+
45
+ def test_close_after_each_clean_up
46
+ h={}
47
+ 1000.times{|i|
48
+ h[i.to_s]=[i%10,Time.now.to_i,0,Time.now.to_i].pack('NNNN')+'old data'
49
+ }
50
+ dmp=Marshal.dump(h)
51
+ @st.load(dmp)
52
+
53
+ assert_raise SQLite3::BusyException do
54
+ @st.each_clean_up(Time.now.to_i-100, Hash.new(:primary) ){|k,vn|
55
+ @st.closedb
56
+ }
57
+ end
58
+ end
59
+ end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  class RoutingLogicTest < Test::Unit::TestCase
4
+ self.test_order = :defined
4
5
  include RomaTestUtils
5
6
 
6
7
  NEW_PORTS = %w(11213 11214)
@@ -0,0 +1,685 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ module StorageTests
4
+ def ndat
5
+ 1000
6
+ end
7
+
8
+ def rmtestdir(dirname)
9
+ if File::directory?(dirname)
10
+ File.delete(*Dir["#{dirname}/*"])
11
+ Dir.rmdir(dirname)
12
+ end
13
+ end
14
+
15
+ def test_set_get
16
+ assert_equal( 'abc_data',@st.set(0,'abc',0,0xffffffff,'abc_data')[4])
17
+ assert_equal( 'abc_data', @st.get(0,'abc',0) )
18
+ end
19
+
20
+ def test_set_delete
21
+ @st.set(0,'abc',0,0xffffffff,'abc_data')
22
+ # delete method returns a value
23
+ assert_equal( 'abc_data', @st.delete(0,'abc',0)[4])
24
+ assert_nil( @st.get(0,'abc',0) )
25
+ # delete method returns :deletemark with deleted key
26
+ assert_equal(:deletemark, @st.delete(0,'abc',0))
27
+ end
28
+
29
+ def test_set_exptime
30
+ @st.set(0,'abc',0,Time.now.to_i,'abc_data')
31
+ # returns a value within a fixed time limit
32
+ assert_equal('abc_data', @st.get(0,'abc',0) )
33
+ # expire time is a second ago
34
+ @st.set(0,'abc',0,Time.now.to_i-1,'abc_data')
35
+ # returns a nil when expired
36
+ assert_nil( @st.get(0,'abc',0))
37
+ end
38
+
39
+ def test_set_get_raw
40
+ n = 100
41
+ n.times{|i|
42
+ assert_equal('abc_data',@st.set(0,'abc',0,0xffffffff,'abc_data')[4])
43
+ vn, t, clk, expt, val = @st.get_raw(0,'abc',0)
44
+ assert_equal(vn,0)
45
+ assert(Time.now.to_i - t <= 1)
46
+ assert_equal(clk,i)
47
+ assert_equal(expt,0xffffffff)
48
+ assert_equal(val,'abc_data')
49
+ }
50
+ end
51
+
52
+ def test_exp_delete
53
+ assert_nil( @st.delete(0,'abc',0)[4])
54
+ # expire time is a second ago
55
+ assert_equal('abc_data' , @st.set(0,'abc',0,Time.now.to_i-1,'abc_data')[4])
56
+ # delete method returns a nil in expired
57
+ assert_nil( @st.delete(0,'abc',0)[4])
58
+ end
59
+
60
+ def test_rset
61
+ # increase a logical clock
62
+ assert_equal(0, @st.set(0,'abc',0,Time.now.to_i,'abc_data')[2] )
63
+ assert_equal(1, @st.set(0,'abc',0,Time.now.to_i,'abc_data')[2] )
64
+ assert_equal(2, @st.set(0,'abc',0,Time.now.to_i,'abc_data')[2] )
65
+ # rset method returns a inputed clock value
66
+ assert_equal(4, @st.rset(0,'abc',0,4,Time.now.to_i,'new_data')[2] )
67
+ # but if input clock value is old then not store the data
68
+ assert_nil( @st.rset(0,'abc',0,4,Time.now.to_i,'new_data') )
69
+ assert_nil( @st.rset(0,'abc',0,3,Time.now.to_i,'new_data') )
70
+ end
71
+
72
+ def test_rdelete
73
+ # save a clock value in the deletemark
74
+ assert_equal(2, @st.rdelete(0,'abc',0,2)[2] )
75
+ # reject a old clock value in rset method
76
+ assert_nil( @st.rset(0,'abc',0,1,Time.now.to_i,'new_data'))
77
+ assert_nil( @st.rset(0,'abc',0,2,Time.now.to_i,'new_data'))
78
+ # also reject a old clock value in rdelete method
79
+ assert_nil( @st.rdelete(0,'abc',0,1) )
80
+ assert_nil( @st.rdelete(0,'abc',0,2) )
81
+ # but input the new clock to allow
82
+ assert_equal( 3, @st.rdelete(0,'abc',0,3)[2] )
83
+ end
84
+
85
+ def test_out
86
+ assert( !@st.out(0,'abc',0) )
87
+ @st.set(0,'abc',0,Time.now.to_i,'abc_data')
88
+ assert( @st.out(0,'abc',0) )
89
+ end
90
+
91
+ # on boundary of a clock
92
+ def test_clock_count
93
+ assert_equal( 0xfffffffe, @st.rset(0,'set',0,0xfffffffe,Time.now.to_i,'new_data')[2])
94
+ assert_equal(0xffffffff, @st.set(0,'set',0,Time.now.to_i,'abc_data')[2])
95
+ assert_equal(0, @st.set(0,'set',0,Time.now.to_i,'abc_data')[2] )
96
+
97
+ assert_equal(0xffffffff,@st.rdelete(0,'add',0,0xffffffff)[2])
98
+ assert_equal(0, @st.add(0,'add',0,Time.now.to_i,'abc_data')[2] )
99
+
100
+ assert_equal(0xffffffff, @st.rset(0,'replace',0,0xffffffff,Time.now.to_i,'abc_data')[2])
101
+ assert_equal(0, @st.replace(0,'replace',0,Time.now.to_i,'abc_data')[2] )
102
+
103
+ assert_equal(0xffffffff, @st.rset(0,'append',0,0xffffffff,Time.now.to_i,'abc_data')[2])
104
+ assert_equal(0, @st.append(0,'append',0,Time.now.to_i,'abc_data')[2] )
105
+
106
+ assert_equal(0xffffffff, @st.rset(0,'prepend',0,0xffffffff,Time.now.to_i,'abc_data')[2])
107
+ assert_equal(0, @st.prepend(0,'prepend',0,Time.now.to_i,'abc_data')[2] )
108
+
109
+ assert_equal(0xffffffff, @st.rset(0,'incr',0,0xffffffff,Time.now.to_i,'10')[2])
110
+ assert_equal(0, @st.incr(0,'incr',0,10)[2] )
111
+
112
+ assert_equal(0xffffffff, @st.rset(0,'decr',0,0xffffffff,Time.now.to_i,'10')[2])
113
+ assert_equal(0, @st.decr(0,'decr',0,10)[2] )
114
+ end
115
+
116
+ def test_add
117
+ assert_equal('abc_data',@st.add(0,'abc',0,Time.now.to_i+1,'abc_data')[4])
118
+ # deny a over write
119
+ assert_nil( @st.add(0,'abc',0,Time.now.to_i+1,'abc_data') )
120
+ assert_equal( 'abc_data', @st.delete(0,'abc',0)[4])
121
+ assert_equal('abc_data', @st.add(0,'abc',0,Time.now.to_i,'abc_data')[4])
122
+ end
123
+
124
+ def test_replace
125
+ assert_nil( @st.replace(0,'abc',0,Time.now.to_i,'abc_data') )
126
+ assert_equal('abc_data', @st.add(0,'abc',0,Time.now.to_i,'abc_data')[4])
127
+ assert_equal('new_data', @st.replace(0,'abc',0,Time.now.to_i,'new_data')[4] )
128
+
129
+ end
130
+
131
+ def test_append
132
+ assert_nil( @st.append(0,'abc',0,Time.now.to_i,'abc_data') )
133
+ assert_equal('abc_data', @st.set(0,'abc',0,Time.now.to_i,'abc_data')[4])
134
+ assert_equal( 'abc_data123',@st.append(0,'abc',0,Time.now.to_i,'123')[4] )
135
+ assert_equal('abc_data123', @st.get(0,'abc',0) )
136
+ end
137
+
138
+ def test_prepend
139
+ assert_nil( @st.prepend(0,'abc',0,Time.now.to_i,'abc_data') )
140
+ assert_equal('abc_data', @st.set(0,'abc',0,Time.now.to_i,'abc_data')[4])
141
+ assert_equal('123abc_data', @st.prepend(0,'abc',0,Time.now.to_i,'123')[4])
142
+ assert_equal('123abc_data', @st.get(0,'abc',0))
143
+ end
144
+
145
+ def test_incr
146
+ assert_nil( @st.incr(0,'abc',0,1) )
147
+ assert_equal('100', @st.set(0,'abc',0,Time.now.to_i,'100')[4] )
148
+ assert_equal('101', @st.incr(0,'abc',0,1)[4])
149
+ assert_equal('106', @st.incr(0,'abc',0,5)[4])
150
+ assert_equal('100', @st.incr(0,'abc',0,-6)[4]) # 106 + (-6) = 100
151
+ assert_equal('0', @st.incr(0,'abc',0,-200)[4] ) # 100 + (-200) = 0
152
+ assert_equal('0', @st.incr(0,'abc',0,-200)[4] ) # 0 + (-200) = 0
153
+ # set to max value
154
+ assert_equal('18446744073709551615', @st.set(0,'abc',0,Time.now.to_i,
155
+ '18446744073709551615')[4])
156
+ assert_equal('1', @st.incr(0,'abc',0,2)[4] ) # max + 2 = 1
157
+ end
158
+
159
+ def test_decr
160
+ assert_nil( @st.decr(0,'abc',0,1) )
161
+ assert_equal('100', @st.set(0,'abc',0,Time.now.to_i,'100')[4] )
162
+ assert_equal('99', @st.decr(0,'abc',0,1)[4])
163
+ assert_equal('94', @st.decr(0,'abc',0,5)[4])
164
+ assert_equal('100', @st.decr(0,'abc',0,-6)[4] ) # 94 - (-6) = 100
165
+ assert_equal('0', @st.decr(0,'abc',0,200)[4] ) # 100 - 200 = 0
166
+ assert_equal('0', @st.decr(0,'abc',0,200)[4] ) # 0 - 200 = 0
167
+ # set to max value
168
+ assert_equal('18446744073709551615', @st.set(0,'abc',0,Time.now.to_i,
169
+ '18446744073709551615')[4])
170
+ assert_equal('2', @st.decr(0,'abc',0,-3)[4]) # max - (-2) = 2
171
+ end
172
+
173
+ def test_dump
174
+ assert_nil( @st.dump(0) )
175
+ @st.set(0,'abc',0,0xffffffff,'abc_data')
176
+ assert_equal(1, Marshal.load(@st.dump(0)).length )
177
+ @st.set(0,'def',0,0xffffffff,'def_data')
178
+ assert_equal(2, Marshal.load(@st.dump(0)).length )
179
+ assert_nil( @st.dump(1) ) # another vnode is empty
180
+
181
+ n=ndat
182
+ n.times{|i|
183
+ @st.set(2,i.to_s,0,0xffffffff,'abc_data')
184
+ }
185
+ assert_equal(n, Marshal.load(@st.dump(2)).length )
186
+ end
187
+
188
+ def test_volume
189
+ n=ndat
190
+ n.times{|i|
191
+ @st.set(0,i.to_s,0,0xffffffff,'abc_data')
192
+ }
193
+ n.times{|i|
194
+ assert_equal('abc_data', @st.get(0,i.to_s,0))
195
+ }
196
+ n.times{|i|
197
+ assert_equal('abc_data', @st.delete(0,i.to_s,0)[4])
198
+ }
199
+ # true_length value is included in number of deletemark
200
+ assert_equal(n, @st.true_length )
201
+ end
202
+
203
+ def test_each_clean_up
204
+ n=10
205
+
206
+ vnhash={}
207
+ n.times{|i|
208
+ n.times{|j|
209
+ @st.set(i,"key#{i}-#{j}",0,0xffffffff,"val#{i}-#{j}")
210
+ }
211
+ vnhash[i]=:primary
212
+ }
213
+ # ---------+------+---------------------
214
+ # last < now+100
215
+ # all data within a fixed time limit
216
+ @st.each_clean_up_sleep = 0
217
+ @st.each_clean_up(Time.now.to_i+100,vnhash){|k,vn|
218
+ puts "k=#{k} vn=#{vn}"
219
+ assert(false)
220
+ }
221
+
222
+ # delete data in vn=0
223
+ n.times{|i| @st.delete(0,"key0-#{i}",0) }
224
+ # time is 100 second ago
225
+ @st.each_clean_up(Time.now.to_i-100,vnhash){|k,vn|
226
+ assert(false)
227
+ }
228
+
229
+ # time is 100 second later
230
+ cnt=0
231
+ @st.each_clean_up(Time.now.to_i+100,vnhash){|k,vn|
232
+ assert_equal(0, vn)
233
+ assert_match(/key0-/, k )
234
+ cnt += 1
235
+ }
236
+ assert_equal(10,cnt )
237
+
238
+ # delete data in vn=1
239
+ n.times{|i| @st.delete(1,"key1-#{i}",0) }
240
+ # set to :secondary in vn=1
241
+ vnhash[1]=:secondary
242
+ # :secondary was not deleted
243
+ @st.each_clean_up(Time.now.to_i-100,vnhash){|k,vn|
244
+ assert(false)
245
+ }
246
+ # set to :primary in vn=1
247
+ vnhash[1]=:primary
248
+ # in :primary data was deleted
249
+ cnt=0
250
+ @st.each_clean_up(Time.now.to_i+100,vnhash){|k,vn|
251
+ assert_equal(1, vn)
252
+ assert_match(/key1-/, k )
253
+ cnt += 1
254
+ }
255
+ assert_equal(10,cnt)
256
+
257
+ # deletemark was empty
258
+ @st.each_clean_up(Time.now.to_i-100,vnhash){|k,vn|
259
+ assert(false)
260
+ }
261
+
262
+ # vn=2 is not taken of charge
263
+ vnhash.delete(2)
264
+ # but still have a data in vn=2
265
+ n.times{|i|
266
+ assert_match(/val2-/,@st.get(2,"key2-#{i}",0) )
267
+ }
268
+ # data was deleted in vn=2
269
+ cnt=0
270
+ @st.each_clean_up(Time.now.to_i+100,vnhash){|k,vn|
271
+ assert_equal(2, vn)
272
+ assert_match(/key2-/, k )
273
+ cnt += 1
274
+ }
275
+ assert_equal(10,cnt)
276
+ # confirm it in vn=2
277
+ n.times{|i|
278
+ assert_nil( @st.get(2,"key2-#{i}",0) )
279
+ }
280
+
281
+ # time is 100 second ago in vn=3
282
+ n.times{|i|
283
+ @st.set(3,"key3-#{i}",0,Time.now.to_i-100,"val3-#{i}")
284
+ }
285
+ # 10 keys deleted
286
+ cnt=0
287
+ @st.each_clean_up(Time.now.to_i-100,vnhash){|k,vn|
288
+ assert_equal(3, vn)
289
+ assert_match(/key3-/, k )
290
+ cnt += 1
291
+ }
292
+ assert_equal(10,cnt)
293
+ end
294
+
295
+ def test_each_clean_up2
296
+ n=10
297
+
298
+ # set and delete is repeated 100 times
299
+ vnhash={}
300
+ n.times{|i|
301
+ n.times{|j|
302
+ @st.set(i,"key#{i}-#{j}",0,0xffffffff,"val#{i}-#{j}")
303
+ @st.delete(i,"key#{i}-#{j}",0)
304
+ }
305
+ vnhash[i]=:primary
306
+ }
307
+
308
+ # each waite is 10 msec
309
+ cnt = 0
310
+ th = Thread.new{
311
+ @st.each_clean_up_sleep = 0.01
312
+ @st.each_clean_up(Time.now.to_i+100,vnhash){|k,vn|
313
+ cnt += 1
314
+ }
315
+ }
316
+ # in 500msec later will stop
317
+ sleep 0.5
318
+ @st.stop_clean_up
319
+ th.join
320
+ # should cnt is less than 100
321
+ assert_operator(100, :>, cnt)
322
+ # delete a remain keys
323
+ @st.each_clean_up_sleep = 0
324
+ @st.each_clean_up(Time.now.to_i+100,vnhash){|k,vn|
325
+ cnt += 1
326
+ }
327
+ # after all cnt is 100
328
+ assert_equal(100, cnt)
329
+ end
330
+
331
+ def test_dump_and_load
332
+ n=10
333
+ n.times{|i|
334
+ # clock = 0
335
+ @st.set(0,i.to_s,0,0xffffffff,'abc_data')
336
+ }
337
+ # not loaded
338
+ assert_equal(0, @st.load(@st.dump(0)) )
339
+
340
+ h={}
341
+ n.times{|i|
342
+ # clock = 1
343
+ h[i.to_s]=[0,Time.now.to_i,1,0xffffffff].pack('NNNN')+'new data'
344
+ }
345
+ dmp=Marshal.dump(h)
346
+
347
+ # loaded
348
+ assert_equal(n, @st.load(dmp) )
349
+ assert_equal('new data', @st.get(0,'0',0))
350
+ end
351
+
352
+ def test_dump_and_load2
353
+ n=10
354
+ # create a deletemark
355
+ n.times{|i|
356
+ assert_nil( @st.delete(0,i.to_s,0)[4] )
357
+ }
358
+ # dump a deletemark
359
+ dmp=@st.dump(0)
360
+ assert_equal(n, Marshal.load(dmp).length )
361
+ # not loaded, it's same data
362
+ assert_equal(0, @st.load(@st.dump(0)) )
363
+
364
+ # create a old clock data
365
+ h={}
366
+ n.times{|i|
367
+ h[i.to_s]=[0,Time.now.to_i,0xffffffff,0xffffffff].pack('NNNN')+'old data'
368
+ }
369
+ dmp=Marshal.dump(h)
370
+ # not loaded
371
+ assert_equal(0, @st.load(dmp) )
372
+ assert_nil( @st.get(0,'0',0) )
373
+ end
374
+
375
+ # access after close
376
+ def test_close
377
+ @st.closedb
378
+
379
+ assert_raise NoMethodError do
380
+ @st.get(0,'abc',0)
381
+ end
382
+
383
+ assert_raise NoMethodError do
384
+ @st.set(0,'abc',0,0xffffffff,'abc_data')
385
+ end
386
+
387
+ assert_raise NoMethodError do
388
+ @st.dump(0)
389
+ end
390
+
391
+ h={}
392
+ 100.times{|i|
393
+ h[i.to_s]=[0,Time.now.to_i,0xffffffff,0xffffffff].pack('NNNN')+'old data'
394
+ }
395
+ dmp=Marshal.dump(h)
396
+
397
+ assert_raise NoMethodError do
398
+ @st.load(dmp)
399
+ end
400
+
401
+ end
402
+
403
+ def test_close_after_each_clean_up
404
+ h={}
405
+ 100.times{|i|
406
+ h[i.to_s]=[i%10,Time.now.to_i,0,Time.now.to_i].pack('NNNN')+'old data'
407
+ }
408
+ dmp=Marshal.dump(h)
409
+ @st.load(dmp)
410
+
411
+ @st.each_clean_up(Time.now.to_i-100, Hash.new(:primary) ){|k,vn|
412
+ @st.closedb
413
+ }
414
+ end
415
+
416
+ def test_each_vn_dump_in_normal
417
+ n=100
418
+ n.times{|i|
419
+ @st.set(0,"key#{i}",0,0x7fffffff,"val#{i}")
420
+ }
421
+ (90..99).each{|i|
422
+ @st.delete(0, "key#{i}", 0)
423
+ }
424
+ count = 0
425
+ res = @st.each_vn_dump(0){|data|
426
+ vn, last, clk, expt, klen = data.slice!(0..19).unpack('NNNNN')
427
+ k = data.slice!(0..(klen-1))
428
+ vlen, = data.slice!(0..3).unpack('N')
429
+ v = data
430
+ count += 1
431
+ # puts "#{vn} #{last} #{clk} #{expt} #{klen} #{k} #{vlen} #{v}"
432
+ assert_equal('key',k[0..2])
433
+ assert_equal('val',v[0..2]) if k[3..-1].to_i < 90
434
+
435
+ assert_nil( @st.load_stream_dump(vn, last, clk, expt, k, v) )
436
+ @st.load_stream_dump(2, last, clk, expt, k, v)
437
+ }
438
+ assert(res)
439
+ assert_equal(100,count)
440
+
441
+ count = 0
442
+ @st.each_vn_dump(1){|data| count += 1 }
443
+ assert_equal(0,count )
444
+
445
+ count = 0
446
+ @st.each_vn_dump(2){|data| count += 1 }
447
+ assert_equal(100,count )
448
+ end
449
+
450
+ def test_each_vn_dump_not_normal
451
+ dn = @st.instance_eval{ @hdiv[0] }
452
+
453
+ n=100
454
+ n.times{|i|
455
+ @st.set(0,"key#{i}",0,0x7fffffff,"val#{i}")
456
+ }
457
+
458
+ # :normal -> :safecopy_flushing
459
+ assert_equal(:safecopy_flushing, @st.set_db_stat(dn, :safecopy_flushing))
460
+ # :safecopy_flushing -> :safecopy_flushed
461
+ assert_equal(:safecopy_flushed, @st.set_db_stat(dn, :safecopy_flushed))
462
+
463
+ (80..99).each{|i|
464
+ @st.set(0,"key#{i}",0,0x7fffffff,"val#{i + 1}")
465
+ }
466
+
467
+ # :safecopy_flushed -> :cachecleaning
468
+ assert_equal(:cachecleaning, @st.set_db_stat(dn, :cachecleaning))
469
+
470
+ (90..99).each{|i|
471
+ @st.delete(0, "key#{i}", 0)
472
+ }
473
+
474
+ count = 0
475
+ res = @st.each_vn_dump(0){|data|
476
+ vn, last, clk, expt, klen = data.slice!(0..19).unpack('NNNNN')
477
+ k = data.slice!(0..(klen-1))
478
+ vlen, = data.slice!(0..3).unpack('N')
479
+ v = data
480
+ count += 1
481
+ # puts "#{vn} #{last} #{clk} #{expt} #{klen} #{k} #{vlen} #{v}"
482
+ }
483
+ assert_equal(false, res)
484
+ assert_equal(0, count)
485
+ end
486
+
487
+ def test_db_stat_with_each_vn_dump
488
+ n = 100 # number of data
489
+ m = 10 # number of vnode
490
+ # set data
491
+ n.times do |i|
492
+ m.times do|vn|
493
+ @st.set(vn,"key#{vn}_#{i}",0,0x7fffffff,"val#{i}")
494
+ end
495
+ end
496
+
497
+ m.times do |vn|
498
+ dn = @st.instance_eval{ @hdiv[vn] }
499
+ count = 0
500
+ res = @st.each_vn_dump(vn) do
501
+ assert_equal(false, @st.each_vn_dump(vn){})
502
+ assert_equal(:normal, @st.dbs[dn])
503
+ assert_equal(false, @st.set_db_stat(dn, :safecopy_flushing))
504
+ count += 1
505
+ end
506
+ assert_equal(n, count)
507
+ assert(res)
508
+ end
509
+ end
510
+
511
+ def test_db_stat
512
+ assert_nil(@st.instance_eval{ @hdbc[0] })
513
+ # :normal -> error case
514
+ assert_equal(false, @st.set_db_stat(0, :safecopy_flushed))
515
+ assert_equal(false, @st.set_db_stat(0, :cachecleaning))
516
+ assert_equal(false, @st.set_db_stat(0, :normal))
517
+ # :normal -> :safecopy_flushing
518
+ assert_equal(:safecopy_flushing, @st.set_db_stat(0, :safecopy_flushing))
519
+ assert_equal(:safecopy_flushing, @st.instance_eval{ @dbs[0] })
520
+ assert(@st.instance_eval{ @hdbc[0] })
521
+
522
+ # :safecopy_flushing -> error case
523
+ assert_equal(false, @st.set_db_stat(0, :safecopy_flushing))
524
+ assert_equal(false, @st.set_db_stat(0, :cachecleaning))
525
+ assert_equal(false, @st.set_db_stat(0, :normal))
526
+ # :safecopy_flushing -> :safecopy_flushed
527
+ assert_equal(:safecopy_flushed, @st.set_db_stat(0, :safecopy_flushed))
528
+ assert_equal(:safecopy_flushed, @st.instance_eval{ @dbs[0] })
529
+ assert(@st.instance_eval{ @hdbc[0] })
530
+
531
+ # :safecopy_flushed -> error case
532
+ assert_equal(false, @st.set_db_stat(0, :safecopy_flushing))
533
+ assert_equal(false, @st.set_db_stat(0, :safecopy_flushed))
534
+ assert_equal(false, @st.set_db_stat(0, :normal))
535
+ # :safecopy_flushed -> :cachecleaning
536
+ assert_equal(:cachecleaning, @st.set_db_stat(0, :cachecleaning))
537
+ assert_equal(:cachecleaning, @st.instance_eval{ @dbs[0] })
538
+ assert(@st.instance_eval{ @hdbc[0] })
539
+
540
+ # :cachecleaning -> error case
541
+ assert_equal(false, @st.set_db_stat(0, :safecopy_flushed))
542
+ assert_equal(false, @st.set_db_stat(0, :cachecleaning))
543
+ # :cachecleaning -> :safecopy_flushing
544
+ assert_equal(:safecopy_flushing, @st.set_db_stat(0, :safecopy_flushing))
545
+ assert_equal(:safecopy_flushing, @st.instance_eval{ @dbs[0] })
546
+ assert_equal(:safecopy_flushed, @st.set_db_stat(0, :safecopy_flushed))
547
+ assert_equal(:cachecleaning, @st.set_db_stat(0, :cachecleaning))
548
+ assert(@st.instance_eval{ @hdbc[0] })
549
+ # :cachecleaning -> :normal
550
+ assert_equal(:normal, @st.set_db_stat(0, :normal))
551
+ assert_equal(:normal, @st.instance_eval{ @dbs[0] })
552
+ assert_nil(@st.instance_eval{ @hdbc[0] })
553
+ end
554
+
555
+ def test_clock_along_status
556
+ vn = 0
557
+ dn = @st.instance_eval{ @hdiv[vn] }
558
+ assert_equal('abc_data', @st.set(vn,'abc',0,0xffffffff,'abc_data')[4])
559
+ assert( @st.get_context(vn, 'abc', 0)[2] == 0 )
560
+ # :normal -> :safecopy_flushing
561
+ assert_equal(:safecopy_flushing, @st.set_db_stat(dn, :safecopy_flushing))
562
+ assert_equal('abc_data', @st.set(vn,'abc',0,0xffffffff,'abc_data')[4])
563
+ assert( @st.get_context(vn, 'abc', 0)[2] == 1 )
564
+ # :safecopy_flushing -> :safecopy_flushed
565
+ assert_equal(:safecopy_flushed, @st.set_db_stat(dn, :safecopy_flushed))
566
+ assert_equal('abc_data', @st.set(vn,'abc',0,0xffffffff,'abc_data')[4])
567
+ assert( @st.get_context(vn, 'abc', 0)[2] == 2 )
568
+ # :safecopy_flushed -> :cachecleaning
569
+ assert_equal(:cachecleaning, @st.set_db_stat(dn, :cachecleaning))
570
+ assert_equal('abc_data', @st.set(vn,'abc',0,0xffffffff,'abc_data')[4])
571
+ assert( @st.get_context(vn, 'abc', 0)[2] == 3 )
572
+ # :cachecleaning -> :normal
573
+ assert_equal(:normal, @st.set_db_stat(dn, :normal))
574
+ assert_equal('abc_data', @st.set(vn,'abc',0,0xffffffff,'abc_data')[4])
575
+ assert( @st.get_context(vn, 'abc', 0)[2] == 4 )
576
+ end
577
+
578
+ def test_set_get_in_safecopy
579
+ vn = 0
580
+ dn = @st.instance_eval{ @hdiv[vn] }
581
+ # :normal -> :safecopy_flushing
582
+ assert_equal(:safecopy_flushing, @st.set_db_stat(dn, :safecopy_flushing))
583
+ assert_equal(:safecopy_flushing, @st.instance_eval{ @dbs[dn] })
584
+ assert_equal('abc_data', @st.set(vn,'abc',0,0xffffffff,'abc_data')[4])
585
+ assert_equal('abc_data', @st.get(vn,'abc',0) )
586
+ # not stored
587
+ assert_nil(@st.instance_eval{ @hdb[dn].get('abc') })
588
+ # stored
589
+ assert(@st.instance_eval{ @hdbc[dn].get('abc') })
590
+
591
+ # :safecopy_flushing -> :safecopy_flushed
592
+ assert_equal(:safecopy_flushed, @st.set_db_stat(dn, :safecopy_flushed))
593
+ assert_equal(:safecopy_flushed, @st.instance_eval{ @dbs[dn] })
594
+ assert_equal('def_data', @st.set(vn,'def',0,0xffffffff,'def_data')[4])
595
+ assert_equal('def_data', @st.get(vn,'def',0) )
596
+ # not stored
597
+ assert_nil(@st.instance_eval{ @hdb[dn].get('def') })
598
+ # stored
599
+ assert(@st.instance_eval{ @hdbc[dn].get('def') })
600
+ end
601
+
602
+ def test_set_get_in_cachecleaning
603
+ vn = 0
604
+ dn = @st.instance_eval{ @hdiv[vn] }
605
+ assert_equal( 'abc_data',@st.set(vn,'abc',0,0xffffffff,'abc_data')[4])
606
+ assert_equal( 'abc_data', @st.get(vn,'abc',0) ) # database
607
+ # :normal -> :safecopy_flushing
608
+ assert_equal(:safecopy_flushing, @st.set_db_stat(dn, :safecopy_flushing))
609
+ # :safecopy_flushing -> :safecopy_flushed
610
+ assert_equal(:safecopy_flushed, @st.set_db_stat(dn, :safecopy_flushed))
611
+ assert_equal( 'abc_data1',@st.set(vn,'abc',0,0xffffffff,'abc_data1')[4])
612
+ assert_equal( 'abc_data1', @st.get(vn,'abc',0) ) # cache
613
+ # :safecopy_flushed -> :cachecleaning
614
+ assert_equal(:cachecleaning, @st.set_db_stat(dn, :cachecleaning))
615
+ assert_equal( 'abc_data1', @st.get(vn,'abc',0) ) # cache
616
+ assert_equal( 'abc_data2',@st.set(vn,'abc',0,0xffffffff,'abc_data2')[4])
617
+ assert_equal( 'abc_data2', @st.get(vn,'abc',0) ) # database
618
+ end
619
+
620
+ def test_out_cache
621
+ vn = 0
622
+ dn = @st.instance_eval{ @hdiv[vn] }
623
+ # :normal -> :safecopy_flushing
624
+ assert_equal(:safecopy_flushing, @st.set_db_stat(dn, :safecopy_flushing))
625
+ assert_equal(:safecopy_flushing, @st.instance_eval{ @dbs[dn] })
626
+ assert_equal('abc_data', @st.set(vn,'abc',0,0xffffffff,'abc_data')[4])
627
+ assert_equal('abc_data', @st.get(vn,'abc',0) )
628
+ # not stored
629
+ assert_nil(@st.instance_eval{ @hdb[dn].get('abc') })
630
+ # stored
631
+ assert(@st.instance_eval{ @hdbc[dn].get('abc') })
632
+ # out
633
+ @st.out_cache(dn, 'abc')
634
+ # not stored
635
+ assert_nil(@st.instance_eval{ @hdb[dn].get('abc') })
636
+ # not stored
637
+ assert_nil(@st.instance_eval{ @hdbc[dn].get('abc') })
638
+ end
639
+
640
+ def test_each_cache_dump_pack
641
+ vn = 0
642
+ dn = @st.instance_eval{ @hdiv[vn] }
643
+ # :normal -> :safecopy_flushing
644
+ assert_equal(:safecopy_flushing, @st.set_db_stat(dn, :safecopy_flushing))
645
+ keys = []
646
+ 10.times do |i|
647
+ k = "key#{i}"
648
+ v = "val#{i}"
649
+ assert_equal(v, @st.set(vn,k,0,0xffffffff,v)[4])
650
+ keys << k
651
+ end
652
+ @st.each_cache_dump_pack(dn, keys) do |data|
653
+ vn, last, clk, expt, klen = data.slice!(0..19).unpack('NNNNN')
654
+ k = data.slice!(0..(klen-1))
655
+ vlen, = data.slice!(0..3).unpack('N')
656
+ v = data
657
+ # puts "#{vn} #{last} #{clk} #{expt} #{klen} #{k} #{vlen} #{v}"
658
+ assert_match(/key\d/, k)
659
+ assert_match("val#{k[3..-1]}", v)
660
+ end
661
+ end
662
+
663
+ def test_get_keys_in_cache
664
+ vn = 0
665
+ dn = @st.instance_eval{ @hdiv[vn] }
666
+ # :normal -> :safecopy_flushing
667
+ assert_equal(:safecopy_flushing, @st.set_db_stat(dn, :safecopy_flushing))
668
+ keys = []
669
+ 100.times do |i|
670
+ k = "key#{i}"
671
+ v = "val#{i}"
672
+ assert_equal(v, @st.set(vn,k,0,0xffffffff,v)[4])
673
+ end
674
+
675
+ assert(@st.instance_eval{ @hdbc[dn].rnum } == 100)
676
+ 10.times do
677
+ keys = @st.get_keys_in_cache(dn, 10)
678
+ assert(keys.length == 10)
679
+ keys.each do |k|
680
+ @st.out_cache(dn, k)
681
+ end
682
+ end
683
+ assert(@st.instance_eval{ @hdbc[dn].rnum } == 0)
684
+ end
685
+ end