droonga-engine 1.0.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 (341) hide show
  1. data/.dir-locals.el +3 -0
  2. data/.gitignore +6 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +7 -0
  5. data/Gemfile +66 -0
  6. data/LICENSE.txt +14 -0
  7. data/README.md +17 -0
  8. data/Rakefile +64 -0
  9. data/benchmark/benchmark.rb +123 -0
  10. data/benchmark/utils.rb +246 -0
  11. data/benchmark/watch/benchmark-notify.rb +143 -0
  12. data/benchmark/watch/benchmark-notify.sh +20 -0
  13. data/benchmark/watch/benchmark-publish.rb +120 -0
  14. data/benchmark/watch/benchmark-scan.rb +213 -0
  15. data/bin/droonga-catalog-generate +103 -0
  16. data/bin/droonga-engine +20 -0
  17. data/bin/droonga-engine-service +20 -0
  18. data/doc/text/news.md +106 -0
  19. data/droonga-engine.gemspec +52 -0
  20. data/lib/droonga/adapter.rb +48 -0
  21. data/lib/droonga/adapter_runner.rb +104 -0
  22. data/lib/droonga/catalog/base.rb +41 -0
  23. data/lib/droonga/catalog/collection_volume.rb +106 -0
  24. data/lib/droonga/catalog/dataset.rb +69 -0
  25. data/lib/droonga/catalog/errors.rb +113 -0
  26. data/lib/droonga/catalog/schema.rb +186 -0
  27. data/lib/droonga/catalog/single_volume.rb +28 -0
  28. data/lib/droonga/catalog/slice.rb +41 -0
  29. data/lib/droonga/catalog/version1.rb +427 -0
  30. data/lib/droonga/catalog/version2.rb +96 -0
  31. data/lib/droonga/catalog/version2_validator.rb +63 -0
  32. data/lib/droonga/catalog/volume.rb +33 -0
  33. data/lib/droonga/catalog/volume_collection.rb +56 -0
  34. data/lib/droonga/catalog_generator.rb +156 -0
  35. data/lib/droonga/catalog_loader.rb +56 -0
  36. data/lib/droonga/catalog_observer.rb +83 -0
  37. data/lib/droonga/collector.rb +38 -0
  38. data/lib/droonga/collector_message.rb +71 -0
  39. data/lib/droonga/collector_runner.rb +64 -0
  40. data/lib/droonga/collectors/and.rb +26 -0
  41. data/lib/droonga/collectors/or.rb +26 -0
  42. data/lib/droonga/collectors/sum.rb +26 -0
  43. data/lib/droonga/collectors.rb +18 -0
  44. data/lib/droonga/dispatcher.rb +326 -0
  45. data/lib/droonga/distributed_command_planner.rb +179 -0
  46. data/lib/droonga/distributor.rb +87 -0
  47. data/lib/droonga/engine/command/droonga_engine.rb +441 -0
  48. data/lib/droonga/engine/version.rb +20 -0
  49. data/lib/droonga/engine.rb +80 -0
  50. data/lib/droonga/engine_state.rb +79 -0
  51. data/lib/droonga/error.rb +73 -0
  52. data/lib/droonga/error_messages.rb +33 -0
  53. data/lib/droonga/event_loop.rb +46 -0
  54. data/lib/droonga/farm.rb +58 -0
  55. data/lib/droonga/fluent_message_receiver.rb +191 -0
  56. data/lib/droonga/fluent_message_sender.rb +140 -0
  57. data/lib/droonga/forwarder.rb +119 -0
  58. data/lib/droonga/handler.rb +49 -0
  59. data/lib/droonga/handler_message.rb +61 -0
  60. data/lib/droonga/handler_messenger.rb +119 -0
  61. data/lib/droonga/handler_runner.rb +125 -0
  62. data/lib/droonga/input_message.rb +51 -0
  63. data/lib/droonga/job_protocol.rb +20 -0
  64. data/lib/droonga/job_pusher.rb +179 -0
  65. data/lib/droonga/job_receiver.rb +70 -0
  66. data/lib/droonga/loggable.rb +29 -0
  67. data/lib/droonga/logger.rb +142 -0
  68. data/lib/droonga/message_matcher.rb +109 -0
  69. data/lib/droonga/output_message.rb +55 -0
  70. data/lib/droonga/planner.rb +47 -0
  71. data/lib/droonga/pluggable.rb +31 -0
  72. data/lib/droonga/plugin/metadata/adapter_input_message.rb +39 -0
  73. data/lib/droonga/plugin/metadata/adapter_output_message.rb +39 -0
  74. data/lib/droonga/plugin/metadata/collector_message.rb +39 -0
  75. data/lib/droonga/plugin/metadata/handler_action.rb +39 -0
  76. data/lib/droonga/plugin/metadata/input_message.rb +54 -0
  77. data/lib/droonga/plugin.rb +43 -0
  78. data/lib/droonga/plugin_loader.rb +63 -0
  79. data/lib/droonga/plugin_registry.rb +66 -0
  80. data/lib/droonga/plugins/basic.rb +54 -0
  81. data/lib/droonga/plugins/crud.rb +145 -0
  82. data/lib/droonga/plugins/dump.rb +97 -0
  83. data/lib/droonga/plugins/error.rb +51 -0
  84. data/lib/droonga/plugins/groonga/column_create.rb +123 -0
  85. data/lib/droonga/plugins/groonga/column_list.rb +124 -0
  86. data/lib/droonga/plugins/groonga/column_remove.rb +65 -0
  87. data/lib/droonga/plugins/groonga/column_rename.rb +67 -0
  88. data/lib/droonga/plugins/groonga/delete.rb +117 -0
  89. data/lib/droonga/plugins/groonga/generic_command.rb +105 -0
  90. data/lib/droonga/plugins/groonga/generic_response.rb +43 -0
  91. data/lib/droonga/plugins/groonga/select.rb +236 -0
  92. data/lib/droonga/plugins/groonga/table_create.rb +111 -0
  93. data/lib/droonga/plugins/groonga/table_list.rb +120 -0
  94. data/lib/droonga/plugins/groonga/table_remove.rb +57 -0
  95. data/lib/droonga/plugins/groonga.rb +37 -0
  96. data/lib/droonga/plugins/search/distributed_search_planner.rb +407 -0
  97. data/lib/droonga/plugins/search.rb +146 -0
  98. data/lib/droonga/plugins/watch.rb +178 -0
  99. data/lib/droonga/processor.rb +63 -0
  100. data/lib/droonga/reducer.rb +169 -0
  101. data/lib/droonga/replier.rb +49 -0
  102. data/lib/droonga/schema_applier.rb +167 -0
  103. data/lib/droonga/searcher/mecab_filter.rb +67 -0
  104. data/lib/droonga/searcher.rb +733 -0
  105. data/lib/droonga/server.rb +45 -0
  106. data/lib/droonga/session.rb +99 -0
  107. data/lib/droonga/single_step.rb +68 -0
  108. data/lib/droonga/single_step_definition.rb +54 -0
  109. data/lib/droonga/slice.rb +122 -0
  110. data/lib/droonga/status_code.rb +25 -0
  111. data/lib/droonga/step_runner.rb +64 -0
  112. data/lib/droonga/sweeper.rb +42 -0
  113. data/lib/droonga/test/stub_handler.rb +37 -0
  114. data/lib/droonga/test/stub_handler_message.rb +35 -0
  115. data/lib/droonga/test/stub_handler_messenger.rb +34 -0
  116. data/lib/droonga/test/stub_planner.rb +31 -0
  117. data/lib/droonga/test.rb +21 -0
  118. data/lib/droonga/watch_schema.rb +92 -0
  119. data/lib/droonga/watcher.rb +257 -0
  120. data/lib/droonga/worker.rb +61 -0
  121. data/sample/cluster/catalog.json +42 -0
  122. data/sample/mecab_filter/data.grn +7 -0
  123. data/sample/mecab_filter/ddl.grn +7 -0
  124. data/sample/mecab_filter/search_with_mecab_filter.json +21 -0
  125. data/sample/mecab_filter/search_without_mecab_filter.json +21 -0
  126. data/test/command/config/default/catalog.json +85 -0
  127. data/test/command/config/default/fluentd.conf +11 -0
  128. data/test/command/config/version1/catalog.json +68 -0
  129. data/test/command/config/version1/fluentd.conf +11 -0
  130. data/test/command/fixture/documents.jsons +208 -0
  131. data/test/command/fixture/event.jsons +41 -0
  132. data/test/command/fixture/user-table-array.jsons +38 -0
  133. data/test/command/fixture/user-table.jsons +47 -0
  134. data/test/command/run-test.rb +34 -0
  135. data/test/command/suite/add/dimension/column.catalog.json +28 -0
  136. data/test/command/suite/add/dimension/column.expected +41 -0
  137. data/test/command/suite/add/dimension/column.test +51 -0
  138. data/test/command/suite/add/dimension/integer.catalog.json +19 -0
  139. data/test/command/suite/add/dimension/integer.expected +41 -0
  140. data/test/command/suite/add/dimension/integer.test +51 -0
  141. data/test/command/suite/add/error/invalid-integer.expected +46 -0
  142. data/test/command/suite/add/error/invalid-integer.test +12 -0
  143. data/test/command/suite/add/error/invalid-time.expected +46 -0
  144. data/test/command/suite/add/error/invalid-time.test +12 -0
  145. data/test/command/suite/add/error/missing-key.expected +25 -0
  146. data/test/command/suite/add/error/missing-key.test +16 -0
  147. data/test/command/suite/add/error/missing-table.expected +25 -0
  148. data/test/command/suite/add/error/missing-table.test +16 -0
  149. data/test/command/suite/add/error/unknown-column.expected +46 -0
  150. data/test/command/suite/add/error/unknown-column.test +12 -0
  151. data/test/command/suite/add/error/unknown-table.expected +25 -0
  152. data/test/command/suite/add/error/unknown-table.test +17 -0
  153. data/test/command/suite/add/minimum.expected +6 -0
  154. data/test/command/suite/add/minimum.test +11 -0
  155. data/test/command/suite/add/with-values.expected +6 -0
  156. data/test/command/suite/add/with-values.test +17 -0
  157. data/test/command/suite/add/without-key.expected +6 -0
  158. data/test/command/suite/add/without-key.test +16 -0
  159. data/test/command/suite/groonga/column_create/scalar.expected +26 -0
  160. data/test/command/suite/groonga/column_create/scalar.test +17 -0
  161. data/test/command/suite/groonga/column_create/unknown-table.expected +14 -0
  162. data/test/command/suite/groonga/column_create/unknown-table.test +7 -0
  163. data/test/command/suite/groonga/column_create/vector.expected +26 -0
  164. data/test/command/suite/groonga/column_create/vector.test +18 -0
  165. data/test/command/suite/groonga/column_list/success.expected +86 -0
  166. data/test/command/suite/groonga/column_list/success.test +24 -0
  167. data/test/command/suite/groonga/column_list/unknown-table.expected +13 -0
  168. data/test/command/suite/groonga/column_list/unknown-table.test +7 -0
  169. data/test/command/suite/groonga/column_remove/success.expected +39 -0
  170. data/test/command/suite/groonga/column_remove/success.test +25 -0
  171. data/test/command/suite/groonga/column_remove/unknown-column.expected +27 -0
  172. data/test/command/suite/groonga/column_remove/unknown-column.test +16 -0
  173. data/test/command/suite/groonga/column_remove/unknown-table.expected +14 -0
  174. data/test/command/suite/groonga/column_remove/unknown-table.test +7 -0
  175. data/test/command/suite/groonga/column_rename/success.expected +39 -0
  176. data/test/command/suite/groonga/column_rename/success.test +26 -0
  177. data/test/command/suite/groonga/column_rename/unknown-column.expected +27 -0
  178. data/test/command/suite/groonga/column_rename/unknown-column.test +16 -0
  179. data/test/command/suite/groonga/column_rename/unknown-table.expected +14 -0
  180. data/test/command/suite/groonga/column_rename/unknown-table.test +7 -0
  181. data/test/command/suite/groonga/delete/duplicated-identifiers.expected +27 -0
  182. data/test/command/suite/groonga/delete/duplicated-identifiers.test +17 -0
  183. data/test/command/suite/groonga/delete/filter.expected +19 -0
  184. data/test/command/suite/groonga/delete/filter.test +19 -0
  185. data/test/command/suite/groonga/delete/invalid-filter.expected +14 -0
  186. data/test/command/suite/groonga/delete/invalid-filter.test +9 -0
  187. data/test/command/suite/groonga/delete/no-identifier.expected +27 -0
  188. data/test/command/suite/groonga/delete/no-identifier.test +15 -0
  189. data/test/command/suite/groonga/delete/success.expected +19 -0
  190. data/test/command/suite/groonga/delete/success.test +19 -0
  191. data/test/command/suite/groonga/delete/unknown-table.expected +14 -0
  192. data/test/command/suite/groonga/delete/unknown-table.test +7 -0
  193. data/test/command/suite/groonga/select/minimum.expected +22 -0
  194. data/test/command/suite/groonga/select/minimum.test +8 -0
  195. data/test/command/suite/groonga/table_create/array.expected +14 -0
  196. data/test/command/suite/groonga/table_create/array.test +8 -0
  197. data/test/command/suite/groonga/table_create/hash.expected +13 -0
  198. data/test/command/suite/groonga/table_create/hash.test +8 -0
  199. data/test/command/suite/groonga/table_list/success.expected +71 -0
  200. data/test/command/suite/groonga/table_list/success.test +15 -0
  201. data/test/command/suite/groonga/table_remove/success.expected +13 -0
  202. data/test/command/suite/groonga/table_remove/success.test +8 -0
  203. data/test/command/suite/groonga/table_remove/unknown-table.expected +14 -0
  204. data/test/command/suite/groonga/table_remove/unknown-table.test +7 -0
  205. data/test/command/suite/message/error/missing-dataset.expected +9 -0
  206. data/test/command/suite/message/error/missing-dataset.test +5 -0
  207. data/test/command/suite/message/error/unknown-dataset.expected +9 -0
  208. data/test/command/suite/message/error/unknown-dataset.test +6 -0
  209. data/test/command/suite/message/error/unknown-type.expected +9 -0
  210. data/test/command/suite/message/error/unknown-type.test +6 -0
  211. data/test/command/suite/search/adjusters/multiple.catalog.json +38 -0
  212. data/test/command/suite/search/adjusters/multiple.expected +19 -0
  213. data/test/command/suite/search/adjusters/multiple.test +75 -0
  214. data/test/command/suite/search/adjusters/one.catalog.json +38 -0
  215. data/test/command/suite/search/adjusters/one.expected +19 -0
  216. data/test/command/suite/search/adjusters/one.test +66 -0
  217. data/test/command/suite/search/attributes/array.expected +21 -0
  218. data/test/command/suite/search/attributes/array.test +28 -0
  219. data/test/command/suite/search/attributes/hash.expected +30 -0
  220. data/test/command/suite/search/attributes/hash.test +36 -0
  221. data/test/command/suite/search/complex.expected +48 -0
  222. data/test/command/suite/search/complex.test +23 -0
  223. data/test/command/suite/search/condition/nested.expected +15 -0
  224. data/test/command/suite/search/condition/nested.test +27 -0
  225. data/test/command/suite/search/condition/query/nonexistent_column.catalog.json +37 -0
  226. data/test/command/suite/search/condition/query/nonexistent_column.expected +48 -0
  227. data/test/command/suite/search/condition/query/nonexistent_column.test +33 -0
  228. data/test/command/suite/search/condition/query/syntax_error.catalog.json +36 -0
  229. data/test/command/suite/search/condition/query/syntax_error.expected +48 -0
  230. data/test/command/suite/search/condition/query/syntax_error.test +33 -0
  231. data/test/command/suite/search/condition/query.expected +24 -0
  232. data/test/command/suite/search/condition/query.test +23 -0
  233. data/test/command/suite/search/condition/script.expected +24 -0
  234. data/test/command/suite/search/condition/script.test +26 -0
  235. data/test/command/suite/search/error/cyclic-source.expected +14 -0
  236. data/test/command/suite/search/error/cyclic-source.test +12 -0
  237. data/test/command/suite/search/error/deeply-cyclic-source.expected +17 -0
  238. data/test/command/suite/search/error/deeply-cyclic-source.test +15 -0
  239. data/test/command/suite/search/error/missing-source-parameter.expected +13 -0
  240. data/test/command/suite/search/error/missing-source-parameter.test +11 -0
  241. data/test/command/suite/search/error/no-query.expected +9 -0
  242. data/test/command/suite/search/error/no-query.test +7 -0
  243. data/test/command/suite/search/error/unknown-source.expected +52 -0
  244. data/test/command/suite/search/error/unknown-source.test +12 -0
  245. data/test/command/suite/search/group/count.expected +10 -0
  246. data/test/command/suite/search/group/count.test +18 -0
  247. data/test/command/suite/search/group/limit.expected +15 -0
  248. data/test/command/suite/search/group/limit.test +20 -0
  249. data/test/command/suite/search/group/string.expected +32 -0
  250. data/test/command/suite/search/group/string.test +40 -0
  251. data/test/command/suite/search/group/subrecord/with-sort.catalog.json +33 -0
  252. data/test/command/suite/search/group/subrecord/with-sort.expected +30 -0
  253. data/test/command/suite/search/group/subrecord/with-sort.test +81 -0
  254. data/test/command/suite/search/multiple/chained.expected +41 -0
  255. data/test/command/suite/search/multiple/chained.test +39 -0
  256. data/test/command/suite/search/multiple/parallel.expected +35 -0
  257. data/test/command/suite/search/multiple/parallel.test +35 -0
  258. data/test/command/suite/search/output/attributes/invalid.catalog.json +13 -0
  259. data/test/command/suite/search/output/attributes/invalid.expected +44 -0
  260. data/test/command/suite/search/output/attributes/invalid.test +28 -0
  261. data/test/command/suite/search/range/only-output.expected +24 -0
  262. data/test/command/suite/search/range/only-output.test +23 -0
  263. data/test/command/suite/search/range/only-sort.expected +24 -0
  264. data/test/command/suite/search/range/only-sort.test +26 -0
  265. data/test/command/suite/search/range/sort-and-output.expected +21 -0
  266. data/test/command/suite/search/range/sort-and-output.test +27 -0
  267. data/test/command/suite/search/range/too-large-output-offset.expected +12 -0
  268. data/test/command/suite/search/range/too-large-output-offset.test +23 -0
  269. data/test/command/suite/search/range/too-large-sort-offset.expected +12 -0
  270. data/test/command/suite/search/range/too-large-sort-offset.test +26 -0
  271. data/test/command/suite/search/response/elapsed_time.catalog.json +13 -0
  272. data/test/command/suite/search/response/elapsed_time.expected +11 -0
  273. data/test/command/suite/search/response/elapsed_time.test +26 -0
  274. data/test/command/suite/search/response/records/value/time.expected +20 -0
  275. data/test/command/suite/search/response/records/value/time.test +22 -0
  276. data/test/command/suite/search/simple.expected +48 -0
  277. data/test/command/suite/search/simple.test +22 -0
  278. data/test/command/suite/search/sort/default-offset-limit.expected +39 -0
  279. data/test/command/suite/search/sort/default-offset-limit.test +24 -0
  280. data/test/command/suite/search/sort/invisible-column.expected +24 -0
  281. data/test/command/suite/search/sort/invisible-column.test +26 -0
  282. data/test/command/suite/watch/subscribe.expected +6 -0
  283. data/test/command/suite/watch/subscribe.test +9 -0
  284. data/test/command/suite/watch/unsubscribe.expected +6 -0
  285. data/test/command/suite/watch/unsubscribe.test +9 -0
  286. data/test/performance/run-test.rb +56 -0
  287. data/test/performance/watch/catalog.json +33 -0
  288. data/test/performance/watch/feed.json +9 -0
  289. data/test/performance/watch/fluentd.conf +11 -0
  290. data/test/performance/watch/subscribe.json +3 -0
  291. data/test/unit/catalog/test_collection_volume.rb +103 -0
  292. data/test/unit/catalog/test_dataset.rb +104 -0
  293. data/test/unit/catalog/test_schema.rb +226 -0
  294. data/test/unit/catalog/test_single_volume.rb +31 -0
  295. data/test/unit/catalog/test_slice.rb +92 -0
  296. data/test/unit/catalog/test_version1.rb +361 -0
  297. data/test/unit/catalog/test_version2.rb +124 -0
  298. data/test/unit/catalog/test_version2_validator.rb +66 -0
  299. data/test/unit/catalog/test_volume_collection.rb +50 -0
  300. data/test/unit/fixtures/array.grn +18 -0
  301. data/test/unit/fixtures/catalog/version1.json +40 -0
  302. data/test/unit/fixtures/catalog/version2.json +62 -0
  303. data/test/unit/fixtures/document.grn +34 -0
  304. data/test/unit/fixtures/reference/array.grn +11 -0
  305. data/test/unit/fixtures/reference/hash.grn +7 -0
  306. data/test/unit/helper/distributed_search_planner_helper.rb +83 -0
  307. data/test/unit/helper/fixture.rb +28 -0
  308. data/test/unit/helper/plugin_helper.rb +38 -0
  309. data/test/unit/helper/sandbox.rb +86 -0
  310. data/test/unit/helper/stub_worker.rb +27 -0
  311. data/test/unit/helper/watch_helper.rb +23 -0
  312. data/test/unit/helper.rb +28 -0
  313. data/test/unit/plugins/crud/test_add.rb +190 -0
  314. data/test/unit/plugins/groonga/select/test_adapter_input.rb +510 -0
  315. data/test/unit/plugins/groonga/select/test_adapter_output.rb +201 -0
  316. data/test/unit/plugins/groonga/test_column_create.rb +171 -0
  317. data/test/unit/plugins/groonga/test_column_list.rb +170 -0
  318. data/test/unit/plugins/groonga/test_column_remove.rb +98 -0
  319. data/test/unit/plugins/groonga/test_column_rename.rb +105 -0
  320. data/test/unit/plugins/groonga/test_delete.rb +127 -0
  321. data/test/unit/plugins/groonga/test_table_create.rb +147 -0
  322. data/test/unit/plugins/groonga/test_table_list.rb +184 -0
  323. data/test/unit/plugins/groonga/test_table_remove.rb +61 -0
  324. data/test/unit/plugins/search/planner/test_basic.rb +120 -0
  325. data/test/unit/plugins/search/planner/test_group_by.rb +573 -0
  326. data/test/unit/plugins/search/planner/test_output.rb +388 -0
  327. data/test/unit/plugins/search/planner/test_sort_by.rb +938 -0
  328. data/test/unit/plugins/search/test_collector.rb +806 -0
  329. data/test/unit/plugins/search/test_handler.rb +930 -0
  330. data/test/unit/plugins/search/test_planner.rb +174 -0
  331. data/test/unit/plugins/test_basic.rb +510 -0
  332. data/test/unit/plugins/test_groonga.rb +70 -0
  333. data/test/unit/plugins/test_watch.rb +211 -0
  334. data/test/unit/run-test.rb +56 -0
  335. data/test/unit/test_catalog_generator.rb +93 -0
  336. data/test/unit/test_message_matcher.rb +160 -0
  337. data/test/unit/test_schema_applier.rb +59 -0
  338. data/test/unit/test_sweeper.rb +95 -0
  339. data/test/unit/test_watch_schema.rb +57 -0
  340. data/test/unit/test_watcher.rb +336 -0
  341. metadata +759 -0
