ruote 2.2.0 → 2.3.0

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 (305) hide show
  1. data/CHANGELOG.txt +166 -1
  2. data/CREDITS.txt +36 -17
  3. data/LICENSE.txt +1 -1
  4. data/README.rdoc +1 -7
  5. data/Rakefile +38 -29
  6. data/TODO.txt +93 -52
  7. data/lib/ruote-fs.rb +3 -0
  8. data/lib/ruote.rb +5 -1
  9. data/lib/ruote/context.rb +140 -35
  10. data/lib/ruote/dashboard.rb +1247 -0
  11. data/lib/ruote/{engine → dboard}/process_error.rb +22 -2
  12. data/lib/ruote/dboard/process_status.rb +587 -0
  13. data/lib/ruote/engine.rb +6 -871
  14. data/lib/ruote/exp/command.rb +7 -2
  15. data/lib/ruote/exp/commanded.rb +2 -2
  16. data/lib/ruote/exp/condition.rb +38 -13
  17. data/lib/ruote/exp/fe_add_branches.rb +1 -1
  18. data/lib/ruote/exp/fe_apply.rb +1 -1
  19. data/lib/ruote/exp/fe_await.rb +357 -0
  20. data/lib/ruote/exp/fe_cancel_process.rb +17 -3
  21. data/lib/ruote/exp/fe_command.rb +8 -4
  22. data/lib/ruote/exp/fe_concurrence.rb +218 -18
  23. data/lib/ruote/exp/fe_concurrent_iterator.rb +71 -10
  24. data/lib/ruote/exp/fe_cron.rb +3 -10
  25. data/lib/ruote/exp/fe_cursor.rb +14 -4
  26. data/lib/ruote/exp/fe_define.rb +3 -1
  27. data/lib/ruote/exp/fe_echo.rb +1 -1
  28. data/lib/ruote/exp/fe_equals.rb +1 -1
  29. data/lib/ruote/exp/fe_error.rb +1 -1
  30. data/lib/ruote/exp/fe_filter.rb +163 -4
  31. data/lib/ruote/exp/fe_forget.rb +21 -4
  32. data/lib/ruote/exp/fe_given.rb +1 -1
  33. data/lib/ruote/exp/fe_if.rb +1 -1
  34. data/lib/ruote/exp/fe_inc.rb +102 -35
  35. data/lib/ruote/exp/fe_iterator.rb +47 -12
  36. data/lib/ruote/exp/fe_listen.rb +96 -11
  37. data/lib/ruote/exp/fe_lose.rb +31 -4
  38. data/lib/ruote/exp/fe_noop.rb +1 -1
  39. data/lib/ruote/exp/fe_on_error.rb +109 -0
  40. data/lib/ruote/exp/fe_once.rb +10 -19
  41. data/lib/ruote/exp/fe_participant.rb +90 -28
  42. data/lib/ruote/exp/fe_read.rb +69 -0
  43. data/lib/ruote/exp/fe_redo.rb +3 -2
  44. data/lib/ruote/exp/fe_ref.rb +57 -27
  45. data/lib/ruote/exp/fe_registerp.rb +1 -3
  46. data/lib/ruote/exp/fe_reserve.rb +1 -1
  47. data/lib/ruote/exp/fe_restore.rb +6 -6
  48. data/lib/ruote/exp/fe_save.rb +12 -19
  49. data/lib/ruote/exp/fe_sequence.rb +38 -2
  50. data/lib/ruote/exp/fe_set.rb +143 -40
  51. data/lib/ruote/exp/{fe_let.rb → fe_stall.rb} +7 -38
  52. data/lib/ruote/exp/fe_subprocess.rb +8 -2
  53. data/lib/ruote/exp/fe_that.rb +1 -1
  54. data/lib/ruote/exp/fe_undo.rb +40 -4
  55. data/lib/ruote/exp/fe_unregisterp.rb +1 -3
  56. data/lib/ruote/exp/fe_wait.rb +12 -25
  57. data/lib/ruote/exp/{flowexpression.rb → flow_expression.rb} +375 -229
  58. data/lib/ruote/exp/iterator.rb +2 -2
  59. data/lib/ruote/exp/merge.rb +78 -17
  60. data/lib/ruote/exp/ro_attributes.rb +46 -36
  61. data/lib/ruote/exp/ro_filters.rb +34 -8
  62. data/lib/ruote/exp/ro_on_x.rb +431 -0
  63. data/lib/ruote/exp/ro_persist.rb +19 -7
  64. data/lib/ruote/exp/ro_timers.rb +123 -0
  65. data/lib/ruote/exp/ro_variables.rb +90 -29
  66. data/lib/ruote/fei.rb +57 -3
  67. data/lib/ruote/fs.rb +3 -0
  68. data/lib/ruote/id/mnemo_wfid_generator.rb +30 -7
  69. data/lib/ruote/id/wfid_generator.rb +17 -38
  70. data/lib/ruote/log/default_history.rb +23 -9
  71. data/lib/ruote/log/fancy_printing.rb +265 -0
  72. data/lib/ruote/log/storage_history.rb +23 -13
  73. data/lib/ruote/log/wait_logger.rb +224 -17
  74. data/lib/ruote/observer.rb +82 -0
  75. data/lib/ruote/part/block_participant.rb +65 -28
  76. data/lib/ruote/part/code_participant.rb +81 -0
  77. data/lib/ruote/part/engine_participant.rb +7 -2
  78. data/lib/ruote/part/local_participant.rb +221 -21
  79. data/lib/ruote/part/no_op_participant.rb +1 -1
  80. data/lib/ruote/part/null_participant.rb +1 -1
  81. data/lib/ruote/part/participant.rb +50 -0
  82. data/lib/ruote/part/rev_participant.rb +178 -0
  83. data/lib/ruote/part/smtp_participant.rb +2 -2
  84. data/lib/ruote/part/storage_participant.rb +228 -60
  85. data/lib/ruote/part/template.rb +1 -1
  86. data/lib/ruote/participant.rb +2 -0
  87. data/lib/ruote/reader.rb +205 -68
  88. data/lib/ruote/reader/json.rb +49 -0
  89. data/lib/ruote/reader/radial.rb +303 -0
  90. data/lib/ruote/reader/ruby_dsl.rb +44 -9
  91. data/lib/ruote/reader/xml.rb +11 -8
  92. data/lib/ruote/receiver/base.rb +98 -45
  93. data/lib/ruote/storage/base.rb +104 -35
  94. data/lib/ruote/storage/composite_storage.rb +50 -60
  95. data/lib/ruote/storage/fs_storage.rb +25 -34
  96. data/lib/ruote/storage/hash_storage.rb +38 -36
  97. data/lib/ruote/svc/dispatch_pool.rb +104 -35
  98. data/lib/ruote/svc/dollar_sub.rb +10 -8
  99. data/lib/ruote/svc/error_handler.rb +108 -52
  100. data/lib/ruote/svc/expression_map.rb +3 -3
  101. data/lib/ruote/svc/participant_list.rb +160 -55
  102. data/lib/ruote/svc/tracker.rb +31 -31
  103. data/lib/ruote/svc/treechecker.rb +28 -16
  104. data/lib/ruote/tree_dot.rb +1 -1
  105. data/lib/ruote/util/deep.rb +143 -0
  106. data/lib/ruote/util/filter.rb +125 -18
  107. data/lib/ruote/util/hashdot.rb +15 -13
  108. data/lib/ruote/util/look.rb +1 -1
  109. data/lib/ruote/util/lookup.rb +60 -22
  110. data/lib/ruote/util/misc.rb +63 -18
  111. data/lib/ruote/util/mpatch.rb +53 -0
  112. data/lib/ruote/util/ometa.rb +1 -2
  113. data/lib/ruote/util/process_observer.rb +177 -0
  114. data/lib/ruote/util/subprocess.rb +1 -1
  115. data/lib/ruote/util/time.rb +2 -2
  116. data/lib/ruote/util/tree.rb +64 -2
  117. data/lib/ruote/version.rb +3 -2
  118. data/lib/ruote/worker.rb +421 -92
  119. data/lib/ruote/workitem.rb +157 -22
  120. data/ruote.gemspec +15 -9
  121. data/test/bm/ci.rb +0 -2
  122. data/test/bm/ici.rb +0 -2
  123. data/test/bm/load_26c.rb +0 -3
  124. data/test/bm/mega.rb +0 -2
  125. data/test/functional/base.rb +57 -43
  126. data/test/functional/concurrent_base.rb +16 -13
  127. data/test/functional/ct_0_concurrence.rb +7 -11
  128. data/test/functional/ct_1_iterator.rb +9 -11
  129. data/test/functional/ct_2_cancel.rb +28 -17
  130. data/test/functional/eft_0_flow_expression.rb +35 -0
  131. data/test/functional/eft_10_cancel_process.rb +1 -1
  132. data/test/functional/eft_11_wait.rb +13 -13
  133. data/test/functional/eft_12_listen.rb +199 -66
  134. data/test/functional/eft_13_iterator.rb +95 -29
  135. data/test/functional/eft_14_cursor.rb +74 -24
  136. data/test/functional/eft_15_loop.rb +7 -7
  137. data/test/functional/eft_16_if.rb +1 -1
  138. data/test/functional/eft_17_equals.rb +1 -1
  139. data/test/functional/eft_18_concurrent_iterator.rb +156 -68
  140. data/test/functional/eft_19_reserve.rb +15 -15
  141. data/test/functional/eft_1_echo.rb +1 -1
  142. data/test/functional/eft_20_save.rb +51 -9
  143. data/test/functional/eft_21_restore.rb +1 -1
  144. data/test/functional/eft_22_noop.rb +1 -1
  145. data/test/functional/eft_23_apply.rb +1 -1
  146. data/test/functional/eft_24_add_branches.rb +7 -8
  147. data/test/functional/eft_25_command.rb +1 -1
  148. data/test/functional/eft_26_error.rb +11 -11
  149. data/test/functional/eft_27_inc.rb +111 -67
  150. data/test/functional/eft_28_once.rb +16 -16
  151. data/test/functional/eft_29_cron.rb +9 -9
  152. data/test/functional/eft_2_sequence.rb +23 -4
  153. data/test/functional/eft_30_ref.rb +36 -24
  154. data/test/functional/eft_31_registerp.rb +24 -24
  155. data/test/functional/eft_32_lose.rb +46 -20
  156. data/test/functional/eft_34_given.rb +1 -1
  157. data/test/functional/eft_35_filter.rb +161 -7
  158. data/test/functional/eft_36_read.rb +97 -0
  159. data/test/functional/{eft_0_process_definition.rb → eft_37_process_definition.rb} +4 -4
  160. data/test/functional/eft_38_on_error.rb +195 -0
  161. data/test/functional/eft_39_stall.rb +35 -0
  162. data/test/functional/eft_3_participant.rb +77 -22
  163. data/test/functional/eft_40_await.rb +297 -0
  164. data/test/functional/eft_4_set.rb +110 -11
  165. data/test/functional/eft_5_subprocess.rb +27 -5
  166. data/test/functional/eft_6_concurrence.rb +299 -60
  167. data/test/functional/eft_7_forget.rb +24 -22
  168. data/test/functional/eft_8_undo.rb +52 -15
  169. data/test/functional/eft_9_redo.rb +18 -20
  170. data/test/functional/ft_0_worker.rb +122 -13
  171. data/test/functional/ft_10_dollar.rb +77 -16
  172. data/test/functional/ft_11_recursion.rb +9 -9
  173. data/test/functional/ft_12_launchitem.rb +7 -9
  174. data/test/functional/ft_13_variables.rb +125 -22
  175. data/test/functional/ft_14_re_apply.rb +112 -56
  176. data/test/functional/ft_15_timeout.rb +64 -33
  177. data/test/functional/ft_16_participant_params.rb +59 -6
  178. data/test/functional/ft_17_conditional.rb +68 -2
  179. data/test/functional/ft_18_kill.rb +48 -30
  180. data/test/functional/ft_19_participant_code.rb +67 -0
  181. data/test/functional/ft_1_process_status.rb +222 -150
  182. data/test/functional/ft_20_storage_participant.rb +445 -44
  183. data/test/functional/ft_21_forget.rb +21 -26
  184. data/test/functional/ft_22_process_definitions.rb +8 -6
  185. data/test/functional/ft_23_load_defs.rb +29 -5
  186. data/test/functional/ft_24_block_participant.rb +199 -20
  187. data/test/functional/ft_25_receiver.rb +98 -46
  188. data/test/functional/ft_26_participant_rtimeout.rb +34 -26
  189. data/test/functional/ft_27_var_indirection.rb +40 -5
  190. data/test/functional/ft_28_null_noop_participants.rb +5 -5
  191. data/test/functional/ft_29_part_template.rb +2 -2
  192. data/test/functional/ft_2_errors.rb +106 -74
  193. data/test/functional/ft_30_smtp_participant.rb +7 -7
  194. data/test/functional/ft_31_part_blocking.rb +11 -11
  195. data/test/functional/ft_32_scope.rb +50 -0
  196. data/test/functional/ft_33_participant_subprocess_priority.rb +3 -3
  197. data/test/functional/ft_34_cursor_rewind.rb +14 -14
  198. data/test/functional/ft_35_add_service.rb +67 -9
  199. data/test/functional/ft_36_storage_history.rb +92 -24
  200. data/test/functional/ft_37_default_history.rb +35 -23
  201. data/test/functional/ft_38_participant_more.rb +189 -32
  202. data/test/functional/ft_39_wait_for.rb +25 -25
  203. data/test/functional/ft_3_participant_registration.rb +235 -107
  204. data/test/functional/ft_40_wait_logger.rb +105 -18
  205. data/test/functional/ft_41_participants.rb +13 -12
  206. data/test/functional/ft_42_storage_copy.rb +12 -12
  207. data/test/functional/ft_43_participant_on_reply.rb +85 -11
  208. data/test/functional/ft_44_var_participant.rb +5 -5
  209. data/test/functional/ft_45_participant_accept.rb +3 -3
  210. data/test/functional/ft_46_launch_single.rb +17 -17
  211. data/test/functional/ft_47_wfids.rb +41 -0
  212. data/test/functional/ft_48_lose.rb +19 -25
  213. data/test/functional/ft_49_engine_on_error.rb +54 -70
  214. data/test/functional/ft_4_cancel.rb +84 -26
  215. data/test/functional/ft_50_engine_config.rb +4 -4
  216. data/test/functional/ft_51_misc.rb +12 -12
  217. data/test/functional/ft_52_case.rb +17 -17
  218. data/test/functional/ft_53_engine_on_terminate.rb +18 -21
  219. data/test/functional/ft_54_patterns.rb +18 -16
  220. data/test/functional/ft_55_engine_participant.rb +55 -55
  221. data/test/functional/ft_56_filter_attribute.rb +90 -52
  222. data/test/functional/ft_57_rev_participant.rb +252 -0
  223. data/test/functional/ft_58_workitem.rb +150 -0
  224. data/test/functional/ft_59_pause.rb +329 -0
  225. data/test/functional/ft_5_on_error.rb +430 -77
  226. data/test/functional/ft_60_code_participant.rb +65 -0
  227. data/test/functional/ft_61_trailing_fields.rb +34 -0
  228. data/test/functional/ft_62_exp_name_and_dollar_substitution.rb +35 -0
  229. data/test/functional/ft_63_participants_221.rb +458 -0
  230. data/test/functional/ft_64_stash.rb +41 -0
  231. data/test/functional/ft_65_timers.rb +313 -0
  232. data/test/functional/ft_66_flank.rb +133 -0
  233. data/test/functional/ft_67_radial_misc.rb +34 -0
  234. data/test/functional/ft_68_reput.rb +72 -0
  235. data/test/functional/ft_69_worker_info.rb +56 -0
  236. data/test/functional/ft_6_on_cancel.rb +189 -36
  237. data/test/functional/ft_70_take_and_discard_attributes.rb +94 -0
  238. data/test/functional/ft_71_retries.rb +144 -0
  239. data/test/functional/ft_72_on_terminate.rb +60 -0
  240. data/test/functional/ft_73_raise_msg.rb +107 -0
  241. data/test/functional/ft_74_respark.rb +106 -0
  242. data/test/functional/ft_75_context.rb +66 -0
  243. data/test/functional/ft_76_observer.rb +53 -0
  244. data/test/functional/ft_77_process_observer.rb +157 -0
  245. data/test/functional/ft_78_part_participant.rb +37 -0
  246. data/test/functional/ft_7_tags.rb +238 -50
  247. data/test/functional/ft_8_participant_consumption.rb +27 -21
  248. data/test/functional/ft_9_subprocesses.rb +48 -18
  249. data/test/functional/restart_base.rb +4 -6
  250. data/test/functional/rt_0_wait.rb +10 -10
  251. data/test/functional/rt_1_listen.rb +6 -6
  252. data/test/functional/rt_2_errors.rb +12 -12
  253. data/test/functional/rt_3_once.rb +17 -12
  254. data/test/functional/rt_4_cron.rb +17 -17
  255. data/test/functional/rt_5_timeout.rb +13 -13
  256. data/test/functional/signals.rb +103 -0
  257. data/test/functional/storage.rb +730 -0
  258. data/test/functional/storage_helper.rb +48 -35
  259. data/test/functional/test.rb +6 -2
  260. data/test/misc/idle.rb +21 -0
  261. data/test/misc/light.rb +29 -0
  262. data/test/path_helper.rb +1 -1
  263. data/test/test.rb +2 -5
  264. data/test/test_helper.rb +13 -0
  265. data/test/unit/test.rb +1 -4
  266. data/test/unit/ut_0_ruby_reader.rb +25 -9
  267. data/test/unit/ut_10_participants.rb +47 -0
  268. data/test/unit/ut_11_lookup.rb +59 -2
  269. data/test/unit/ut_12_wait_logger.rb +123 -0
  270. data/test/unit/ut_14_is_uri.rb +1 -1
  271. data/test/unit/ut_15_util.rb +1 -1
  272. data/test/unit/ut_16_reader.rb +136 -14
  273. data/test/unit/ut_17_merge.rb +155 -0
  274. data/test/unit/ut_19_part_template.rb +1 -1
  275. data/test/unit/ut_1_fei.rb +11 -2
  276. data/test/unit/ut_20_composite_storage.rb +27 -1
  277. data/test/unit/{ut_21_participant_list.rb → ut_21_svc_participant_list.rb} +2 -3
  278. data/test/unit/ut_22_filter.rb +231 -10
  279. data/test/unit/ut_23_svc_tracker.rb +48 -0
  280. data/test/unit/ut_24_radial_reader.rb +458 -0
  281. data/test/unit/ut_25_process_status.rb +143 -0
  282. data/test/unit/ut_26_deep.rb +131 -0
  283. data/test/unit/ut_2_dashboard.rb +114 -0
  284. data/test/unit/ut_3_worker.rb +54 -0
  285. data/test/unit/ut_4_expmap.rb +1 -1
  286. data/test/unit/ut_5_tree.rb +23 -23
  287. data/test/unit/ut_6_condition.rb +71 -29
  288. data/test/unit/ut_7_workitem.rb +18 -4
  289. data/test/unit/ut_8_tree_to_dot.rb +1 -1
  290. data/test/unit/ut_9_xml_reader.rb +1 -1
  291. metadata +142 -63
  292. data/jruby_issue.txt +0 -32
  293. data/lib/ruote/engine/process_status.rb +0 -403
  294. data/lib/ruote/log/pretty.rb +0 -165
  295. data/lib/ruote/log/test_logger.rb +0 -204
  296. data/lib/ruote/util/serializer.rb +0 -103
  297. data/phil.txt +0 -14
  298. data/test/functional/eft_33_let.rb +0 -31
  299. data/test/functional/ft_19_alias.rb +0 -33
  300. data/test/functional/ft_47_wfid_generator.rb +0 -54
  301. data/test/unit/storage.rb +0 -403
  302. data/test/unit/storages.rb +0 -37
  303. data/test/unit/ut_13_serializer.rb +0 -65
  304. data/test/unit/ut_18_engine.rb +0 -47
  305. data/test/unit/ut_3_wait_logger.rb +0 -39
