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
@@ -8,6 +8,7 @@
8
8
  require File.join(File.dirname(__FILE__), 'base')
9
9
 
10
10
  require 'ruote/part/hash_participant'
11
+ require 'ruote/part/storage_participant'
11
12
 
12
13
 
13
14
  class FtReApplyTest < Test::Unit::TestCase
@@ -219,5 +220,80 @@ class FtReApplyTest < Test::Unit::TestCase
219
220
 
220
221
  assert_equal "re_applied\ndone.", @tracer.to_s
221
222
  end
223
+
224
+ def test_new_tree_and_process_status_current_tree
225
+
226
+ @engine.register_participant '.+', Ruote::StorageParticipant
227
+
228
+ wfid = @engine.launch(Ruote.define { alpha })
229
+
230
+ @engine.wait_for(:alpha)
231
+
232
+ assert_equal(
233
+ [ 'define', {}, [ [ 'participant', { 'ref' => 'alpha' }, [] ] ] ],
234
+ @engine.process(wfid).current_tree)
235
+
236
+ fei = @engine.storage_participant.first.fei
237
+
238
+ @engine.re_apply(fei, :tree => [ 'bravo', {}, [] ])
239
+
240
+ @engine.wait_for(:bravo)
241
+
242
+ assert_equal(
243
+ 'bravo',
244
+ @engine.storage_participant.first.participant_name)
245
+
246
+ assert_equal(
247
+ [ 'participant', { 'ref' => 'bravo', '_triggered' => 'on_re_apply' }, [] ],
248
+ @engine.process(wfid).expressions.last.tree)
249
+
250
+ assert_equal(
251
+ [ 'define', {}, [ [ 'participant', { 'ref' => 'bravo', '_triggered' => 'on_re_apply' }, [] ] ] ],
252
+ @engine.process(wfid).current_tree)
253
+ end
254
+
255
+ # Issue reported by Brett Anthoine
256
+ #
257
+ def test_re_apply_root
258
+
259
+ @engine.register_participant '.+', Ruote::StorageParticipant
260
+
261
+ wfid = @engine.launch(Ruote.define { alpha })
262
+
263
+ @engine.wait_for(:alpha)
264
+ at0 = @engine.storage_participant.first.dispatched_at
265
+
266
+ root = @engine.process(wfid).root_expression
267
+ @engine.re_apply(root.fei)
268
+
269
+ @engine.wait_for(:alpha)
270
+ at1 = @engine.storage_participant.first.dispatched_at
271
+
272
+ assert at1 > at0
273
+ end
274
+
275
+ def test_re_apply_define
276
+
277
+ @engine.register_participant '.+', Ruote::StorageParticipant
278
+
279
+ wfid = @engine.launch(Ruote.define do
280
+ sub0
281
+ define 'sub0' do
282
+ alpha
283
+ end
284
+ end)
285
+
286
+ @engine.wait_for(:alpha)
287
+ at0 = @engine.storage_participant.first.dispatched_at
288
+
289
+ exp = @engine.process(wfid).expressions[1]
290
+
291
+ @engine.re_apply(exp.fei)
292
+
293
+ @engine.wait_for(:alpha)
294
+ at1 = @engine.storage_participant.first.dispatched_at
295
+
296
+ assert at1 > at0
297
+ end
222
298
  end
223
299
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  require File.join(File.dirname(__FILE__), 'base')
9
9
 
10
- require 'ruote/part/hash_participant'
10
+ require 'ruote/participant'
11
11
 
12
12
 
13
13
  class FtProcessStatusTest < Test::Unit::TestCase
@@ -36,29 +36,6 @@ class FtProcessStatusTest < Test::Unit::TestCase
36
36
  assert_equal(
37
37
  {"my process"=>["0", ["define", {"name"=>"my process"}, [["participant", {"ref"=>"alpha"}, []]]]]},
38
38
  ps.variables)
