ruote 2.1.10 → 2.1.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/CHANGELOG.txt +51 -1
  2. data/CREDITS.txt +9 -0
  3. data/README.rdoc +13 -0
  4. data/Rakefile +50 -21
  5. data/TODO.txt +42 -4
  6. data/examples/pong.rb +37 -0
  7. data/lib/ruote/context.rb +19 -9
  8. data/lib/ruote/engine/process_error.rb +10 -0
  9. data/lib/ruote/engine/process_status.rb +140 -41
  10. data/lib/ruote/engine.rb +394 -27
  11. data/lib/ruote/exp/command.rb +2 -0
  12. data/lib/ruote/exp/fe_concurrence.rb +8 -0
  13. data/lib/ruote/exp/fe_concurrent_iterator.rb +3 -0
  14. data/lib/ruote/exp/fe_cursor.rb +48 -4
  15. data/lib/ruote/exp/fe_iterator.rb +40 -0
  16. data/lib/ruote/exp/fe_listen.rb +3 -3
  17. data/lib/ruote/exp/fe_participant.rb +30 -12
  18. data/lib/ruote/exp/fe_ref.rb +126 -0
  19. data/lib/ruote/exp/fe_subprocess.rb +20 -1
  20. data/lib/ruote/exp/fe_wait.rb +4 -1
  21. data/lib/ruote/exp/fe_when.rb +7 -10
  22. data/lib/ruote/exp/flowexpression.rb +23 -12
  23. data/lib/ruote/exp/ro_attributes.rb +5 -8
  24. data/lib/ruote/exp/ro_variables.rb +4 -2
  25. data/lib/ruote/fei.rb +2 -0
  26. data/lib/ruote/id/wfid_generator.rb +1 -1
  27. data/lib/ruote/log/pretty.rb +137 -0
  28. data/lib/ruote/log/storage_history.rb +1 -1
  29. data/lib/ruote/log/test_logger.rb +51 -126
  30. data/lib/ruote/log/wait_logger.rb +8 -13
  31. data/lib/ruote/parser/ruby_dsl.rb +4 -4
  32. data/lib/ruote/parser.rb +2 -2
  33. data/lib/ruote/part/block_participant.rb +1 -1
  34. data/lib/ruote/part/engine_participant.rb +1 -1
  35. data/lib/ruote/part/storage_participant.rb +27 -28
  36. data/lib/ruote/part/template.rb +8 -3
  37. data/lib/ruote/receiver/base.rb +24 -6
  38. data/lib/ruote/storage/base.rb +76 -11
  39. data/lib/ruote/storage/fs_storage.rb +10 -0
  40. data/lib/ruote/storage/hash_storage.rb +19 -8
  41. data/lib/ruote/{part → svc}/dispatch_pool.rb +3 -2
  42. data/lib/ruote/svc/dollar_sub.rb +265 -0
  43. data/lib/ruote/{error_handler.rb → svc/error_handler.rb} +6 -1
  44. data/lib/ruote/{exp → svc}/expression_map.rb +31 -37
  45. data/lib/ruote/{part → svc}/participant_list.rb +165 -25
  46. data/lib/ruote/{evt → svc}/tracker.rb +0 -0
  47. data/lib/ruote/{util → svc}/treechecker.rb +0 -0
  48. data/lib/ruote/util/look.rb +4 -1
  49. data/lib/ruote/util/ometa.rb +21 -5
  50. data/lib/ruote/{subprocess.rb → util/subprocess.rb} +0 -0
  51. data/lib/ruote/version.rb +1 -1
  52. data/lib/ruote/worker.rb +29 -69
  53. data/lib/ruote/workitem.rb +28 -1
  54. data/ruote.gemspec +26 -22
  55. data/test/functional/base.rb +3 -0
  56. data/test/functional/concurrent_base.rb +1 -0
  57. data/test/functional/crunner.sh +1 -1
  58. data/test/functional/ct_0_concurrence.rb +6 -0
  59. data/test/functional/ct_1_iterator.rb +3 -0
  60. data/test/functional/ct_2_cancel.rb +5 -0
  61. data/test/functional/eft_13_iterator.rb +39 -4
  62. data/test/functional/eft_14_cursor.rb +39 -0
  63. data/test/functional/eft_30_ref.rb +140 -0
  64. data/test/functional/eft_3_participant.rb +25 -23
  65. data/test/functional/ft_10_dollar.rb +17 -1
  66. data/test/functional/ft_14_re_apply.rb +76 -0
  67. data/test/functional/ft_1_process_status.rb +170 -29
  68. data/test/functional/ft_20_storage_participant.rb +14 -0
  69. data/test/functional/ft_24_block_participants.rb +1 -1
  70. data/test/functional/ft_26_participant_timeout.rb +93 -0
  71. data/test/functional/ft_2_errors.rb +24 -17
  72. data/test/functional/ft_30_smtp_participant.rb +7 -2
  73. data/test/functional/ft_38_participant_more.rb +15 -0
  74. data/test/functional/ft_39_wait_for.rb +34 -1
  75. data/test/functional/ft_3_participant_registration.rb +270 -2
  76. data/test/functional/ft_40_wait_logger.rb +61 -0
  77. data/test/functional/ft_42_storage_copy.rb +4 -0
  78. data/test/functional/{ft_40_participant_on_reply.rb → ft_43_participant_on_reply.rb} +17 -0
  79. data/test/functional/ft_44_var_participant.rb +35 -0
  80. data/test/functional/ft_45_participant_accept.rb +64 -0
  81. data/test/functional/ft_46_launch_single.rb +49 -0
  82. data/test/functional/ft_5_on_error.rb +39 -1
  83. data/test/functional/storage_helper.rb +7 -1
  84. data/test/test_helper.rb +1 -1
  85. data/test/unit/storage.rb +105 -32
  86. data/test/unit/ut_0_ruby_parser.rb +31 -1
  87. data/test/unit/ut_16_parser.rb +20 -0
  88. data/test/unit/ut_19_part_template.rb +11 -1
  89. data/test/unit/ut_20_composite_storage.rb +1 -1
  90. data/test/unit/ut_4_expmap.rb +1 -1
  91. data/test/unit/ut_6_condition.rb +2 -2
  92. metadata +112 -74
  93. data/lib/ruote/exp/raw.rb +0 -44
  94. data/lib/ruote/util/dollar.rb +0 -193