@@ -5,8 +5,8 @@
5
5
  # Wed Oct 28 12:51:04 JST 2009
6
6
  #
7
7
 
8
- require File.join(File.dirname(__FILE__), 'base')
9
- require File.join(File.dirname(__FILE__), 'restart_base')
8
+ require File.expand_path('../base', __FILE__)
9
+ require File.expand_path('../restart_base', __FILE__)
10
10
 
11
11
 
12
12
  class RtCronTest < Test::Unit::TestCase
@@ -23,42 +23,42 @@ class RtCronTest < Test::Unit::TestCase
23
23
  end
24
24
  end
25
25
 
26
- @engine.variables['text'] = 'pre'
26
+ @dashboard.variables['text'] = 'pre'
27
27
 
28
- #noisy
28
+ #@dashboard.noisy = true
29
29
 
30
- wfid = @engine.launch(pdef)
30
+ wfid = @dashboard.launch(pdef)
31
31
 
32
- wait_for(3)
32
+ wait_for(5)
33
33
 
34
- assert_equal 1, @engine.processes.size
35
- assert_equal 1, @engine.storage.get_many('schedules').size
34
+ assert_equal 1, @dashboard.processes.size
35
+ assert_equal 1, @dashboard.storage.get_many('schedules').size
36
36
 