39
-
40
- # checking process_status.to_h
41
-
42
- h = ps.to_h
43
- #p h
44
-
45
- assert_equal wfid, h['wfid']
46
- assert_equal 2, h['expressions'].size
47
- assert_equal 'my process', h['definition_name']
48
-
49
- assert_equal Time, Time.parse(h['launched_time']).class
50
-
51
- assert_equal(
52
- ["define", {"name"=>"my process"}, [["participant", {"ref"=>"alpha"}, []]]],
53
- h['original_tree'])
54
-
55
- assert_equal(
56
- ["define", {"name"=>"my process"}, [["participant", {"ref"=>"alpha"}, []]]],
57
- h['current_tree'])
58
-
59
- assert_equal(
60
- {"my process"=>["0", ["define", {"name"=>"my process"}, [["participant", {"ref"=>"alpha"}, []]]]]},
61
- h['variables'])
62
39
  end
63
40
 
64
41
  def test_variables
@@ -90,19 +67,21 @@ class FtProcessStatusTest < Test::Unit::TestCase
90
67
  nada
91
68
  end
92
69
 
93
- wfid = @engine.launch( pdef )
94
- wait_for( wfid )
70
+ wfid = @engine.launch(pdef)
71
+ wait_for(wfid)
95
72
 
96
73
  errs = @engine.errors
97
74
 
98
75
  assert_equal 1, errs.size
99
76
 
100
- assert_equal wfid, errs.first['fei']['wfid']
77
+ assert_equal wfid, errs.first.wfid
101
78
 
102
- err = @engine.errors( wfid )
79
+ err = @engine.errors(wfid)
103
80
 
104
81
  assert_equal 1, err.size
105
- assert_equal wfid, err.first['fei']['wfid']
82
+ assert_equal wfid, err.first.wfid
83
+
84
+ assert_equal 1, @engine.errors(:count => true)
106
85
  end
107
86
 
108
87
  def test_tree
@@ -496,5 +475,167 @@ digraph "process wfid wfid" {
496
475
  }.strip,
497
476
  dot)
498
477
  end
