fluent-plugin-droonga 0.9.0 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/Gemfile +8 -1
  4. data/fluent-plugin-droonga.gemspec +2 -2
  5. data/lib/droonga/adapter.rb +39 -0
  6. data/lib/droonga/adapter_runner.rb +99 -0
  7. data/lib/droonga/catalog/base.rb +11 -11
  8. data/lib/droonga/catalog/dataset.rb +54 -0
  9. data/lib/droonga/catalog/version1.rb +1 -1
  10. data/lib/droonga/collector.rb +5 -7
  11. data/lib/droonga/collector_plugin.rb +7 -7
  12. data/lib/droonga/command.rb +36 -0
  13. data/lib/droonga/{plugin/input_adapter/crud.rb → command_repository.rb} +14 -8
  14. data/lib/droonga/dispatcher.rb +86 -54
  15. data/lib/droonga/distributed_command_planner.rb +183 -0
  16. data/lib/droonga/distributor.rb +43 -17
  17. data/lib/droonga/handler.rb +13 -72
  18. data/lib/droonga/handler_message.rb +5 -5
  19. data/lib/droonga/handler_messenger.rb +4 -1
  20. data/lib/droonga/handler_plugin.rb +2 -2
  21. data/lib/droonga/handler_runner.rb +104 -0
  22. data/lib/droonga/input_message.rb +4 -4
  23. data/lib/droonga/legacy_pluggable.rb +66 -0
  24. data/lib/droonga/{input_adapter.rb → legacy_plugin.rb} +27 -22
  25. data/lib/droonga/{plugin_repository.rb → legacy_plugin_repository.rb} +2 -4
  26. data/lib/droonga/message_matcher.rb +101 -0
  27. data/lib/droonga/{input_adapter_plugin.rb → planner.rb} +14 -10
  28. data/lib/droonga/planner_plugin.rb +54 -0
  29. data/lib/droonga/pluggable.rb +9 -45
  30. data/lib/droonga/plugin.rb +9 -33
  31. data/lib/droonga/plugin/collector/basic.rb +2 -0
  32. data/lib/droonga/plugin/collector/search.rb +31 -37
  33. data/lib/droonga/plugin/{handler/groonga/table_remove.rb → metadata/adapter_message.rb} +23 -18
  34. data/lib/droonga/plugin/{handler/search.rb → metadata/handler_action.rb} +19 -15
  35. data/lib/droonga/plugin/metadata/input_message.rb +39 -0
  36. data/lib/droonga/plugin/planner/crud.rb +49 -0
  37. data/lib/droonga/plugin/{distributor → planner}/distributed_search_planner.rb +62 -70
  38. data/lib/droonga/plugin/{distributor → planner}/groonga.rb +11 -32
  39. data/lib/droonga/plugin/{distributor → planner}/search.rb +5 -5
  40. data/lib/droonga/plugin/{distributor → planner}/watch.rb +15 -6
  41. data/lib/droonga/plugin_loader.rb +10 -0
  42. data/lib/droonga/plugin_registerable.rb +34 -10
  43. data/lib/droonga/plugin_registry.rb +58 -0
  44. data/lib/droonga/plugins/crud.rb +124 -0
  45. data/lib/droonga/plugins/error.rb +50 -0
  46. data/lib/droonga/{output_adapter_plugin.rb → plugins/groonga.rb} +9 -13
  47. data/lib/droonga/plugins/groonga/column_create.rb +123 -0
  48. data/lib/droonga/plugins/groonga/generic_command.rb +65 -0
  49. data/lib/droonga/{plugin/output_adapter/groonga.rb → plugins/groonga/generic_response.rb} +16 -15
  50. data/lib/droonga/plugins/groonga/select.rb +124 -0
  51. data/lib/droonga/plugins/groonga/table_create.rb +106 -0
  52. data/lib/droonga/plugins/groonga/table_remove.rb +57 -0
  53. data/lib/droonga/plugins/search.rb +40 -0
  54. data/lib/droonga/plugins/watch.rb +156 -0
  55. data/lib/droonga/processor.rb +8 -10
  56. data/lib/droonga/searcher.rb +14 -4
  57. data/lib/droonga/searcher/mecab_filter.rb +67 -0
  58. data/lib/droonga/session.rb +5 -5
  59. data/lib/droonga/test.rb +1 -1
  60. data/lib/droonga/test/stub_handler_message.rb +1 -1
  61. data/lib/droonga/test/{stub_distributor.rb → stub_planner.rb} +1 -1
  62. data/lib/droonga/worker.rb +7 -8
  63. data/lib/fluent/plugin/out_droonga.rb +0 -1
  64. data/sample/cluster/catalog.json +2 -4
  65. data/sample/mecab_filter/data.grn +7 -0
  66. data/sample/mecab_filter/ddl.grn +7 -0
  67. data/sample/mecab_filter/search_with_mecab_filter.json +21 -0
  68. data/sample/mecab_filter/search_without_mecab_filter.json +21 -0
  69. data/test/command/config/default/catalog.json +2 -5
  70. data/test/command/suite/search/error/no-query.expected +13 -0
  71. data/test/command/suite/search/error/no-query.test +7 -0
  72. data/test/command/suite/search/error/unknown-source.expected +26 -0
  73. data/test/command/suite/watch/subscribe.expected +3 -3
  74. data/test/command/suite/watch/unsubscribe.expected +3 -3
  75. data/test/unit/catalog/test_dataset.rb +385 -0
  76. data/test/unit/catalog/test_version1.rb +111 -45
  77. data/test/unit/fixtures/catalog/version1.json +0 -3
  78. data/test/unit/helper.rb +2 -1
  79. data/test/unit/helper/distributed_search_planner_helper.rb +83 -0
  80. data/test/unit/plugin/collector/test_basic.rb +233 -376
  81. data/test/unit/plugin/collector/test_search.rb +8 -17
  82. data/test/unit/plugin/planner/search_planner/test_basic.rb +120 -0
  83. data/test/unit/plugin/planner/search_planner/test_group_by.rb +573 -0
  84. data/test/unit/plugin/planner/search_planner/test_output.rb +388 -0
  85. data/test/unit/plugin/planner/search_planner/test_sort_by.rb +938 -0
  86. data/test/unit/plugin/{distributor → planner}/test_search.rb +20 -75
  87. data/test/unit/{plugin/handler → plugins/crud}/test_add.rb +11 -11
  88. data/test/unit/plugins/groonga/select/test_adapter_input.rb +213 -0
  89. data/test/unit/{plugin/output_adapter/groonga/test_select.rb → plugins/groonga/select/test_adapter_output.rb} +12 -13
  90. data/test/unit/{plugin/handler → plugins}/groonga/test_column_create.rb +20 -5
  91. data/test/unit/{plugin/handler → plugins}/groonga/test_table_create.rb +5 -0
  92. data/test/unit/{plugin/handler → plugins}/groonga/test_table_remove.rb +8 -1
  93. data/test/unit/{plugin/handler → plugins}/test_groonga.rb +5 -5
  94. data/test/unit/{plugin/handler → plugins}/test_search.rb +21 -5
  95. data/test/unit/{plugin/handler → plugins}/test_watch.rb +29 -10
  96. data/{lib/droonga/command_mapper.rb → test/unit/test_command_repository.rb} +16 -22
  97. data/test/unit/{test_plugin.rb → test_legacy_plugin.rb} +3 -3
  98. data/test/unit/{test_plugin_repository.rb → test_legacy_plugin_repository.rb} +3 -3
  99. data/test/unit/test_message_matcher.rb +137 -0
  100. metadata +86 -66
  101. data/bin/grn2jsons +0 -82
  102. data/lib/droonga/distribution_planner.rb +0 -76
  103. data/lib/droonga/distributor_plugin.rb +0 -95
  104. data/lib/droonga/output_adapter.rb +0 -53
  105. data/lib/droonga/plugin/collector/groonga.rb +0 -83
  106. data/lib/droonga/plugin/distributor/crud.rb +0 -84
  107. data/lib/droonga/plugin/handler/add.rb +0 -109
  108. data/lib/droonga/plugin/handler/forward.rb +0 -75
  109. data/lib/droonga/plugin/handler/groonga.rb +0 -99
  110. data/lib/droonga/plugin/handler/groonga/column_create.rb +0 -106
  111. data/lib/droonga/plugin/handler/groonga/table_create.rb +0 -91
  112. data/lib/droonga/plugin/handler/watch.rb +0 -108
  113. data/lib/droonga/plugin/input_adapter/groonga.rb +0 -49
  114. data/lib/droonga/plugin/input_adapter/groonga/select.rb +0 -63
  115. data/lib/droonga/plugin/output_adapter/crud.rb +0 -51
  116. data/lib/droonga/plugin/output_adapter/groonga/select.rb +0 -54
  117. data/lib/groonga_command_converter.rb +0 -143
  118. data/sample/fluentd.conf +0 -8
  119. data/test/unit/plugin/distributor/test_search_planner.rb +0 -1102
  120. data/test/unit/plugin/input_adapter/groonga/test_select.rb +0 -248
  121. data/test/unit/test_command_mapper.rb +0 -44
  122. data/test/unit/test_groonga_command_converter.rb +0 -242