@@ -7,6 +7,8 @@
7
7
 
8
8
  require File.join(File.dirname(__FILE__), 'base')
9
9
 
10
+ require 'ruote'
11
+
10
12
 
11
13
  class FtParticipantRegistrationTest < Test::Unit::TestCase
12
14
  include FunctionalBase
@@ -28,6 +30,10 @@ class FtParticipantRegistrationTest < Test::Unit::TestCase
28
30
  assert_equal(
29
31
  [ 'inpa_:alpha' ],
30
32
  @engine.context.plist.instantiated_participants.collect { |e| e.first })
33
+
34
+ assert_equal(
35
+ [ [ '^alpha$', 'inpa_:alpha' ] ],
36
+ @engine.participant_list.collect { |pe| pe.to_a })
31
37
  end
32
38
 
33
39
  def test_double_registration
@@ -97,7 +103,7 @@ class FtParticipantRegistrationTest < Test::Unit::TestCase
97
103
 
98
104
  def test_participant_shutdown
99
105
 
100
- alpha = @engine.register_participant :alpha, MyParticipant.new
106
+ alpha = @engine.register :alpha, MyParticipant.new
101
107
 
102
108
  @engine.context.plist.shutdown
103
109
 
@@ -109,7 +115,269 @@ class FtParticipantRegistrationTest < Test::Unit::TestCase
109
115
  pa = @engine.register_participant :alpha do |workitem|