478
+
479
+ def test_last_active
480
+
481
+ pdef = Ruote.define do
482
+ alpha
483
+ bravo
484
+ end
485
+
486
+ @engine.register_participant '.+', Ruote::StorageParticipant
487
+
488
+ wfid = @engine.launch(pdef)
489
+
490
+ @engine.wait_for(:alpha)
491
+
492
+ t0 = Time.parse(@engine.process(wfid).last_active)
493
+
494
+ sp = @engine.storage_participant
495
+ sp.reply(sp.first)
496
+
497
+ @engine.wait_for(:bravo)
498
+
499
+ t1 = Time.parse(@engine.process(wfid).last_active)
500
+
501
+ assert t1 > t0
502
+ end
503
+
504
+ def test_position
505
+
506
+ pdef = Ruote.define do
507
+ alpha :task => 'clean car'
508
+ end
509
+
510
+ @engine.register_participant '.+', Ruote::StorageParticipant
511
+
512
+ wfid = @engine.launch(pdef)
513
+ @engine.wait_for(:alpha)
514
+
515
+ assert_equal(
516
+ [ [ "0_0!!#{wfid}", 'alpha', { 'task' => 'clean car' } ] ],
517
+ @engine.process(wfid).position)
518
+
519
+ # #position leverages #workitems
520
+
521
+ assert_equal(
522
+ [ 'alpha' ],
523
+ @engine.process(wfid).workitems.collect { |wi| wi.participant_name })
524
+ end
525
+
526
+ def test_ps_with_stored_workitems
527
+
528
+ @engine.register_participant '.+', Ruote::StorageParticipant
529
+
530
+ wfid = @engine.launch(Ruote.define { alpha })
531
+ @engine.wait_for(:alpha)
532
+
533
+ ps = @engine.process(wfid)
534
+
535
+ assert_equal 1, ps.stored_workitems.size
536
+ assert_equal Ruote::Workitem, ps.stored_workitems.first.class
537
+ end
538
+
539
+ def test_ps_without_stored_workitems
540
+
541
+ @engine.register_participant '.+', Ruote::NullParticipant
542
+
543
+ wfid = @engine.launch(Ruote.define { alpha })
544
+ @engine.wait_for(:alpha)
545
+
546
+ ps = @engine.process(wfid)
547
+
548
+ assert_equal 0, ps.stored_workitems.size
549
+ end
550
+
551
+ def test_schedules
552
+
553
+ @engine.register_participant '.+', Ruote::NullParticipant
554
+
555
+ wfid = @engine.launch(Ruote.define { alpha :timeout => '2d' })
556
+ @engine.wait_for(:alpha)
557
+
558
+ assert_equal 1, @engine.schedules.size
559
+ assert_equal 1, @engine.schedules(:count => true)
560
+ end
561
+
562
+ def test_ps_and_schedules
563
+
564
+ @engine.register_participant '.+', Ruote::NullParticipant
565
+
566
+ #noisy
567
+
568
+ wfid = @engine.launch(Ruote.define { alpha :timeout => '2d' })
569
+ @engine.wait_for(:alpha)
570
+
571
+ ps = @engine.process(wfid)
572
+
573
+ assert_equal 1, ps.schedules.size
574
+ assert_equal "0_0!!#{wfid}", ps.schedules.first['target'].sid
575
+ end
576
+
577
+ def test_ps_pagination
578
+
579
+ n = 7
580
+
581
+ @engine.register_participant '.+', Ruote::StorageParticipant
582
+
583
+ wfids = (1..n).collect { |i|
584
+ @engine.launch(Ruote.define { alpha })
585
+ }.sort
586
+
587
+ while @engine.storage_participant.size < n; sleep 0.140; end
588
+
589
+ assert_equal wfids, @engine.process_wfids
590
+
591
+ assert_equal(
592
+ wfids,
593
+ @engine.processes.collect { |ps| ps.wfid })
594
+
595
+ assert_equal(
596
+ wfids[0, 3],
597
+ @engine.processes(:limit => 3).collect { |ps| ps.wfid })
598
+
599
+ assert_equal(
600
+ wfids[3, 3],
601
+ @engine.processes(:skip => 3, :limit => 3).collect { |ps| ps.wfid })
602
+
603
+ #puts "==="
604
+ #wfids.each { |wfid| puts wfid }
605
+ #puts "---"
606
+ #@engine.processes(:limit => 3, :descending => false).collect { |ps| ps.wfid }.each { |wfid| puts wfid }
607
+ #puts "---"
608
+ #@engine.processes(:limit => 3, :descending => true).collect { |ps| ps.wfid }.each { |wfid| puts wfid }
609
+
610
+ assert_equal(
611
+ wfids.reverse[0, 3],
612
+ @engine.processes(
613
+ :limit => 3, :descending => true
614
+ ).collect { |ps| ps.wfid })
615
+
616
+ assert_equal(
617
+ n,
618
+ @engine.processes(:count => true))
619
+ end
620
+
621
+ # Issue identified by David Goodlad :
622
+ #
623
+ # http://gist.github.com/600451
624
+ #
625
+ def test_ps_and_schedules
626
+
627
+ pdef = Ruote.define do
628
+ concurrence do
629
+ wait '4h'
630
+ wait '2h'
631
+ end
632
+ end
633
+
634
+ @engine.launch(pdef)
635
+
636
+ sleep 0.400
637
+
638
+ assert_equal 1, @engine.processes.size
639
+ end
499
640
  end
500
641
 
@@ -180,6 +180,8 @@ class FtStorageParticipantTest < Test::Unit::TestCase
180
180
  assert_equal 2, @part.query('place' => 'heiankyou', :limit => 2).size
181
181
  assert_equal 4, @part.query('place' => 'heiankyou', :limit => 20).size
182
182
 
183
+ assert_equal 4, @part.query(:count => true)
184
+
183
185
  page0 =