@@ -87,7 +87,7 @@ class SearchCollectorTest < Test::Unit::TestCase
87
87
  "output" => "search_result",
88
88
  "elements" => {
89
89
  "records" => {
90
- "type" => "sort",
90
+ "attributes" => ["_key"],
91
91
  "offset" => 1,
92
92
  "limit" => 1,
93
93
  },
@@ -114,7 +114,7 @@ class SearchCollectorTest < Test::Unit::TestCase
114
114
  "output" => "search_result",
115
115
  "elements" => {
116
116
  "records" => {
117
- "type" => "sort",
117
+ "attributes" => ["_key"],
118
118
  "offset" => 1,
119
119
  "limit" => -1,
120
120
  },
@@ -138,7 +138,6 @@ class SearchCollectorTest < Test::Unit::TestCase
138
138
  "output" => "search_result",
139
139
  "elements" => {
140
140
  "records" => {
141
- "type" => "sort",
142
141
  "format" => "simple",
143
142
  "attributes" => [],
144
143
  "offset" => 10000,
@@ -166,7 +165,6 @@ class SearchCollectorTest < Test::Unit::TestCase
166
165
  "output" => "search_result",
167
166
  "elements" => {
168
167
  "records" => {
169
- "type" => "sort",
170
168
  "attributes" => ["_key", "chapter", "section", "subsection", "paragraph"],
171
169
  "limit" => -1,
172
170
  },
@@ -192,7 +190,6 @@ class SearchCollectorTest < Test::Unit::TestCase
192
190
  "output" => "search_result",
193
191
  "elements" => {
194
192
  "records" => {
195
- "type" => "sort",
196
193
  "attributes" => ["_key", "chapter", "section"],
197
194
  "limit" => -1,
198
195
  },
@@ -218,7 +215,6 @@ class SearchCollectorTest < Test::Unit::TestCase
218
215
  "output" => "search_result",
219
216
  "elements" => {
220
217
  "records" => {
221
- "type" => "sort",
222
218
  "format" => "simple",
223
219
  "attributes" => ["_key", "chapter", "section"],
224
220
  "limit" => -1,
@@ -245,7 +241,6 @@ class SearchCollectorTest < Test::Unit::TestCase
245
241
  "output" => "search_result",
246
242
  "elements" => {
247
243
  "records" => {
248
- "type" => "sort",
249
244
  "format" => "complex",
250
245
  "attributes" => ["_key", "chapter", "section"],
251
246
  "limit" => -1,
@@ -272,11 +267,9 @@ class SearchCollectorTest < Test::Unit::TestCase
272
267
  "output" => "search_result",
273
268
  "elements" => {
274
269
  "count" => {
275
- "type" => "count",
276
270
  "target" => "records",
277
271
  },
278
272
  "records" => {
279
- "type" => "sort",
280
273
  "format" => "simple",
281
274
  "attributes" => [],
282
275
  "limit" => -1,
@@ -299,11 +292,9 @@ class SearchCollectorTest < Test::Unit::TestCase
299
292
  "output" => "search_result",
300
293
  "elements" => {
301
294
  "count" => {
302
- "type" => "count",
303
295
  "target" => "records",
304
296
  },
305
297
  "records" => {
306
- "type" => "sort",
307
298
  "format" => "simple",
308
299
  "attributes" => [],
309
300
  "limit" => -1,
@@ -317,7 +308,7 @@ class SearchCollectorTest < Test::Unit::TestCase
317
308
  request = {
318
309
  "task" => {
319
310
  "values" => nil,
320
- "component" => {
311
+ "step" => {
321
312
  "body" => nil,
322
313
  "outputs" => nil,
323
314
  },
@@ -355,7 +346,7 @@ class SearchCollectorTest < Test::Unit::TestCase
355
346
  ],
356
347
  },
357
348
  },
358
- "component" => {
349
+ "step" => {
359
350
  "body" => {
360
351
  input_name => {
361
352
  output_name => {
@@ -440,7 +431,7 @@ class SearchCollectorTest < Test::Unit::TestCase
440
431
  ],
441
432
  },
442
433
  },
443
- "component" => {
434
+ "step" => {
444
435
  "body" => {
445
436
  input_name => {
446
437
  output_name => {
@@ -520,7 +511,7 @@ class SearchCollectorTest < Test::Unit::TestCase
520
511
  ],
521
512
  },
522
513
  },
523
- "component" => {
514
+ "step" => {
524
515
  "body" => {
525
516
  input_name => {
526
517
  output_name => {
@@ -604,7 +595,7 @@ class SearchCollectorTest < Test::Unit::TestCase
604
595
  ],
605
596
  },
606
597
  },
607
- "component" => {
598
+ "step" => {
608
599
  "body" => {
609
600
  input_name => {
610
601
  output_name => {
@@ -705,7 +696,7 @@ class SearchCollectorTest < Test::Unit::TestCase
705
696
  ],
706
697
  },
707
698
  },
708
- "component" => {
699
+ "step" => {
709
700
  "body" => {
710
701
  input_name => {
711
702
  output_name => {
@@ -0,0 +1,120 @@
1
+ # Copyright (C) 2013-2014 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ class DistributedSearchPlannerBasicTest < Test::Unit::TestCase
17
+ include DistributedSearchPlannerHelper
18
+
19
+ class MultipleQueriesTest < self
20
+ class MultipleOutputsTest < self
21
+ def setup
22
+ @request = {
23
+ "type" => "search",
24
+ "dataset" => "Droonga",
25
+ "body" => {
26
+ "queries" => {
27
+ "query1" => {
28
+ "source" => "User",
29
+ "output" => {
30
+ "elements" => ["count"],
31
+ },
32
+ },
33
+ "query2" => {
34
+ "source" => "User",
35
+ "output" => {
36
+ "elements" => ["count"],
37
+ },
38
+ },
39
+ },
40
+ },
41
+ }
42
+ end
43
+
44
+ def test_dependencies
45
+ reduce_inputs = [
46
+ "errors",
47
+ "query1",
48
+ "query2",
49
+ ]
50
+ gather_inputs = [
51
+ "errors_reduced",
52
+ "query1_reduced",
53
+ "query2_reduced",
54
+ ]
55
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
56
+ dependencies)
57
+ end
58
+ end
59
+ end
60
+
61
+ # this should be moved to the test for DistributedCommandPlanner
62
+ class BasicTest < self
63
+ def setup
64
+ @request = {
65
+ "type" => "search",
66
+ "dataset" => "Droonga",
67
+ "body" => {
68
+ "queries" => {
69
+ "no_output" => {
70
+ "source" => "User",
71
+ },
72
+ },
73
+ },
74
+ }
75
+ end
76
+
77
+ def test_dependencies
78
+ reduce_inputs = ["errors"]
79
+ gather_inputs = ["errors_reduced"]
80
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
81
+ dependencies)
82
+ end
83
+
84
+ def test_broadcast_message_metadata
85
+ message = broadcast_message
86
+ metadata = {
87
+ "command" => message["command"],
88
+ "dataset" => message["dataset"],
89
+ "replica" => message["replica"],
90
+ }
91
+ expected = {
92
+ "command" => @request["type"],
93
+ "dataset" => @request["dataset"],
94
+ "replica" => "random",
95
+ }
96
+ assert_equal(expected, metadata)
97
+ end
98
+
99
+ def test_reduce_body
100
+ assert_equal({
101
+ "errors" => {
102
+ "errors_reduced" => {
103
+ "type" => "sum",
104
+ "limit" => -1,
105
+ },
106
+ },
107
+ },
108
+ reduce_message["body"])
109
+ end
110
+
111
+ def test_gather_body
112
+ assert_equal({
113
+ "errors_reduced" => {
114
+ "output" => "errors",
115
+ },
116
+ },
117
+ gather_message["body"])
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,573 @@
1
+ # Copyright (C) 2013-2014 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ class DistributedSearchPlannerGroupByTest < Test::Unit::TestCase
17
+ include DistributedSearchPlannerHelper
18
+
19
+ class SimpleTest < self
20
+ def setup
21
+ @output = {
22
+ "elements" => ["records"],
23
+ "attributes" => ["_nsubrecs", "_key"],
24
+ "limit" => 1,
25
+ }
26
+ @group_by = "family_name"
27
+ @request = {
28
+ "type" => "search",
29
+ "dataset" => "Droonga",
30
+ "body" => {
31
+ "queries" => {
32
+ "families" => {
33
+ "source" => "User",
34
+ "groupBy" => @group_by,
35
+ "output" => @output,
36
+ },
37
+ },
38
+ },
39
+ }
40
+ end
41
+
42
+ def test_dependencies
43
+ reduce_inputs = ["errors", "families"]
44
+ gather_inputs = ["errors_reduced", "families_reduced"]
45
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
46
+ dependencies)
47
+ end
48
+
49
+ def test_broadcast_body
50
+ changed_output_parameters = {
51
+ "unifiable" => true,
52
+ }
53
+ assert_equal({
54
+ "queries" => {
55
+ "families" => {
56
+ "source" => "User",
57
+ "groupBy" => @group_by,
58
+ "output" => @output.merge(changed_output_parameters),
59
+ },
60
+ },
61
+ },
62
+ broadcast_message["body"])
63
+ end
64
+
65
+ def test_reduce_body
66
+ assert_equal({
67
+ "families_reduced" => {
68
+ "records" => {
69
+ "type" => "sort",
70
+ "operators" => [],
71
+ "key_column" => 1,
72
+ "limit" => 1,
73
+ },
74
+ },
75
+ },
76
+ reduce_message["body"]["families"])
77
+ end
78
+
79
+ def test_gather_records
80
+ assert_equal({
81
+ "elements" => {
82
+ "records" => {
83
+ "attributes" => ["_nsubrecs", "_key"],
84
+ "limit" => 1,
85
+ },
86
+ },
87
+ "output" => "families",
88
+ },
89
+ gather_message["body"]["families_reduced"])
90
+ end
91
+ end
92
+
93
+ class WithHashAttributesTest < self
94
+ def setup
95
+ @output = {
96
+ "elements" => ["records"],
97
+ "attributes" => {
98
+ "family_name" => "_key",
99
+ "count" => { "source" => "_nsubrecs" },
100
+ },
101
+ "limit" => 1,
102
+ }
103
+ @group_by = "family_name"
104
+ @request = {
105
+ "type" => "search",
106
+ "dataset" => "Droonga",
107
+ "body" => {
108
+ "queries" => {
109
+ "families" => {
110
+ "source" => "User",
111
+ "groupBy" => @group_by,
112
+ "output" => @output,
113
+ },
114
+ },
115
+ },
116
+ }
117
+ end
118
+
119
+ def test_dependencies
120
+ reduce_inputs = ["errors", "families"]
121
+ gather_inputs = ["errors_reduced", "families_reduced"]
122
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
123
+ dependencies)
124
+ end
125
+
126
+ def test_broadcast_body
127
+ changed_output_parameters = {
128
+ "attributes" => [
129
+ { "label" => "family_name", "source" => "_key" },
130
+ { "label" => "count", "source" => "_nsubrecs" },
131
+ ],
132
+ "unifiable" => true,
133
+ }
134
+ assert_equal({
135
+ "queries" => {
136
+ "families" => {
137
+ "source" => "User",
138
+ "groupBy" => @group_by,
139
+ "output" => @output.merge(changed_output_parameters),
140
+ },
141
+ },
142
+ },
143
+ broadcast_message["body"])
144
+ end
145
+
146
+ def test_reduce_body
147
+ assert_equal({
148
+ "families_reduced" => {
149
+ "records" => {
150
+ "type" => "sort",
151
+ "operators" => [],
152
+ "key_column" => 0,
153
+ "limit" => 1,
154
+ },
155
+ },
156
+ },
157
+ reduce_message["body"]["families"])
158
+ end
159
+
160
+ def test_gather_records
161
+ assert_equal({
162
+ "elements" => {
163
+ "records" => {
164
+ "attributes" => ["family_name", "count"],
165
+ "limit" => 1,
166
+ },
167
+ },
168
+ "output" => "families",
169
+ },
170
+ gather_message["body"]["families_reduced"])
171
+ end
172
+ end
173
+
174
+ class WithHashAttributesMissingKeyTest < self
175
+ def setup
176
+ @output = {
177
+ "elements" => ["records"],
178
+ "attributes" => {
179
+ "count" => { "source" => "_nsubrecs" },
180
+ },
181
+ "limit" => 1,
182
+ }
183
+ @group_by = "family_name"
184
+ @request = {
185
+ "type" => "search",
186
+ "dataset" => "Droonga",
187
+ "body" => {
188
+ "queries" => {
189
+ "families" => {
190
+ "source" => "User",
191
+ "groupBy" => @group_by,
192
+ "output" => @output,
193
+ },
194
+ },
195
+ },
196
+ }
197
+ end
198
+
199
+ def test_dependencies
200
+ reduce_inputs = ["errors", "families"]
201
+ gather_inputs = ["errors_reduced", "families_reduced"]
202
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
203
+ dependencies)
204
+ end
205
+
206
+ def test_broadcast_body
207
+ changed_output_parameters = {
208
+ "attributes" => [
209
+ { "label" => "count", "source" => "_nsubrecs" },
210
+ "_key",
211
+ ],
212
+ "unifiable" => true,
213
+ }
214
+ assert_equal({
215
+ "queries" => {
216
+ "families" => {
217
+ "source" => "User",
218
+ "groupBy" => @group_by,
219
+ "output" => @output.merge(changed_output_parameters),
220
+ },
221
+ },
222
+ },
223
+ broadcast_message["body"])
224
+ end
225
+
226
+ def test_reduce_body
227
+ assert_equal({
228
+ "families_reduced" => {
229
+ "records" => {
230
+ "type" => "sort",
231
+ "operators" => [],
232
+ "key_column" => 1,
233
+ "limit" => 1,
234
+ },
235
+ },
236
+ },
237
+ reduce_message["body"]["families"])
238
+ end
239
+
240
+ def test_gather_records
241
+ assert_equal({
242
+ "elements" => {
243
+ "records" => {
244
+ "attributes" => ["count"],
245
+ "limit" => 1,
246
+ },
247
+ },
248
+ "output" => "families",
249
+ },
250
+ gather_message["body"]["families_reduced"])
251
+ end
252
+ end
253
+
254
+ class WithComplexAttributesArrayTest < self
255
+ def setup
256
+ @output = {
257
+ "elements" => ["records"],
258
+ "attributes" => [
259
+ { "label" => "family_name", "source" => "_key" },
260
+ { "label" => "count", "source" => "_nsubrecs" },
261
+ ],
262
+ "limit" => 1,
263
+ }
264
+ @group_by = "family_name"
265
+ @request = {
266
+ "type" => "search",
267
+ "dataset" => "Droonga",
268
+ "body" => {
269
+ "queries" => {
270
+ "families" => {
271
+ "source" => "User",
272
+ "groupBy" => @group_by,
273
+ "output" => @output,
274
+ },
275
+ },
276
+ },
277
+ }
278
+ end
279
+
280
+ def test_dependencies
281
+ reduce_inputs = ["errors", "families"]
282
+ gather_inputs = ["errors_reduced", "families_reduced"]
283
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
284
+ dependencies)
285
+ end
286
+
287
+ def test_broadcast_body
288
+ changed_output_parameters = {
289
+ "unifiable" => true,
290
+ }
291
+ assert_equal({
292
+ "queries" => {
293
+ "families" => {
294
+ "source" => "User",
295
+ "groupBy" => @group_by,
296
+ "output" => @output.merge(changed_output_parameters),
297
+ },
298
+ },
299
+ },
300
+ broadcast_message["body"])
301
+ end
302
+
303
+ def test_reduce_body
304
+ assert_equal({
305
+ "families_reduced" => {
306
+ "records" => {
307
+ "type" => "sort",
308
+ "operators" => [],
309
+ "key_column" => 0,
310
+ "limit" => 1,
311
+ },
312
+ },
313
+ },
314
+ reduce_message["body"]["families"])
315
+ end
316
+
317
+ def test_gather_records
318
+ assert_equal({
319
+ "elements" => {
320
+ "records" => {
321
+ "attributes" => ["family_name", "count"],
322
+ "limit" => 1,
323
+ },
324
+ },
325
+ "output" => "families",
326
+ },
327
+ gather_message["body"]["families_reduced"])
328
+ end
329
+ end
330
+
331
+ class WithComplexAttributesArrayMissingKeyTest < self
332
+ def setup
333
+ @output = {
334
+ "elements" => ["records"],
335
+ "attributes" => [
336
+ { "label" => "count", "source" => "_nsubrecs" },
337
+ ],
338
+ "limit" => 1,
339
+ }
340
+ @group_by = "family_name"
341
+ @request = {
342
+ "type" => "search",
343
+ "dataset" => "Droonga",
344
+ "body" => {
345
+ "queries" => {
346
+ "families" => {
347
+ "source" => "User",
348
+ "groupBy" => @group_by,
349
+ "output" => @output,
350
+ },
351
+ },
352
+ },
353
+ }
354
+ end
355
+
356
+ def test_dependencies
357
+ reduce_inputs = ["errors", "families"]
358
+ gather_inputs = ["errors_reduced", "families_reduced"]
359
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
360
+ dependencies)
361
+ end
362
+
363
+ def test_broadcast_body
364
+ changed_output_parameters = {
365
+ "attributes" => [
366
+ { "label" => "count", "source" => "_nsubrecs" },
367
+ "_key",
368
+ ],
369
+ "unifiable" => true,
370
+ }
371
+ assert_equal({
372
+ "queries" => {
373
+ "families" => {
374
+ "source" => "User",
375
+ "groupBy" => @group_by,
376
+ "output" => @output.merge(changed_output_parameters),
377
+ },
378
+ },
379
+ },
380
+ broadcast_message["body"])
381
+ end
382
+
383
+ def test_reduce_body
384
+ assert_equal({
385
+ "families_reduced" => {
386
+ "records" => {
387
+ "type" => "sort",
388
+ "operators" => [],
389
+ "key_column" => 1,
390
+ "limit" => 1,
391
+ },
392
+ },
393
+ },
394
+ reduce_message["body"]["families"])
395
+ end
396
+
397
+ def test_gather_records
398
+ assert_equal({
399
+ "elements" => {
400
+ "records" => {
401
+ "attributes" => ["count"],
402
+ "limit" => 1,
403
+ },
404
+ },
405
+ "output" => "families",
406
+ },
407
+ gather_message["body"]["families_reduced"])
408
+ end
409
+ end
410
+
411
+ class SubRecodsTest < self
412
+ def setup
413
+ @output = {
414
+ "elements" => ["records"],
415
+ "attributes" => [
416
+ "_key",
417
+ "_nsubrecs",
418
+ { "label" => "users",
419
+ "source" => "_subrecs",
420
+ "attributes" => ["_key"] },
421
+ ],
422
+ "limit" => 1,
423
+ }
424
+ @group_by = {
425
+ "key" => "family_name",
426
+ "maxNSubRecords" => 3,
427
+ }
428
+ @request = {
429
+ "type" => "search",
430
+ "dataset" => "Droonga",
431
+ "body" => {
432
+ "queries" => {
433
+ "families" => {
434
+ "source" => "User",
435
+ "groupBy" => @group_by,
436
+ "output" => @output,
437
+ },
438
+ },
439
+ },
440
+ }
441
+ end
442
+
443
+ def test_dependencies
444
+ reduce_inputs = ["errors", "families"]
445
+ gather_inputs = ["errors_reduced", "families_reduced"]
446
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
447
+ dependencies)
448
+ end
449
+
450
+ def test_broadcast_body
451
+ changed_output_parameters = {
452
+ "unifiable" => true,
453
+ }
454
+ assert_equal({
455
+ "queries" => {
456
+ "families" => {
457
+ "source" => "User",
458
+ "groupBy" => @group_by,
459
+ "output" => @output.merge(changed_output_parameters),
460
+ },
461
+ },
462
+ },
463
+ broadcast_message["body"])
464
+ end
465
+
466
+ def test_reduce_body
467
+ assert_equal({
468
+ "families_reduced" => {
469
+ "records" => {
470
+ "type" => "sort",
471
+ "operators" => [],
472
+ "key_column" => 0,
473
+ "limit" => 1,
474
+ },
475
+ },
476
+ },
477
+ reduce_message["body"]["families"])
478
+ end
479
+
480
+ def test_gather_records
481
+ assert_equal({
482
+ "elements" => {
483
+ "records" => {
484
+ "attributes" => ["_key", "_nsubrecs", "users"],
485
+ "limit" => 1,
486
+ },
487
+ },
488
+ "output" => "families",
489
+ },
490
+ gather_message["body"]["families_reduced"])
491
+ end
492
+ end
493
+
494
+ class CountOnlyTest < self
495
+ def setup
496
+ @output = {
497
+ "elements" => ["count"],
498
+ }
499
+ @group_by = "family_name"
500
+ @request = {
501
+ "type" => "search",
502
+ "dataset" => "Droonga",
503
+ "body" => {
504
+ "queries" => {
505
+ "families" => {
506
+ "source" => "User",
507
+ "groupBy" => @group_by,
508
+ "output" => @output,
509
+ },
510
+ },
511
+ },
512
+ }
513
+ end
514
+
515
+ def test_dependencies
516
+ reduce_inputs = ["errors", "families"]
517
+ gather_inputs = ["errors_reduced", "families_reduced"]
518
+ assert_equal(expected_dependencies(reduce_inputs, gather_inputs),
519
+ dependencies)
520
+ end
521
+
522
+ def test_broadcast_body
523
+ changed_output_parameters = {
524
+ "elements" => ["count", "records"],
525
+ "attributes" => ["_key"],
526
+ "limit" => -1,
527
+ "unifiable" => true,
528
+ }
529
+ assert_equal({
530
+ "queries" => {
531
+ "families" => {
532
+ "source" => "User",
533
+ "groupBy" => @group_by,
534
+ "output" => @output.merge(changed_output_parameters),
535
+ },
536
+ },
537
+ },
538
+ broadcast_message["body"])
539
+ end
540
+
541
+ def test_reduce_body
542
+ assert_equal({
543
+ "families_reduced" => {
544
+ "count" => {
545
+ "type" => "sum",
546
+ },
547
+ "records" => {
548
+ "type" => "sort",
549
+ "operators" => [],
550
+ "key_column" => 0,
551
+ "limit" => -1,
552
+ },
553
+ },
554
+ },
555
+ reduce_message["body"]["families"])
556
+ end
557
+
558
+ def test_gather_records
559
+ assert_equal({
560
+ "elements" => {
561
+ "count" => {
562
+ "target" => "records",
563
+ },
564
+ "records" => {
565
+ "no_output" => true,
566
+ },
567
+ },
568
+ "output" => "families",
569
+ },
570
+ gather_message["body"]["families_reduced"])
571
+ end
572
+ end
573
+ end