droonga-engine 1.1.0 → 1.1.1

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -1
  3. data/Rakefile +6 -0
  4. data/bin/droonga-engine-absorb-data +14 -14
  5. data/bin/droonga-engine-catalog-generate +24 -12
  6. data/bin/droonga-engine-catalog-modify +13 -7
  7. data/bin/droonga-engine-join +8 -8
  8. data/bin/droonga-engine-set-role +1 -1
  9. data/bin/droonga-engine-unjoin +2 -2
  10. data/lib/droonga/address.rb +3 -0
  11. data/lib/droonga/cluster.rb +16 -10
  12. data/lib/droonga/command/droonga_engine_service.rb +5 -2
  13. data/lib/droonga/command/remote_command_base.rb +3 -3
  14. data/lib/droonga/distributed_command_planner.rb +11 -1
  15. data/lib/droonga/engine.rb +12 -11
  16. data/lib/droonga/engine/version.rb +2 -2
  17. data/lib/droonga/engine_node.rb +28 -28
  18. data/lib/droonga/engine_state.rb +41 -36
  19. data/lib/droonga/forward_buffer.rb +21 -10
  20. data/lib/droonga/node_role.rb +2 -0
  21. data/lib/droonga/plugins/groonga/select.rb +3 -0
  22. data/lib/droonga/plugins/search.rb +3 -1
  23. data/lib/droonga/plugins/search/distributed_search_planner.rb +17 -5
  24. data/lib/droonga/plugins/system/statistics.rb +1 -0
  25. data/lib/droonga/searcher.rb +13 -4
  26. data/test/command/config/single_slice/catalog.json +38 -0
  27. data/test/command/config/single_slice/droonga-engine.yaml +4 -0
  28. data/test/command/run-test.rb +3 -2
  29. data/test/command/suite/catalog/fetch.expected.single_slice +50 -0
  30. data/test/command/suite/dump/column/index.expected.single_slice +86 -0
  31. data/test/command/suite/dump/column/scalar.expected.single_slice +52 -0
  32. data/test/command/suite/dump/column/vector.expected.single_slice +55 -0
  33. data/test/command/suite/dump/record/scalar.expected.single_slice +52 -0
  34. data/test/command/suite/dump/record/vector/reference.expected.single_slice +117 -0
  35. data/test/command/suite/dump/table/array.expected.single_slice +39 -0
  36. data/test/command/suite/dump/table/double_array_trie.expected.single_slice +40 -0
  37. data/test/command/suite/dump/table/hash.expected.single_slice +40 -0
  38. data/test/command/suite/dump/table/patricia_trie.expected.single_slice +40 -0
  39. data/test/command/suite/message/error/missing-dataset.test +3 -0
  40. data/test/command/suite/search/condition/query/nonexistent_column.expected.single_slice +26 -0
  41. data/test/command/suite/search/condition/query/syntax_error.expected.single_slice +26 -0
  42. data/test/command/suite/search/error/unknown-source.expected.single_slice +28 -0
  43. data/test/command/suite/search/output/attributes/invalid.expected.single_slice +24 -0
  44. data/test/command/suite/system/absorb-data/records.catalog.json.single_slice +44 -0
  45. data/test/command/suite/system/absorb-data/records.expected.single_slice +32 -0
  46. data/test/command/suite/system/statistics/object/count/per-volume/empty.test +1 -0
  47. data/test/command/suite/system/statistics/object/count/record.expected.single_slice +11 -0
  48. data/test/command/suite/system/statistics/object/count/schema.expected.single_slice +11 -0
  49. data/test/unit/catalog/test_generator.rb +3 -2
  50. data/test/unit/helper.rb +2 -1
  51. data/test/unit/helper/stub_serf.rb +28 -0
  52. data/test/unit/plugins/system/statistics/test_object_count.rb +135 -0
  53. data/test/unit/plugins/system/statistics/test_object_count_per_volume.rb +149 -0
  54. data/test/unit/plugins/test_basic.rb +0 -406
  55. data/test/unit/test_address.rb +111 -10
  56. data/test/unit/test_cluster.rb +232 -0
  57. data/test/unit/test_differ.rb +49 -0
  58. data/test/unit/test_engine_node.rb +556 -0
  59. data/test/unit/test_engine_state.rb +151 -0
  60. data/test/unit/test_forward_buffer.rb +106 -0
  61. data/test/unit/test_node_name.rb +160 -0
  62. data/test/unit/test_node_role.rb +53 -0
  63. data/test/unit/test_reducer.rb +525 -0
  64. metadata +111 -49
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014 Droonga Project
1
+ # Copyright (C) 2014-2015 Droonga Project
2
2
  #