110
116
  end
111
117
 
112
- assert_equal ['^alpha$'], @engine.context.plist.names
118
+ assert_equal [ '^alpha$' ], @engine.context.plist.names
119
+ end
120
+
121
+ def test_register_require_path
122
+
123
+ rpath = File.join(
124
+ File.dirname(__FILE__), "#{Time.now.to_f}_#{$$}_required_participant")
125
+ path = "#{rpath}.rb"
126
+
127
+ File.open(path, 'wb') do |f|
128
+ f.write(%{
129
+ class RequiredParticipant
130
+ include Ruote::LocalParticipant
131
+ def initialize (opts)
132
+ @opts = opts
133
+ end
134
+ def consume (workitem)
135
+ workitem.fields['message'] = @opts['message']
136
+ reply(workitem)
137
+ end
138
+ end
139
+ })
140
+ end
141
+
142
+ @engine.register_participant(
143
+ :alfred,
144
+ 'RequiredParticipant',
145
+ :require_path => rpath, :message => 'hello')
146
+
147
+ assert_equal [ '^alfred$' ], @engine.context.plist.names
148
+
149
+ # first run
150
+
151
+ assert_equal(
152
+ [ 'RequiredParticipant',
153
+ { 'require_path' => rpath, 'message' => 'hello' } ],
154
+ @engine.context.plist.lookup_info('alfred', nil))
155
+
156
+ wfid = @engine.launch(Ruote.define { alfred })
157
+ r = @engine.wait_for(wfid)
158
+
159
+ assert_equal 'hello', r['workitem']['fields']['message']
160
+
161
+ # second run
162
+
163
+ File.open(path, 'wb') do |f|
164
+ f.write(%{
165
+ class RequiredParticipant
166
+ include Ruote::LocalParticipant
167
+ def initialize (opts)
168
+ @opts = opts
169
+ end
170
+ def consume (workitem)
171
+ workitem.fields['message'] = 'second run'
172
+ reply(workitem)
173
+ end
174
+ end
175
+ })
176
+ end
177
+
178
+ wfid = @engine.launch(Ruote.define { alfred })
179
+ r = @engine.wait_for(wfid)
180
+
181
+ # since it's a 'require', the code isn't reloaded
182
+
183
+ assert_equal 'hello', r['workitem']['fields']['message']
184
+
185
+ FileUtils.rm(path)
186
+ end
187
+
188
+ def test_reqister_load_path
189
+
190
+ path = File.join(
191
+ File.dirname(__FILE__), "#{Time.now.to_f}_#{$$}_loaded_participant.rb")
192
+
193
+ File.open(path, 'wb') do |f|
194
+ f.write(%{
195
+ class LoadedParticipant
196
+ include Ruote::LocalParticipant
197
+ def initialize (opts)
198
+ @opts = opts
199
+ end
200
+ def consume (workitem)
201
+ workitem.fields['message'] = @opts['message']
202
+ reply(workitem)
203
+ end
204
+ end
205
+ })
206
+ end
207
+
208
+ @engine.register_participant(
209
+ :alfred,
210
+ 'LoadedParticipant',
211
+ :load_path => path, :message => 'bondzoi')
212
+
213
+ assert_equal [ '^alfred$' ], @engine.context.plist.names
214
+
215
+ # first run
216
+
217
+ assert_equal(
218
+ [ 'LoadedParticipant',
219
+ { 'load_path' => path, 'message' => 'bondzoi' } ],
220
+ @engine.context.plist.lookup_info('alfred', nil))
221
+
222
+ wfid = @engine.launch(Ruote.define { alfred })
223
+ r = @engine.wait_for(wfid)
224
+
225
+ assert_equal 'bondzoi', r['workitem']['fields']['message']
226
+
227
+ # second run
228
+
229
+ File.open(path, 'wb') do |f|
230
+ f.write(%{
231
+ class LoadedParticipant
232
+ include Ruote::LocalParticipant
233
+ def initialize (opts)
234
+ @opts = opts
235
+ end
236
+ def consume (workitem)
237
+ workitem.fields['message'] = 'second run'
238
+ reply(workitem)
239
+ end
240
+ end
241
+ })
242
+ end
243
+
244
+ wfid = @engine.launch(Ruote.define { alfred })
245
+ r = @engine.wait_for(wfid)
246
+
247
+ # since it's a 'load', the code is reloaded
248
+
249
+ assert_equal 'second run', r['workitem']['fields']['message']
250
+
251
+ FileUtils.rm(path)
252
+ end
253
+
254
+ def test_participant_list
255
+
256
+ #noisy
257
+
258
+ @engine.register_participant 'alpha', Ruote::StorageParticipant
259
+
260
+ assert_equal(
261
+ [ '/^alpha$/ ==> Ruote::StorageParticipant {}' ],
262
+ @engine.participant_list.collect { |pe| pe.to_s })
263
+
264
+ # launching a process with a missing participant
265
+
266
+ wfid = @engine.launch(Ruote.define { bravo })
267
+ @engine.wait_for(wfid)
268
+
269
+ assert_equal 1, @engine.process(wfid).errors.size
270
+
271
+ # fixing the error by updating the participant list
272
+
273
+ list = @engine.participant_list
274
+ list.first.regex = '^.+$' # instead of '^alpha$'
275
+ @engine.participant_list = list
276
+
277
+ # replay at error
278
+
279
+ @engine.replay_at_error(@engine.process(wfid).errors.first)
280
+ @engine.wait_for(:bravo)
281
+
282
+ # bravo should hold a workitem
283
+
284
+ assert_equal 1, @engine.storage_participant.size
285
+ assert_equal 'bravo', @engine.storage_participant.first.participant_name
286
+ end
287
+
288
+ def test_participant_list_update
289
+
290
+ @engine.register_participant 'alpha', Ruote::StorageParticipant
291
+
292
+ assert_equal(
293
+ [ '/^alpha$/ ==> Ruote::StorageParticipant {}' ],
294
+ @engine.participant_list.collect { |pe| pe.to_s })
295
+
296
+ # 0
297
+
298
+ @engine.participant_list = [
299
+ { 'regex' => '^bravo$',
300
+ 'classname' => 'Ruote::StorageParticipant',
301
+ 'options' => {} },
302
+ { 'regex' => '^charly$',
303
+ 'classname' => 'Ruote::StorageParticipant',
304
+ 'options' => {} }
305
+ ]
306
+
307
+ assert_equal(
308
+ [
309
+ '/^bravo$/ ==> Ruote::StorageParticipant {}',
310
+ '/^charly$/ ==> Ruote::StorageParticipant {}'
311
+ ],
312
+ @engine.participant_list.collect { |pe| pe.to_s })
313
+
314
+ # 1
315
+
316
+ @engine.participant_list = [
317
+ [ '^charly$', [ 'Ruote::StorageParticipant', {} ] ],
318
+ [ '^bravo$', [ 'Ruote::StorageParticipant', {} ] ]
319
+ ]
320
+
321
+ assert_equal(
322
+ [
323
+ '/^charly$/ ==> Ruote::StorageParticipant {}',
324
+ '/^bravo$/ ==> Ruote::StorageParticipant {}'
325
+ ],
326
+ @engine.participant_list.collect { |pe| pe.to_s })
327
+
328
+ # 2
329
+
330
+ @engine.participant_list = [
331
+ [ '^delta$', Ruote::StorageParticipant, {} ],
332
+ [ '^echo$', 'Ruote::StorageParticipant', {} ]
333
+ ]
334
+
335
+ assert_equal(
336
+ [
337
+ '/^delta$/ ==> Ruote::StorageParticipant {}',
338
+ '/^echo$/ ==> Ruote::StorageParticipant {}'
339
+ ],
340
+ @engine.participant_list.collect { |pe| pe.to_s })
341
+ end
342
+
343
+ class ParticipantCharlie; end
344
+
345
+ def test_register_block
346
+
347
+ @engine.register do
348
+ alpha 'Participants::Alpha', 'flavour' => 'vanilla'
349
+ participant 'bravo', 'Participants::Bravo', :flavour => 'peach'
350
+ participant 'charlie', 'Participants::Charlie'
351
+ catchall 'Participants::Zebda', 'flavour' => 'coconut'
352
+ end
353
+
354
+ assert_equal 4, @engine.participant_list.size
355
+
356
+ assert_equal(
357
+ %w[ ^alpha$ ^bravo$ ^charlie$ ^.+$ ],
358
+ @engine.participant_list.collect { |pe| pe.regex.to_s })
359
+
360
+ assert_equal(
361
+ %w[ Participants::Alpha
362
+ Participants::Bravo
363
+ Participants::Charlie
364
+ Participants::Zebda ],
365
+ @engine.participant_list.collect { |pe| pe.classname })
366
+
367
+ assert_equal(
368
+ %w[ vanilla peach nil coconut ],
369
+ @engine.participant_list.collect { |pe| pe.options['flavour'] || 'nil' })
370
+ end
371
+
372
+ def test_register_block_catchall_default
373
+
374
+ @engine.register do
375
+ catchall
376
+ end
377
+
378
+ assert_equal(
379
+ %w[ Ruote::StorageParticipant ],
380
+ @engine.participant_list.collect { |pe| pe.classname })
113
381
  end