184
186
  @part.query('place' => 'heiankyou', :limit => 2).collect { |wi|
185
187
  "#{wi.fei.wfid}-#{wi.participant_name}" }
@@ -309,5 +311,17 @@ class FtStorageParticipantTest < Test::Unit::TestCase
309
311
  assert_equal wi, sp[wi.fei.to_h]
310
312
  assert_equal wi, sp[wi.fei.to_storage_id]
311
313
  end
314
+
315
+ def test_engine_storage_participant
316
+
317
+ @engine.register_participant 'step_.*', Ruote::StorageParticipant
318
+
319
+ wfid = @engine.launch(Ruote.process_definition { step_one })
320
+
321
+ wait_for(:step_one)
322
+
323
+ assert_equal 1, @engine.storage_participant.size
324
+ assert_equal 'step_one', @engine.storage_participant.first.participant_name
325
+ end
312
326
  end
313
327
 
@@ -62,7 +62,7 @@ class FtBlockParticipantTest < Test::Unit::TestCase
62
62
  def test_non_jsonfiable_result
63
63
 
64
64
  return if Ruote::WIN
65
- # defective 'json' lib on windows render this test useless
65
+ # defective 'json' lib on windows renders this test useless
66
66
 
67
67
  t = Time.now
68
68
 
@@ -45,5 +45,98 @@ class FtParticipantTimeoutTest < Test::Unit::TestCase
45
45
 
46
46
  assert_not_nil bravo.first.fields['__timed_out__']
47
47
  end
48
+
49
+ class MyParticipant
50
+ include Ruote::LocalParticipant
51
+ def consume (workitem)
52
+ # do nothing
53
+ end
54
+ def cancel (fei, flavour)
55
+ # do nothing
56
+ end
57
+ def timeout
58
+ '1s'
59
+ end
60
+ def do_not_thread
61
+ true
62
+ end
63
+ end
64
+
65
+ def test_participant_class_defined_timeout
66
+
67
+ pdef = Ruote.define do
68
+ alpha
69
+ echo 'done.'
70
+ end
71
+
72
+ @engine.register_participant :alpha, MyParticipant
73
+
74
+ #noisy
75
+
76
+ wfid = @engine.launch(pdef)
77
+
78
+ @engine.wait_for(wfid)
79
+
80
+ assert_equal 'done.', @tracer.to_s
81
+ assert_equal 2, logger.log.select { |e| e['flavour'] == 'timeout' }.size
82
+ end
83
+
84
+ def test_pdef_overriden_timeout
85
+
86
+ # process definition cancels timeout given by participant
87
+
88
+ pdef = Ruote.define do
89
+ alpha :timeout => ''
90
+ echo 'done.'
91
+ end
92
+
93
+ @engine.register_participant :alpha, MyParticipant
94
+
95
+ wfid = @engine.launch(pdef)
96
+
97
+ @engine.wait_for(:alpha)
98
+
99
+ sleep 0.350
100
+
101
+ assert_equal 0, @engine.storage.get_many('schedules').size
102
+ assert_equal '', @tracer.to_s
103
+ end
104
+
105
+ class MyOtherParticipant
106
+ include Ruote::LocalParticipant
107
+ def initialize (opts)
108
+ @opts = opts
109
+ end
110
+ def consume (workitem)
111
+ # do nothing
112
+ end
113
+ def cancel (fei, flavour)
114
+ # do nothing
115
+ end
116
+ def timeout
117
+ @opts['timeout']
118
+ end
119
+ end
120
+
121
+ def test_participant_option_defined_timeout
122
+
123
+ pdef = Ruote.define do
124
+ alpha
125
+ bravo
126
+ echo 'done.'
127
+ end
128
+
129
+ @engine.register_participant :alpha, MyOtherParticipant, 'timeout' => '1s'
130
+ @engine.register_participant :bravo, MyOtherParticipant
131
+
132
+ #noisy
133
+
134
+ wfid = @engine.launch(pdef)
135
+
136
+ @engine.wait_for(:bravo)
137
+
138
+ assert_equal 0, @engine.storage.get_many('schedules').size
139
+ # no timeout for participant :bravo
140
+ end
48
141
  end