3
3
  # This library is free software; you can redistribute it and/or
4
4
  # modify it under the terms of the GNU Lesser General Public
@@ -28,19 +28,80 @@ class AddressTest < Test::Unit::TestCase
28
28
  Droonga::Address.parse(string)
29
29
  end
30
30
 
31
- def test_full
32
- assert_equal(address("192.168.0.1", 2929, "droonga", "local_name"),
33
- parse("192.168.0.1:2929/droonga.local_name"))
31
+ data(:full => {
32
+ :input => "node29:2929/droonga.local_name",
33
+ :host => "node29",
34
+ :port => 2929,
35
+ :tag => "droonga",
36
+ :local_name => "local_name",
37
+ },
38
+ :ip_address => {
39
+ :input => "192.168.0.1:2929/droonga.local_name",
40
+ :host => "192.168.0.1",
41
+ :port => 2929,
42
+ :tag => "droonga",
43
+ :local_name => "local_name",
44
+ },
45
+ :internal_name => {
46
+ :input => "node29:2929/droonga.\#1",
47
+ :host => "node29",
48
+ :port => 2929,
49
+ :tag => "droonga",
50
+ :local_name => "#1",
51
+ },
52
+ :no_local_name => {
53
+ :input => "node29:2929/droonga",
54
+ :host => "node29",
55
+ :port => 2929,
56
+ :tag => "droonga",
57
+ :local_name => nil,
58
+ })
59
+ def test_success(data)
60
+ assert_equal(address(data[:host], data[:port], data[:tag],
61
+ data[:local_name]),
62
+ parse(data[:input]))
34
63
  end
35
64
 
36
- def test_internal_name
37
- assert_equal(address("192.168.0.1", 2929, "droonga", "#1"),
38
- parse("192.168.0.1:2929/droonga.\#1"))
65
+ data(:no_host => ":2929/droonga",
66
+ :no_port => "192.168.0.1/droonga",
67
+ :no_tag => "192.168.0.1:2929",
68
+ :blank => "",
69
+ :nil => nil)
70
+ def test_fail(input)
71
+ assert_raise(ArgumentError) do
72
+ parse(input)
73
+ end
74
+ end
75
+ end
76
+
77
+ class AttributeTest < self
78
+ def test_attributes
79
+ address = address("192.168.0.1", 2929, "droonga", "000")
80
+ assert_equal({:host => "192.168.0.1",
81
+ :port => 2929,
82
+ :tag => "droonga",
83
+ :local_name => "000"},
84
+ {:host => address.host,
85
+ :port => address.port,
86
+ :tag => address.tag,
87
+ :local_name => address.local_name})
88
+ end
89
+ end
90
+
91
+ class ComparisonTest < self
92
+ def test_address_vs_string
93
+ string = "192.168.0.1:2929/droonga.000"
94
+ address = address("192.168.0.1", 2929, "droonga", "000")
95
+ assert_true(address == string)
39
96
  end
40
97
 
41
- def test_no_name
42
- assert_equal(address("192.168.0.1", 2929, "droonga", nil),
43
- parse("192.168.0.1:2929/droonga"))
98
+ #XXX This is a confusable behavior. It seems should be true
99
+ # but actually false, so you have to be careful when you
100
+ # compare string with Address.
101
+ def test_string_vs_address
102
+ string = "192.168.0.1:2929/droonga.000"
103
+ address = address("192.168.0.1", 2929, "droonga", "000")
104
+ assert_false(string == address)
44
105
  end
45
106
  end
46
107
 
@@ -49,5 +110,45 @@ class AddressTest < Test::Unit::TestCase
49
110
  assert_equal("192.168.0.1:2929/droonga",
50
111
  address("192.168.0.1", 2929, "droonga", "000").node)