114
382
  end
115
383
 
@@ -0,0 +1,61 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Tue Apr 20 12:32:44 JST 2010
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'ruote/part/storage_participant'
11
+
12
+
13
+ class FtWaitLoggerTest < Test::Unit::TestCase
14
+
15
+ def teardown
16
+
17
+ @engine.shutdown
18
+ @engine.context.storage.purge!
19
+ end
20
+
21
+ def test_wait_logger
22
+
23
+ @engine = Ruote::Engine.new(Ruote::Worker.new(determine_storage({})))
24
+
25
+ sp = @engine.register_participant :alpha, Ruote::StorageParticipant
26
+
27
+ pdef = Ruote.process_definition { alpha }
28
+
29
+ wfid = @engine.launch(pdef)
30
+
31
+ r = @engine.wait_for(:alpha)
32
+ assert_equal 'dispatch', r['action']
33
+
34
+ sp.reply(sp.first)
35
+
36
+ r = @engine.wait_for(wfid)
37
+
38
+ assert_equal 'terminated', r['action']
39
+ end
40
+
41
+ def test_wait_logger_seen
42
+
43
+ @engine = Ruote::Engine.new(Ruote::Worker.new(determine_storage({})))
44
+
45
+ #@engine.noisy = true
46
+
47
+ pdef = Ruote.process_definition { }
48
+
49
+ wfid = @engine.launch(pdef)
50
+
51
+ sleep 1.400 # worst case is ruote-couch
52
+
53
+ assert_equal 2, @engine.context.logger.instance_variable_get(:@seen).size
54
+
55
+ r = @engine.wait_for(wfid)
56
+
57
+ assert_equal 'terminated', r['action']
58
+ assert_equal 0, @engine.context.logger.instance_variable_get(:@seen).size
59
+ end
60
+ end
61
+
@@ -27,6 +27,8 @@ class FtStorageCopyTest < Test::Unit::TestCase
27
27
 
