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,69 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Wed Apr 6 08:39:36 JST 2011
6
+ #
7
+ # Santa Barbara
8
+ #
9
+
10
+ require File.join(File.dirname(__FILE__), 'base')
11
+
12
+ require 'ruote'
13
+
14
+
15
+ class FtWorkitemTest < Test::Unit::TestCase
16
+ include FunctionalBase
17
+
18
+ class TraceParticipant
19
+ include Ruote::LocalParticipant
20
+
21
+ def consume(wi)
22
+ @context.tracer << "#{wi.wf_name}/#{wi.wf_revision}\n"
23
+ reply_to_engine(wi)
24
+ end
25
+ end
26
+
27
+ def test_wf_info
28
+
29
+ @engine.register :alpha, TraceParticipant
30
+
31
+ #@engine.noisy = true
32
+
33
+ assert_trace(
34
+ 'x/y',
35
+ Ruote.process_definition(:name => 'x', :revision => 'y') do
36
+ alpha
37
+ end,
38
+ :clear)
39
+
40
+ assert_trace(
41
+ 'x/y',
42
+ Ruote.process_definition('x', :revision => 'y') do
43
+ alpha
44
+ end,
45
+ :clear)
46
+
47
+ assert_trace(
48
+ 'x/y',
49
+ Ruote.process_definition('x', :rev => 'y') do
50
+ alpha
51
+ end,
52
+ :clear)
53
+
54
+ assert_trace(
55
+ 'x/',
56
+ Ruote.process_definition('x') do
57
+ alpha
58
+ end,
59
+ :clear)
60
+
61
+ assert_trace(
62
+ '/',
63
+ Ruote.process_definition do
64
+ alpha
65
+ end,
66
+ :clear)
67
+ end
68
+ end
69
+
@@ -0,0 +1,343 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Tue Apr 12 06:10:17 JST 2011
6
+ #
7
+ # Santa Barbara
8
+ #
9
+
10
+ require File.join(File.dirname(__FILE__), 'base')
11
+
12
+
13
+ class FtPauseTest < Test::Unit::TestCase
14
+ include FunctionalBase
15
+
16
+ def test_pause_process
17
+
18
+ pdef = Ruote.process_definition do
19
+ alice
20
+ end
21
+
22
+ @engine.register do
23
+ catchall
24
+ end
25
+
26
+ wfid = @engine.launch(pdef)
27
+
28
+ @engine.wait_for(:alice)
29
+
30
+ #
31
+ # pause the process
32
+
33
+ @engine.pause(wfid)
34
+
35
+ sleep 0.500
36
+
37
+ ps = @engine.ps(wfid)
38
+
39
+ assert_equal %w[ paused ], ps.expressions.collect { |fexp| fexp.state }.uniq
40
+
41
+ @engine.storage_participant.proceed(@engine.storage_participant.first)
42
+
43
+ sleep 0.500
44
+
45
+ ps = @engine.ps(wfid)
46
+
47
+ exp = ps.expressions.last
48
+
49
+ assert_not_nil exp.h.paused_replies
50
+
51
+ #
52
+ # resume the process
53
+
54
+ @engine.resume(wfid)
55
+
56
+ @engine.wait_for(wfid)
57
+
58
+ assert_nil @engine.ps(wfid)
59
+ end
60
+
61
+ def test_pause_process_in_error
62
+
63
+ pdef = Ruote.process_definition do
64
+ nada
65
+ end
66
+
67
+ #@engine.noisy = true
68
+
69
+ wfid = @engine.launch(pdef)
70
+
71
+ @engine.wait_for(wfid)
72
+
73
+ @engine.pause(wfid)
74
+
75
+ sleep 0.500
76
+
77
+ ps = @engine.ps(wfid)
78
+
79
+ assert_equal(
80
+ %w[ paused failed ],
81
+ ps.expressions.collect { |fexp| fexp.state })
82
+
83
+ #
84
+ # cancel at error
85
+
86
+ @engine.cancel(ps.expressions.last.fei)
87
+
88
+ #
89
+ # resume the process
90
+
91
+ @engine.resume(wfid)
92
+
93
+ @engine.wait_for(wfid)
94
+
95
+ assert_nil @engine.ps(wfid)
96
+ end
97
+
98
+ def test_cancel_paused_branch
99
+
100
+ pdef = Ruote.process_definition do
101
+ sequence do
102
+ alice
103
+ end
104
+ bob
105
+ end
106
+
107
+ @engine.register do
108
+ catchall
109
+ end
110
+
111
+ #@engine.noisy = true
112
+
113
+ wfid = @engine.launch(pdef)
114
+
115
+ @engine.wait_for(:alice)
116
+
117
+ exp = @engine.ps(wfid).expressions.find { |e| e.name == 'sequence' }
118
+
119
+ @engine.pause(exp.fei)
120
+
121
+ sleep 0.500
122
+
123
+ assert_equal(
124
+ %w[ 0/ 0_0/paused 0_0_0/paused ],
125
+ @engine.ps(wfid).expressions.collect { |fe|
126
+ "#{fe.fei.expid}/#{fe.state}"
127
+ })
128
+
129
+ @engine.cancel(exp.fei)
130
+
131
+ @engine.wait_for(:bob)
132
+
133
+ assert_equal(
134
+ %w[ 0/ 0_1/ ],
135
+ @engine.ps(wfid).expressions.collect { |fe|
136
+ "#{fe.fei.expid}/#{fe.state}"
137
+ })
138
+ end
139
+
140
+ class AlphaParticipant
141
+ include Ruote::LocalParticipant
142
+ def consume(workitem)
143
+ @context.tracer << "dispatched:#{workitem.fei.wfid}\n"
144
+ end
145
+ def on_pause(fei)
146
+ @context.tracer << "pause:#{fei.wfid}\n"
147
+ end
148
+ def on_resume(fei)
149
+ @context.tracer << "resume:#{fei.wfid}\n"
150
+ end
151
+ end
152
+
153
+ def test_propagation_to_participant
154
+
155
+ pdef = Ruote.define do
156
+ alpha
157
+ end
158
+
159
+ @engine.register do
160
+ alpha AlphaParticipant
161
+ end
162
+
163
+ #@engine.noisy = true
164
+
165
+ wfid = @engine.launch(pdef)
166
+
167
+ @engine.wait_for(:alpha)
168
+
169
+ @engine.pause(wfid)
170
+
171
+ sleep 0.7 # give time to the pause propagation to reach the participant
172
+
173
+ assert_equal(
174
+ [ "dispatched:#{wfid}", "pause:#{wfid}" ],
175
+ @tracer.to_a)
176
+
177
+ @engine.resume(wfid)
178
+
179
+ sleep 0.7 # give time to the resume propagation to reach the participant
180
+
181
+ assert_equal(
182
+ [ "dispatched:#{wfid}", "pause:#{wfid}", "resume:#{wfid}" ],
183
+ @tracer.to_a)
184
+ end
185
+
186
+ def test_propagation_to_participant_when_participant_has_already_replied
187
+
188
+ pdef = Ruote.define do
189
+ alpha
190
+ end
191
+
192
+ @engine.register do
193
+ alpha AlphaParticipant
194
+ end
195
+
196
+ #@engine.noisy = true
197
+
198
+ wfid = @engine.launch(pdef)
199
+
200
+ @engine.wait_for(:alpha)
201
+
202
+ @engine.pause(wfid)
203
+
204
+ sleep 0.7 # give time to the pause propagation to reach the participant
205
+
206
+ wi = @engine.ps(wfid).expressions.last.h.applied_workitem
207
+
208
+ part = @engine.participant(:alpha.to_s)
209
+
210
+ part.instance_eval { reply_to_engine(Ruote::Workitem.new(wi)) }
211
+
212
+ @engine.wait_for(1)
213
+
214
+ assert_equal(
215
+ [ "dispatched:#{wfid}", "pause:#{wfid}" ],
216
+ @tracer.to_a)
217
+
218
+ @engine.resume(wfid)
219
+
220
+ sleep 0.7 # give time to the resume propagation to reach the participant
221
+
222
+ assert_equal(
223
+ [ "dispatched:#{wfid}", "pause:#{wfid}" ],
224
+ @tracer.to_a)
225
+ #
226
+ # no 'resume:xxx'
227
+ end
228
+
229
+ def test_breakpoint
230
+
231
+ pdef = Ruote.define do
232
+ sequence do
233
+ alpha
234
+ end
235
+ end
236
+
237
+ @engine.register do
238
+ catchall
239
+ end
240
+
241
+ #@engine.noisy = true
242
+
243
+ wfid = @engine.launch(pdef)
244
+
245
+ @engine.wait_for(:alpha)
246
+
247
+ sequence = @engine.ps(wfid).expressions[1]
248
+
249
+ @engine.pause(sequence.fei, :breakpoint => true)
250
+
251
+ @engine.storage_participant.proceed(@engine.storage_participant.first)
252
+
253
+ sleep 0.7
254
+
255
+ assert_equal(
256
+ [ nil, 'paused' ],
257
+ @engine.ps(wfid).expressions.collect { |fexp| fexp.state })
258
+ end
259
+
260
+ def test_no_propagation_to_participant_when_breakpoint
261
+
262
+ pdef = Ruote.define do
263
+ alpha
264
+ end
265
+
266
+ @engine.register do
267
+ alpha AlphaParticipant
268
+ end
269
+
270
+ #@engine.noisy = true
271
+
272
+ wfid = @engine.launch(pdef)
273
+
274
+ @engine.wait_for(:alpha)
275
+
276
+ alpha = @engine.ps(wfid).expressions.last
277
+
278
+ @engine.pause(alpha.fei, :breakpoint => true)
279
+
280
+ sleep 0.7 # give time to the pause propagation to reach the participant
281
+
282
+ assert_equal([ "dispatched:#{wfid}" ], @tracer.to_a)
283
+
284
+ @engine.resume(alpha.fei)
285
+
286
+ sleep 0.7 # give time to the resume propagation to reach the participant
287
+
288
+ assert_equal([ "dispatched:#{wfid}" ], @tracer.to_a)
289
+ end
290
+
291
+ def test_resume_anyway
292
+
293
+ pdef = Ruote.define do
294
+ concurrence do
295
+ alpha
296
+ sequence do
297
+ bravo
298
+ end
299
+ end
300
+ end
301
+
302
+ @engine.register do
303
+ catchall
304
+ end
305
+
306
+ #@engine.noisy = true
307
+
308
+ wfid = @engine.launch(pdef)
309
+
310
+ @engine.wait_for(:alpha)
311
+ @engine.wait_for(:bravo)
312
+
313
+ exps = @engine.ps(wfid).expressions.select { |fexp|
314
+ fexp.fei.expid.match(/^0_0_[01]$/)
315
+ }
316
+
317
+ exps.each { |fexp| @engine.pause(fexp.fei) }
318
+
319
+ sleep 0.7
320
+
321
+ assert_equal(
322
+ [ nil, nil, 'paused', 'paused', 'paused' ],
323
+ @engine.ps(wfid).expressions.collect { |fexp| fexp.state })
324
+
325
+ @engine.resume(wfid)
326
+ # won't resume the process, since the root is not paused
327
+
328
+ sleep 0.4
329
+
330
+ assert_equal(
331
+ [ nil, nil, 'paused', 'paused', 'paused' ],
332
+ @engine.ps(wfid).expressions.collect { |fexp| fexp.state })
333
+
334
+ @engine.resume(wfid, :anyway => true)
335
+
336
+ sleep 0.7
337
+
338
+ assert_equal(
339
+ [ nil, nil, nil, nil, nil ],
340
+ @engine.ps(wfid).expressions.collect { |fexp| fexp.state })
341
+ end
342
+ end
343
+
@@ -0,0 +1,384 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Tue Jun 2 18:48:02 JST 2009
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'ruote/participant'
11
+
12
+
13
+ class FtOnErrorTest < Test::Unit::TestCase
14
+ include FunctionalBase
15
+
16
+ def test_on_error
17
+
18
+ pdef = Ruote.process_definition do
19
+ sequence :on_error => 'catcher' do
20
+ nada
21
+ end
22
+ end
23
+
24
+ @engine.register_participant :catcher do
25
+ @tracer << "caught\n"
26
+ end
27
+
28
+ #noisy
29
+
30
+ assert_trace('caught', pdef)
31
+
32
+ assert_equal 1, logger.log.select { |e| e['action'] == 'fail' }.size
33
+ end
34
+
35
+ def test_on_error_unknown_participant_name
36
+
37
+ pdef = Ruote.process_definition :name => 'test' do
38
+ participant :mark_started
39
+ sequence :on_error => :mark_failed do
40
+ participant :bogus
41
+ end
42
+ participant :mark_finished
43
+ end
44
+
45
+ @engine.context.stash[:marks] = []
46
+
47
+ @engine.register_participant 'mark\_.+' do |workitem|
48
+ stash[:marks] << workitem.participant_name
49
+ end
50
+
51
+ #noisy
52
+
53
+ wfid = @engine.launch(pdef)
54
+
55
+ wait_for(wfid)
56
+
57
+ assert_equal(
58
+ %w[ mark_started mark_failed mark_finished ],
59
+ @engine.context.stash[:marks])
60
+ end
61
+
62
+ def test_on_error_unknown_participant_name_2
63
+
64
+ pdef = Ruote.process_definition :name => 'test' do
65
+ participant :mark_started
66
+ participant :bogus, :on_error => :mark_failed
67
+ participant :mark_finished
68
+ end
69
+
70
+ @engine.context.stash[:marks] = []
71
+
72
+ @engine.register_participant 'mark\_.+' do |workitem|
73
+ stash[:marks] << workitem.participant_name
74
+ end
75
+
76
+ #noisy
77
+
78
+ wfid = @engine.launch(pdef)
79
+
80
+ wait_for(wfid)
81
+
82
+ assert_equal(
83
+ %w[ mark_started mark_failed mark_finished ],
84
+ @engine.context.stash[:marks])
85
+ end
86
+
87
+ def test_on_error_neutralization
88
+
89
+ pdef = Ruote.process_definition do
90
+ sequence :on_error => 'catcher' do
91
+ sequence :on_error => '' do
92
+ nada
93
+ end
94
+ end
95
+ end
96
+
97
+ @engine.register_participant :catcher do
98
+ @tracer << "caught\n"
99
+ end
100
+
101
+ #noisy
102
+
103
+ wfid = @engine.launch(pdef)
104
+ wait_for(wfid)
105
+ ps = @engine.process(wfid)
106
+
107
+ assert_equal(1, ps.errors.size)
108
+ end
109
+
110
+ class TroubleMaker
111
+ include Ruote::LocalParticipant
112
+ def consume(workitem)
113
+ hits = (workitem.fields['hits'] || 0) + 1
114
+ workitem.fields['hits'] = hits
115
+ workitem.trace << "#{hits.to_s}\n"
116
+ raise 'Houston, we have a problem !' if hits == 1
117
+ workitem.trace << 'done.'
118
+ reply(workitem)
119
+ end
120
+ def cancel(fei, flavour)
121
+ # nothing to do
122
+ end
123
+ end
124
+
125
+ def test_on_error_redo
126
+
127
+ pdef = Ruote.process_definition do
128
+ sequence :on_error => :redo do
129
+ troublemaker
130
+ end
131
+ end
132
+
133
+ #noisy
134
+
135
+ @engine.register_participant :troublemaker, TroubleMaker
136
+
137
+ assert_trace(%w[ 1 2 done. ], pdef)
138
+ end
139
+
140
+ def test_on_error_retry
141
+
142
+ pdef = Ruote.process_definition do
143
+ sequence :on_error => :retry do
144
+ troublemaker
145
+ end
146
+ end
147
+
148
+ @engine.register_participant :troublemaker, TroubleMaker
149
+
150
+ assert_trace(%w[ 1 2 done. ], pdef)
151
+ end
152
+
153
+ def test_on_error_undo
154
+
155
+ pdef = Ruote.process_definition do
156
+ sequence do
157
+ echo 'a'
158
+ sequence :on_error => :undo do
159
+ echo 'b'
160
+ nemo
161
+ echo 'c'
162
+ end
163
+ echo 'd'
164
+ end
165
+ end
166
+
167
+ #noisy
168
+
169
+ wfid = assert_trace(%w[ a b d ], pdef)
170
+
171
+ assert_nil @engine.process(wfid)
172
+ end
173
+
174
+ def test_on_error_undo_single_expression
175
+
176
+ @engine.register_participant :nemo do |wi|
177
+ wi.fields['fail_count'] = 1
178
+ raise 'nemo'
179
+ end
180
+
181
+ pdef = Ruote.process_definition do
182
+ sequence do
183
+ echo 'in'
184
+ nemo :on_error => 'undo'
185
+ echo '${f:error}|${f:fail_count}'
186
+ end
187
+ end
188
+
189
+ wfid = assert_trace(%w[ in |1 ], pdef)
190
+
191
+ assert_nil @engine.process(wfid)
192
+ end
193
+
194
+ def test_on_error_pass
195
+
196
+ pdef = Ruote.process_definition do
197
+ sequence do
198
+ echo 'a'
199
+ sequence :on_error => :pass do
200
+ echo 'b'
201
+ nemo
202
+ echo 'c'
203
+ end
204
+ echo 'd'
205
+ end
206
+ end
207
+
208
+ #noisy
209
+
210
+ wfid = assert_trace(%w[ a b d ], pdef)
211
+
212
+ assert_nil @engine.process(wfid)
213
+ end
214
+
215
+ def test_missing_handler_triggers_regular_error
216
+
217
+ pdef = Ruote.process_definition :on_error => 'failpath' do
218
+ nemo
219
+ end
220
+
221
+ #noisy
222
+
223
+ wfid = @engine.launch(pdef)
224
+ wait_for(wfid)
225
+ ps = @engine.process(wfid)
226
+
227
+ assert_equal 1, ps.errors.size
228
+
229
+ assert_equal 1, logger.log.select { |e| e['action'] == 'error_intercepted' }.size
230
+ end
231
+
232
+ def test_on_error_at_process_level
233
+
234
+ pdef = Ruote.process_definition :on_error => 'failpath' do
235
+ nemo
236
+ define :failpath do
237
+ echo 'failed.'
238
+ end
239
+ end
240
+
241
+ #noisy
242
+
243
+ assert_trace('failed.', pdef)
244
+ end
245
+
246
+ def test_with_concurrence
247
+
248
+ pdef = Ruote.process_definition do
249
+ sequence do
250
+ concurrence :on_error => 'emil' do
251
+ alpha
252
+ error 'nada0'
253
+ error 'nada1'
254
+ end
255
+ echo 'done.'
256
+ end
257
+ end
258
+
259
+ @engine.context.stash[:a_count] = 0
260
+ @engine.context.stash[:e_count] = 0
261
+
262
+ @engine.register_participant(:alpha) { |wi| stash[:a_count] += 1 }
263
+ @engine.register_participant(:emil) { |wi| stash[:e_count] += 1 }
264
+
265
+ #noisy
266
+
267
+ assert_trace 'done.', pdef
268
+ assert_equal 1, @engine.context.stash[:a_count]
269
+ assert_equal 1, @engine.context.stash[:e_count]
270
+ end
271
+
272
+ def test_participant_on_error
273
+
274
+ pdef = Ruote.process_definition do
275
+ troublemaker :on_error => 'handle_error'
276
+ define 'handle_error' do
277
+ troublespotter
278
+ end
279
+ end
280
+
281
+ @engine.register_participant :troublemaker do |wi|
282
+ wi.fields['seen'] = true
283
+ raise 'Beijing, we have a problem !'
284
+ end
285
+ @engine.register_participant :troublespotter do |wi|
286
+ stash[:workitem] = wi
287
+ @tracer << 'err...'
288
+ end
289
+
290
+ #noisy
291
+
292
+ wfid = @engine.launch(pdef)
293
+ wait_for(wfid)
294
+
295
+ #er = @engine.process(wfid).errors.first
296
+ #puts er.message
297
+ #puts er.trace
298
+
299
+ wi = @engine.context.stash[:workitem]
300
+
301
+ assert_equal 'err...', @tracer.to_s
302
+ assert_equal 5, wi.error.size
303
+ assert_equal 'RuntimeError', wi.error['class']
304
+ assert_equal 'Beijing, we have a problem !', wi.error['message']
305
+ assert_equal Array, wi.error['trace'].class
306
+ assert_equal true, wi.fields['seen']
307
+ end
308
+
309
+ class Murphy
310
+ include Ruote::LocalParticipant
311
+
312
+ def cancel(fei, flavour)
313
+ # nothing to do
314
+ end
315
+ def consume(workitem)
316
+ raise "something got wrong"
317
+ end
318
+ end
319
+
320
+ def test_subprocess_on_error
321
+
322
+ pdef = Ruote.process_definition do
323
+ sequence :on_error => 'error_path' do
324
+ murphy
325
+ end
326
+ define 'error_path' do
327
+ catcher
328
+ end
329
+ end
330
+
331
+ @engine.register do
332
+ murphy FtOnErrorTest::Murphy
333
+ catchall
334
+ end
335
+
336
+ #@engine.noisy = true
337
+
338
+ @engine.launch(pdef)
339
+
340
+ @engine.wait_for(:catcher)
341
+ end
342
+
343
+ class RescuerOne
344
+ include Ruote::LocalParticipant
345
+ def consume(workitem)
346
+ @context.tracer << 'one'
347
+ reply_to_engine(workitem)
348
+ end
349
+ def accept?(workitem)
350
+ false
351
+ end
352
+ end
353
+ class RescuerTwo
354
+ include Ruote::LocalParticipant
355
+ def consume(workitem)
356
+ @context.tracer << 'two'
357
+ reply_to_engine(workitem)
358
+ end
359
+ #def accept?(workitem)
360
+ # true
361
+ #end
362
+ end
363
+
364
+ def test_participants_and_accept
365
+
366
+ pdef = Ruote.process_definition do
367
+ sequence :on_error => 'rescuer' do
368
+ nada
369
+ end
370
+ end
371
+
372
+ @engine.register do
373
+ rescuer RescuerOne
374
+ rescuer RescuerTwo
375
+ end
376
+
377
+ #@engine.noisy = true
378
+
379
+ assert_trace('two', pdef)
380
+
381
+ assert_equal 1, logger.log.select { |e| e['action'] == 'fail' }.size
382
+ end
383
+ end
384
+