51
112
  end
113
+
114
+ data(:full => {
115
+ :expected => "192.168.0.1:2929/droonga.000",
116
+ :host => "192.168.0.1",
117
+ :port => 2929,
118
+ :tag => "droonga",
119
+ :local_name => "000",
120
+ },
121
+ :no_local_name => {
122
+ :expected => "192.168.0.1:2929/droonga",
123
+ :host => "192.168.0.1",
124
+ :port => 2929,
125
+ :tag => "droonga",
126
+ :local_name => nil,
127
+ })
128
+ def test_string(data)
129
+ assert_equal(data[:expected],
130
+ address(data[:host], data[:port], data[:tag],
131
+ data[:local_name]).to_s)
132
+ end
133
+
134
+ data(:full => {
135
+ :expected => ["192.168.0.1", 2929, "droonga", "000"],
136
+ :host => "192.168.0.1",
137
+ :port => 2929,
138
+ :tag => "droonga",
139
+ :local_name => "000",
140
+ },
141
+ :no_local_name => {
142
+ :expected => ["192.168.0.1", 2929, "droonga", nil],
143
+ :host => "192.168.0.1",
144
+ :port => 2929,
145
+ :tag => "droonga",
146
+ :local_name => nil,
147
+ })
148
+ def test_array(data)
149
+ assert_equal(data[:expected],
150
+ address(data[:host], data[:port], data[:tag],
151
+ data[:local_name]).to_a)
152
+ end
52
153
  end
53
154
  end