28
28
  wait_for(:alpha)
29
29
 
30
+ sleep 0.100 # making sure msgs have all been processed
31
+
30
32
  target = Ruote::HashStorage.new
31
33
  source = @engine.context.storage
32
34
 
@@ -53,6 +55,8 @@ class FtStorageCopyTest < Test::Unit::TestCase
53
55
 
54
56
  engine.wait_for(:alpha)
55
57
 
58
+ sleep 0.100 # making sure msgs have all been processed
59
+
56
60
  source = engine.context.storage
57
61
  target = @engine.context.storage
58
62
 
@@ -41,6 +41,23 @@ class FtParticipantOnReplyTest < Test::Unit::TestCase
41
41
  assert_trace('hello', pdef)
42
42
  end
43
43
 
44
+ def test_instantiated_participant_on_reply
45
+
46
+ pdef = Ruote.process_definition do
47
+ sequence do
48
+ alpha
49
+ echo '${f:message}'
50
+ end
51
+ end
52
+
53
+ @engine.register_participant :alpha, MyParticipant.new(nil)
54
+ # instantiated participant :-(
55
+
56
+ #noisy
57
+
58
+ assert_trace('hello', pdef)
59
+ end
60
+
44
61
  class AwkwardParticipant
45
62
  include Ruote::LocalParticipant
