ruote-maestrodev 2.2.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 (265) hide show
  1. data/CHANGELOG.txt +290 -0
  2. data/CREDITS.txt +99 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.rdoc +88 -0
  5. data/Rakefile +108 -0
  6. data/TODO.txt +488 -0
  7. data/lib/ruote.rb +7 -0
  8. data/lib/ruote/context.rb +194 -0
  9. data/lib/ruote/engine.rb +1062 -0
  10. data/lib/ruote/engine/process_error.rb +122 -0
  11. data/lib/ruote/engine/process_status.rb +448 -0
  12. data/lib/ruote/exp/command.rb +87 -0
  13. data/lib/ruote/exp/commanded.rb +69 -0
  14. data/lib/ruote/exp/condition.rb +227 -0
  15. data/lib/ruote/exp/fe_add_branches.rb +138 -0
  16. data/lib/ruote/exp/fe_apply.rb +154 -0
  17. data/lib/ruote/exp/fe_cancel_process.rb +78 -0
  18. data/lib/ruote/exp/fe_command.rb +156 -0
  19. data/lib/ruote/exp/fe_concurrence.rb +321 -0
  20. data/lib/ruote/exp/fe_concurrent_iterator.rb +219 -0
  21. data/lib/ruote/exp/fe_cron.rb +141 -0
  22. data/lib/ruote/exp/fe_cursor.rb +324 -0
  23. data/lib/ruote/exp/fe_define.rb +112 -0
  24. data/lib/ruote/exp/fe_echo.rb +60 -0
  25. data/lib/ruote/exp/fe_equals.rb +115 -0
  26. data/lib/ruote/exp/fe_error.rb +82 -0
  27. data/lib/ruote/exp/fe_filter.rb +648 -0
  28. data/lib/ruote/exp/fe_forget.rb +88 -0
  29. data/lib/ruote/exp/fe_given.rb +154 -0
  30. data/lib/ruote/exp/fe_if.rb +127 -0
  31. data/lib/ruote/exp/fe_inc.rb +205 -0
  32. data/lib/ruote/exp/fe_iterator.rb +234 -0
  33. data/lib/ruote/exp/fe_let.rb +75 -0
  34. data/lib/ruote/exp/fe_listen.rb +304 -0
  35. data/lib/ruote/exp/fe_lose.rb +110 -0
  36. data/lib/ruote/exp/fe_noop.rb +45 -0
  37. data/lib/ruote/exp/fe_once.rb +215 -0
  38. data/lib/ruote/exp/fe_participant.rb +287 -0
  39. data/lib/ruote/exp/fe_read.rb +69 -0
  40. data/lib/ruote/exp/fe_redo.rb +82 -0
  41. data/lib/ruote/exp/fe_ref.rb +152 -0
  42. data/lib/ruote/exp/fe_registerp.rb +110 -0
  43. data/lib/ruote/exp/fe_reserve.rb +126 -0
  44. data/lib/ruote/exp/fe_restore.rb +102 -0
  45. data/lib/ruote/exp/fe_save.rb +72 -0
  46. data/lib/ruote/exp/fe_sequence.rb +59 -0
  47. data/lib/ruote/exp/fe_set.rb +154 -0
  48. data/lib/ruote/exp/fe_subprocess.rb +211 -0
  49. data/lib/ruote/exp/fe_that.rb +92 -0
  50. data/lib/ruote/exp/fe_undo.rb +67 -0
  51. data/lib/ruote/exp/fe_unregisterp.rb +69 -0
  52. data/lib/ruote/exp/fe_wait.rb +95 -0
  53. data/lib/ruote/exp/flowexpression.rb +886 -0
  54. data/lib/ruote/exp/iterator.rb +81 -0
  55. data/lib/ruote/exp/merge.rb +118 -0
  56. data/lib/ruote/exp/ro_attributes.rb +212 -0
  57. data/lib/ruote/exp/ro_filters.rb +136 -0
  58. data/lib/ruote/exp/ro_persist.rb +154 -0
  59. data/lib/ruote/exp/ro_variables.rb +189 -0
  60. data/lib/ruote/exp/ro_vf.rb +68 -0
  61. data/lib/ruote/fei.rb +260 -0
  62. data/lib/ruote/id/mnemo_wfid_generator.rb +43 -0
  63. data/lib/ruote/id/wfid_generator.rb +81 -0
  64. data/lib/ruote/log/default_history.rb +122 -0
  65. data/lib/ruote/log/pretty.rb +176 -0
  66. data/lib/ruote/log/storage_history.rb +159 -0
  67. data/lib/ruote/log/test_logger.rb +208 -0
  68. data/lib/ruote/log/wait_logger.rb +64 -0
  69. data/lib/ruote/part/block_participant.rb +137 -0
  70. data/lib/ruote/part/code_participant.rb +81 -0
  71. data/lib/ruote/part/engine_participant.rb +189 -0
  72. data/lib/ruote/part/local_participant.rb +138 -0
  73. data/lib/ruote/part/no_op_participant.rb +60 -0
  74. data/lib/ruote/part/null_participant.rb +54 -0
  75. data/lib/ruote/part/rev_participant.rb +169 -0
  76. data/lib/ruote/part/smtp_participant.rb +116 -0
  77. data/lib/ruote/part/storage_participant.rb +392 -0
  78. data/lib/ruote/part/template.rb +84 -0
  79. data/lib/ruote/participant.rb +7 -0
  80. data/lib/ruote/reader.rb +278 -0
  81. data/lib/ruote/reader/json.rb +49 -0
  82. data/lib/ruote/reader/radial.rb +290 -0
  83. data/lib/ruote/reader/ruby_dsl.rb +186 -0
  84. data/lib/ruote/reader/xml.rb +99 -0
  85. data/lib/ruote/receiver/base.rb +212 -0
  86. data/lib/ruote/storage/base.rb +364 -0
  87. data/lib/ruote/storage/composite_storage.rb +121 -0
  88. data/lib/ruote/storage/fs_storage.rb +139 -0
  89. data/lib/ruote/storage/hash_storage.rb +211 -0
  90. data/lib/ruote/svc/dispatch_pool.rb +158 -0
  91. data/lib/ruote/svc/dollar_sub.rb +298 -0
  92. data/lib/ruote/svc/error_handler.rb +138 -0
  93. data/lib/ruote/svc/expression_map.rb +97 -0
  94. data/lib/ruote/svc/participant_list.rb +397 -0
  95. data/lib/ruote/svc/tracker.rb +172 -0
  96. data/lib/ruote/svc/treechecker.rb +141 -0
  97. data/lib/ruote/tree_dot.rb +85 -0
  98. data/lib/ruote/util/filter.rb +525 -0
  99. data/lib/ruote/util/hashdot.rb +79 -0
  100. data/lib/ruote/util/look.rb +128 -0
  101. data/lib/ruote/util/lookup.rb +127 -0
  102. data/lib/ruote/util/misc.rb +167 -0
  103. data/lib/ruote/util/ometa.rb +71 -0
  104. data/lib/ruote/util/serializer.rb +103 -0
  105. data/lib/ruote/util/subprocess.rb +88 -0
  106. data/lib/ruote/util/time.rb +100 -0
  107. data/lib/ruote/util/tree.rb +58 -0
  108. data/lib/ruote/version.rb +29 -0
  109. data/lib/ruote/worker.rb +386 -0
  110. data/lib/ruote/workitem.rb +394 -0
  111. data/phil.txt +14 -0
  112. data/ruote.gemspec +44 -0
  113. data/test/bm/ci.rb +55 -0
  114. data/test/bm/ici.rb +71 -0
  115. data/test/bm/juuman.rb +54 -0
  116. data/test/bm/launch_bench.rb +37 -0
  117. data/test/bm/load_26c.rb +97 -0
  118. data/test/bm/mega.rb +64 -0
  119. data/test/bm/seq_thousand.rb +31 -0
  120. data/test/bm/t.rb +35 -0
  121. data/test/functional/base.rb +247 -0
  122. data/test/functional/concurrent_base.rb +98 -0
  123. data/test/functional/crunner.rb +31 -0
  124. data/test/functional/ct_0_concurrence.rb +65 -0
  125. data/test/functional/ct_1_iterator.rb +67 -0
  126. data/test/functional/ct_2_cancel.rb +81 -0
  127. data/test/functional/eft_0_process_definition.rb +65 -0
  128. data/test/functional/eft_10_cancel_process.rb +46 -0
  129. data/test/functional/eft_11_wait.rb +109 -0
  130. data/test/functional/eft_12_listen.rb +500 -0
  131. data/test/functional/eft_13_iterator.rb +342 -0
  132. data/test/functional/eft_14_cursor.rb +456 -0
  133. data/test/functional/eft_15_loop.rb +69 -0
  134. data/test/functional/eft_16_if.rb +183 -0
  135. data/test/functional/eft_17_equals.rb +55 -0
  136. data/test/functional/eft_18_concurrent_iterator.rb +410 -0
  137. data/test/functional/eft_19_reserve.rb +136 -0
  138. data/test/functional/eft_1_echo.rb +68 -0
  139. data/test/functional/eft_20_save.rb +116 -0
  140. data/test/functional/eft_21_restore.rb +61 -0
  141. data/test/functional/eft_22_noop.rb +28 -0
  142. data/test/functional/eft_23_apply.rb +168 -0
  143. data/test/functional/eft_24_add_branches.rb +98 -0
  144. data/test/functional/eft_25_command.rb +28 -0
  145. data/test/functional/eft_26_error.rb +77 -0
  146. data/test/functional/eft_27_inc.rb +280 -0
  147. data/test/functional/eft_28_once.rb +135 -0
  148. data/test/functional/eft_29_cron.rb +64 -0
  149. data/test/functional/eft_2_sequence.rb +58 -0
  150. data/test/functional/eft_30_ref.rb +155 -0
  151. data/test/functional/eft_31_registerp.rb +130 -0
  152. data/test/functional/eft_32_lose.rb +93 -0
  153. data/test/functional/eft_33_let.rb +31 -0
  154. data/test/functional/eft_34_given.rb +123 -0
  155. data/test/functional/eft_35_filter.rb +375 -0
  156. data/test/functional/eft_36_read.rb +95 -0
  157. data/test/functional/eft_3_participant.rb +149 -0
  158. data/test/functional/eft_4_set.rb +296 -0
  159. data/test/functional/eft_5_subprocess.rb +163 -0
  160. data/test/functional/eft_6_concurrence.rb +304 -0
  161. data/test/functional/eft_7_forget.rb +61 -0
  162. data/test/functional/eft_8_undo.rb +114 -0
  163. data/test/functional/eft_9_redo.rb +138 -0
  164. data/test/functional/ft_0_worker.rb +65 -0
  165. data/test/functional/ft_10_dollar.rb +304 -0
  166. data/test/functional/ft_11_recursion.rb +109 -0
  167. data/test/functional/ft_12_launchitem.rb +43 -0
  168. data/test/functional/ft_13_variables.rb +151 -0
  169. data/test/functional/ft_14_re_apply.rb +324 -0
  170. data/test/functional/ft_15_timeout.rb +226 -0
  171. data/test/functional/ft_16_participant_params.rb +98 -0
  172. data/test/functional/ft_17_conditional.rb +102 -0
  173. data/test/functional/ft_18_kill.rb +138 -0
  174. data/test/functional/ft_19_participant_code.rb +67 -0
  175. data/test/functional/ft_1_process_status.rb +796 -0
  176. data/test/functional/ft_20_storage_participant.rb +543 -0
  177. data/test/functional/ft_21_forget.rb +153 -0
  178. data/test/functional/ft_22_process_definitions.rb +90 -0
  179. data/test/functional/ft_23_load_defs.rb +79 -0
  180. data/test/functional/ft_24_block_participant.rb +235 -0
  181. data/test/functional/ft_25_receiver.rb +207 -0
  182. data/test/functional/ft_26_participant_rtimeout.rb +179 -0
  183. data/test/functional/ft_27_var_indirection.rb +128 -0
  184. data/test/functional/ft_28_null_noop_participants.rb +51 -0
  185. data/test/functional/ft_29_part_template.rb +60 -0
  186. data/test/functional/ft_2_errors.rb +380 -0
  187. data/test/functional/ft_30_smtp_participant.rb +122 -0
  188. data/test/functional/ft_31_part_blocking.rb +72 -0
  189. data/test/functional/ft_33_participant_subprocess_priority.rb +32 -0
  190. data/test/functional/ft_34_cursor_rewind.rb +101 -0
  191. data/test/functional/ft_35_add_service.rb +56 -0
  192. data/test/functional/ft_36_storage_history.rb +150 -0
  193. data/test/functional/ft_37_default_history.rb +109 -0
  194. data/test/functional/ft_38_participant_more.rb +193 -0
  195. data/test/functional/ft_39_wait_for.rb +136 -0
  196. data/test/functional/ft_3_participant_registration.rb +574 -0
  197. data/test/functional/ft_40_wait_logger.rb +62 -0
  198. data/test/functional/ft_41_participants.rb +91 -0
  199. data/test/functional/ft_42_storage_copy.rb +71 -0
  200. data/test/functional/ft_43_participant_on_reply.rb +87 -0
  201. data/test/functional/ft_44_var_participant.rb +35 -0
  202. data/test/functional/ft_45_participant_accept.rb +64 -0
  203. data/test/functional/ft_46_launch_single.rb +83 -0
  204. data/test/functional/ft_47_wfid_generator.rb +54 -0
  205. data/test/functional/ft_48_lose.rb +112 -0
  206. data/test/functional/ft_49_engine_on_error.rb +201 -0
  207. data/test/functional/ft_4_cancel.rb +132 -0
  208. data/test/functional/ft_50_engine_config.rb +22 -0
  209. data/test/functional/ft_51_misc.rb +67 -0
  210. data/test/functional/ft_52_case.rb +134 -0
  211. data/test/functional/ft_53_engine_on_terminate.rb +95 -0
  212. data/test/functional/ft_54_patterns.rb +104 -0
  213. data/test/functional/ft_55_engine_participant.rb +303 -0
  214. data/test/functional/ft_56_filter_attribute.rb +259 -0
  215. data/test/functional/ft_57_rev_participant.rb +252 -0
  216. data/test/functional/ft_58_workitem.rb +69 -0
  217. data/test/functional/ft_59_pause.rb +343 -0
  218. data/test/functional/ft_5_on_error.rb +384 -0
  219. data/test/functional/ft_60_code_participant.rb +45 -0
  220. data/test/functional/ft_61_trailing_fields.rb +34 -0
  221. data/test/functional/ft_62_exp_name_and_dollar_substitution.rb +35 -0
  222. data/test/functional/ft_6_on_cancel.rb +221 -0
  223. data/test/functional/ft_7_tags.rb +177 -0
  224. data/test/functional/ft_8_participant_consumption.rb +124 -0
  225. data/test/functional/ft_9_subprocesses.rb +146 -0
  226. data/test/functional/restart_base.rb +34 -0
  227. data/test/functional/rt_0_wait.rb +55 -0
  228. data/test/functional/rt_1_listen.rb +56 -0
  229. data/test/functional/rt_2_errors.rb +56 -0
  230. data/test/functional/rt_3_once.rb +70 -0
  231. data/test/functional/rt_4_cron.rb +64 -0
  232. data/test/functional/rt_5_timeout.rb +60 -0
  233. data/test/functional/rtest.rb +8 -0
  234. data/test/functional/storage_helper.rb +93 -0
  235. data/test/functional/test.rb +44 -0
  236. data/test/functional/vertical.rb +46 -0
  237. data/test/path_helper.rb +15 -0
  238. data/test/test.rb +13 -0
  239. data/test/test_helper.rb +28 -0
  240. data/test/unit/storage.rb +428 -0
  241. data/test/unit/storages.rb +37 -0
  242. data/test/unit/test.rb +28 -0
  243. data/test/unit/ut_0_ruby_reader.rb +223 -0
  244. data/test/unit/ut_11_lookup.rb +122 -0
  245. data/test/unit/ut_13_serializer.rb +65 -0
  246. data/test/unit/ut_14_is_uri.rb +28 -0
  247. data/test/unit/ut_15_util.rb +57 -0
  248. data/test/unit/ut_16_reader.rb +225 -0
  249. data/test/unit/ut_18_engine.rb +47 -0
  250. data/test/unit/ut_19_part_template.rb +86 -0
  251. data/test/unit/ut_1_fei.rb +165 -0
  252. data/test/unit/ut_20_composite_storage.rb +74 -0
  253. data/test/unit/ut_21_svc_participant_list.rb +46 -0
  254. data/test/unit/ut_22_filter.rb +1094 -0
  255. data/test/unit/ut_23_svc_tracker.rb +48 -0
  256. data/test/unit/ut_24_radial_reader.rb +332 -0
  257. data/test/unit/ut_25_merge.rb +113 -0
  258. data/test/unit/ut_3_wait_logger.rb +39 -0
  259. data/test/unit/ut_4_expmap.rb +20 -0
  260. data/test/unit/ut_5_tree.rb +54 -0
  261. data/test/unit/ut_6_condition.rb +303 -0
  262. data/test/unit/ut_7_workitem.rb +99 -0
  263. data/test/unit/ut_8_tree_to_dot.rb +72 -0
  264. data/test/unit/ut_9_xml_reader.rb +61 -0
  265. metadata +504 -0