@@ -0,0 +1,232 @@
1
+ # Copyright (C) 2014-2015 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
+
16
+ require "droonga/cluster"
17
+ require "droonga/node_role"
18
+
19
+ class ClusterTest < Test::Unit::TestCase
20
+ class StubCatalog
21
+ attr_accessor :all_nodes
22
+
23
+ def initialize(all_nodes)
24
+ @all_nodes = all_nodes || []
25
+ end
26
+ end
27
+
28
+ class StubEngineNode < Droonga::EngineNode
29
+ attr_reader :forwarded_messages, :bounced_messages
30
+
31
+ def initialize(params)
32
+ @forwarded_messages = []
33
+ @bounced_messages = []
34
+ super
35
+ end
36
+
37
+ def resume
38
+ end
39
+
40
+ def forward(message, destination)
41
+ @forwarded_messages << {:message => message,
42
+ :destination => destination}
43
+ end
44
+
45
+ def bounce(message)
46
+ @bounced_messages << message
47
+ end
48
+
49
+ private
50
+ def sender_role
51
+ Droonga::NodeRole::SERVICE_PROVIDER
52
+ end
53
+
54
+ def create_buffer
55
+ []
56
+ end
57
+ end
58
+
59
+ class Cluster < Droonga::Cluster
60
+ def reload
61
+ end
62
+
63
+ def start
64
+ engine_nodes # instantiate it
65
+ end
66
+
67
+ private
68
+ def create_engine_node(params)
69
+ StubEngineNode.new(params)
70
+ end
71
+ end
72
+
73
+ def create_cluster(options={})
74
+ catalog = StubCatalog.new(options[:all_nodes])
75
+ Cluster.new(:state => options[:state],
76
+ :catalog => catalog)
77
+ end
78
+
79
+ def test_engine_nodes
80
+ cluster = create_cluster(:all_nodes => [
81
+ "node29:2929/droonga",
82
+ "node30:2929/droonga",
83
+ ])
84
+ assert_equal([
85
+ {:class => StubEngineNode,
86
+ :name => "node29:2929/droonga"},
87
+ {:class => StubEngineNode,
88
+ :name => "node30:2929/droonga"},
89
+ ],
90
+ cluster.engine_nodes.collect do |node|
91
+ {:class => node.class,
92
+ :name => node.name}
93
+ end)
94
+ end
95
+
96
+ def test_engine_node_names
97
+ cluster = create_cluster(:all_nodes => [
98
+ "node29:2929/droonga",
99
+ "node30:2929/droonga",
100
+ ])
101
+ assert_equal([
102
+ "node29:2929/droonga",
103
+ "node30:2929/droonga",
104
+ ],
105
+ cluster.engine_node_names)
106
+ end
107
+
108
+ def test_engine_nodes_status
109
+ cluster = create_cluster(:state => {
110
+ "node29:2929/droonga" => {
111
+ "live" => true,
112
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
113
+ },
114
+ "node30:2929/droonga" => {
115
+ "live" => true,
116
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
117
+ },
118
+ },
119
+ :all_nodes => [
120
+ "node29:2929/droonga",
121
+ "node30:2929/droonga",
122
+ ])
123
+ assert_equal({
124
+ "node29:2929/droonga" => {
125
+ "status" => "active",
126
+ },
127
+ "node30:2929/droonga" => {
128
+ "status" => "active",
129
+ },
130
+ },
131
+ cluster.engine_nodes_status)
132
+ end
133
+
134
+ def test_readable_nodes
135
+ cluster = create_cluster(:state => {
136
+ "node29:2929/droonga" => {
137
+ "live" => true,
138
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
139
+ },
140
+ "node30:2929/droonga" => {
141
+ "live" => false,
142
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
143
+ },
144
+ },
145
+ :all_nodes => [
146
+ "node29:2929/droonga",
147
+ "node30:2929/droonga",
148
+ ])
149
+ assert_equal([
150
+ "node29:2929/droonga",
151
+ ],
152
+ cluster.readable_nodes)
153
+ end
154
+
155
+ def test_writable_nodes
156
+ cluster = create_cluster(:all_nodes => [
157
+ "node29:2929/droonga",
158
+ "node30:2929/droonga",
159
+ ])
160
+ assert_equal([
161
+ "node29:2929/droonga",
162
+ "node30:2929/droonga",
163
+ ],
164
+ cluster.writable_nodes)
165
+ end
166
+
167
+ def test_forward
168
+ cluster = create_cluster(:state => {
169
+ "node29:2929/droonga" => {
170
+ "live" => true,
171
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
172
+ },
173
+ "node30:2929/droonga" => {
174
+ "live" => true,
175
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
176
+ },
177
+ },
178
+ :all_nodes => [
179
+ "node29:2929/droonga",
180
+ "node30:2929/droonga",
181
+ ])
182
+ cluster.start
183
+ cluster.forward({"id" => 1},
184
+ {"to" => "node29:2929/droonga"})
185
+ assert_equal([
186
+ {:name => "node29:2929/droonga",
187
+ :forwarded => [
188
+ {:message => {"id" => 1},
189
+ :destination => {"to" => "node29:2929/droonga"}}
190
+ ]},
191
+ {:name => "node30:2929/droonga",
192
+ :forwarded => []}
193
+ ],
194
+ cluster.engine_nodes.collect do |node|
195
+ {:name => node.name,
196
+ :forwarded => node.forwarded_messages}
197
+ end)
198
+ end
199
+
200
+ def test_bounce
201
+ cluster = create_cluster(:state => {
202
+ "node29:2929/droonga" => {
203
+ "live" => true,
204
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
205
+ },
206
+ "node30:2929/droonga" => {
207
+ "live" => true,
208
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
209
+ },
210
+ },
211
+ :all_nodes => [
212
+ "node29:2929/droonga",
213
+ "node30:2929/droonga",
214
+ ])
215
+ cluster.start
216
+ cluster.bounce({"id" => 1,
217
+ "targetRole" => Droonga::NodeRole::ABSORB_SOURCE})
218
+ assert_equal([
219
+ {:name => "node29:2929/droonga",
220
+ :bounced => []},
221
+ {:name => "node30:2929/droonga",
222
+ :bounced => [
223
+ {"id" => 1,
224
+ "targetRole" => Droonga::NodeRole::ABSORB_SOURCE},
225
+ ]}
226
+ ],
227
+ cluster.engine_nodes.collect do |node|
228
+ {:name => node.name,
229
+ :bounced => node.bounced_messages}
230
+ end)
231
+ end
232
+ end
@@ -0,0 +1,49 @@
1
+ # Copyright (C) 2015 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
+
16
+ require "droonga/differ"
17
+
18
+ class DifferTest < Test::Unit::TestCase
19
+ data(:string => {
20
+ :left => "a",
21
+ :right => "b",
22
+ :expected => "\"a\" <=> \"b\"",
23
+ },
24
+ :numeric => {
25
+ :left => 0,
26
+ :right => 1,
27
+ :expected => "0 <=> 1",
28
+ },
29
+ :hash => {
30
+ :left => {:a => 0, :b => 1},
31
+ :right => {:a => 0, :b => 2},
32
+ :expected => {:b => "1 <=> 2"},
33
+ },
34
+ :array => {
35
+ :left => [0, 1, 2],
36
+ :right => [0, 1, 3],
37
+ :expected => {2 => "2 <=> 3"},
38
+ },
39
+ :nested => {
40
+ :left => {:a => 0, :b => {:aa => 0, :bb => 1}},
41
+ :right => {:a => 1, :b => {:aa => 0, :bb => 2}},
42
+ :expected => {:a => "0 <=> 1",
43
+ :b => {:bb => "1 <=> 2"}},
44
+ })
45
+ def test_diff(data)
46
+ assert_equal(data[:expected],
47
+ Droonga::Differ.diff(data[:left], data[:right]))
48
+ end
49
+ end
@@ -0,0 +1,556 @@
1
+ # Copyright (C) 2015 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
+
16
+ require "droonga/engine_node"
17
+ require "droonga/node_role"
18
+
19
+ class EngineNodeTest < Test::Unit::TestCase
20
+ def node(params)
21
+ Droonga::EngineNode.new(params)
22
+ end
23
+
24
+ data(:no_state => {
25
+ :expected => Droonga::NodeRole::SERVICE_PROVIDER,
26
+ :state => nil,
27
+ },
28
+ :valid => {
29
+ :expected => Droonga::NodeRole::ABSORB_SOURCE,
30
+ :state => {
31
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
32
+ },
33
+ },
34
+ :invalid => {
35
+ :expected => Droonga::NodeRole::SERVICE_PROVIDER,
36
+ :state => {
37
+ "role" => "unknown",
38
+ },
39
+ })
40
+ def test_role(data)
41
+ assert_equal(data[:expected],
42
+ node(:name => "node29:2929/droonga",
43
+ :state => data[:state]).role)
44
+ end
45
+
46
+ data(:no_state => nil,
47
+ :live_info => {
48
+ "live" => true,
49
+ })
50
+ def test_live(state)
51
+ assert_true(node(:name => "node29:2929/droonga",
52
+ :state => state).live?)
53
+ end
54
+
55
+ data(:no_live_info => {
56
+ },
57
+ :live_info => {
58
+ "live" => false,
59
+ })
60
+ def test_not_live(state)
61
+ assert_false(node(:name => "node29:2929/droonga",
62
+ :state => state).live?)
63
+ end
64
+
65
+ data(:valid => {
66
+ :state => {
67
+ "live" => true,
68
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
69
+ },
70
+ :expected => {
71
+ "name" => "node29:2929/droonga",
72
+ "live" => true,
73
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
74
+ "status" => "active",
75
+ },
76
+ })
77
+ def test_to_json(data)
78
+ json = node(:name => "node29:2929/droonga",
79
+ :state => data[:state]).to_json
80
+ assert_equal(data[:expected], json)
81
+ end
82
+
83
+ class Buffered < Droonga::EngineNode
84
+ private
85
+ def create_buffer
86
+ [0]
87
+ end
88
+ end
89
+
90
+ class NotBuffered < Droonga::EngineNode
91
+ private
92
+ def create_buffer
93
+ []
94
+ end
95
+ end
96
+
97
+ class FromServiceProvider < self
98
+ class BufferedEngineNode < Buffered
99
+ private
100
+ def sender_role
101
+ Droonga::NodeRole::SERVICE_PROVIDER
102
+ end
103
+ end
104
+
105
+ class NotBufferedEngineNode < NotBuffered
106
+ private
107
+ def sender_role
108
+ Droonga::NodeRole::SERVICE_PROVIDER
109
+ end
110
+ end
111
+
112
+ class EngineNode < NotBufferedEngineNode
113
+ end
114
+
115
+ data(:same_role => {
116
+ "live" => true,
117
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
118
+ })
119
+ def test_forwardable(state)
120
+ assert_true(EngineNode.new(:name => "node29:2929/droonga",
121
+ :state => state).forwardable?)
122
+ end
123
+
124
+ data(:dead => {
125
+ "live" => false,
126
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
127
+ },
128
+ :to_absorb_source => {
129
+ "live" => true,
130
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
131
+ },
132
+ :to_absorb_destination => {
133
+ "live" => true,
134
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
135
+ })
136
+ def test_not_forwardable(state)
137
+ assert_false(EngineNode.new(:name => "node29:2929/droonga",
138
+ :state => state).forwardable?)
139
+ end
140
+
141
+ data(:same_role_with_no_unprocessed_message => {
142
+ :state => {
143
+ "live" => true,
144
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
145
+ },
146
+ :class => NotBufferedEngineNode,
147
+ })
148
+ def test_readable(data)
149
+ assert_true(data[:class].new(:name => "node29:2929/droonga",
150
+ :state => data[:state]).readable?)
151
+ end
152
+
153
+ data(:dead => {
154
+ :state => {
155
+ "live" => false,
156
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
157
+ },
158
+ :class => NotBufferedEngineNode,
159
+ },
160
+ :have_unprocessed_message_in_other_node => {
161
+ :state => {
162
+ "live" => true,
163
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
164
+ "have_unprocessed_messages" => true,
165
+ },
166
+ :class => NotBufferedEngineNode,
167
+ },
168
+ :have_unprocessed_message => {
169
+ :state => {
170
+ "live" => true,
171
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
172
+ },
173
+ :class => BufferedEngineNode,
174
+ },
175
+ :to_absorb_source => {
176
+ :state => {
177
+ "live" => true,
178
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
179
+ },
180
+ :class => NotBufferedEngineNode,
181
+ },
182
+ :to_absorb_destination => {
183
+ :state => {
184
+ "live" => true,
185
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
186
+ },
187
+ :class => NotBufferedEngineNode,
188
+ })
189
+ def test_not_readable(data)
190
+ assert_false(data[:class].new(:name => "node29:2929/droonga",
191
+ :state => data[:state]).readable?)
192
+ end
193
+
194
+ data(:same_role => {
195
+ "live" => true,
196
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
197
+ },
198
+ :to_absorb_source => {
199
+ "live" => true,
200
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
201
+ },
202
+ :to_absorb_destination => {
203
+ "live" => true,
204
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
205
+ },
206
+ :to_dead => {
207
+ "live" => false,
208
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
209
+ },
210
+ :to_node_have_unprocessed_message => {
211
+ "live" => true,
212
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
213
+ "have_unprocessed_messages" => true,
214
+ })
215
+ def test_writable(state)
216
+ assert_true(EngineNode.new(:name => "node29:2929/droonga",
217
+ :state => state).writable?)
218
+ end
219
+
220
+ data(:dead => {
221
+ :state => {
222
+ "live" => false,
223
+ },
224
+ :expected => "dead",
225
+ },
226
+ :readable => {
227
+ :state => {
228
+ "live" => true,
229
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
230
+ },
231
+ :expected => "active",
232
+ },
233
+ :not_readable_but_writable => {
234
+ :state => {
235
+ "live" => true,
236
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
237
+ },
238
+ :expected => "inactive",
239
+ })
240
+ def test_status(data)
241
+ assert_equal(data[:expected],
242
+ EngineNode.new(:name => "node29:2929/droonga",
243
+ :state => data[:state]).status)
244
+ end
245
+ end
246
+
247
+ class FromAbsorbSource < self
248
+ class BufferedEngineNode < Buffered
249
+ private
250
+ def sender_role
251
+ Droonga::NodeRole::ABSORB_SOURCE
252
+ end
253
+ end
254
+
255
+ class NotBufferedEngineNode < NotBuffered
256
+ private
257
+ def sender_role
258
+ Droonga::NodeRole::ABSORB_SOURCE
259
+ end
260
+ end
261
+
262
+ class EngineNode < NotBufferedEngineNode
263
+ end
264
+
265
+ data(:same_role => {
266
+ "live" => true,
267
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
268
+ })
269
+ def test_forwardable(state)
270
+ assert_true(EngineNode.new(:name => "node29:2929/droonga",
271
+ :state => state).forwardable?)
272
+ end
273
+
274
+ data(:dead => {
275
+ "live" => false,
276
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
277
+ },
278
+ :to_service_provider => {
279
+ "live" => true,
280
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
281
+ },
282
+ :to_absorb_destination => {
283
+ "live" => true,
284
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
285
+ })
286
+ def test_not_forwardable(state)
287
+ assert_false(EngineNode.new(:name => "node29:2929/droonga",
288
+ :state => state).forwardable?)
289
+ end
290
+
291
+ data(:same_role_with_no_unprocessed_message => {
292
+ :state => {
293
+ "live" => true,
294
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
295
+ },
296
+ :class => NotBufferedEngineNode,
297
+ },
298
+ :have_unprocessed_message_in_other_node => {
299
+ :state => {
300
+ "live" => true,
301
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
302
+ "have_unprocessed_messages" => true,
303
+ },
304
+ :class => NotBufferedEngineNode,
305
+ })
306
+ def test_readable(data)
307
+ assert_true(data[:class].new(:name => "node29:2929/droonga",
308
+ :state => data[:state]).readable?)
309
+ end
310
+
311
+ data(:dead => {
312
+ :state => {
313
+ "live" => false,
314
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
315
+ },
316
+ :class => NotBufferedEngineNode,
317
+ },
318
+ :have_unprocessed_message => {
319
+ :state => {
320
+ "live" => true,
321
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
322
+ },
323
+ :class => BufferedEngineNode,
324
+ },
325
+ :to_service_provider => {
326
+ :state => {
327
+ "live" => true,
328
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
329
+ },
330
+ :class => NotBufferedEngineNode,
331
+ },
332
+ :to_absorb_destination => {
333
+ :state => {
334
+ "live" => true,
335
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
336
+ },
337
+ :class => NotBufferedEngineNode,
338
+ })
339
+ def test_not_readable(data)
340
+ assert_false(data[:class].new(:name => "node29:2929/droonga",
341
+ :state => data[:state]).readable?)
342
+ end
343
+
344
+ data(:same_role => {
345
+ "live" => true,
346
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
347
+ },
348
+ :to_dead => {
349
+ "live" => false,
350
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
351
+ },
352
+ :to_node_have_unprocessed_message => {
353
+ "live" => true,
354
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
355
+ "have_unprocessed_messages" => true,
356
+ })
357
+ def test_writable(state)
358
+ assert_true(EngineNode.new(:name => "node29:2929/droonga",
359
+ :state => state).writable?)
360
+ end
361
+
362
+ data(:to_service_provider => {
363
+ "live" => true,
364
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
365
+ },
366
+ :to_absorb_destination => {
367
+ "live" => true,
368
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
369
+ })
370
+ def test_not_writable(state)
371
+ assert_false(EngineNode.new(:name => "node29:2929/droonga",
372
+ :state => state).writable?)
373
+ end
374
+
375
+ data(:dead => {
376
+ :state => {
377
+ "live" => false,
378
+ },
379
+ :expected => "dead",
380
+ },
381
+ :readable => {
382
+ :state => {
383
+ "live" => true,
384
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
385
+ },
386
+ :expected => "active",
387
+ },
388
+ :not_readable_but_writable => {
389
+ :state => {
390
+ "live" => true,
391
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
392
+ },
393
+ :expected => "inactive",
394
+ })
395
+ def test_status(data)
396
+ assert_equal(data[:expected],
397
+ EngineNode.new(:name => "node29:2929/droonga",
398
+ :state => data[:state]).status)
399
+ end
400
+ end
401
+
402
+ class FromAbsorbDestination < self
403
+ class BufferedEngineNode < Buffered
404
+ private
405
+ def sender_role
406
+ Droonga::NodeRole::ABSORB_DESTINATION
407
+ end
408
+ end
409
+
410
+ class NotBufferedEngineNode < NotBuffered
411
+ private
412
+ def sender_role
413
+ Droonga::NodeRole::ABSORB_DESTINATION
414
+ end
415
+ end
416
+
417
+ class EngineNode < NotBufferedEngineNode
418
+ end
419
+
420
+ data(:same_role => {
421
+ "live" => true,
422
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
423
+ })
424
+ def test_forwardable(state)
425
+ assert_true(EngineNode.new(:name => "node29:2929/droonga",
426
+ :state => state).forwardable?)
427
+ end
428
+
429
+ data(:dead => {
430
+ "live" => false,
431
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
432
+ },
433
+ :to_service_provider => {
434
+ "live" => true,
435
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
436
+ },
437
+ :to_absorb_source => {
438
+ "live" => true,
439
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
440
+ })
441
+ def test_not_forwardable(state)
442
+ assert_false(EngineNode.new(:name => "node29:2929/droonga",
443
+ :state => state).forwardable?)
444
+ end
445
+
446
+ data(:same_role_with_no_unprocessed_message => {
447
+ :state => {
448
+ "live" => true,
449
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
450
+ },
451
+ :class => NotBufferedEngineNode,
452
+ },
453
+ :have_unprocessed_message_in_other_node => {
454
+ :state => {
455
+ "live" => true,
456
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
457
+ "have_unprocessed_messages" => true,
458
+ },
459
+ :class => NotBufferedEngineNode,
460
+ })
461
+ def test_readable(data)
462
+ assert_true(data[:class].new(:name => "node29:2929/droonga",
463
+ :state => data[:state]).readable?)
464
+ end
465
+
466
+ data(:dead => {
467
+ :state => {
468
+ "live" => false,
469
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
470
+ },
471
+ :class => NotBufferedEngineNode,
472
+ },
473
+ :have_unprocessed_message => {
474
+ :state => {
475
+ "live" => true,
476
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
477
+ },
478
+ :class => BufferedEngineNode,
479
+ },
480
+ :to_service_provider => {
481
+ :state => {
482
+ "live" => true,
483
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
484
+ },
485
+ :class => NotBufferedEngineNode,
486
+ },
487
+ :to_absorb_source => {
488
+ :state => {
489
+ "live" => true,
490
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
491
+ },
492
+ :class => NotBufferedEngineNode,
493
+ })
494
+ def test_not_readable(data)
495
+ assert_false(data[:class].new(:name => "node29:2929/droonga",
496
+ :state => data[:state]).readable?)
497
+ end
498
+
499
+ data(:same_role => {
500
+ "live" => true,
501
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
502
+ },
503
+ :to_dead => {
504
+ "live" => false,
505
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
506
+ },
507
+ :to_node_have_unprocessed_message => {
508
+ "live" => true,
509
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
510
+ "have_unprocessed_messages" => true,
511
+ })
512
+ def test_writable(state)
513
+ assert_true(EngineNode.new(:name => "node29:2929/droonga",
514
+ :state => state).writable?)
515
+ end
516
+
517
+ data(:to_service_provider => {
518
+ "live" => true,
519
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
520
+ },
521
+ :to_absorb_source => {
522
+ "live" => true,
523
+ "role" => Droonga::NodeRole::ABSORB_SOURCE,
524
+ })
525
+ def test_not_writable(state)
526
+ assert_false(EngineNode.new(:name => "node29:2929/droonga",
527
+ :state => state).writable?)
528
+ end
529
+
530
+ data(:dead => {
531
+ :state => {
532
+ "live" => false,
533
+ },
534
+ :expected => "dead",
535
+ },
536
+ :readable => {
537
+ :state => {
538
+ "live" => true,
539
+ "role" => Droonga::NodeRole::ABSORB_DESTINATION,
540
+ },
541
+ :expected => "active",
542
+ },
543
+ :not_readable_but_writable => {
544
+ :state => {
545
+ "live" => true,
546
+ "role" => Droonga::NodeRole::SERVICE_PROVIDER,
547
+ },
548
+ :expected => "inactive",
549
+ })
550
+ def test_status(data)
551
+ assert_equal(data[:expected],
552
+ EngineNode.new(:name => "node29:2929/droonga",
553
+ :state => data[:state]).status)
554
+ end
555
+ end
556
+ end