46
63
  def initialize (opts)
@@ -0,0 +1,35 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Wed Jul 14 09:43:58 JST 2010
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'ruote/participant'
11
+
12
+
13
+ class FtVarParticipantTest < Test::Unit::TestCase
14
+ include FunctionalBase
15
+
16
+ def test_var_participant
17
+
18
+ pdef = Ruote.process_definition do
19
+ sequence do
20
+ set 'v:alpha' => [ 'Ruote::StorageParticipant', {} ]
21
+ alpha
22
+ end
23
+ end
24
+
25
+ #noisy
26
+
27
+ wfid = @engine.launch(pdef)
28
+
29
+ @engine.wait_for(:alpha)
30
+
31
+ assert_equal 1, @engine.storage_participant.size
32
+ assert_equal 'alpha', @engine.storage_participant.first.participant_name
33
+ end
34
+ end
35
+
@@ -0,0 +1,64 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Wed Jul 21 13:37:59 JST 2010
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+ require 'ruote/part/local_participant'
11
+
12
+
13
+ class FtParticipantAcceptTest < Test::Unit::TestCase
14
+ include FunctionalBase
15
+
16
+ class MyParticipant
17
+ include Ruote::LocalParticipant
18
+
19
+ def initialize (opts)
20
+ @opts = opts
21
+ end
22
+
23
+ def accept? (workitem)
24
+ workitem.participant_name.match(@opts['filter'] || '.?')
25
+ end
26
+
27
+ def consume (workitem)
28
+ @context.tracer << 'filtered:'
29
+ @context.tracer << workitem.participant_name
30
+ @context.tracer << "\n"
31
+ reply(workitem)
32
+ end
33
+ end
34
+
35
+ class MyOtherParticipant
36
+ include Ruote::LocalParticipant
37
+
38
+ def consume (workitem)
39
+ @context.tracer << workitem.participant_name
40
+ @context.tracer << "\n"
41
+ reply(workitem)
42
+ end
43
+ end
44
+
45
+ def test_participant_on_reply
46
+
47
+ pdef = Ruote.process_definition do
48
+ sequence do
49
+ absolute
50
+ aberrant
51
+ aloof
52
+ nada
53
+ end
54
+ end
55
+
56
+ @engine.register_participant 'a.+', MyParticipant, 'filter' => '^ab'
57
+ @engine.register_participant '.+', MyOtherParticipant
58
+
59
+ #noisy
60
+
61
+ assert_trace %w[ filtered:absolute filtered:aberrant aloof nada ], pdef
62
+ end
63
+ end
64
+
@@ -0,0 +1,49 @@
1
+
2
+ #
3
+ # testing ruote
4
+ #
5
+ # Sat Sep 25 23:24:16 JST 2010
6
+ #
7
+
8
+ require File.join(File.dirname(__FILE__), 'base')
9
+
10
+
11
+ class FtLaunchSingleTest < Test::Unit::TestCase
12
+ include FunctionalBase
13
+
14
+ def test_no_name_singles_are_rejected
15
+
16
+ assert_raise ArgumentError do
17
+ @engine.launch_single(Ruote.process_definition do
18
+ wait '2y'
19
+ echo 'over.'
20
+ end)
21
+ end
22
+ end
23
+
24
+ def test_launch_single
25
+
26
+ pdef = Ruote.process_definition 'unique_process' do
27
+ wait '2y'
28
+ echo 'over.'
29
+ end
30
+
31
+ wfid = @engine.launch_single(pdef)
32
+
33
+ assert_equal(
34
+ wfid,
35
+ @engine.storage.get('variables', 'singles')['h']['unique_process'].first)
36
+
37
+ sleep 0.700
38
+
39
+ assert_not_nil @engine.process(wfid)
40
+
41
+ wfid1 = @engine.launch_single(pdef)
42
+
43
+ sleep 0.700
44
+
45
+ assert_equal wfid, wfid1
46
+ assert_equal 1, @engine.processes.size
47
+ end
48
+ end
49
+
@@ -7,6 +7,8 @@
7
7
 
