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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/Rakefile +6 -0
- data/bin/droonga-engine-absorb-data +14 -14
- data/bin/droonga-engine-catalog-generate +24 -12
- data/bin/droonga-engine-catalog-modify +13 -7
- data/bin/droonga-engine-join +8 -8
- data/bin/droonga-engine-set-role +1 -1
- data/bin/droonga-engine-unjoin +2 -2
- data/lib/droonga/address.rb +3 -0
- data/lib/droonga/cluster.rb +16 -10
- data/lib/droonga/command/droonga_engine_service.rb +5 -2
- data/lib/droonga/command/remote_command_base.rb +3 -3
- data/lib/droonga/distributed_command_planner.rb +11 -1
- data/lib/droonga/engine.rb +12 -11
- data/lib/droonga/engine/version.rb +2 -2
- data/lib/droonga/engine_node.rb +28 -28
- data/lib/droonga/engine_state.rb +41 -36
- data/lib/droonga/forward_buffer.rb +21 -10
- data/lib/droonga/node_role.rb +2 -0
- data/lib/droonga/plugins/groonga/select.rb +3 -0
- data/lib/droonga/plugins/search.rb +3 -1
- data/lib/droonga/plugins/search/distributed_search_planner.rb +17 -5
- data/lib/droonga/plugins/system/statistics.rb +1 -0
- data/lib/droonga/searcher.rb +13 -4
- data/test/command/config/single_slice/catalog.json +38 -0
- data/test/command/config/single_slice/droonga-engine.yaml +4 -0
- data/test/command/run-test.rb +3 -2
- data/test/command/suite/catalog/fetch.expected.single_slice +50 -0
- data/test/command/suite/dump/column/index.expected.single_slice +86 -0
- data/test/command/suite/dump/column/scalar.expected.single_slice +52 -0
- data/test/command/suite/dump/column/vector.expected.single_slice +55 -0
- data/test/command/suite/dump/record/scalar.expected.single_slice +52 -0
- data/test/command/suite/dump/record/vector/reference.expected.single_slice +117 -0
- data/test/command/suite/dump/table/array.expected.single_slice +39 -0
- data/test/command/suite/dump/table/double_array_trie.expected.single_slice +40 -0
- data/test/command/suite/dump/table/hash.expected.single_slice +40 -0
- data/test/command/suite/dump/table/patricia_trie.expected.single_slice +40 -0
- data/test/command/suite/message/error/missing-dataset.test +3 -0
- data/test/command/suite/search/condition/query/nonexistent_column.expected.single_slice +26 -0
- data/test/command/suite/search/condition/query/syntax_error.expected.single_slice +26 -0
- data/test/command/suite/search/error/unknown-source.expected.single_slice +28 -0
- data/test/command/suite/search/output/attributes/invalid.expected.single_slice +24 -0
- data/test/command/suite/system/absorb-data/records.catalog.json.single_slice +44 -0
- data/test/command/suite/system/absorb-data/records.expected.single_slice +32 -0
- data/test/command/suite/system/statistics/object/count/per-volume/empty.test +1 -0
- data/test/command/suite/system/statistics/object/count/record.expected.single_slice +11 -0
- data/test/command/suite/system/statistics/object/count/schema.expected.single_slice +11 -0
- data/test/unit/catalog/test_generator.rb +3 -2
- data/test/unit/helper.rb +2 -1
- data/test/unit/helper/stub_serf.rb +28 -0
- data/test/unit/plugins/system/statistics/test_object_count.rb +135 -0
- data/test/unit/plugins/system/statistics/test_object_count_per_volume.rb +149 -0
- data/test/unit/plugins/test_basic.rb +0 -406
- data/test/unit/test_address.rb +111 -10
- data/test/unit/test_cluster.rb +232 -0
- data/test/unit/test_differ.rb +49 -0
- data/test/unit/test_engine_node.rb +556 -0
- data/test/unit/test_engine_state.rb +151 -0
- data/test/unit/test_forward_buffer.rb +106 -0
- data/test/unit/test_node_name.rb +160 -0
- data/test/unit/test_node_role.rb +53 -0
- data/test/unit/test_reducer.rb +525 -0
- metadata +111 -49
data/test/unit/test_address.rb
CHANGED
@@ -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
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
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
|