37
- @engine.shutdown
37
+ @dashboard.shutdown
38
38
 
39
39
  # restart...
40
40
 
41
41
  start_new_engine
42
42
 
43
- #noisy
43
+ #@dashboard.noisy = true
44
44
 
45
- @engine.variables['text'] = 'post'
45
+ @dashboard.variables['text'] = 'post'
46
46
 
47
- assert_equal 1, @engine.processes.size
48
- assert_equal 1, @engine.storage.get_many('schedules').size
47
+ assert_equal 1, @dashboard.processes.size
48
+ assert_equal 1, @dashboard.storage.get_many('schedules').size
49
49
 
50
- wait_for(4)
50
+ wait_for(5)
51
51
 
52
52
  assert_match /pre\npost/, @tracer.to_s
53
53
 
54
- @engine.cancel_process(wfid)
54
+ @dashboard.cancel_process(wfid)
55
55
 
56
56
  while msg = wait_for(wfid)
57
57
  break if msg['action'] == 'terminated'
58
58
  end
59
59
 
60
- assert_equal 0, @engine.processes.size
61
- assert_equal 0, @engine.storage.get_many('schedules').size
60
+ assert_equal 0, @dashboard.processes.size
61
+ assert_equal 0, @dashboard.storage.get_many('schedules').size
62
62
  end