@@ -0,0 +1,67 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Fri Apr 22 15:44:38 JST 2011
6
+ #
7
+ # Singapore
8
+ #
9
+
10
+ require File.join(File.dirname(__FILE__), 'base')
11
+
12
+
13
+ class FtParticipantCodeTest < Test::Unit::TestCase
14
+ include FunctionalBase
15
+
16
+ def test_block_participant
17
+
18
+ pdef = Ruote.process_definition :name => 'def0' do
19
+
20
+ set 'v:alpha' => {
21
+ 'on_workitem' => lambda { |wi|
22
+ wi.fields['alpha'] = wi.participant_name
23
+ wi.fields['x'] = 0
24
+ }
25
+ }
26
+
27
+ alpha
28
+ end
29
+
30
+ #@engine.noisy = true
31
+
32
+ wfid = @engine.launch(pdef)
33
+
34
+ r = @engine.wait_for(wfid)
35
+
36
+ assert_equal(
37
+ { 'alpha' => 'alpha', 'x' => 0, '__result__' => 0 },
38
+ r['workitem']['fields'])
39
+ end
40
+
41
+ def test_code_participant
42
+
43
+ pdef = Ruote.process_definition do
44
+
45
+ set 'v:alpha' => %{
46
+ def consume(workitem)
47
+ workitem.fields['x'] = 0
48
+ workitem.fields['alpha'] = workitem.participant_name
49
+ reply_to_engine(workitem)
50
+ end
51
+ }
52
+
53
+ alpha
54
+ end
55
+
56
+ #@engine.noisy = true
57
+
58
+ wfid = @engine.launch(pdef)
59
+
60
+ r = @engine.wait_for(wfid)
61
+
62
+ assert_equal(
63
+ { 'x' => 0, 'alpha' => 'alpha' },
64
+ r['workitem']['fields'])
65
+ end
66
+ end
67
+
@@ -0,0 +1,796 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Fri May 15 09:51:28 JST 2009
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'ruote/participant'
11
+
12
+
13
+ class FtProcessStatusTest < Test::Unit::TestCase
14
+ include FunctionalBase
15
+
16
+ def test_process
17
+
18
+ pdef = Ruote.process_definition :name => 'my process' do
19
+ participant :ref => 'alpha'
20
+ end
21
+
22
+ #noisy
23
+
24
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
25
+
26
+ wfid = @engine.launch(pdef, :workitem => { 'kilroy' => 'was here' })
27
+
28
+ wait_for(:alpha)
29
+
30
+ ps = @engine.process(wfid)
31
+
32
+ assert_equal 'my process', ps.definition_name
33
+ assert_equal nil, ps.definition_revision
34
+ assert_not_nil ps.launched_time
35
+
36
+ assert_equal(
37
+ {"my process"=>["0", ["define", {"name"=>"my process"}, [["participant", {"ref"=>"alpha"}, []]]]]},
38
+ ps.variables)
39
+ end
40
+
41
+ def test_variables
42
+
43
+ pdef = Ruote.process_definition 'my process' do
44
+ sequence do
45
+ set :var => 'toto', :val => 'nada'
46
+ participant :ref => 'alpha'
47
+ end
48
+ end
49
+
50
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
51
+ wfid = @engine.launch(pdef, :workitem => { 'kilroy' => 'was here' })
52
+
53
+ wait_for(:alpha)
54
+
55
+ ps = @engine.process(wfid)
56
+
57
+ assert_equal 'my process', ps.definition_name
58
+
59
+ assert_equal(
60
+ {"my process"=>["0", ["define", {"my process"=>nil}, [["sequence", {}, [["set", {"var"=>"toto", "val"=>"nada"}, []], ["participant", {"ref"=>"alpha"}, []]]]]]], "toto"=>"nada"},
61
+ ps.variables)
62
+ end
63
+
64
+ def test_errors
65
+
66
+ pdef = Ruote.process_definition 'my process' do
67
+ nada
68
+ end
69
+
70
+ wfid = @engine.launch(pdef)
71
+ wait_for(wfid)
72
+
73
+ errs = @engine.errors
74
+
75
+ assert_equal 1, errs.size
76
+
77
+ assert_equal wfid, errs.first.wfid
78
+
79
+ err = @engine.errors(wfid)
80
+
81
+ assert_equal 1, err.size
82
+ assert_equal wfid, err.first.wfid
83
+
84
+ assert_equal 1, @engine.errors(:count => true)
85
+ end
86
+
87
+ def test_tree
88
+
89
+ pdef = Ruote.process_definition 'my process' do
90
+ sequence do
91
+ echo 'ok'
92
+ participant :ref => :alpha
93
+ end
94
+ end
95
+
96
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
97
+ wfid = @engine.launch(pdef)
98
+
99
+ wait_for(:alpha)
100
+
101
+ ps = @engine.process(wfid)
102
+
103
+ assert_equal(
104
+ ["define", {"my process"=>nil}, [
105
+ ["sequence", {}, [
106
+ ["echo", {"ok"=>nil}, []],
107
+ ["participant", {"ref"=>"alpha"}, []]]]]],
108
+ ps.current_tree)
109
+
110
+ assert_equal(
111
+ ["define", {"my process"=>nil}, [
112
+ ["sequence", {}, [
113
+ ["echo", {"ok"=>nil}, []],
114
+ ["participant", {"ref"=>"alpha"}, []]]]]],
115
+ ps.original_tree)
116
+
117
+ #
118
+ # tinkering with trees ...
119
+
120
+ e = ps.expressions.find { |e| e.fei.expid == '0_0_1' }
121
+
122
+ e.update_tree([ 'participant', { 'ref' => 'bravo' }, [] ])
123
+
124
+ assert_equal(
125
+ ["define", {"my process"=>nil}, [
126
+ ["sequence", {}, [
127
+ ["echo", {"ok"=>nil}, []],
128
+ ["participant", {"ref"=>"bravo"}, []]]]]],
129
+ ps.current_tree)
130
+
131
+ assert_equal(
132
+ ["define", {"my process"=>nil}, [
133
+ ["sequence", {}, [
134
+ ["echo", {"ok"=>nil}, []],
135
+ ["participant", {"ref"=>"alpha"}, []]]]]],
136
+ ps.original_tree)
137
+ end
138
+
139
+ def test_tree_when_define_rewrites_it
140
+
141
+ pdef = Ruote.process_definition 'my process' do
142
+ participant :ref => :alpha
143
+ define 'sub0' do
144
+ echo 'meh'
145
+ end
146
+ end
147
+
148
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
149
+ wfid = @engine.launch(pdef)
150
+
151
+ wait_for(:alpha)
152
+
153
+ ps = @engine.process(wfid)
154
+
155
+ assert_equal(
156
+ {"my process"=>["0", ["define", {"my process"=>nil}, [["define", {"sub0"=>nil}, [["echo", {"meh"=>nil}, []]]], ["participant", {"ref"=>"alpha"}, []]]]], "sub0"=>["0_0", ["define", {"sub0"=>nil}, [["echo", {"meh"=>nil}, []]]]]},
157
+ ps.variables)
158
+
159
+ assert_equal(
160
+ ["define", {"my process"=>nil}, [
161
+ ["define", {"sub0"=>nil}, [["echo", {"meh"=>nil}, []]]],
162
+ ["participant", {"ref"=>"alpha"}, []]]],
163
+ ps.current_tree)
164
+
165
+ assert_equal(
166
+ ["define", {"my process"=>nil}, [
167
+ ["define", {"sub0"=>nil}, [["echo", {"meh"=>nil}, []]]],
168
+ ["participant", {"ref"=>"alpha"}, []]]],
169
+ ps.original_tree)
170
+ end
171
+
172
+ def test_all_variables
173
+
174
+ pdef = Ruote.process_definition do
175
+ define 'sub0' do
176
+ sequence do
177
+ set :var => 'v1', :val => 1
178
+ alpha
179
+ end
180
+ end
181
+ sequence do
182
+ set :var => 'v0', :val => 0
183
+ sub0
184
+ end
185
+ end
186
+
187
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
188
+
189
+ #noisy
190
+
191
+ wfid = @engine.launch(pdef)
192
+
193
+ wait_for(:alpha)
194
+
195
+ ps = @engine.process(wfid)
196
+
197
+ assert_equal(0, ps.variables['v0'])
198
+ assert_equal(nil, ps.variables['v1'])
199
+
200
+ #p ps.all_variables
201
+ assert_equal(2, ps.all_variables.size)
202
+
203
+ h = ps.all_variables.values.inject({}) { |h, vh| h.merge!(vh) }
204
+
205
+ assert_equal(0, h['v0'])
206
+ assert_equal(1, h['v1'])
207
+ end
208
+
209
+ def test_tags
210
+
211
+ pdef = Ruote.process_definition do
212
+ sequence :tag => 'main' do
213
+ alpha :tag => 'part'
214
+ end
215
+ end
216
+
217
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
218
+
219
+ #noisy
220
+
221
+ wfid = @engine.launch(pdef)
222
+ wait_for(:alpha)
223
+
224
+ ps = @engine.process(wfid)
225
+
226
+ assert_equal %w[ main part ], ps.tags.keys.sort
227
+
228
+ assert_equal 2, ps.all_tags.size
229
+ assert_kind_of Array, ps.all_tags['main']
230
+ assert_equal 1, ps.all_tags['main'].size
231
+ end
232
+
233
+ def test_all_tags
234
+
235
+ pdef = Ruote.process_definition do
236
+ define 'sub0' do
237
+ sequence :tag => 'tag0' do
238
+ alpha
239
+ end
240
+ end
241
+ sequence :tag => 'tag0' do
242
+ sub0
243
+ end
244
+ end
245
+
246
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
247
+
248
+ #noisy
249
+
250
+ wfid = @engine.launch(pdef)
251
+ wait_for(:alpha)
252
+
253
+ ps = @engine.process(wfid)
254
+
255
+ assert_equal 1, ps.tags.size
256
+ assert_equal 2, ps.all_tags['tag0'].size
257
+ end
258
+
259
+ def test_processes
260
+
261
+ pdef = Ruote.process_definition :name => 'my process' do
262
+ participant :ref => 'alpha'
263
+ end
264
+
265
+ #noisy
266
+
267
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
268
+
269
+ wfid0 = @engine.launch(pdef)
270
+ wfid1 = @engine.launch(pdef)
271
+
272
+ wait_for(:alpha)
273
+ wait_for(:alpha)
274
+
275
+ ps = @engine.processes
276
+
277
+ assert_equal 2, ps.size
278
+ assert_equal [ wfid0, wfid1 ].sort, ps.collect { |e| e.wfid }.sort
279
+
280
+ assert_equal 2, alpha.size
281
+ end
282
+
283
+ def test_processes_and_leftovers
284
+
285
+ n = 3
286
+
287
+ @engine.register_participant :alpha, Ruote::StorageParticipant
288
+
289
+ n.times.collect { @engine.launch(Ruote.define { alpha }) }
290
+
291
+ while @engine.storage_participant.size < n; sleep 0.100; end
292
+ sleep 0.100
293
+
294
+ @engine.ps(@engine.storage_participant.first.wfid).expressions.each do |exp|
295
+ @engine.storage.delete(exp.h)
296
+ end
297
+ # nuking all the expressions of a process instance
298
+
299
+ assert_equal n - 1, @engine.processes.size
300
+ assert_equal n, @engine.storage_participant.size
301
+ # orphan workitem left in storage
302
+
303
+ assert_equal 1, @engine.leftovers.size
304
+ end
305
+
306
+ def test_left_overs
307
+
308
+ [
309
+ { '_id' => '0!f!x', 'type' => 'workitems', 'fei' => { 'wfid' => 'x' } },
310
+ { '_id' => '0!f!y', 'type' => 'errors', 'fei' => { 'wfid' => 'y' } },
311
+ { '_id' => '0!f!a', 'type' => 'workitems', 'fei' => { 'wfid' => 'a' } },
312
+ { '_id' => '0!f!a', 'type' => 'expressions', 'fei' => { 'wfid' => 'a' } },
313
+ { '_id' => '0!f!z', 'type' => 'schedules', 'fei' => { 'wfid' => 'z' },
314
+ 'at' => Ruote.time_to_utc_s(Time.now + 24 * 3600) }
315
+ ].each do |doc|
316
+ @engine.storage.put(doc)
317
+ end
318
+
319
+ assert_equal(
320
+ 3,
321
+ @engine.leftovers.size)
322
+ assert_equal(
323
+ %w[ workitems errors schedules ],
324
+ @engine.leftovers.collect { |lo| lo['type'] })
325
+ end
326
+
327
+ def test_tree_rewrite
328
+
329
+ pdef = Ruote.process_definition :name => 'test' do
330
+ sequence do
331
+ alpha
332
+ bravo
333
+ charly
334
+ end
335
+ delta
336
+ end
337
+
338
+ @engine.register_participant :alpha do |wi, fexp|
339
+
340
+ @tracer << "a\n"
341
+
342
+ parent = fexp.parent
343
+ parent.update_tree
344
+ parent.updated_tree[2][1] = [ 'charly', {}, [] ]
345
+ parent.persist
346
+ end
347
+
348
+ @engine.register_participant :bravo do |wi, fexp|
349
+ @tracer << "b\n"
350
+ end
351
+ @engine.register_participant :charly do |wi, fexp|
352
+ @tracer << "c\n"
353
+ stash[:tree0] = fexp.context.engine.process(fexp.fei.wfid).current_tree
354
+ end
355
+ @engine.register_participant :delta do |wi, fexp|
356
+ @tracer << "d\n"
357
+ stash[:tree1] = fexp.context.engine.process(fexp.fei.wfid).current_tree
358
+ end
359
+
360
+ #noisy
361
+
362
+ assert_trace %w[ a c c d ], pdef
363
+
364
+ assert_equal(
365
+ ["define", {"name"=>"test"}, [["sequence", {}, [["alpha", {}, []], ["charly", {}, []], ["participant", {"ref"=>"charly"}, []]]], ["delta", {}, []]]],
366
+ @engine.context.stash[:tree0])
367
+
368
+ assert_equal(
369
+ ["define", {"name"=>"test"}, [["sequence", {}, [["alpha", {}, []], ["charly", {}, []], ["charly", {}, []]]], ["participant", {"ref"=>"delta"}, []]]],
370
+ @engine.context.stash[:tree1])
371
+ end
372
+
373
+ def test_when_on_cancel_subprocess
374
+
375
+ pdef = Ruote.process_definition :name => 'test' do
376
+ sequence :on_cancel => 'sub0' do
377
+ alpha
378
+ end
379
+ define 'sub0' do
380
+ alpha
381
+ end
382
+ end
383
+
384
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
385
+
386
+ #noisy
387
+
388
+ wfid = @engine.launch(pdef)
389
+
390
+ wait_for(:alpha)
391
+
392
+ @engine.cancel_process(wfid)
393
+
394
+ wait_for(:alpha)
395
+ wait_for(1)
396
+
397
+ assert_match wfid, alpha.first.fei.wfid
398
+ assert_not_nil alpha.first.fei.subid
399
+
400
+ assert_equal 0, @engine.process(wfid).errors.size
401
+ assert_equal 4, @engine.process(wfid).expressions.size
402
+
403
+ assert_equal(
404
+ ["define", {"name"=>"test"}, [
405
+ ["define", {"sub0"=>nil}, [["alpha", {}, []]]],
406
+ ["sequence", {"on_cancel"=>"sub0"}, [["alpha", {}, []]]]]],
407
+ @engine.process(wfid).original_tree)
408
+
409
+ assert_equal(
410
+ ["define", {"name"=>"test"}, [
411
+ ["define", {"sub0"=>nil}, [
412
+ ["participant", {"ref"=>"alpha"}, []]]],
413
+ ["sequence", {"on_cancel"=>"sub0", "_triggered"=>"on_cancel"}, [
414
+ ["alpha", {}, []]]]]],
415
+ @engine.process(wfid).current_tree)
416
+ end
417
+
418
+ def test_fexp_to_h
419
+
420
+ pdef = Ruote.process_definition :name => 'my process' do
421
+ participant :ref => 'alpha'
422
+ end
423
+
424
+ #noisy
425
+
426
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
427
+
428
+ wfid = @engine.launch(pdef)
429
+
430
+ wait_for(:alpha)
431
+
432
+ ps = @engine.process(wfid)
433
+
434
+ h = ps.expressions.find { |hf|
435
+ hf.is_a?(Ruote::Exp::ParticipantExpression)
436
+ }.to_h
437
+
438
+ assert_equal 'participant', h['name']
439
+ assert_equal 'alpha', h['participant_name']
440
+ assert_equal ["participant", {"ref"=>"alpha"}, []], h['original_tree']
441
+ end
442
+
443
+ def test_to_dot
444
+
445
+ pdef = Ruote.process_definition :name => 'my process' do
446
+ concurrence do
447
+ participant :ref => 'alpha'
448
+ participant :ref => 'bravo'
449
+ end
450
+ end
451
+
452
+ alpha = @engine.register_participant :alpha, Ruote::StorageParticipant
453
+
454
+ wfid = @engine.launch(pdef)
455
+
456
+ wait_for(:alpha)
457
+
458
+ ps = @engine.process(wfid)
459
+
460
+ #puts
461
+ #puts ps.to_dot
462
+
463
+ dot = ps.to_dot
464
+
465
+ dot = dot.gsub(wfid, 'wfid')
466
+ dot = dot.gsub(/![^!]+!/, '!!')
467
+ dot = dot.gsub(/wfid [^ ]+ /, 'wfid ')
468
+ dot = dot.strip
469
+
470
+ assert_equal(
471
+ %{
472
+ digraph "process wfid {
473
+ "0!!wfid" [ label="wfid 0 define" ];
474
+ "0!!wfid" -> "0_0!!wfid";
475
+ "0_0!!wfid" [ label="wfid 0_0 concurrence" ];
476
+ "0_0!!wfid" -> "0!!wfid";
477
+ "0_0!!wfid" -> "0_0_0!!wfid";
478
+ "0_0!!wfid" -> "0_0_1!!wfid";
479
+ "0_0_0!!wfid" [ label="wfid 0_0_0 participant" ];
480
+ "0_0_0!!wfid" -> "0_0!!wfid";
481
+ "0_0_1!!wfid" [ label="wfid 0_0_1 participant" ];
482
+ "0_0_1!!wfid" -> "0_0!!wfid";
483
+ "err_0_0_1!!wfid" [ label = "error : #<ArgumentError: no participant named 'bravo'>" ];
484
+ "err_0_0_1!!wfid" -> "0_0_1!!wfid" [ style = "dotted" ];
485
+ }
486
+ }.strip,
487
+ dot)
488
+ end
489
+
490
+ def test_last_active
491
+
492
+ pdef = Ruote.define do
493
+ alpha
494
+ bravo
495
+ end
496
+
497
+ @engine.register_participant '.+', Ruote::StorageParticipant
498
+
499
+ wfid = @engine.launch(pdef)
500
+
501
+ @engine.wait_for(:alpha)
502
+
503
+ t0 = Time.parse(@engine.process(wfid).last_active)
504
+
505
+ sp = @engine.storage_participant
506
+ sp.proceed(sp.first)
507
+
508
+ @engine.wait_for(:bravo)
509
+
510
+ t1 = Time.parse(@engine.process(wfid).last_active)
511
+
512
+ assert t1 > t0
513
+ end
514
+
515
+ def test_position
516
+
517
+ pdef = Ruote.define do
518
+ alpha :task => 'clean car'
519
+ end
520
+
521
+ @engine.register_participant '.+', Ruote::StorageParticipant
522
+
523
+ wfid = @engine.launch(pdef)
524
+ @engine.wait_for(:alpha)
525
+
526
+ assert_equal(
527
+ [ [ 'alpha', { 'task' => 'clean car' } ] ],
528
+ @engine.process(wfid).position.collect { |pos| pos[1..-1] })
529
+
530
+ # #position leverages #workitems
531
+
532
+ assert_equal(
533
+ [ [ wfid, 'alpha' ] ],
534
+ @engine.process(wfid).workitems.collect { |wi|
535
+ [ wi.fei.wfid, wi.participant_name ]
536
+ })
537
+ end
538
+
539
+ def test_position_when_error
540
+
541
+ pdef = Ruote.define do
542
+ participant
543
+ end
544
+
545
+ wfid = @engine.launch(pdef)
546
+ @engine.wait_for(wfid)
547
+
548
+ assert_equal 1, @engine.process(wfid).errors.size
549
+
550
+ assert_equal(
551
+ [ [ nil,
552
+ { 'error' => '#<ArgumentError: no participant name specified>' } ] ],
553
+ @engine.process(wfid).position.collect { |pos| pos[1..-1] })
554
+ end
555
+
556
+ def test_ps_with_stored_workitems
557
+
558
+ @engine.register_participant '.+', Ruote::StorageParticipant
559
+
560
+ wfid = @engine.launch(Ruote.define { alpha })
561
+ @engine.wait_for(:alpha)
562
+
563
+ ps = @engine.process(wfid)
564
+
565
+ assert_equal 1, ps.stored_workitems.size
566
+ assert_equal Ruote::Workitem, ps.stored_workitems.first.class
567
+ end
568
+
569
+ def test_ps_without_stored_workitems
570
+
571
+ @engine.register_participant '.+', Ruote::NullParticipant
572
+
573
+ wfid = @engine.launch(Ruote.define { alpha })
574
+ @engine.wait_for(:alpha)
575
+
576
+ ps = @engine.process(wfid)
577
+
578
+ assert_equal 0, ps.stored_workitems.size
579
+ end
580
+
581
+ def test_schedules
582
+
583
+ @engine.register_participant '.+', Ruote::NullParticipant
584
+
585
+ wfid = @engine.launch(Ruote.define { alpha :timeout => '2d' })
586
+ @engine.wait_for(:alpha)
587
+
588
+ assert_equal 1, @engine.schedules.size
589
+ assert_equal 1, @engine.schedules(:count => true)
590
+ end
591
+
592
+ def test_processes_and_schedules
593
+
594
+ @engine.register_participant '.+', Ruote::NullParticipant
595
+
596
+ #noisy
597
+
598
+ wfid = @engine.launch(Ruote.define { alpha :timeout => '2d' })
599
+ @engine.wait_for(:alpha)
600
+
601
+ ps = @engine.process(wfid)
602
+
603
+ assert_equal 1, ps.schedules.size
604
+ assert_match /^0_0![a-f0-9]+!#{wfid}$/, ps.schedules.first['target'].sid
605
+ end
606
+
607
+ def test_ps_pagination
608
+
609
+ n = 7
610
+
611
+ @engine.register_participant '.+', Ruote::StorageParticipant
612
+
613
+ wfids = (1..n).collect { |i|
614
+ @engine.launch(Ruote.define { alpha })
615
+ }.sort
616
+
617
+ while @engine.storage_participant.size < n; sleep 0.140; end
618
+
619
+ assert_equal wfids, @engine.process_wfids
620
+
621
+ assert_equal(
622
+ wfids,
623
+ @engine.processes.collect { |ps| ps.wfid })
624
+
625
+ assert_equal(
626
+ wfids,
627
+ @engine.processes(:test => :garbage).collect { |ps| ps.wfid })
628
+ # prompted by
629
+ # http://groups.google.com/group/openwferu-users/browse_thread/thread/ee493bdf8d8cdb37
630
+
631
+ assert_equal(
632
+ wfids[0, 3],
633
+ @engine.processes(:limit => 3).collect { |ps| ps.wfid })
634
+
635
+ assert_equal(
636
+ wfids[3, 3],
637
+ @engine.processes(:skip => 3, :limit => 3).collect { |ps| ps.wfid })
638
+
639
+ #puts "==="
640
+ #wfids.each { |wfid| puts wfid }
641
+ #puts "---"
642
+ #@engine.processes(:limit => 3, :descending => false).collect { |ps| ps.wfid }.each { |wfid| puts wfid }
643
+ #puts "---"
644
+ #@engine.processes(:limit => 3, :descending => true).collect { |ps| ps.wfid }.each { |wfid| puts wfid }
645
+
646
+ assert_equal(
647
+ wfids.reverse[0, 3],
648
+ @engine.processes(
649
+ :limit => 3, :descending => true
650
+ ).collect { |ps| ps.wfid })
651
+
652
+ assert_equal(
653
+ n,
654
+ @engine.processes(:count => true))
655
+ end
656
+
657
+ # Issue identified by David Goodlad :
658
+ #
659
+ # http://gist.github.com/600451
660
+ #
661
+ def test_ps_and_schedules
662
+
663
+ pdef = Ruote.define do
664
+ concurrence do
665
+ wait '4h'
666
+ wait '2h'
667
+ end
668
+ end
669
+
670
+ #noisy
671
+
672
+ wfid = @engine.launch(pdef)
673
+
674
+ @engine.wait_for(4)
675
+
676
+ #assert_equal 1, @engine.processes.size
677
+ assert_equal [ wfid ], @engine.processes.collect { |ps| ps.wfid }
678
+ end
679
+
680
+ def test_ps
681
+
682
+ @engine.register 'alpha', Ruote::NullParticipant
683
+
684
+ wfid = nil
685
+
686
+ 2.times { wfid = @engine.launch(Ruote.define { alpha }) }
687
+
688
+ @engine.wait_for(4)
689
+
690
+ assert_equal 2, @engine.ps.size
691
+ assert_equal wfid, @engine.ps(wfid).wfid
692
+ end
693
+
694
+ def test_definition_name
695
+
696
+ pdef = Ruote.process_definition :name => 'invictus' do
697
+ alpha
698
+ end
699
+
700
+ #noisy
701
+
702
+ alpha = @engine.register_participant :alpha, Ruote::NullParticipant
703
+
704
+ wfid = @engine.launch(pdef)
705
+
706
+ wait_for(:alpha)
707
+
708
+ assert_equal 'invictus', @engine.process(wfid).definition_name
709
+
710
+ exp = @engine.process(wfid).expressions.first
711
+ @engine.storage.delete(exp.h)
712
+
713
+ assert_nil @engine.process(wfid).definition_name
714
+ assert_nil @engine.process(wfid).definition_revision
715
+ end
716
+
717
+ def test_leaves
718
+
719
+ pdef = Ruote.define do
720
+ concurrence do
721
+ alpha
722
+ wait '1w'
723
+ end
724
+ end
725
+
726
+ @engine.register_participant :alpha, Ruote::NullParticipant
727
+
728
+ #@engine.noisy = true
729
+
730
+ wfid = @engine.launch(pdef)
731
+
732
+ wait_for(:alpha)
733
+ wait_for(1)
734
+
735
+ leaves = @engine.process(wfid).leaves
736
+
737
+ assert_equal(
738
+ [ "0_0_0:Ruote::Exp::ParticipantExpression:",
739
+ "0_0_1:Ruote::Exp::WaitExpression:" ],
740
+ leaves.collect { |fexp|
741
+ [ fexp.fei.expid,
742
+ fexp.class.to_s,
743
+ fexp.error ? fexp.error.message : '' ].join(':')
744
+ })
745
+ end
746
+
747
+ def test_leaves_when_errors
748
+
749
+ pdef = Ruote.define do
750
+ concurrence do
751
+ wait '1w'
752
+ participant
753
+ alpha
754
+ end
755
+ end
756
+
757
+ @engine.register_participant :alpha, Ruote::NullParticipant
758
+
759
+ #@engine.noisy = true
760
+
761
+ wfid = @engine.launch(pdef)
762
+
763
+ wait_for(:alpha)
764
+ wait_for(1)
765
+
766
+ leaves = @engine.process(wfid).leaves
767
+
768
+ assert_equal(
769
+ [ "0_0_0:Ruote::Exp::WaitExpression:",
770
+ "0_0_1:Ruote::Exp::ParticipantExpression:#<ArgumentError: no participant name specified>",
771
+ "0_0_2:Ruote::Exp::ParticipantExpression:" ],
772
+ leaves.collect { |fexp|
773
+ [ fexp.fei.expid,
774
+ fexp.class.to_s,
775
+ fexp.error ? fexp.error.message : '' ].join(':')
776
+ })
777
+ end
778
+
779
+ def test_root_workitem
780
+
781
+ pdef = Ruote.define do
782
+ alpha
783
+ end
784
+
785
+ @engine.register_participant :alpha, Ruote::NullParticipant
786
+
787
+ wfid = @engine.launch(pdef, 'small' => 'town')
788
+
789
+ wait_for(:alpha)
790
+
791
+ wi = @engine.process(wfid).root_workitem
792
+
793
+ assert_equal 'town', wi.fields['small']
794
+ end
795
+ end
796
+