roma 0.8.11 → 0.8.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -70,6 +70,7 @@ module Roma
70
70
  bin = bin[2..-1]
71
71
  nid, = bin.unpack("a#{len}")
72
72
  bin = bin[len..-1]
73
+ nid.encode!("utf-8") if RUBY_VERSION >= "1.9.3"
73
74
  rd.nodes << nid
74
75
  }
75
76
  (2**div_bits).times{|i|
@@ -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 = false
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'] = @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
- hdb.out(k) if hdb.get(k) == v
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
- hdb.out(k) if hdb.get(k) == v
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
- @divnum.times{|i|
461
- tn = Time.now.to_i
462
- @hdb[i].each{|k,v|
463
- vn, last, clk, expt, val = unpack_data(v)
464
- if vn != target_vn || (expt != 0 && tn > expt)
465
- count += 1
466
- sleep @each_vn_dump_sleep if count % @each_vn_dump_sleep_count == 0
467
- next
468
- end
469
- if val
470
- yield [vn, last, clk, expt, k.length, k, val.length, val].pack("NNNNNa#{k.length}Na#{val.length}")
471
- else
472
- yield [vn, last, clk, expt, k.length, k, 0].pack("NNNNNa#{k.length}N")
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
- @divnum.times{|i|
48
- tn = Time.now.to_i
49
- keys = @hdb[i].keys
50
- keys.each{|k|
51
- v = @hdb[i][k]
52
- vn, last, clk, expt, val = unpack_data(v)
53
- if vn != target_vn || (expt != 0 && tn > expt)
54
- count += 1
55
- sleep @each_vn_dump_sleep if count % @each_vn_dump_sleep_count == 0
56
- next
57
- end
58
- if val
59
- yield [vn, last, clk, expt, k.length, k, val.length, val].pack("NNNNNa#{k.length}Na#{val.length}")
60
- else
61
- yield [vn, last, clk, expt, k.length, k, 0].pack("NNNNNa#{k.length}N")
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
- n=10000
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 "usage:simple_bench addr:port"
88
+ STDERR.puts opts.help
47
89
  exit
48
90
  end
49
91
 
50
- tn=10
51
- t=[]
52
- tn.times{
53
- t << Thread.new{
54
- random_rquest_sender(ARGV)
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[0].join
106
+ t.each{|th| th.join }
59
107
 
108
+ puts "#{File.basename($0)} has done."
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Roma
3
- VERSION = "0.8.11"
3
+ VERSION = "0.8.12"
4
4
  end
@@ -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
@@ -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