49
142
 
@@ -19,8 +19,6 @@ class FtErrorsTest < Test::Unit::TestCase
19
19
  nada
20
20
  end
21
21
 
22
- #noisy
23
-
24
22
  wfid = @engine.launch(pdef)
25
23
  wait_for(wfid)
26
24
 
@@ -49,7 +47,7 @@ class FtErrorsTest < Test::Unit::TestCase
49
47
 
50
48
  ps = @engine.process(wfid)
51
49
 
52
- exp = ps.expressions.find { |fe| fe.class == Ruote::Exp::RawExpression }
50
+ exp = ps.expressions.find { |fe| fe.class == Ruote::Exp::RefExpression }
53
51
 
54
52
  assert_not_nil exp
55
53
 
@@ -115,7 +113,7 @@ class FtErrorsTest < Test::Unit::TestCase
115
113
  ps = @engine.process(wfid)
116
114
 
117
115
  err = ps.errors.first
118
- assert_equal [ 'nada', {}, [] ], err.tree
116
+ assert_equal [ 'nada', { 'ref' => 'nada' }, [] ], err.tree
119
117
 
120
118
  err.tree = [ 'alpha', {}, [] ]
121
119
  @engine.replay_at_error(err)
@@ -339,26 +337,35 @@ class FtErrorsTest < Test::Unit::TestCase
339
337
  assert_nil @engine.process(wfid)
340
338
  end
341
339
 
342
- def test_ps_to_h
340
+ #def test_ps_to_h
341
+ # pdef = Ruote.process_definition do
342
+ # error 'nada'
343
+ # end
344
+ # #noisy
345
+ # wfid = @engine.launch(pdef)
346
+ # wait_for(wfid)
347
+ # ps = @engine.process(wfid)
348
+ # es = ps.to_h['errors']
349
+ # e = es.first
350
+ # assert_equal 1, es.size
351
+ # assert_equal 'reply', e['msg']['action']
352
+ # assert_equal wfid, e['msg']['fei']['wfid']
353
+ # assert_equal 8, e.size
354
+ #end
355
+
356
+ def test_error_intercepted
343
357
 
344
358
  pdef = Ruote.process_definition do
345
- error 'nada'
359
+ nada
346
360
  end
347
361
 
348
- #noisy
349
-
350
362
  wfid = @engine.launch(pdef)
351
- wait_for(wfid)
352
-
353
- ps = @engine.process(wfid)
354
363
 
355
- es = ps.to_h['errors']
356
- e = es.first
364
+ r = @engine.wait_for(wfid)
357
365
 
358
- assert_equal 1, es.size
359
- assert_equal 'reply', e['msg']['action']
360
- assert_equal wfid, e['msg']['fei']['wfid']
361
- assert_equal 8, e.size
366
+ assert_equal 'RuntimeError', r['error_class']
367
+ assert_equal "unknown participant or subprocess 'nada'", r['error_message']
368
+ assert_equal Array, r['error_backtrace'].class
362
369
  end
363
370
  end
364
371
 
@@ -80,7 +80,9 @@ class NftSmtpParticipantTest < Test::Unit::TestCase
80
80
  end
81
81
  end
82
82
 
83
- trapfile = Ruote::WIN ? 'ruote_mailtrap.txt' : '/tmp/ruote_mailtrap.txt'
83
+ trapfile = "ruote_mailtrap_#{$$}_#{Time.now.to_f}.txt"
84
+
85
+ trapfile = Ruote::WIN ? trapfile : "/tmp/#{trapfile}"
84
86
  FileUtils.rm_f(trapfile)
85
87
 
86
88
  t = Thread.new do
@@ -108,7 +110,10 @@ class NftSmtpParticipantTest < Test::Unit::TestCase
108
110
  #sleep 0.450
