roma 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +44 -1
- data/Gemfile.lock +18 -15
- data/README.md +15 -1
- data/bin/consistency_test +10 -0
- data/bin/data_accumulation +11 -0
- data/lib/roma/async_process.rb +39 -2
- data/lib/roma/command/sys_command_receiver.rb +80 -0
- data/lib/roma/command/vn_command_receiver.rb +1 -1
- data/lib/roma/config.rb +1 -1
- data/lib/roma/plugin/plugin_storage.rb +105 -1
- data/lib/roma/romad.rb +13 -1
- data/lib/roma/routing/cb_rttable.rb +1 -1
- data/lib/roma/tools/consistency_test.rb +77 -0
- data/lib/roma/tools/data_accumulation.rb +64 -0
- data/lib/roma/version.rb +1 -1
- data/lib/roma/write_behind.rb +138 -1
- data/test/config4mhash.rb +1 -1
- data/test/config4storage_error.rb +1 -1
- data/test/config4test.rb +1 -1
- data/test/cpdbtest/config4cpdb_base.rb +1 -1
- data/test/optional_test/t_mkroute_rich.rb +44 -0
- data/test/optional_test/t_other_cpdb.rb +45 -0
- data/test/optional_test/t_other_database.rb +59 -0
- data/test/{t_routing_logic.rb → optional_test/t_routing_logic.rb} +1 -0
- data/test/roma-test-storage.rb +685 -0
- data/test/roma-test-utils.rb +24 -0
- data/test/run-test.rb +9 -0
- data/test/t_command_definition.rb +2 -0
- data/test/t_cpdata.rb +1 -0
- data/test/t_cpdb.rb +22 -34
- data/test/t_eventmachine.rb +1 -0
- data/test/t_listplugin.rb +2 -0
- data/test/t_logshift.rb +2 -4
- data/test/t_mapcountplugin.rb +48 -37
- data/test/t_mapplugin.rb +2 -0
- data/test/t_mhash.rb +2 -1
- data/test/t_new_func.rb +386 -0
- data/test/t_protocol.rb +66 -1
- data/test/t_rclient.rb +2 -0
- data/test/t_replication.rb +299 -0
- data/test/t_routing_data.rb +6 -5
- data/test/t_storage.rb +5 -740
- data/test/t_storage_error.rb +1 -0
- data/test/t_writebehind.rb +11 -2
- 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
|
@@ -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
|