@@ -0,0 +1,92 @@
1
+ # Copyright (C) 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
+ require "droonga/catalog/dataset"
17
+
18
+ class CatalogSliceTest < Test::Unit::TestCase
19
+ private
20
+ def create_slice(data)
21
+ minimum_dataset_data = {
22
+ "replicas" => {
23
+ },
24
+ }
25
+ dataset = Droonga::Catalog::Dataset.new("DatasetName", minimum_dataset_data)
26
+ Droonga::Catalog::Slice.new(dataset, data)
27
+ end
28
+
29
+ class WeightTest < self
30
+ def test_default
31
+ data = {
32
+ }
33
+ slice = create_slice(data)
34
+ assert_equal(1, slice.weight)
35
+ end
36
+
37
+ def test_specified
38
+ data = {
39
+ "weight" => 29,
40
+ }
41
+ slice = create_slice(data)
42
+ assert_equal(29, slice.weight)
43
+ end
44
+ end
45
+
46
+ class LabelTest < self
47
+ def test_default
48
+ data = {
49
+ }
50
+ slice = create_slice(data)
51
+ assert_nil(slice.label)
52
+ end
53
+
54
+ def test_specified
55
+ data = {
56
+ "label" => "High",
57
+ }
58
+ slice = create_slice(data)
59
+ assert_equal("High", slice.label)
60
+ end
61
+ end
62
+
63
+ class BoundaryTest < self
64
+ def test_default
65
+ data = {
66
+ }
67
+ slice = create_slice(data)
68
+ assert_nil(slice.boundary)
69
+ end
70
+
71
+ def test_specified
72
+ data = {
73
+ "boundary" => "2014-03-21",
74
+ }
75
+ slice = create_slice(data)
76
+ assert_equal("2014-03-21", slice.boundary)
77
+ end
78
+ end
79
+
80
+ class VolumeTest < self
81
+ def test_single
82
+ data = {
83
+ "volume" => {
84
+ "address" => "127.0.0.1:10047/volume.000",
85
+ },
86
+ }
87
+ slice = create_slice(data)
88
+ assert_equal("127.0.0.1:10047/volume.000",
89
+ slice.volume.address)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,361 @@
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
+ require "droonga/catalog/version1"
17
+
18
+ class CatalogVersion1Test < Test::Unit::TestCase
19
+ class << self
20
+ def minimum_data
21
+ {
22
+ "effective_date" => "2013-09-01T00:00:00Z",
23
+ "zones" => [],
24
+ "farms" => {},
25
+ "datasets" => {},
26
+ }
27
+ end
28
+ end
29
+
30
+ private
31
+ def minimum_data
32
+ self.class.minimum_data
33
+ end
34
+
35
+ def create_catalog(data, path)
36
+ Droonga::Catalog::Version1.new(data, path)
37
+ end
38
+
39
+ class PartitionTest < self
40
+ def setup
41
+ data = JSON.parse(File.read(catalog_path))
42
+ @catalog = create_catalog(data, catalog_path)
43
+ end
44
+
45
+ def test_get_partitions
46
+ partitions = @catalog.get_partitions("localhost:23003/test")
47
+ assert_equal({
48
+ "localhost:23003/test.000" => {
49
+ :database => "#{base_path}/000/db",
50
+ :dataset => "Test",
51
+ :plugins => ["for_dataset"],
52
+ :n_workers => 0
53
+ },
54
+ "localhost:23003/test.001" => {
55
+ :database => "#{base_path}/001/db",
56
+ :dataset => "Test",
57
+ :plugins => ["for_dataset"],
58
+ :n_workers => 0
59
+ },
60
+ "localhost:23003/test.002" => {
61
+ :database => "#{base_path}/002/db",
62
+ :dataset => "Test",
63
+ :plugins => ["for_dataset"],
64
+ :n_workers => 0
65
+ },
66
+ "localhost:23003/test.003" => {
67
+ :database => "#{base_path}/003/db",
68
+ :dataset => "Test",
69
+ :plugins => ["for_dataset"],
70
+ :n_workers => 0
71
+ },
72
+ },
73
+ partitions)
74
+ end
75
+
76
+ def fixture_path(base_path)
77
+ File.expand_path("../../fixtures/#{base_path}", __FILE__)
78
+ end
79
+
80
+ def catalog_path
81
+ @catalog_path ||= fixture_path("catalog/version1.json")
82
+ end
83
+
84
+ def base_path
85
+ File.dirname(catalog_path)
86
+ end
87
+
88
+ class PluginsTest < self
89
+ def setup
90
+ @data = minimum_data.merge({
91
+ "zones" => [farm_name],
92
+ "farms" => {
93
+ farm_name => {
94
+ "device" => ".",
95
+ },
96
+ },
97
+ "datasets" => {
98
+ "Droonga" => {
99
+ "workers" => 1,
100
+ "number_of_partitions" => 1,
101
+ "number_of_replicas" => 1,
102
+ "date_range" => "infinity",
103
+ "partition_key" => "_key",
104
+ "plugins" => [],
105
+ "ring" => {
106
+ "localhost:23041" => {
107
+ "weight" => 50,
108
+ "partitions" => {
109
+ "2014-02-09" => [
110
+ "#{farm_name}.000",
111
+ ],
112
+ },
113
+ },
114
+ },
115
+ },
116
+ },
117
+ })
118
+ end
119
+
120
+ def farm_name
121
+ "localhost:23041/droonga"
122
+ end
123
+
124
+ def plugins(data)
125
+ catalog = create_catalog(data, catalog_path)
126
+ catalog.get_partitions(farm_name).collect do |partition, options|
127
+ options[:plugins]
128
+ end
129
+ end
130
+
131
+ def test_plugins
132
+ @data["datasets"]["Droonga"]["plugins"] = ["search", "groonga", "add"]
133
+ assert_equal([["search", "groonga", "add"]],
134
+ plugins(@data))
135
+
136
+ end
137
+ end
138
+ end
139
+
140
+ class DataSetTest < self
141
+ class RingTest < self
142
+ class TotalWeightTest < self
143
+ def test_three_zones
144
+ dataset = {
145
+ "ring" => {
146
+ "zone1" => {
147
+ "weight" => 10,
148
+ },
149
+ "zone2" => {
150
+ "weight" => 20,
151
+ },
152
+ "zone3" => {
153
+ "weight" => 30,
154
+ },
155
+ }
156
+ }
157
+ assert_equal(10 + 20 + 30,
158
+ total_weight(dataset))
159
+ end
160
+
161
+ private
162
+ def total_weight(dataset)
163
+ catalog = create_catalog(minimum_data,
164
+ "base-path")
165
+ catalog.send(:compute_total_weight, dataset)
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ class ValidationTest < self
172
+ class << self
173
+ def farm_name
174
+ "localhost:23041/droonga"
175
+ end
176
+
177
+ def ring_name
178
+ "localhost:23041"
179
+ end
180
+
181
+ def range_name
182
+ "2013-09-01"
183
+ end
184
+
185
+ def path
186
+ "path/to/catalog"
187
+ end
188
+
189
+ def valid_farms
190
+ {
191
+ farm_name => {
192
+ "device" => ".",
193
+ },
194
+ }
195
+ end
196
+
197
+ def valid_zones
198
+ valid_farms.keys
199
+ end
200
+
201
+ def valid_dataset_base
202
+ {
203
+ "workers" => 0,
204
+ "number_of_replicas" => 1,
205
+ "number_of_partitions" => 1,
206
+ "partition_key" => "_key",
207
+ "date_range" => "infinity",
208
+ "ring" => {},
209
+ }
210
+ end
211
+ end
212
+
213
+ data(
214
+ :missing_root_elements => {
215
+ :catalog => {},
216
+ :errors => [
217
+ Droonga::Catalog::MissingRequiredParameter.new(
218
+ "effective_date", path),
219
+ Droonga::Catalog::MissingRequiredParameter.new(
220
+ "zones", path),
221
+ Droonga::Catalog::MissingRequiredParameter.new(
222
+ "farms", path),
223
+ Droonga::Catalog::MissingRequiredParameter.new(
224
+ "datasets", path),
225
+ ],
226
+ },
227
+ :invalid_farms => {
228
+ :catalog => minimum_data.merge(
229
+ "farms" => {
230
+ farm_name => {
231
+ },
232
+ },
233
+ "zones" => [farm_name],
234
+ ),
235
+ :errors => [
236
+ Droonga::Catalog::MissingRequiredParameter.new(
237
+ "farms.#{farm_name}.device", path),
238
+ ],
239
+ },
240
+ :missing_dataset_parameters => {
241
+ :catalog => minimum_data.merge(
242
+ "farms" => valid_farms,
243
+ "zones" => valid_zones,
244
+ "datasets" => {
245
+ "Droonga" => {
246
+ },
247
+ },
248
+ ),
249
+ :errors => [
250
+ Droonga::Catalog::MissingRequiredParameter.new(
251
+ "datasets.Droonga.workers", path),
252
+ Droonga::Catalog::MissingRequiredParameter.new(
253
+ "datasets.Droonga.number_of_replicas", path),
254
+ Droonga::Catalog::MissingRequiredParameter.new(
255
+ "datasets.Droonga.number_of_partitions", path),
256
+ Droonga::Catalog::MissingRequiredParameter.new(
257
+ "datasets.Droonga.partition_key", path),
258
+ Droonga::Catalog::MissingRequiredParameter.new(
259
+ "datasets.Droonga.date_range", path),
260
+ Droonga::Catalog::MissingRequiredParameter.new(
261
+ "datasets.Droonga.ring", path),
262
+ ],
263
+ },
264
+ :invalid_date_parameters => {
265
+ :catalog => minimum_data.merge(
266
+ "effective_date" => "invalid",
267
+ ),
268
+ :errors => [
269
+ Droonga::Catalog::InvalidDate.new(
270
+ "effective_date", "invalid", path),
271
+ ],
272
+ },
273
+ :non_integer_numeric_parameters => {
274
+ :catalog => minimum_data.merge(
275
+ "farms" => valid_farms,
276
+ "zones" => valid_zones,
277
+ "datasets" => {
278
+ "Droonga" => valid_dataset_base.merge(
279
+ "workers" => 0.1,
280
+ "number_of_replicas" => 0.1,
281
+ "number_of_partitions" => 0.1,
282
+ "ring" => {
283
+ ring_name => {
284
+ "weight" => 0.1,
285
+ "partitions" => {},
286
+ },
287
+ },
288
+ ),
289
+ },
290
+ ),
291
+ :errors => [
292
+ Droonga::Catalog::MismatchedParameterType.new(
293
+ "datasets.Droonga.workers", Integer, Float, path),
294
+ Droonga::Catalog::MismatchedParameterType.new(
295
+ "datasets.Droonga.number_of_replicas", Integer, Float, path),
296
+ Droonga::Catalog::MismatchedParameterType.new(
297
+ "datasets.Droonga.number_of_partitions", Integer, Float, path),
298
+ ],
299
+ },
300
+ :negative_numeric_parameters => {
301
+ :catalog => minimum_data.merge(
302
+ "farms" => valid_farms,
303
+ "zones" => valid_zones,
304
+ "datasets" => {
305
+ "Droonga" => valid_dataset_base.merge(
306
+ "workers" => -1,
307
+ "number_of_replicas" => -1,
308
+ "number_of_partitions" => -1,
309
+ "ring" => {
310
+ ring_name => {
311
+ "weight" => -1,
312
+ "partitions" => {},
313
+ },
314
+ },
315
+ ),
316
+ },
317
+ ),
318
+ :errors => [
319
+ Droonga::Catalog::NegativeNumber.new(
320
+ "datasets.Droonga.workers", -1, path),
321
+ Droonga::Catalog::SmallerThanOne.new(
322
+ "datasets.Droonga.number_of_replicas", -1, path),
323
+ Droonga::Catalog::SmallerThanOne.new(
324
+ "datasets.Droonga.number_of_partitions", -1, path),
325
+ Droonga::Catalog::NegativeNumber.new(
326
+ "datasets.Droonga.ring.#{ring_name}.weight", -1, path),
327
+ ],
328
+ },
329
+ :broken_relations_unknown_farm => {
330
+ :catalog => minimum_data.merge(
331
+ "farms" => valid_farms,
332
+ "zones" => valid_zones,
333
+ "datasets" => {
334
+ "Droonga" => valid_dataset_base.merge(
335
+ "ring" => {
336
+ ring_name => {
337
+ "weight" => 1,
338
+ "partitions" => {
339
+ range_name => [
340
+ "unknown:0/unknown.000",
341
+ ],
342
+ },
343
+ },
344
+ },
345
+ ),
346
+ },
347
+ ),
348
+ :errors => [
349
+ Droonga::Catalog::UnknownFarmForPartition.new(
350
+ "datasets.Droonga.ring.#{ring_name}.partitions.#{range_name}[0]",
351
+ "unknown:0/unknown.000", path),
352
+ ],
353
+ },
354
+ )
355
+ def test_validation(data)
356
+ assert_raise(Droonga::MultiplexError.new(data[:errors])) do
357
+ create_catalog(data[:catalog], "path/to/catalog")
358
+ end
359
+ end
360
+ end
361
+ end
@@ -0,0 +1,124 @@
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
+ require "droonga/catalog/version2"
17
+
18
+ class CatalogVersion2Test < Test::Unit::TestCase
19
+ class << self
20
+ def minimum_data
21
+ {
22
+ "effectiveDate" => "2014-02-28T00:00:00Z",
23
+ "datasets" => {
24
+ },
25
+ }
26
+ end
27
+ end
28
+
29
+ private
30
+ def minimum_data
31
+ self.class.minimum_data
32
+ end
33
+
34
+ def create_catalog(data, path)
35
+ Droonga::Catalog::Version2.new(data, path)
36
+ end
37
+
38
+ class SliceTest < self
39
+ def setup
40
+ data = JSON.parse(File.read(catalog_path))
41
+ @catalog = create_catalog(data, catalog_path)
42
+ end
43
+
44
+ def test_slices
45
+ slices = @catalog.slices("localhost:23003/test")
46
+ assert_equal({
47
+ "localhost:23003/test.000" => {
48
+ :database => "#{base_path}/000/db",
49
+ :dataset => "Test",
50
+ :plugins => ["plugin1", "plugin2", "plugin3"],
51
+ :n_workers => 4,
52
+ },
53
+ "localhost:23003/test.001" => {
54
+ :database => "#{base_path}/001/db",
55
+ :dataset => "Test",
56
+ :plugins => ["plugin1", "plugin2", "plugin3"],
57
+ :n_workers => 4,
58
+ },
59
+ "localhost:23003/test.002" => {
60
+ :database => "#{base_path}/002/db",
61
+ :dataset => "Test",
62
+ :plugins => ["plugin1", "plugin2", "plugin3"],
63
+ :n_workers => 4,
64
+ },
65
+ },
66
+ slices)
67
+ end
68
+
69
+ def fixture_path(base_path)
70
+ File.expand_path("../../fixtures/#{base_path}", __FILE__)
71
+ end
72
+
73
+ def catalog_path
74
+ @catalog_path ||= fixture_path("catalog/version2.json")
75
+ end
76
+
77
+ def base_path
78
+ File.dirname(catalog_path)
79
+ end
80
+
81
+ class PluginsTest < self
82
+ def setup
83
+ custom_data = {
84
+ "datasets" => {
85
+ "Droonga" => {
86
+ "nWorkers" => 1,
87
+ "replicas" => [
88
+ {
89
+ "slices" => [
90
+ {
91
+ "volume" => {
92
+ "address" => "#{farm_name}.000",
93
+ },
94
+ },
95
+ ],
96
+ },
97
+ ],
98
+ },
99
+ },
100
+
101
+ }
102
+ @data = minimum_data.merge(custom_data)
103
+ end
104
+
105
+ def farm_name
106
+ "localhost:23041/droonga"
107
+ end
108
+
109
+ def plugins(data)
110
+ catalog = create_catalog(data, catalog_path)
111
+ catalog.slices(farm_name).collect do |volum_address, options|
112
+ options[:plugins]
113
+ end
114
+ end
115
+
116
+ def test_plugins
117
+ @data["datasets"]["Droonga"]["plugins"] = ["search", "groonga", "add"]
118
+ assert_equal([["search", "groonga", "add"]],
119
+ plugins(@data))
120
+
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,66 @@
1
+ # Copyright (C) 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
+ require "droonga/catalog/version2_validator"
17
+
18
+ class CatalogVersion2ValidatorTest < Test::Unit::TestCase
19
+ def setup
20
+ @path = "catalog.json"
21
+ end
22
+
23
+ def validate(data)
24
+ validator = Droonga::Catalog::Version2Validator.new(data, @path)
25
+ validator.validate
26
+ end
27
+
28
+ def validation_error(details)
29
+ Droonga::Catalog::ValidationError.new(@path, details)
30
+ end
31
+
32
+ def detail(value_path, message)
33
+ Droonga::Catalog::ValidationError::Detail.new(value_path, message)
34
+ end
35
+
36
+ class DatasetsTest < self
37
+ def test_missing
38
+ details = [
39
+ detail("datasets", "required parameter is missing"),
40
+ ]
41
+ assert_raise(validation_error(details)) do
42
+ validate({})
43
+ end
44
+ end
45
+
46
+ class DatasetTest < self
47
+ class ReplicasTest < self
48
+ def test_missing
49
+ details = [
50
+ detail("datasets.Droonga.replicas",
51
+ "required parameter is missing"),
52
+ ]
53
+ assert_raise(validation_error(details)) do
54
+ data = {
55
+ "datasets" => {
56
+ "Droonga" => {
57
+ }
58
+ }
59
+ }
60
+ validate(data)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright (C) 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
+ require "droonga/catalog/volume_collection"
17
+
18
+ class CatalogVolumeCollectionTest < Test::Unit::TestCase
19
+ private
20
+ def create_volume_collection(volumes)
21
+ Droonga::Catalog::VolumeCollection.new(volumes)
22
+ end
23
+
24
+ class SelectTest < self
25
+ def setup
26
+ volumes = [
27
+ "volume1",
28
+ "volume2",
29
+ "volume3",
30
+ ]
31
+ @collection = create_volume_collection(volumes)
32
+ end
33
+
34
+ def test_top
35
+ assert_equal(["volume1"], @collection.select(:top))
36
+ end
37
+
38
+ def test_random
39
+ random_volumes = @collection.select(:random).collect do |volume|
40
+ volume.gsub(/\Avolume[123]\z/, "any volume")
41
+ end
42
+ assert_equal(["any volume"], random_volumes)
43
+ end
44
+
45
+ def test_all
46
+ assert_equal(["volume1", "volume2", "volume3"],
47
+ @collection.select(:all))
48
+ end
49
+ end
50
+ end