ruote 2.1.10 → 2.1.11
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.
- data/CHANGELOG.txt +51 -1
- data/CREDITS.txt +9 -0
- data/README.rdoc +13 -0
- data/Rakefile +50 -21
- data/TODO.txt +42 -4
- data/examples/pong.rb +37 -0
- data/lib/ruote/context.rb +19 -9
- data/lib/ruote/engine/process_error.rb +10 -0
- data/lib/ruote/engine/process_status.rb +140 -41
- data/lib/ruote/engine.rb +394 -27
- data/lib/ruote/exp/command.rb +2 -0
- data/lib/ruote/exp/fe_concurrence.rb +8 -0
- data/lib/ruote/exp/fe_concurrent_iterator.rb +3 -0
- data/lib/ruote/exp/fe_cursor.rb +48 -4
- data/lib/ruote/exp/fe_iterator.rb +40 -0
- data/lib/ruote/exp/fe_listen.rb +3 -3
- data/lib/ruote/exp/fe_participant.rb +30 -12
- data/lib/ruote/exp/fe_ref.rb +126 -0
- data/lib/ruote/exp/fe_subprocess.rb +20 -1
- data/lib/ruote/exp/fe_wait.rb +4 -1
- data/lib/ruote/exp/fe_when.rb +7 -10
- data/lib/ruote/exp/flowexpression.rb +23 -12
- data/lib/ruote/exp/ro_attributes.rb +5 -8
- data/lib/ruote/exp/ro_variables.rb +4 -2
- data/lib/ruote/fei.rb +2 -0
- data/lib/ruote/id/wfid_generator.rb +1 -1
- data/lib/ruote/log/pretty.rb +137 -0
- data/lib/ruote/log/storage_history.rb +1 -1
- data/lib/ruote/log/test_logger.rb +51 -126
- data/lib/ruote/log/wait_logger.rb +8 -13
- data/lib/ruote/parser/ruby_dsl.rb +4 -4
- data/lib/ruote/parser.rb +2 -2
- data/lib/ruote/part/block_participant.rb +1 -1
- data/lib/ruote/part/engine_participant.rb +1 -1
- data/lib/ruote/part/storage_participant.rb +27 -28
- data/lib/ruote/part/template.rb +8 -3
- data/lib/ruote/receiver/base.rb +24 -6
- data/lib/ruote/storage/base.rb +76 -11
- data/lib/ruote/storage/fs_storage.rb +10 -0
- data/lib/ruote/storage/hash_storage.rb +19 -8
- data/lib/ruote/{part → svc}/dispatch_pool.rb +3 -2
- data/lib/ruote/svc/dollar_sub.rb +265 -0
- data/lib/ruote/{error_handler.rb → svc/error_handler.rb} +6 -1
- data/lib/ruote/{exp → svc}/expression_map.rb +31 -37
- data/lib/ruote/{part → svc}/participant_list.rb +165 -25
- data/lib/ruote/{evt → svc}/tracker.rb +0 -0
- data/lib/ruote/{util → svc}/treechecker.rb +0 -0
- data/lib/ruote/util/look.rb +4 -1
- data/lib/ruote/util/ometa.rb +21 -5
- data/lib/ruote/{subprocess.rb → util/subprocess.rb} +0 -0
- data/lib/ruote/version.rb +1 -1
- data/lib/ruote/worker.rb +29 -69
- data/lib/ruote/workitem.rb +28 -1
- data/ruote.gemspec +26 -22
- data/test/functional/base.rb +3 -0
- data/test/functional/concurrent_base.rb +1 -0
- data/test/functional/crunner.sh +1 -1
- data/test/functional/ct_0_concurrence.rb +6 -0
- data/test/functional/ct_1_iterator.rb +3 -0
- data/test/functional/ct_2_cancel.rb +5 -0
- data/test/functional/eft_13_iterator.rb +39 -4
- data/test/functional/eft_14_cursor.rb +39 -0
- data/test/functional/eft_30_ref.rb +140 -0
- data/test/functional/eft_3_participant.rb +25 -23
- data/test/functional/ft_10_dollar.rb +17 -1
- data/test/functional/ft_14_re_apply.rb +76 -0
- data/test/functional/ft_1_process_status.rb +170 -29
- data/test/functional/ft_20_storage_participant.rb +14 -0
- data/test/functional/ft_24_block_participants.rb +1 -1
- data/test/functional/ft_26_participant_timeout.rb +93 -0
- data/test/functional/ft_2_errors.rb +24 -17
- data/test/functional/ft_30_smtp_participant.rb +7 -2
- data/test/functional/ft_38_participant_more.rb +15 -0
- data/test/functional/ft_39_wait_for.rb +34 -1
- data/test/functional/ft_3_participant_registration.rb +270 -2
- data/test/functional/ft_40_wait_logger.rb +61 -0
- data/test/functional/ft_42_storage_copy.rb +4 -0
- data/test/functional/{ft_40_participant_on_reply.rb → ft_43_participant_on_reply.rb} +17 -0
- data/test/functional/ft_44_var_participant.rb +35 -0
- data/test/functional/ft_45_participant_accept.rb +64 -0
- data/test/functional/ft_46_launch_single.rb +49 -0
- data/test/functional/ft_5_on_error.rb +39 -1
- data/test/functional/storage_helper.rb +7 -1
- data/test/test_helper.rb +1 -1
- data/test/unit/storage.rb +105 -32
- data/test/unit/ut_0_ruby_parser.rb +31 -1
- data/test/unit/ut_16_parser.rb +20 -0
- data/test/unit/ut_19_part_template.rb +11 -1
- data/test/unit/ut_20_composite_storage.rb +1 -1
- data/test/unit/ut_4_expmap.rb +1 -1
- data/test/unit/ut_6_condition.rb +2 -2
- metadata +112 -74
- data/lib/ruote/exp/raw.rb +0 -44
- 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/
|
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(
|
94
|
-
wait_for(
|
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
|
77
|
+
assert_equal wfid, errs.first.wfid
|
101
78
|
|
102
|
-
err = @engine.errors(
|
79
|
+
err = @engine.errors(wfid)
|
103
80
|
|
104
81
|
assert_equal 1, err.size
|
105
|
-
assert_equal wfid, err.first
|
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
|
|
@@ -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::
|
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
|
-
|
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
|
-
|
356
|
-
e = es.first
|
364
|
+
r = @engine.wait_for(wfid)
|
357
365
|
|
358
|
-
assert_equal
|
359
|
-
assert_equal '
|
360
|
-
assert_equal
|
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 =
|
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
|
-
|
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
|
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
|
|