63
63
  end
64
64
 
@@ -5,8 +5,8 @@
5
5
  # Wed Oct 28 14:51:07 JST 2009
6
6
  #
7
7
 
8
- require File.join(File.dirname(__FILE__), 'base')
9
- require File.join(File.dirname(__FILE__), 'restart_base')
8
+ require File.expand_path('../base', __FILE__)
9
+ require File.expand_path('../restart_base', __FILE__)
10
10
 
11
11
  require 'ruote/part/null_participant'
12
12
 
@@ -25,18 +25,18 @@ class RtTimeoutTest < Test::Unit::TestCase
25
25
  participant 'alpha', :timeout => '2d'
26
26
  end
27
27
 
28
- @engine.register_participant 'alpha', Ruote::NullParticipant
28
+ @dashboard.register_participant 'alpha', Ruote::NullParticipant
29
29
 
30
30
  #noisy
31
31
 
32
- wfid = @engine.launch(pdef)
32
+ wfid = @dashboard.launch(pdef)
33
33
 
34
34
  wait_for(3)
35
35
 
36
- assert_equal 1, @engine.processes.size
37
- assert_equal 1, @engine.storage.get_many('schedules').size
36
+ assert_equal 1, @dashboard.processes.size
37
+ assert_equal 1, @dashboard.storage.get_many('schedules').size
38
38
 
39
- @engine.shutdown
39
+ @dashboard.shutdown
40
40
 
41
41
  # restart...
42
42
 
@@ -44,17 +44,17 @@ class RtTimeoutTest < Test::Unit::TestCase
44
44
 
45
45
  #noisy
46
46
 
47
- @engine.register_participant 'alpha', Ruote::NullParticipant
47
+ @dashboard.register_participant 'alpha', Ruote::NullParticipant
48
48
 
49
- assert_equal 1, @engine.processes.size
50
- assert_equal 1, @engine.storage.get_many('schedules').size
49
+ assert_equal 1, @dashboard.processes.size
50
+ assert_equal 1, @dashboard.storage.get_many('schedules').size
51
51
 
52
- @engine.cancel_process(wfid)
52
+ @dashboard.cancel_process(wfid)
53
53
 
54
54
  wait_for(wfid)
55
55
 
56
- assert_equal 0, @engine.processes.size
57
- assert_equal 0, @engine.storage.get_many('schedules').size
56
+ assert_equal 0, @dashboard.processes.size
57
+ assert_equal 0, @dashboard.storage.get_many('schedules').size
58
58
  end
59
59
  end
60
60
 