8
8
  require File.join(File.dirname(__FILE__), 'base')
9
9
 
10
+ require 'ruote/participant'
11
+
10
12
 
11
13
  class FtOnErrorTest < Test::Unit::TestCase
12
14
  include FunctionalBase
@@ -250,9 +252,45 @@ class FtOnErrorTest < Test::Unit::TestCase
250
252
  #puts er.trace
251
253
 
252
254
  assert_equal 'err...', @tracer.to_s
253
- assert_equal 4, workitem.error.size
255
+ assert_equal 5, workitem.error.size
254
256
  assert_equal 'RuntimeError', workitem.error[2]
257
+ assert_equal 'Beijing, we have a problem !', workitem.error[3]
258
+ assert_equal Array, workitem.error[4].class
255
259
  assert_equal true, workitem.fields['seen']
256
260
  end
261
+
262
+ class Murphy
263
+ include Ruote::LocalParticipant
264
+
265
+ def cancel (fei, flavour)
266
+ # nothing to do
267
+ end
268
+ def consume (workitem)
269
+ raise "something got wrong"
270
+ end
271
+ end
272
+
273
+ def test_subprocess_on_error
274
+
275
+ pdef = Ruote.process_definition do
276
+ sequence :on_error => 'error_path' do
277
+ murphy
278
+ end
279
+ define 'error_path' do
280
+ catcher
281
+ end
282
+ end
283
+
284
+ @engine.register do
285
+ murphy FtOnErrorTest::Murphy
286
+ catchall
287
+ end
288
+
289
+ #@engine.noisy = true
290
+
291
+ @engine.launch(pdef)
292
+
293
+ @engine.wait_for(:catcher)
294
+ end
257
295
  end
258
296
 
@@ -69,7 +69,13 @@ else uses the in-memory Ruote::Engine (fastest, but no persistence at all)
69
69
  begin
70
70
  load File.join(path, %w[ test functional_connection.rb ])
71
71
  rescue LoadError => le
72
- load File.join(path, %w[ test integration_connection.rb ])
72
+ begin
73
+ load File.join(path, %w[ test integration_connection.rb ])
74
+ rescue LoadError => lee
75
+ p le
76
+ p lee
77
+ raise lee
78
+ end
73
79
  end
74
80
 
75
81
  new_storage(opts)
data/test/test_helper.rb CHANGED
@@ -22,7 +22,7 @@ end
22
22
  def require_patron
23
23
  begin
24
24
  require 'patron'
25
- rescue LoadError
25
+ rescue LoadError => le
26
26
  # stick with net/http
27
27
  end
28
28
  end