roma 0.8.11 → 0.8.12
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +31 -0
- data/ruby/server/bin/simple_bench +0 -15
- data/ruby/server/lib/roma/async_process.rb +214 -332
- data/ruby/server/lib/roma/command/bg_command_receiver.rb +19 -122
- data/ruby/server/lib/roma/command/vn_command_receiver.rb +33 -45
- data/ruby/server/lib/roma/config.rb +2 -0
- data/ruby/server/lib/roma/event/handler.rb +6 -1
- data/ruby/server/lib/roma/plugin/plugin_alist.rb +29 -3
- data/ruby/server/lib/roma/plugin/plugin_storage.rb +23 -2
- data/ruby/server/lib/roma/romad.rb +26 -20
- data/ruby/server/lib/roma/routing/cb_rttable.rb +28 -1
- data/ruby/server/lib/roma/routing/random_partitioner.rb +95 -0
- data/ruby/server/lib/roma/routing/routing_data.rb +1 -0
- data/ruby/server/lib/roma/stats.rb +24 -5
- data/ruby/server/lib/roma/storage/basic_storage.rb +21 -20
- data/ruby/server/lib/roma/storage/rh_storage.rb +15 -17
- data/ruby/server/lib/roma/storage/sqlite3_storage.rb +3 -0
- data/ruby/server/lib/roma/tools/simple_bench.rb +67 -18
- data/ruby/server/lib/roma/version.rb +1 -1
- data/ruby/server/test/t_cpdata.rb +1 -50
- data/ruby/server/test/t_eventmachine.rb +23 -0
- data/ruby/server/test/t_mhash.rb +0 -17
- data/ruby/server/test/t_protocol.rb +131 -0
- data/ruby/server/test/t_routing_data.rb +9 -0
- metadata +127 -132
@@ -0,0 +1,95 @@
|
|
1
|
+
module Roma
|
2
|
+
module Routing
|
3
|
+
module RandomPartitioner
|
4
|
+
|
5
|
+
def exclude_nodes(ap_str, rep_host)
|
6
|
+
exclude_nodes = self.nodes
|
7
|
+
if rep_host
|
8
|
+
exclude_nodes = [ap_str]
|
9
|
+
else
|
10
|
+
myhost = ap_str.split(/[:_]/)[0]
|
11
|
+
exclude_nodes.delete_if{|nid| nid.split(/[:_]/)[0] != myhost }
|
12
|
+
end
|
13
|
+
exclude_nodes
|
14
|
+
end
|
15
|
+
|
16
|
+
alias :exclude_nodes_for_join :exclude_nodes
|
17
|
+
alias :exclude_nodes_for_recover :exclude_nodes
|
18
|
+
alias :exclude_nodes_for_balance :exclude_nodes
|
19
|
+
|
20
|
+
# vnode sampling exclude +exclude_nodes+
|
21
|
+
def select_vn_for_join(exclude_nodes)
|
22
|
+
short_idx = {}
|
23
|
+
idx = {}
|
24
|
+
@rd.v_idx.each_pair do |vn, nids|
|
25
|
+
unless list_include?(nids, exclude_nodes)
|
26
|
+
idx[vn] = nids
|
27
|
+
short_idx[vn] = nids if nids.length < @rd.rn
|
28
|
+
end
|
29
|
+
end
|
30
|
+
idx = short_idx if short_idx.length > 0
|
31
|
+
|
32
|
+
ks = idx.keys
|
33
|
+
return nil if ks.length == 0
|
34
|
+
vn = ks[rand(ks.length)]
|
35
|
+
nids = idx[vn]
|
36
|
+
[vn, nids, rand(@rd.rn) == 0]
|
37
|
+
end
|
38
|
+
|
39
|
+
# select a vnodes where short of redundancy.
|
40
|
+
def select_vn_for_recover(exclude_nodes)
|
41
|
+
ret = []
|
42
|
+
@rd.v_idx.each_pair do |vn, nids|
|
43
|
+
if nids.length < @rd.rn && list_include?(nids,exclude_nodes) == false
|
44
|
+
ret << [vn,nids]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
if ret.length == 0
|
48
|
+
nil
|
49
|
+
else
|
50
|
+
n = rand(ret.length)
|
51
|
+
[ret[n][0], ret[n][1], (rand(@rd.rn) == 0)]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def select_node_for_release(ap_str, rep_host, nids)
|
56
|
+
buf = self.nodes
|
57
|
+
|
58
|
+
unless rep_host
|
59
|
+
deny_hosts = []
|
60
|
+
nids.each{ |nid|
|
61
|
+
host = nid.split(/[:_]/)[0]
|
62
|
+
deny_hosts << host if host != ap_str.split(/[:_]/)[0]
|
63
|
+
}
|
64
|
+
buf.delete_if{|nid| deny_hosts.include?(nid.split(/[:_]/)[0])}
|
65
|
+
else
|
66
|
+
nids.each{|nid| buf.delete(nid) }
|
67
|
+
end
|
68
|
+
|
69
|
+
to_nid = buf[rand(buf.length)]
|
70
|
+
new_nids = nids.map{|n| n == ap_str ? to_nid : n }
|
71
|
+
[to_nid, new_nids]
|
72
|
+
end
|
73
|
+
|
74
|
+
# vnode sampling exclude +exclude_nodes+
|
75
|
+
def select_vn_for_balance(exclude_nodes)
|
76
|
+
short_idx = {}
|
77
|
+
idx = {}
|
78
|
+
@rd.v_idx.each_pair do |vn, nids|
|
79
|
+
unless list_include?(nids, exclude_nodes)
|
80
|
+
idx[vn] = nids
|
81
|
+
short_idx[vn] = nids if nids.length < @rd.rn
|
82
|
+
end
|
83
|
+
end
|
84
|
+
idx = short_idx if short_idx.length > 0
|
85
|
+
|
86
|
+
ks = idx.keys
|
87
|
+
return nil if ks.length == 0
|
88
|
+
vn = ks[rand(ks.length)]
|
89
|
+
nids = idx[vn]
|
90
|
+
[vn, nids, rand(@rd.rn) == 0]
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -16,23 +16,29 @@ module Roma
|
|
16
16
|
attr_accessor :name
|
17
17
|
attr_accessor :verbose
|
18
18
|
attr_accessor :enabled_repetition_host_in_routing
|
19
|
+
alias :rep_host :enabled_repetition_host_in_routing
|
19
20
|
attr_accessor :disabled_cmd_protect
|
20
21
|
|
21
22
|
# proc mode
|
22
23
|
attr_accessor :enabled_vnodes_balance
|
23
24
|
|
24
25
|
# proc status
|
25
|
-
attr_accessor :run_acquire_vnodes
|
26
26
|
attr_accessor :run_recover
|
27
27
|
attr_accessor :run_sync_routing
|
28
28
|
attr_accessor :run_iterate_storage
|
29
29
|
attr_accessor :run_storage_clean_up
|
30
30
|
attr_accessor :run_receive_a_vnode
|
31
31
|
attr_accessor :run_release
|
32
|
+
attr_accessor :run_join
|
33
|
+
attr_accessor :run_balance
|
34
|
+
|
35
|
+
attr_accessor :last_clean_up
|
36
|
+
attr_accessor :spushv_protection
|
32
37
|
|
33
38
|
# proc param
|
34
39
|
attr_accessor :stream_copy_wait_param
|
35
40
|
attr_accessor :dcnice
|
41
|
+
attr_accessor :clean_up_interval
|
36
42
|
|
37
43
|
# compressed redundant param
|
38
44
|
attr_accessor :size_of_zredundant
|
@@ -52,15 +58,19 @@ module Roma
|
|
52
58
|
|
53
59
|
def initialize
|
54
60
|
@config_path = nil
|
55
|
-
@run_acquire_vnodes = false
|
56
61
|
@run_recover = false
|
57
62
|
@run_sync_routing = false
|
58
63
|
@run_iterate_storage = false
|
59
64
|
@run_storage_clean_up = false
|
60
|
-
@run_receive_a_vnode =
|
65
|
+
@run_receive_a_vnode = {}
|
61
66
|
@run_release = false
|
67
|
+
@run_join = false
|
68
|
+
@run_balance = false
|
69
|
+
@last_clean_up = Time.now
|
70
|
+
@spushv_protection = false
|
62
71
|
@stream_copy_wait_param = 0.0001
|
63
72
|
@dcnice = 3
|
73
|
+
@clean_up_interval = 300
|
64
74
|
@enabled_vnodes_balance = nil
|
65
75
|
@write_count = 0
|
66
76
|
@read_count = 0
|
@@ -85,15 +95,20 @@ module Roma
|
|
85
95
|
ret['stats.daemon'] = @daemon
|
86
96
|
ret['stats.name'] = @name
|
87
97
|
ret['stats.verbose'] = @verbose
|
88
|
-
ret['stats.enabled_repetition_host_in_routing'] =
|
89
|
-
ret['stats.run_acquire_vnodes'] = @run_acquire_vnodes
|
98
|
+
ret['stats.enabled_repetition_host_in_routing'] = rep_host
|
90
99
|
ret['stats.run_recover'] = @run_recover
|
91
100
|
ret['stats.run_sync_routing'] = @run_sync_routing
|
92
101
|
ret['stats.run_iterate_storage'] = @run_iterate_storage
|
93
102
|
ret['stats.run_storage_clean_up'] = @run_storage_clean_up
|
103
|
+
ret['stats.run_receive_a_vnode'] = @run_receive_a_vnode.inspect
|
94
104
|
ret['stats.run_release'] = @run_release
|
105
|
+
ret['stats.run_join'] = @run_join
|
106
|
+
ret['stats.run_balance'] = @run_balance
|
107
|
+
ret['stats.last_clean_up'] = @last_clean_up
|
108
|
+
ret['stats.spushv_protection'] = @spushv_protection
|
95
109
|
ret['stats.stream_copy_wait_param'] = @stream_copy_wait_param
|
96
110
|
ret['stats.dcnice'] = @dcnice
|
111
|
+
ret['stats.clean_up_interval'] = @clean_up_interval
|
97
112
|
ret['stats.size_of_zredundant'] = @size_of_zredundant
|
98
113
|
ret['stats.write_count'] = @write_count
|
99
114
|
ret['stats.read_count'] = @read_count
|
@@ -115,6 +130,10 @@ module Roma
|
|
115
130
|
clear_count(:@redundant_count)
|
116
131
|
end
|
117
132
|
|
133
|
+
def do_clean_up?
|
134
|
+
@last_clean_up.to_i + @clean_up_interval < Time.now.to_i
|
135
|
+
end
|
136
|
+
|
118
137
|
private
|
119
138
|
|
120
139
|
def clear_count(var)
|
@@ -366,16 +366,19 @@ module Roma
|
|
366
366
|
nt = Time.now.to_i
|
367
367
|
@hdb.each{ |hdb|
|
368
368
|
hdb.each{ |k, v|
|
369
|
-
return unless @do_clean_up
|
369
|
+
return unless @do_clean_up # 1st check
|
370
370
|
vn, last, clk, expt = unpack_header(v)
|
371
371
|
vn_stat = vnhash[vn]
|
372
372
|
if vn_stat == :primary && ( (expt != 0 && nt > expt) || (expt == 0 && t > last) )
|
373
|
-
yield k, vn
|
374
|
-
|
373
|
+
if yield k, vn
|
374
|
+
hdb.out(k) if hdb.get(k) == v
|
375
|
+
end
|
375
376
|
elsif vn_stat == nil && t > last
|
376
|
-
yield k, vn
|
377
|
-
|
377
|
+
if yield k, vn
|
378
|
+
hdb.out(k) if hdb.get(k) == v
|
379
|
+
end
|
378
380
|
end
|
381
|
+
return unless @do_clean_up # 2nd ckeck
|
379
382
|
sleep @each_clean_up_sleep
|
380
383
|
}
|
381
384
|
}
|
@@ -457,21 +460,19 @@ module Roma
|
|
457
460
|
|
458
461
|
def each_vn_dump(target_vn)
|
459
462
|
count = 0
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
end
|
474
|
-
}
|
463
|
+
tn = Time.now.to_i
|
464
|
+
@hdb[@hdiv[target_vn]].each{|k,v|
|
465
|
+
vn, last, clk, expt, val = unpack_data(v)
|
466
|
+
if vn != target_vn || (expt != 0 && tn > expt)
|
467
|
+
count += 1
|
468
|
+
sleep @each_vn_dump_sleep if count % @each_vn_dump_sleep_count == 0
|
469
|
+
next
|
470
|
+
end
|
471
|
+
if val
|
472
|
+
yield [vn, last, clk, expt, k.length, k, val.length, val].pack("NNNNNa#{k.length}Na#{val.length}")
|
473
|
+
else
|
474
|
+
yield [vn, last, clk, expt, k.length, k, 0].pack("NNNNNa#{k.length}N")
|
475
|
+
end
|
475
476
|
}
|
476
477
|
end
|
477
478
|
|
@@ -44,23 +44,21 @@ module Roma
|
|
44
44
|
|
45
45
|
def each_vn_dump(target_vn)
|
46
46
|
count = 0
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
63
|
-
}
|
47
|
+
tn = Time.now.to_i
|
48
|
+
keys = @hdb[@hdiv[target_vn]].keys
|
49
|
+
keys.each{|k|
|
50
|
+
v = @hdb[@hdiv[target_vn]][k]
|
51
|
+
vn, last, clk, expt, val = unpack_data(v)
|
52
|
+
if vn != target_vn || (expt != 0 && tn > expt)
|
53
|
+
count += 1
|
54
|
+
sleep @each_vn_dump_sleep if count % @each_vn_dump_sleep_count == 0
|
55
|
+
next
|
56
|
+
end
|
57
|
+
if val
|
58
|
+
yield [vn, last, clk, expt, k.length, k, val.length, val].pack("NNNNNa#{k.length}Na#{val.length}")
|
59
|
+
else
|
60
|
+
yield [vn, last, clk, expt, k.length, k, 0].pack("NNNNNa#{k.length}N")
|
61
|
+
end
|
64
62
|
}
|
65
63
|
end
|
66
64
|
|
@@ -6,6 +6,7 @@ module Roma
|
|
6
6
|
|
7
7
|
module SQLite3_Ext
|
8
8
|
def put(k,v)
|
9
|
+
k = k.encode("ascii-8bit") if RUBY_VERSION >= "1.9.3"
|
9
10
|
if self.execute("select count(*) from t_roma where key=?",k)[0][0].to_i==0
|
10
11
|
self.execute("insert into t_roma values (?,?)",k,SQLite3::Blob.new(v))
|
11
12
|
else
|
@@ -14,12 +15,14 @@ module Roma
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def get(k)
|
18
|
+
k = k.encode("ascii-8bit") if RUBY_VERSION >= "1.9.3"
|
17
19
|
r = self.execute("select * from t_roma where key=?",k)
|
18
20
|
return nil if r.length==0
|
19
21
|
r[0][1]
|
20
22
|
end
|
21
23
|
|
22
24
|
def out(k)
|
25
|
+
k = k.encode("ascii-8bit") if RUBY_VERSION >= "1.9.3"
|
23
26
|
return nil if get(k) == nil
|
24
27
|
self.execute("delete from t_roma where key=?",k)
|
25
28
|
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
2
3
|
require 'date'
|
3
4
|
require 'roma/client/rclient'
|
4
5
|
|
5
|
-
@@cnt=0
|
6
|
-
@@tmax=0
|
7
|
-
@@tmin=100
|
6
|
+
@@cnt = 0
|
7
|
+
@@tmax = 0
|
8
|
+
@@tmin = 100
|
8
9
|
|
9
|
-
Thread.new
|
10
|
+
Thread.new do
|
10
11
|
sleep_time=10
|
11
12
|
while(true)
|
12
13
|
sleep sleep_time
|
@@ -15,13 +16,13 @@ Thread.new {
|
|
15
16
|
@@tmax=0
|
16
17
|
@@tmin=100
|
17
18
|
end
|
18
|
-
|
19
|
+
end
|
19
20
|
|
20
|
-
def random_rquest_sender(ini_nodes)
|
21
|
+
def random_rquest_sender(ini_nodes, n)
|
22
|
+
puts __method__
|
21
23
|
rc=Roma::Client::RomaClient.new(ini_nodes)
|
22
24
|
|
23
|
-
|
24
|
-
loop{
|
25
|
+
loop do
|
25
26
|
i=rand(n)
|
26
27
|
ts = DateTime.now
|
27
28
|
case rand(3)
|
@@ -39,21 +40,69 @@ def random_rquest_sender(ini_nodes)
|
|
39
40
|
@@tmax=t if t > @@tmax
|
40
41
|
@@tmin=t if t < @@tmin
|
41
42
|
@@cnt+=1
|
42
|
-
|
43
|
+
end
|
43
44
|
end
|
44
45
|
|
46
|
+
def set_sequence(ini_nodes, n)
|
47
|
+
puts __method__
|
48
|
+
rc=Roma::Client::RomaClient.new(ini_nodes)
|
49
|
+
|
50
|
+
n.times do |i|
|
51
|
+
ts = DateTime.now
|
52
|
+
res=rc.set("key_#{i}","value_#{i}")
|
53
|
+
puts "set k=#{i} #{res}" if res==nil || res.chomp != 'STORED'
|
54
|
+
t=(DateTime.now - ts).to_f * 86400.0
|
55
|
+
@@tmax=t if t > @@tmax
|
56
|
+
@@tmin=t if t < @@tmin
|
57
|
+
@@cnt+=1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_sequence(ini_nodes, n)
|
62
|
+
puts __method__
|
63
|
+
rc=Roma::Client::RomaClient.new(ini_nodes)
|
64
|
+
|
65
|
+
n.times do |i|
|
66
|
+
ts = DateTime.now
|
67
|
+
res=rc.get("key_#{i}")
|
68
|
+
puts "get #{i} #{res}" if res != "value_#{i}"
|
69
|
+
t=(DateTime.now - ts).to_f * 86400.0
|
70
|
+
@@tmax=t if t > @@tmax
|
71
|
+
@@tmin=t if t < @@tmin
|
72
|
+
@@cnt+=1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
param = { :num=>10000, :th=>1 }
|
77
|
+
|
78
|
+
opts = OptionParser.new
|
79
|
+
opts.banner = "usage:#{File.basename($0)} [options] addr:port"
|
80
|
+
opts.on("-s", "--set", "set request"){|v| param[:set] = v }
|
81
|
+
opts.on("-g", "--get", "get request"){|v| param[:get] = v }
|
82
|
+
opts.on("-r", "--rand", "random request"){|v| param[:rand] = v }
|
83
|
+
opts.on("-n", "--num [num]", "number of kyes"){|v| param[:num] = v.to_i }
|
84
|
+
opts.on("-t", "--threads [num]", "number of threads"){|v| param[:th] = v.to_i }
|
85
|
+
opts.parse!(ARGV)
|
86
|
+
|
45
87
|
if ARGV.length == 0
|
46
|
-
STDERR.puts
|
88
|
+
STDERR.puts opts.help
|
47
89
|
exit
|
48
90
|
end
|
49
91
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
}
|
92
|
+
if param.key?(:get) == false && param.key?(:set) == false
|
93
|
+
param[:rand] = true
|
94
|
+
end
|
95
|
+
|
96
|
+
t = []
|
97
|
+
param[:th].times do |i|
|
98
|
+
puts "Start thread #{i}"
|
99
|
+
t << Thread.new do
|
100
|
+
get_sequence(ARGV, param[:num]) if param.key?(:get)
|
101
|
+
set_sequence(ARGV, param[:num]) if param.key?(:set)
|
102
|
+
random_rquest_sender(ARGV, param[:num]) if param.key?(:rand)
|
103
|
+
end
|
104
|
+
end
|
57
105
|
|
58
|
-
t
|
106
|
+
t.each{|th| th.join }
|
59
107
|
|
108
|
+
puts "#{File.basename($0)} has done."
|
@@ -98,56 +98,7 @@ class CopyDataTest < Test::Unit::TestCase
|
|
98
98
|
@th.kill
|
99
99
|
$gs.close
|
100
100
|
Roma::Messaging::ConPool::instance.close_all
|
101
|
-
end
|
102
|
-
|
103
|
-
def test_pushv
|
104
|
-
make_dummy(1000)
|
105
|
-
dat = reqpushv('roma',0)
|
106
|
-
assert_not_nil( dat )
|
107
|
-
# 正常ケース
|
108
|
-
con = Roma::Messaging::ConPool.instance.get_connection("localhost_11211")
|
109
|
-
assert_equal("STORED", push_a_vnode('roma',0,con,Marshal.dump(dat)))
|
110
|
-
|
111
|
-
# 存在しない仮想ストレージ
|
112
|
-
con = Roma::Messaging::ConPool.instance.get_connection("localhost_11211")
|
113
|
-
assert_equal("SERVER_ERROR @storages[roma1] dose not found.",
|
114
|
-
push_a_vnode('roma1',0,con,Marshal.dump(dat)))
|
115
|
-
|
116
|
-
# END を送らない
|
117
|
-
con = Roma::Messaging::ConPool.instance.get_connection("localhost_11211")
|
118
|
-
assert_equal("SERVER_ERROR END was not able to be received.",
|
119
|
-
push_a_vnode('roma',0,con,Marshal.dump(dat),true))
|
120
|
-
|
121
|
-
# 壊れたデータを送る
|
122
|
-
dat['abc']="ajjkdlfsoifulwkejrweorlkjflksjflskaf"
|
123
|
-
con = Roma::Messaging::ConPool.instance.get_connection("localhost_11211")
|
124
|
-
assert_equal(
|
125
|
-
"SERVER_ERROR An invalid vnode number is include.key=abc vn=1634364011",
|
126
|
-
push_a_vnode('roma',2,con,Marshal.dump(dat)))
|
127
|
-
end
|
128
|
-
|
129
|
-
def push_a_vnode(hname ,vn, con, dmp, nonend=false)
|
130
|
-
con.write("pushv #{hname} #{vn}\r\n")
|
131
|
-
res = con.gets # READY\r\n or error string
|
132
|
-
if res != "READY\r\n"
|
133
|
-
con.close
|
134
|
-
return res.chomp
|
135
|
-
end
|
136
|
-
if nonend
|
137
|
-
con.write("#{dmp.length}\r\n#{dmp}\r\n\r\n")
|
138
|
-
else
|
139
|
-
con.write("#{dmp.length}\r\n#{dmp}\r\nEND\r\n")
|
140
|
-
end
|
141
|
-
res = con.gets # STORED\r\n or error string
|
142
|
-
con.close
|
143
|
-
res.chomp! if res
|
144
|
-
res
|
145
|
-
rescue =>e
|
146
|
-
con.close if con
|
147
|
-
"#{e}"
|
148
|
-
end
|
149
|
-
private :push_a_vnode
|
150
|
-
|
101
|
+
end
|
151
102
|
|
152
103
|
def test_spushv
|
153
104
|
# vn = 0 のキー
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'eventmachine'
|
4
|
+
|
5
|
+
class EventMachineTest < Test::Unit::TestCase
|
6
|
+
LOOP_NUM = 5
|
7
|
+
|
8
|
+
def test_context_switch
|
9
|
+
EM.epoll
|
10
|
+
t = Thread.new do
|
11
|
+
LOOP_NUM.times do |i|
|
12
|
+
100.times{ Thread.pass }
|
13
|
+
sleep 1
|
14
|
+
#puts i
|
15
|
+
end
|
16
|
+
EM.stop_event_loop
|
17
|
+
end
|
18
|
+
s = Time.now
|
19
|
+
EventMachine::run
|
20
|
+
e = Time.now
|
21
|
+
assert((e - s) < (LOOP_NUM + 1))
|
22
|
+
end
|
23
|
+
end
|
data/ruby/server/test/t_mhash.rb
CHANGED
@@ -203,20 +203,3 @@ class MHashTest < Test::Unit::TestCase
|
|
203
203
|
assert_equal("STORED", @rc.set("key", "value"))
|
204
204
|
end
|
205
205
|
end
|
206
|
-
|
207
|
-
class MHashTestForward < RClientTest
|
208
|
-
def setup
|
209
|
-
super
|
210
|
-
@rc.rttable.instance_eval{
|
211
|
-
undef search_node
|
212
|
-
|
213
|
-
def search_node(key); search_node2(key); end
|
214
|
-
|
215
|
-
def search_node2(key)
|
216
|
-
d = Digest::SHA1.hexdigest(key).hex % @hbits
|
217
|
-
@rd.v_idx[d & @search_mask][1]
|
218
|
-
end
|
219
|
-
}
|
220
|
-
end
|
221
|
-
|
222
|
-
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
|
5
|
+
class ProtocolTest < Test::Unit::TestCase
|
6
|
+
include RomaTestUtils
|
7
|
+
|
8
|
+
def setup
|
9
|
+
start_roma
|
10
|
+
@sock = TCPSocket.new("localhost", 11211)
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
@sock.close
|
15
|
+
stop_roma
|
16
|
+
rescue => e
|
17
|
+
puts "#{e} #{$@}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_set_get_delete
|
21
|
+
# Set data
|
22
|
+
@sock.write("set key 0 0 5\r\nvalue\r\n")
|
23
|
+
assert_equal("STORED", @sock.gets.chomp)
|
24
|
+
|
25
|
+
# Get data
|
26
|
+
@sock.write("get key\r\n")
|
27
|
+
assert_equal("VALUE key 0 5", @sock.gets.chomp)
|
28
|
+
assert_equal("value", @sock.gets.chomp)
|
29
|
+
assert_equal("END", @sock.gets.chomp)
|
30
|
+
|
31
|
+
# Update data
|
32
|
+
@sock.write("set key 0 0 9\r\nnew_value\r\n")
|
33
|
+
assert_equal("STORED", @sock.gets.chomp)
|
34
|
+
|
35
|
+
# Confirm updated data
|
36
|
+
@sock.write("get key\r\n")
|
37
|
+
assert_equal("VALUE key 0 9", @sock.gets.chomp)
|
38
|
+
assert_equal("new_value", @sock.gets.chomp)
|
39
|
+
assert_equal("END", @sock.gets.chomp)
|
40
|
+
|
41
|
+
# Delete data
|
42
|
+
@sock.write("delete key\r\n")
|
43
|
+
assert_equal("DELETED", @sock.gets.chomp)
|
44
|
+
|
45
|
+
# Confirm deleted data
|
46
|
+
@sock.write("get key\r\n")
|
47
|
+
assert_equal("END", @sock.gets.chomp)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_gets
|
51
|
+
# Set first data
|
52
|
+
@sock.write("set key-1 0 0 7\r\nvalue-1\r\n")
|
53
|
+
assert_equal("STORED", @sock.gets.chomp)
|
54
|
+
|
55
|
+
# Gets data
|
56
|
+
@sock.write("gets key-1 key-2\r\n")
|
57
|
+
assert_equal("VALUE key-1 0 7 0", @sock.gets.chomp)
|
58
|
+
assert_equal("value-1", @sock.gets.chomp)
|
59
|
+
assert_equal("END", @sock.gets.chomp)
|
60
|
+
|
61
|
+
# Set second data
|
62
|
+
@sock.write("set key-2 0 0 7\r\nvalue-2\r\n")
|
63
|
+
assert_equal("STORED", @sock.gets.chomp)
|
64
|
+
|
65
|
+
# Gets data (order is not sorted)
|
66
|
+
@sock.write("gets key-1 key-2\r\n")
|
67
|
+
if(@sock.gets.include?("key-1"))
|
68
|
+
assert_equal("value-1", @sock.gets.chomp)
|
69
|
+
assert_equal("VALUE key-2 0 7 0", @sock.gets.chomp)
|
70
|
+
assert_equal("value-2", @sock.gets.chomp)
|
71
|
+
else
|
72
|
+
assert_equal("value-2", @sock.gets.chomp)
|
73
|
+
assert_equal("VALUE key-1 0 7 0", @sock.gets.chomp)
|
74
|
+
assert_equal("value-1", @sock.gets.chomp)
|
75
|
+
end
|
76
|
+
assert_equal("END", @sock.gets.chomp)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_get_non_exisitent_key
|
80
|
+
@sock.write("get key\r\n")
|
81
|
+
assert_equal("END", @sock.gets.chomp)
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_delete_non_exisitent_key
|
85
|
+
@sock.write("delete key\r\n")
|
86
|
+
assert_equal("NOT_FOUND", @sock.gets.chomp)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_gets_non_exisitent_key
|
90
|
+
@sock.write("gets key\r\n")
|
91
|
+
assert_equal("END", @sock.gets.chomp)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_set_zero_arguments
|
95
|
+
@sock.write("get\r\n")
|
96
|
+
assert(@sock.gets.chomp.start_with?("CLIENT_ERROR"))
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_get_zero_arguments
|
100
|
+
@sock.write("get\r\n")
|
101
|
+
assert(@sock.gets.chomp.start_with?("CLIENT_ERROR"))
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_delete_zero_arguments
|
105
|
+
@sock.write("delete\r\n")
|
106
|
+
assert(@sock.gets.chomp.start_with?("CLIENT_ERROR"))
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_gets_zero_arguments
|
110
|
+
@sock.write("gets\r\n")
|
111
|
+
assert_equal("END", @sock.gets.chomp)
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_set_too_much_arguments
|
115
|
+
@sock.write("set key 0 0 5 0\r\nvalue\r\n")
|
116
|
+
assert(@sock.gets.chomp.start_with?("CLIENT_ERROR"))
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_set_wrong_key_size
|
120
|
+
@sock.write("set key 0 0 -1\r\nvalue\r\n")
|
121
|
+
assert(@sock.gets.start_with?("CLIENT_ERROR"))
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_set_zero_byte_value
|
125
|
+
@sock.write("set key 0 0 0\r\n\r\n")
|
126
|
+
assert_equal("STORED", @sock.gets.chomp)
|
127
|
+
@sock.write("get key\r\n")
|
128
|
+
assert_equal("VALUE key 0 0", @sock.gets.chomp)
|
129
|
+
assert_equal("", @sock.gets.chomp)
|
130
|
+
end
|
131
|
+
end
|
@@ -47,6 +47,15 @@ class RoutingDataTest < Test::Unit::TestCase
|
|
47
47
|
assert( 0x56000000 == rd.next_vnode(0x55000000) )
|
48
48
|
end
|
49
49
|
|
50
|
+
def test_saved_format
|
51
|
+
rd=Roma::Routing::RoutingData.create(32,8,1,['roma0_3300'])
|
52
|
+
decoded_rd=Roma::Routing::RoutingData.decode_binary(rd.dump_binary)
|
53
|
+
decoded_rd.save("routing_data.test.route")
|
54
|
+
rd_text=File.open("routing_data.test.route"){|f| f.read }
|
55
|
+
assert( /\!binary \|\-/ !~ rd_text )
|
56
|
+
File::unlink("routing_data.test.route")
|
57
|
+
end
|
58
|
+
|
50
59
|
def test_create_nodes_from_v_idx
|
51
60
|
rd=Roma::Routing::RoutingData.create(32,8,1,['roma0','roma1','roma2'])
|
52
61
|
rd.nodes.clear
|