109
111
  wait_for(wfid)
110
112
 
111
- assert_match(/want cat food/, File.read(trapfile))
113
+ trapped = File.read(trapfile)
114
+ FileUtils.rm_f(trapfile)
115
+
116
+ assert_match /want cat food/, trapped
112
117
  assert_nil @engine.process(wfid)
113
118
 
114
119
  t.kill
@@ -30,6 +30,8 @@ class FtParticipantMoreTest < Test::Unit::TestCase
30
30
  end
31
31
  end
32
32
 
33
+ # Reject and re_dispatch are aliases.
34
+ #
33
35
  def test_participant_reject
34
36
 
35
37
  pdef = Ruote.process_definition do
@@ -59,6 +61,8 @@ class FtParticipantMoreTest < Test::Unit::TestCase
59
61
  end
60
62
  end
61
63
 
64
+ # Reject and re_dispatch are aliases.
65
+ #
62
66
  def test_participant_re_dispatch
63
67
 
64
68
  pdef = Ruote.process_definition do
@@ -92,6 +96,11 @@ class FtParticipantMoreTest < Test::Unit::TestCase
92
96
  end
93
97
  end
94
98
 
99
+ # Reject and re_dispatch are aliases.
100
+ #
101
+ # re_dispatch with an :in or an :at parameter makes sure the dispatch is
102
+ # performed once more, but a bit later (:in / :at timepoint).
103
+ #
95
104
  def test_participant_re_dispatch_later
96
105
 
97
106
  pdef = Ruote.process_definition do
@@ -112,6 +121,9 @@ class FtParticipantMoreTest < Test::Unit::TestCase
112
121
  assert t < 2.0, "took more than 1.99 second"
113
122
  end
114
123
 
124
+ # Making sure that when a process gets cancelled, its 'later' re-dispatches
125
+ # are cancelled as well.
126
+ #
115
127
  def test_participant_re_dispatch_later_cancel
116
128
 
117
129
  pdef = Ruote.process_definition do
@@ -146,6 +158,9 @@ class FtParticipantMoreTest < Test::Unit::TestCase
146
158
  end
147
159
  end
148
160
 
161
+ # Stashing lets a stateless participant 'stash' state via put() and get()
162
+ # into the engine.
163
+ #
149
164
  def test_stash
150
165
 
151
166
  BLACKBOARD.clear
@@ -10,7 +10,7 @@ require File.join(File.dirname(__FILE__), 'base')
10
10
  require 'ruote/part/storage_participant'
11
11
 
12
12
 
13
- class FtEngineTest < Test::Unit::TestCase
13
+ class FtWaitForTest < Test::Unit::TestCase
14
14
  include FunctionalBase
15
15
 
16
16
  def test_workitem
@@ -96,5 +96,38 @@ class FtEngineTest < Test::Unit::TestCase
96
96
 
97
97
  assert_equal wfids.sort, @engine.processes.collect { |ps| ps.wfid }.sort
98
98
  end
99
+
100
+ def test_wait_for_multithreaded
101
+
102
+ pdef = Ruote.process_definition { alpha }
103
+
104
+ sp = @engine.register_participant :alpha, Ruote::StorageParticipant
105
+
106
+ #noisy
107
+
108
+ wfid = @engine.launch(pdef)
109
+
110
+ seen = []
111
+
112
+ Thread.new do
113
+ @engine.wait_for(wfid)
114
+ seen << 'this'
115
+ end
116
+ Thread.new do
117
+ @engine.wait_for(wfid)
118
+ seen << 'that'
119
+ end
120
+
121
+ @engine.wait_for(:alpha)
122
+
123
+ sp.reply(sp.first)
124
+
125
+ @engine.wait_for(wfid)
126
+
127
+ sleep 0.100
128
+
129
+ assert_equal %w[ that this ], seen.sort
130
+ assert_equal [], @engine.context.logger.instance_variable_get(:@waiting)
131
+ end
99
132
  end
100
133