@@ -0,0 +1,103 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Sat Sep 20 23:40:10 JST 2008
6
+ #
7
+
8
+
9
+ # Hitting CTRL-C reveals the fancy dashboard log (if any) and the
10
+ # current backtrace.
11
+ #
12
+ trap 'INT' do
13
+
14
+ if $_dashboard && ! (ARGV.include?('-N') || ENV['NOISY'])
15
+ puts
16
+ puts '-' * 80
17
+ puts $_dashboard.context.logger.fancy_log
18
+ end
19
+
20
+ puts
21
+ puts '-' * 80
22
+ puts *caller
23
+ puts '-' * 80
24
+
25
+ exit 1
26
+
27
+ end #if RUBY_VERSION.match(/^1.9./)
28
+
29
+
30
+ # Didn't use it much, pops a console while tests are running.
31
+ #
32
+ trap 'USR1' do
33
+
34
+ require 'irb'
35
+ require 'irb/completion'
36
+
37
+ IRB.setup(nil)
38
+ ws = IRB::WorkSpace.new(binding)
39
+ irb = IRB::Irb.new(ws)
40
+ IRB::conf[:MAIN_CONTEXT] = irb.context
41
+ irb.eval_input
42
+ end
43
+
44
+
45
+ # USR2 is used for CI timeouts. Tries to print a max of useful information
46
+ # and then exits.
47
+ #
48
+ trap 'USR2' do
49
+
50
+ # for CI timeouts
51
+
52
+ begin
53
+
54
+ puts
55
+ puts '-' * 80
56
+ puts *$_engine.context.logger.fancy_log if $_engine
57
+
58
+ puts
59
+ puts '-' * 80
60
+ if defined?(MiniTest)
61
+ ObjectSpace.each_object(
62
+ MiniTest::Unit
63
+ ).first.instance_eval do
64
+ self.status
65
+ puts
66
+ @report.each_with_index do |msg, i|
67
+ @@out.puts "\n%3d) %s" % [i + 1, msg]
68
+ end
69
+ end
70
+ elsif defined?(Test::Unit::UI::Console::TestRunner)
71
+ ObjectSpace.each_object(
72
+ Test::Unit::UI::Console::TestRunner
73
+ ).first.instance_eval do
74
+ finished(-1)
75
+ end
76
+ else
77
+ puts "no test/unit or MiniTest"
78
+ end
79
+
80
+ puts '-' * 80
81
+ puts "threads: #{Thread.list.size}"
82
+ Thread.list.each do |t|
83
+ puts '-' * 80
84
+ if Thread.current.respond_to?(:backtrace) # only >= 1.9.2p290 it seems
85
+ puts "thread backtrace:"
86
+ puts *t.backtrace
87
+ else
88
+ t.exit unless t == Thread.main
89
+ end
90
+ end
91
+
92
+ puts '-' * 80
93
+
94
+ rescue Exception => e
95
+ p e
96
+ puts *e.backtrace
97
+ end
98
+
99
+ exit 1
100
+ end
101
+
102
+ puts "pid #{$$}"
103
+
@@ -0,0 +1,730 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Mon Dec 14 15:03:13 JST 2009
6
+ #
7
+
8
+ require File.expand_path('../../test_helper', __FILE__)
9
+ require_json
10
+ require File.expand_path('../../functional/storage_helper', __FILE__)
11
+ require File.expand_path('../../functional/signals', __FILE__)
12
+ require 'ruote'
13
+
14
+
15
+ # Please note:
16
+
17
+ # Operations return something trueish when they fail and nil
18
+ # when they succeed.
19
+ #
20
+ # The pattern is: when it fails because the document passed as argument is
21
+ # outdated, you will receive the current version of the document (trueish),
22
+ # when it fails because the document is gone (deleted meanwhile), you will
23
+ # receive true (which is obviously trueish).
24
+
25
+ class FtStorage < Test::Unit::TestCase
26
+
27
+ #
28
+ # test preparation
29
+
30
+ def setup
31
+
32
+ @s = determine_storage({})
33
+ @s = @s.storage if @s.respond_to?(:storage)
34
+
35
+ %w[ errors expressions msgs workitems ].each do |t|
36
+ @s.purge_type!(t)
37
+ end
38
+ end
39
+
40
+ def teardown
41
+
42
+ return unless @s
43
+
44
+ @s.purge!
45
+
46
+ @s.shutdown
47
+ end
48
+
49
+ #
50
+ # helpers
51
+
52
+ def put_toto_doc
53
+
54
+ @s.put('_id' => 'toto', 'type' => 'errors', 'message' => 'testing')
55
+ end
56
+
57
+ def get_toto_doc
58
+
59
+ @s.get('errors', 'toto')
60
+ end
61
+
62
+ #
63
+ # the tests
64
+
65
+ # === put
66
+
67
+ # When successful, #put returns nil.
68
+ #
69
+ def test_put
70
+
71
+ doc = { '_id' => 'toto', 'type' => 'errors', 'message' => 'testing' }
72
+
73
+ r = @s.put(doc)
74
+
75
+ assert_nil r
76
+
77
+ assert_nil doc['_rev']
78
+ assert_nil doc['put_at']
79
+
80
+ doc = @s.get('errors', 'toto')
81
+
82
+ assert_not_nil doc['_rev']
83
+ assert_not_nil doc['put_at']
84
+
85
+ assert_equal 'testing', doc['message']
86
+ end
87
+
88
+ # When a document with the same _id and type already existent, the put
89
+ # doesn't happen and #put returns that already existing document.
90
+ #
91
+ def test_put_when_already_existent
92
+
93
+ put_toto_doc
94
+
95
+ doc = { '_id' => 'toto', 'type' => 'errors', 'message' => 'two' }
96
+
97
+ r = @s.put(doc)
98
+
99
+ assert_match /Hash$/, r.class.name
100
+ assert_not_nil r['_rev']
101
+ assert_not_nil r['put_at']
102
+
103
+ assert_nil doc['_rev']
104
+ assert_nil doc['put_at']
105
+ end
106
+
107
+ # A successful reput (_id/type/_rev do match) returns nil.
108
+ #
109
+ def test_reput
110
+
111
+ put_toto_doc
112
+
113
+ d0 = get_toto_doc
114
+
115
+ d0['message'] = 'test_reput'
116
+
117
+ r = @s.put(d0)
118
+
119
+ assert_nil r
120
+
121
+ d1 = get_toto_doc
122
+
123
+ assert_not_equal d1['_rev'], d0['_rev']
124
+ assert_not_equal d1['put_at'], d0['put_at']
125
+
126
+ assert_equal 'test_reput', d1['message']
127
+ end
128
+
129
+ # A reput with the wrong rev (our document is outdated probably) will
130
+ # not happen and #put will return the current (newest probably) document.
131
+ #
132
+ def test_reput_fail_wrong_rev
133
+
134
+ put_toto_doc
135
+
136
+ d1 = get_toto_doc
137
+
138
+ rev = d1['_rev']
139
+
140
+ @s.put(d1.merge('message' => 'x'))
141
+
142
+ d2 = get_toto_doc
143
+
144
+ r = @s.put(d2.merge('_rev' => rev, 'message' => 'y'))
145
+
146
+ assert_not_nil r
147
+ assert_not_equal d1['_rev'], d2['_rev']
148
+ assert_equal 'x', d2['message']
149
+ end
150
+
151
+ # Attempting to put a document that is gone (got deleted meanwhile) will
152
+ # return true.
153
+ #
154
+ def test_reput_fail_gone
155
+
156
+ put_toto_doc
157
+
158
+ doc = get_toto_doc
159
+
160
+ @s.delete(doc)
161
+
162
+ r = @s.put(doc)
163
+
164
+ assert_equal true, r
165
+ end
166
+
167
+ # Attempting to put a document with a _rev directly will raise an
168
+ # ArgumentError.
169
+ #
170
+ def test_put_doc_with_rev
171
+
172
+ put_toto_doc; doc = get_toto_doc
173
+ # just to get a valid _rev
174
+
175
+ r = @s.put(
176
+ '_id' => 'doc_with_rev', 'type' => 'errors', '_rev' => doc['_rev'])
177
+
178
+ assert_equal true, r
179
+ end
180
+
181
+ # #put takes an optional :update_rev. When set to true and the put
182
+ # succeeds, the _rev and the put_at of the [local] document are set/updated.
183
+ #
184
+ def test_put_update_rev_new_document
185
+
186
+ doc = { '_id' => 'urev', 'type' => 'errors' }
187
+
188
+ r = @s.put(doc, :update_rev => true)
189
+
190
+ assert_nil r
191
+ assert_not_nil doc['_rev']
192
+ assert_not_nil doc['put_at']
193
+ end
194
+
195
+ # When putting a document with the :update_rev option set, the just put
196
+ # document will get the new _rev (and the put_at)
197
+ #
198
+ def test_put_update_rev_existing_document
199
+
200
+ put_toto_doc; doc = get_toto_doc
201
+
202
+ initial_rev = doc['_rev']
203
+ initial_put_at = doc['put_at']
204
+
205
+ r = @s.put(doc, :update_rev => true)
206
+
207
+ assert_nil r
208
+ assert_not_nil initial_rev
209
+ assert_not_nil initial_put_at
210
+ assert_not_nil doc['_rev']
211
+ assert_not_equal doc['_rev'], initial_rev
212
+ assert_not_nil doc['put_at']
213
+ assert_not_equal doc['put_at'], initial_put_at
214
+ end
215
+
216
+ # put_at and _rev should not repeat
217
+ #
218
+ def test_put_sequence
219
+
220
+ revs = []
221
+ put_ats = []
222
+ doc = { '_id' => 'putseq', 'type' => 'errors' }
223
+
224
+ 77.times do |i|
225
+
226
+ @s.put(doc)
227
+ doc = @s.get('errors', 'putseq')
228
+
229
+ revs << doc['_rev']
230
+ put_ats << doc['put_at']
231
+
232
+ assert_equal i + 1, revs.uniq.size
233
+ assert_equal i + 1, put_ats.uniq.size
234
+ end
235
+ end
236
+
237
+ # Be lenient with the input (accept symbols, but turn them into strings).
238
+ #
239
+ def test_put_turns_symbols_into_strings
240
+
241
+ r = @s.put('_id' => 'skeys', 'type' => 'errors', :a => :b)
242
+
243
+ assert_nil r
244
+
245
+ doc = @s.get('errors', 'skeys')
246
+
247
+ return if doc.class != Hash
248
+ # MongoDB uses BSON::OrderedHash which is happy with symbols...
249
+
250
+ assert_equal 'b', doc['a']
251
+ end
252
+
253
+ # === get
254
+
255
+ # Getting a non-existent document returns nil.
256
+ #
257
+ def test_get_non_existent
258
+
259
+ assert_nil @s.get('errors', 'nemo')
260
+ end
261
+
262
+ # Getting a document returns it (well the most up-to-date revision of it).
263
+ #
264
+ def test_get
265
+
266
+ put_toto_doc
267
+
268
+ doc = @s.get('errors', 'toto')
269
+
270
+ doc.delete('_rev')
271
+ doc.delete('put_at')
272
+ doc.delete('_wfid') # ruote-mon
273
+
274
+ assert_equal(
275
+ { '_id' => 'toto', 'type' => 'errors', 'message' => 'testing' },
276
+ doc)
277
+ end
278
+
279
+ # === delete
280
+
281
+ # When successful, #delete returns nil (like the other methods...).
282
+ #
283
+ def test_delete
284
+
285
+ put_toto_doc
286
+
287
+ doc = @s.get('errors', 'toto')
288
+
289
+ r = @s.delete(doc)
290
+
291
+ assert_equal nil, r
292
+
293
+ doc = @s.get('errors', 'toto')
294
+
295
+ assert_equal nil, doc
296
+ end
297
+
298
+ # When attempting to delete a document and that document argument has no
299
+ # _rev, it will raise an ArgumentError.
300
+ #
301
+ def test_delete_document_without_rev
302
+
303
+ assert_raise(
304
+ ArgumentError, "can't delete doc without _rev"
305
+ ) do
306
+ @s.delete('_id' => 'without_rev', 'type' => 'errors')
307
+ end
308
+ end
309
+
310
+ # Deleting a document that doesn't exist returns true.
311
+ #
312
+ def test_delete_non_existent_document
313
+
314
+ put_toto_doc; doc = get_toto_doc
315
+ # just to get a valid _rev
316
+
317
+ r = @s.delete('_id' => 'ned', 'type' => 'errors', '_rev' => doc['_rev'])
318
+
319
+ assert_equal true, r
320
+ end
321
+
322
+ # Deleting a document that is gone (got deleted meanwhile) returns true.
323
+ #
324
+ def test_delete_gone_document
325
+
326
+ put_toto_doc
327
+ doc = get_toto_doc
328
+ @s.delete(doc)
329
+
330
+ r = @s.delete(doc)
331
+
332
+ assert_equal true, r
333
+ end
334
+
335
+ # === get_many
336
+
337
+ # Get many documents at once, use a string or regex key, or not.
338
+ #
339
+ def test_get_many
340
+
341
+ load_30_errors
342
+
343
+ assert_equal 30, @s.get_many('errors').size
344
+ assert_equal 0, @s.get_many('errors', '7').size
345
+ assert_equal 1, @s.get_many('errors', '07').size
346
+ assert_equal 1, @s.get_many('errors', /!07$/).size
347
+ assert_equal 30, @s.get_many('errors', /^yy!/).size
348
+ assert_equal 30, @s.get_many('errors', /y/).size
349
+
350
+ assert_equal 'yy!07', @s.get_many('errors', '07').first['_id']
351
+ assert_equal 'yy!07', @s.get_many('errors', /!07/).first['_id']
352
+ end
353
+
354
+ # Get many documents at once, use an array of string or regex keys.
355
+ #
356
+ def test_get_many_array_of_keys
357
+
358
+ load_30_errors
359
+
360
+ assert_equal 30, @s.get_many('errors').size
361
+ assert_equal 2, @s.get_many('errors', [ '07', '08' ]).size
362
+ assert_equal 2, @s.get_many('errors', [ /!07$/, /!08$/ ]).size
363
+
364
+ assert_equal(
365
+ %w[ yy!07 yy!08 ],
366
+ @s.get_many('errors', [ '07', '08' ]).collect { |d| d['_id'] }.sort)
367
+ assert_equal(
368
+ %w[ yy!07 yy!08 ],
369
+ @s.get_many('errors', [ /!07$/, /!08$/ ]).collect { |d| d['_id'] }.sort)
370
+ end
371
+
372
+ # Limit the number of documents received.
373
+ #
374
+ def test_get_many_limit
375
+
376
+ load_30_errors
377
+
378
+ assert_equal 10, @s.get_many('errors', nil, :limit => 10).size
379
+ end
380
+
381
+ # Count the documents (in a type).
382
+ #
383
+ def test_get_many_count
384
+
385
+ load_30_errors
386
+
387
+ assert_equal 30, @s.get_many('errors', nil, :count => true)
388
+ end
389
+
390
+ # Paginate documents.
391
+ #
392
+ def test_get_many_skip_and_limit
393
+
394
+ load_30_errors
395
+
396
+ assert_equal(
397
+ %w[ yy!01 yy!02 yy!03 yy!04 ],
398
+ @s.get_many(
399
+ 'errors', nil, :skip => 0, :limit => 4
400
+ ).collect { |d| d['_id'] })
401
+ assert_equal(
402
+ %w[ yy!04 yy!05 yy!06 ],
403
+ @s.get_many(
404
+ 'errors', nil, :skip => 3, :limit => 3
405
+ ).collect { |d| d['_id'] })
406
+ end
407
+
408
+ # Pagination and :descending are not incompatible.
409
+ #
410
+ def test_get_many_skip_limit_and_reverse
411
+
412
+ load_30_errors
413
+
414
+ assert_equal(
415
+ %w[ yy!30 yy!29 yy!28 ],
416
+ @s.get_many(
417
+ 'errors', nil, :skip => 0, :limit => 3, :descending => true
418
+ ).collect { |d| d['_id'] })
419
+ assert_equal(
420
+ %w[ yy!27 yy!26 yy!25 ],
421
+ @s.get_many(
422
+ 'errors', nil, :skip => 3, :limit => 3, :descending => true
423
+ ).collect { |d| d['_id'] })
424
+ end
425
+
426
+ # === purge!
427
+
428
+ # Purge removes all the documents in the storage.
429
+ #
430
+ def test_purge
431
+
432
+ put_toto_doc
433
+
434
+ assert_equal 1, @s.get_many('errors').size
435
+
436
+ @s.purge!
437
+
438
+ assert_equal 0, @s.get_many('errors').size
439
+ end
440
+
441
+ # === reserve
442
+
443
+ # Making sure that Storage#reserve(msg) returns true once and only once
444
+ # for a given msg. Stresses the storage for a while and then checks
445
+ # for collisions.
446
+ #
447
+ def test_reserve
448
+
449
+ # TODO: eventually return here if the storage being tested has
450
+ # no need for a real reserve implementation (ruote-swf for example).
451
+
452
+ taoe = Thread.abort_on_exception
453
+ Thread.abort_on_exception = true
454
+
455
+ reserved = []
456
+ threads = []
457
+
458
+ threads << Thread.new do
459
+ i = 0
460
+ loop do
461
+ @s.put_msg('launch', 'tree' => i)
462
+ i = i + 1
463
+ end
464
+ end
465
+
466
+ 2.times do
467
+
468
+ threads << Thread.new do
469
+ loop do
470
+ msgs = @s.get_msgs
471
+ msgs[0, 100].each do |msg|
472
+ next if msg['tree'].nil?
473
+ next unless @s.reserve(msg)
474
+ if reserved.include?(msg['tree'])
475
+ puts "=" * 80
476
+ p [ :dbl, :r, msg['_rev'], :t, msg['tree'] ]
477
+ end
478
+ reserved << msg['tree']
479
+ sleep(rand * 0.01)
480
+ end
481
+ end
482
+ end
483
+ end
484
+
485
+ sleep 7
486
+
487
+ threads.each { |t| t.terminate }
488
+
489
+ Thread.abort_on_exception = taoe
490
+
491
+ assert_equal false, reserved.empty?
492
+ assert_equal reserved.size, reserved.uniq.size
493
+ end
494
+
495
+ # === ids
496
+
497
+ # Storage#ids(type) returns all the ids present for a document type, in
498
+ # sorted order.
499
+ #
500
+ def test_ids
501
+
502
+ ids = load_30_errors
503
+
504
+ assert_equal ids.sort, @s.ids('errors')
505
+ end
506
+
507
+ # === dump
508
+
509
+ # #dump returns a string representation of the storage's content. Warning,
510
+ # this is a debug/test method.
511
+ #
512
+ def test_dump
513
+
514
+ load_30_errors
515
+
516
+ dump = @s.dump('errors')
517
+
518
+ assert_match /^[ -] _id: yy!01\n/, dump
519
+ assert_match /^[ -] _id: yy!21\n/, dump
520
+ end
521
+
522
+ # === clear
523
+
524
+ # #clear clears the storage
525
+ #
526
+ def test_clear
527
+
528
+ put_toto_doc
529
+
530
+ assert_equal 1, @s.get_many('errors').size
531
+
532
+ @s.clear
533
+
534
+ assert_equal 0, @s.get_many('errors').size
535
+ end
536
+
537
+ # === remove_process
538
+
539
+ # Put documents for process 0 and process 1, remove_process(1), check that
540
+ # only documents for process 0 are remaining.
541
+ #
542
+ # Don't forget to deal with trackers and schedules.
543
+ #
544
+ def test_remove_process
545
+
546
+ @s.purge_type!('errors')
547
+ ts = @s.get_trackers
548
+ @s.delete(ts) if ts['_rev']
549
+
550
+ dboard = Ruote::Dashboard.new(Ruote::Worker.new(@s))
551
+ dboard.noisy = ENV['NOISY'] == 'true'
552
+
553
+ dboard.register :human, Ruote::StorageParticipant
554
+
555
+ pdef = Ruote.define do
556
+ concurrence do
557
+ wait '1d'
558
+ human
559
+ listen :to => 'bob'
560
+ error 'nada'
561
+ end
562
+ end
563
+
564
+ wfid0 = dboard.launch(pdef)
565
+ wfid1 = dboard.launch(pdef)
566
+
567
+ dboard.wait_for('error_intercepted')
568
+ dboard.wait_for('error_intercepted')
569
+
570
+ assert_equal 12, @s.get_many('expressions').size
571
+ assert_equal 2, @s.get_many('schedules').size
572
+ assert_equal 2, @s.get_many('workitems').size
573
+ assert_equal 2, @s.get_many('errors').size
574
+ assert_equal 2, @s.get_trackers['trackers'].size
575
+
576
+ @s.remove_process(wfid0)
577
+
578
+ assert_equal 6, @s.get_many('expressions').size
579
+ assert_equal 1, @s.get_many('schedules').size
580
+ assert_equal 1, @s.get_many('workitems').size
581
+ assert_equal 1, @s.get_many('errors').size
582
+ assert_equal 1, @s.get_trackers['trackers'].size
583
+
584
+ ensure
585
+ dboard.shutdown rescue nil
586
+ end
587
+
588
+ # === configuration
589
+
590
+ # Simply getting the engine configuration should work.
591
+ #
592
+ def test_get_configuration
593
+
594
+ assert_not_nil @s.get_configuration('engine')
595
+ end
596
+
597
+ # The initial configuration passed when initializing the storage overrides
598
+ # any previous configuration.
599
+ #
600
+ def test_override_configuration
601
+
602
+ determine_storage('house' => 'taira', 'domain' => 'harima')
603
+ s = determine_storage('house' => 'minamoto')
604
+
605
+ assert_equal 'minamoto', s.get_configuration('engine')['house']
606
+ assert_equal nil, s.get_configuration('engine')['domain']
607
+ end
608
+
609
+ # Testing the 'preserve_configuration' option for storage initialization.
610
+ #
611
+ def test_preserve_configuration
612
+
613
+ return if @s.class == Ruote::HashStorage
614
+ # this test makes no sense with an in-memory hash
615
+
616
+ determine_storage(
617
+ 'house' => 'taira')
618
+ s = determine_storage(
619
+ 'house' => 'minamoto', 'preserve_configuration' => true)
620
+
621
+ assert_equal 'taira', s.get_configuration('engine')['house']
622
+
623
+ # if this test is giving a
624
+ # "NoMethodError: undefined method `[]' for nil:NilClass"
625
+ # for ruote-dm, comment out the auto_upgrade! block in
626
+ # ruote-dm/test/functional_connection.rb
627
+ end
628
+
629
+ # === query workitems
630
+
631
+ # Query by workitem field.
632
+ #
633
+ def test_by_field
634
+
635
+ return unless @s.respond_to?(:by_field)
636
+
637
+ load_workitems
638
+
639
+ assert_equal 3, @s.by_field('workitems', 'place', 'kyouto').size
640
+ assert_equal 1, @s.by_field('workitems', 'place', 'sendai').size
641
+
642
+ assert_equal(
643
+ Ruote::Workitem, @s.by_field('workitems', 'place', 'sendai').first.class)
644
+ end
645
+
646
+ # Query by participant name.
647
+ #
648
+ def test_by_participant
649
+
650
+ return unless @s.respond_to?(:by_participant)
651
+
652
+ load_workitems
653
+
654
+ assert_equal 2, @s.by_participant('workitems', 'fujiwara', {}).size
655
+ assert_equal 1, @s.by_participant('workitems', 'shingen', {}).size
656
+
657
+ assert_equal(
658
+ Ruote::Workitem, @s.by_participant('workitems', 'shingen', {}).first.class)
659
+ end
660
+
661
+ # General #query_workitems method.
662
+ #
663
+ def test_query_workitems
664
+
665
+ return unless @s.respond_to?(:query_workitems)
666
+
667
+ load_workitems
668
+
669
+ assert_equal 3, @s.query_workitems('place' => 'kyouto').size
670
+ assert_equal 1, @s.query_workitems('place' => 'kyouto', 'at' => 'kamo').size
671
+
672
+ assert_equal(
673
+ Ruote::Workitem, @s.query_workitems('place' => 'kyouto').first.class)
674
+ end
675
+
676
+ # === misc
677
+
678
+ # Simply make sure the storage (well, at least its "error" type) is empty.
679
+ #
680
+ def test_starts_empty
681
+
682
+ assert_equal 0, @s.get_many('errors').size
683
+ end
684
+
685
+ protected
686
+
687
+ #
688
+ # helpers
689
+
690
+ def load_30_errors
691
+
692
+ (1..30).to_a.shuffle.collect do |i|
693
+
694
+ id = sprintf('yy!%0.2d', i)
695
+
696
+ @s.put(
697
+ '_id' => id,
698
+ 'type' => 'errors',
699
+ 'msg' => "whatever #{i}",
700
+ 'wfid' => id.split('!').last)
701
+
702
+ id
703
+ end
704
+ end
705
+
706
+ def put_workitem(wfid, participant_name, fields)
707
+
708
+ @s.put(
709
+ 'type' => 'workitems',
710
+ '_id' => "wi!0_0!12ff!#{wfid}",
711
+ 'participant_name' => participant_name,
712
+ 'wfid' => wfid,
713
+ 'fields' => fields)
714
+ end
715
+
716
+ def load_workitems
717
+
718
+ put_workitem(
719
+ '20110218-nadanada', 'fujiwara', 'place' => 'kyouto')
720
+ put_workitem(
721
+ '20110218-nedenada', 'fujiwara', 'place' => 'kyouto', 'at' => 'kamo')
722
+ put_workitem(
723
+ '20110218-nadanodo', 'taira', 'place' => 'kyouto')
724
+ put_workitem(
725
+ '20110218-nodonada', 'date', 'place' => 'sendai')
726
+ put_workitem(
727
+ '20110218-nadanudu', 'shingen', 'place' => 'nagoya')
728
+ end
729
+ end
730
+