weel 1.0.3
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/AUTHORS +2 -0
- data/COPYING +504 -0
- data/FEATURES +20 -0
- data/INSTALL +7 -0
- data/README +4 -0
- data/Rakefile +15 -0
- data/example/SimpleHandlerWrapper.rb +68 -0
- data/example/SimpleWorkflow.rb +15 -0
- data/example/runme.rb +12 -0
- data/lib/weel.rb +749 -0
- data/test/ContinueTest.rb +25 -0
- data/test/TestHandlerWrapper.rb +120 -0
- data/test/TestWorkflow.rb +35 -0
- data/test/basic/tc_choose.rb +82 -0
- data/test/basic/tc_codereplace.rb +38 -0
- data/test/basic/tc_data.rb +32 -0
- data/test/basic/tc_endpoint.rb +40 -0
- data/test/basic/tc_handler.rb +19 -0
- data/test/basic/tc_parallel.rb +115 -0
- data/test/basic/tc_search.rb +37 -0
- data/test/basic/tc_state.rb +17 -0
- data/test/basic/tc_wf_control.rb +68 -0
- data/test/complex/tc_generalsynchonizingmerge_loopsearch.rb +113 -0
- data/test/complex/tc_parallel_stop.rb +32 -0
- data/test/wfp_adv_branching/tc_generalizedjoin.rb +11 -0
- data/test/wfp_adv_branching/tc_generalsynchronizingmerge.rb +45 -0
- data/test/wfp_adv_branching/tc_localsynchronizingmerge.rb +37 -0
- data/test/wfp_adv_branching/tc_multichoice_structuredsynchronizingmerge.rb +47 -0
- data/test/wfp_adv_branching/tc_multimerge.rb +11 -0
- data/test/wfp_adv_branching/tc_structured_discriminator.rb +28 -0
- data/test/wfp_adv_branching/tc_structured_partial_join.rb +41 -0
- data/test/wfp_adv_branching/tc_threadmerge.rb +11 -0
- data/test/wfp_adv_branching/tc_threadsplit.rb +11 -0
- data/test/wfp_basic/tc_exclusivechoice_simplemerge.rb +22 -0
- data/test/wfp_basic/tc_parallelsplit_synchronization.rb +26 -0
- data/test/wfp_basic/tc_sequence.rb +16 -0
- data/test/wfp_iteration/tc_structuredloop.rb +65 -0
- data/test/wfp_state_based/tc_deferredchoice.rb +38 -0
- data/test/wfp_state_based/tc_interleavedparallelrouting.rb +30 -0
- data/weel.gemspec +25 -0
- metadata +127 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
vim ./wfp_state_based/tc_interleavedparallelrouting.rb
|
2
|
+
vim ./wfp_state_based/tc_deferredchoice.rb
|
3
|
+
vim ./wfp_iteration/tc_structuredloop.rb
|
4
|
+
vim ./wfp_adv_branching
|
5
|
+
vim ./wfp_adv_branching/tc_multichoice_structuredsynchronizingmerge.rb
|
6
|
+
vim ./wfp_adv_branching/tc_generalsynchronizingmerge.rb
|
7
|
+
vim ./wfp_adv_branching/tc_localsynchronizingmerge.rb
|
8
|
+
vim ./wfp_adv_branching/tc_threadmerge.rb
|
9
|
+
vim ./wfp_adv_branching/tc_generalizedjoin.rb
|
10
|
+
vim ./wfp_adv_branching/tc_threadsplit.rb
|
11
|
+
vim ./wfp_adv_branching/tc_multimerge.rb
|
12
|
+
vim ./wfp_adv_branching/tc_structured_discriminator.rb
|
13
|
+
vim ./wfp_adv_branching/tc_structured_partial_join.rb
|
14
|
+
vim ./basic/tc_codereplace.rb
|
15
|
+
vim ./basic/tc_data.rb
|
16
|
+
vim ./basic/tc_handler.rb
|
17
|
+
vim ./basic/tc_parallel.rb
|
18
|
+
vim ./basic/tc_search.rb
|
19
|
+
vim ./basic/tc_endpoint.rb
|
20
|
+
vim ./basic/tc_wf_control.rb
|
21
|
+
vim ./basic/tc_choose.rb
|
22
|
+
vim ./basic/tc_state.rb
|
23
|
+
vim ./wfp_basic/tc_exclusivechoice_simplemerge.rb
|
24
|
+
vim ./wfp_basic/tc_sequence.rb
|
25
|
+
vim ./wfp_basic/tc_parallelsplit_synchronization.rb
|
@@ -0,0 +1,120 @@
|
|
1
|
+
class TestHandlerWrapper < WEEL::HandlerWrapperBase
|
2
|
+
def initialize(args,endpoint=nil,position=nil,continue=nil)
|
3
|
+
@__myhandler_stopped = false
|
4
|
+
@__myhandler_position = position
|
5
|
+
@__myhandler_continue = continue
|
6
|
+
@__myhandler_endpoint = endpoint
|
7
|
+
@__myhandler_returnValue = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
# executes a ws-call to the given endpoint with the given parameters. the call
|
11
|
+
# can be executed asynchron, see finished_call & return_value
|
12
|
+
def activity_handle(passthrough, parameters)
|
13
|
+
$long_track << "CALL #{@__myhandler_position}: passthrough=[#{passthrough}], endpoint=[#{@__myhandler_endpoint}], parameters=[#{parameters.inspect}]\n"
|
14
|
+
$short_track << "C#{@__myhandler_position}"
|
15
|
+
|
16
|
+
if @__myhandler_endpoint == 'stop it'
|
17
|
+
raise WEEL::Signal::Stop
|
18
|
+
end
|
19
|
+
if parameters[:call]
|
20
|
+
@t = Thread.new do
|
21
|
+
parameters[:call].call
|
22
|
+
@__myhandler_returnValue = parameters.has_key?(:result) ? parameters[:result] : 'Handler_Dummy_Result'
|
23
|
+
@__myhandler_continue.continue
|
24
|
+
end
|
25
|
+
# give nothing back
|
26
|
+
else
|
27
|
+
@__myhandler_returnValue = parameters.has_key?(:result) ? parameters[:result] : 'Handler_Dummy_Result'
|
28
|
+
@__myhandler_continue.continue
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# returns the result of the last handled call
|
33
|
+
def activity_result_value
|
34
|
+
@__myhandler_returnValue
|
35
|
+
end
|
36
|
+
# Called if the WS-Call should be interrupted. The decision how to deal
|
37
|
+
# with this situation is given to the handler. To provide the possibility
|
38
|
+
# of a continue the Handler will be asked for a passthrough
|
39
|
+
def activity_stop
|
40
|
+
$long_track += "STOPPED #{@__myhandler_position}\n"
|
41
|
+
$short_track << "S#{@__myhandler_position}"
|
42
|
+
@t.exit if @t
|
43
|
+
@__myhandler_stopped = true
|
44
|
+
end
|
45
|
+
# is called from WEEL after stop_call to ask for a passthrough-value that may give
|
46
|
+
# information about how to continue the call. This passthrough-value is given
|
47
|
+
# to activity_handle if the workflow is configured to do so.
|
48
|
+
def activity_passthrough_value
|
49
|
+
"SOME passthrough"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Called if the execution of the actual activity_handle is not necessary anymore
|
53
|
+
# It is definit that the call will not be continued.
|
54
|
+
# At this stage, this is only the case if parallel branches are not needed
|
55
|
+
# anymore to continue the workflow
|
56
|
+
def activity_no_longer_necessary
|
57
|
+
$long_track += "NO_LONGER_NECCESARY #{@__myhandler_position}\n"
|
58
|
+
$short_track << "NLN#{@__myhandler_position}"
|
59
|
+
@t.exit if @t
|
60
|
+
@__myhandler_returnValue = "No longer necessary"
|
61
|
+
@__myhandler_stopped = true
|
62
|
+
end
|
63
|
+
# Is called if a Activity is executed correctly
|
64
|
+
def inform_activity_manipulate
|
65
|
+
$long_track += "MANIPULATE #{@__myhandler_position}\n"
|
66
|
+
$short_track << "M#{@__myhandler_position}"
|
67
|
+
end
|
68
|
+
# Is called if a Activity is executed correctly
|
69
|
+
def inform_activity_done
|
70
|
+
$long_track += "DONE #{@__myhandler_position}\n"
|
71
|
+
$short_track << "D#{@__myhandler_position}"
|
72
|
+
end
|
73
|
+
# Is called if a Activity is executed with an error
|
74
|
+
def inform_activity_failed(err)
|
75
|
+
$long_track += "FAILED #{@__myhandler_position}: #{err}\n"
|
76
|
+
$short_track << "F#{@__myhandler_position}"
|
77
|
+
raise(err)
|
78
|
+
end
|
79
|
+
def inform_syntax_error(err,code)
|
80
|
+
$long_track += "ERROR: Syntax messed with error #{err}\n"
|
81
|
+
$short_track << "E"
|
82
|
+
raise(err)
|
83
|
+
end
|
84
|
+
def inform_state_change(newstate)
|
85
|
+
$long_track += "---> STATE #{newstate}\n"
|
86
|
+
$short_track << "|#{newstate}|"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
module TestMixin #{{{
|
91
|
+
def setup
|
92
|
+
$long_track = ""
|
93
|
+
$short_track = ""
|
94
|
+
@wf = TestWorkflow.new
|
95
|
+
end
|
96
|
+
|
97
|
+
def teardown
|
98
|
+
@wf.stop.join
|
99
|
+
$long_track = ""
|
100
|
+
$short_track = ""
|
101
|
+
end
|
102
|
+
|
103
|
+
def wf_assert(what,cond=true)
|
104
|
+
if cond
|
105
|
+
assert($long_track.include?(what),"Missing \"#{what}\":\n#{$long_track}")
|
106
|
+
else
|
107
|
+
assert(!$long_track.include?(what),"Missing \"#{what}\":\n#{$long_track}")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
def wf_sassert(what,cond=true)
|
111
|
+
if cond
|
112
|
+
assert($short_track.include?(what),"#{$short_track}\nNot Present \"#{what}\":\n#{$long_track}")
|
113
|
+
else
|
114
|
+
assert(!$short_track.include?(what),"#{$short_track}\nNot Present \"#{what}\":\n#{$long_track}")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
def wf_rsassert(pat='')
|
118
|
+
assert($short_track =~ /#{pat}/,"Somehow executed different #{$short_track} should be '#{pat}'")
|
119
|
+
end
|
120
|
+
end #}}}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../lib/weel')
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/TestHandlerWrapper')
|
3
|
+
|
4
|
+
class TestWorkflow < WEEL
|
5
|
+
handlerwrapper TestHandlerWrapper
|
6
|
+
|
7
|
+
endpoint :endpoint1 => 'http://www.heise.de'
|
8
|
+
endpoint :stop => 'stop it'
|
9
|
+
data :x => 'begin_'
|
10
|
+
|
11
|
+
control flow do
|
12
|
+
activity :a1_1, :call, :endpoint1 do |result|
|
13
|
+
data.x += "#{result}"
|
14
|
+
end
|
15
|
+
parallel :wait => 2 do
|
16
|
+
parallel_branch do
|
17
|
+
activity :a2_1_1, :call, :endpoint1
|
18
|
+
end
|
19
|
+
parallel_branch do
|
20
|
+
activity :a2_2_1, :call, :endpoint1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
activity :a3, :manipulate do
|
24
|
+
data.x += '_end'
|
25
|
+
end
|
26
|
+
choose do
|
27
|
+
alternative data.x != nil do
|
28
|
+
activity :a4a, :call, :endpoint1
|
29
|
+
end
|
30
|
+
otherwise do
|
31
|
+
activity :a4b, :call, :endpoint1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestChoose < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_choose_alternative
|
8
|
+
@wf.description do
|
9
|
+
choose do
|
10
|
+
alternative true do
|
11
|
+
activity :a_1, :call, :endpoint1
|
12
|
+
end
|
13
|
+
alternative false do
|
14
|
+
activity :a_2, :call, :endpoint1
|
15
|
+
end
|
16
|
+
otherwise do
|
17
|
+
activity :a_3, :call, :endpoint1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
@wf.start.join
|
22
|
+
wf_assert("CALL a_1: passthrough=[], endpoint=[http://www.heise.de], parameters=[{}]")
|
23
|
+
wf_assert("CALL a_2:",false)
|
24
|
+
wf_assert("CALL a_3:",false)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_choose_otherwise
|
28
|
+
@wf.description do
|
29
|
+
choose do
|
30
|
+
alternative false do
|
31
|
+
activity :a_1, :call, :endpoint1
|
32
|
+
end
|
33
|
+
otherwise do
|
34
|
+
activity :a_2, :call, :endpoint1
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
@wf.start.join
|
39
|
+
wf_assert("CALL a_2: passthrough=[], endpoint=[http://www.heise.de], parameters=[{}]")
|
40
|
+
wf_assert("CALL a_1:",false)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_choose_nested
|
44
|
+
@wf.description do
|
45
|
+
choose do
|
46
|
+
alternative true do
|
47
|
+
choose do
|
48
|
+
alternative false do
|
49
|
+
activity :a_1_1, :call, :endpoint1
|
50
|
+
end
|
51
|
+
alternative true do
|
52
|
+
choose do
|
53
|
+
alternative false do
|
54
|
+
activity :a_1_1_1, :call, :endpoint1
|
55
|
+
end
|
56
|
+
otherwise do
|
57
|
+
activity :a_1_1_2, :call, :endpoint1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
otherwise do
|
62
|
+
activity :a_1_3, :call, :endpoint1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
otherwise do
|
67
|
+
activity :a_2, :call, :endpoint1
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
@wf.start.join
|
72
|
+
wf_assert("CALL a_1_1_2: passthrough=[], endpoint=[http://www.heise.de], parameters=[{}]",true)
|
73
|
+
wf_assert("CALL a_1_1:",false)
|
74
|
+
wf_assert("CALL a_1_1_1:",false)
|
75
|
+
wf_assert("CALL a_1_3:",false)
|
76
|
+
wf_assert("CALL a_2:",false)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_choose_searchmode
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestCodeReplace < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_replace
|
8
|
+
@wf.description do
|
9
|
+
activity :a_test_1_1, :call, :endpoint1
|
10
|
+
activity :a_test_1_2, :call, :endpoint1
|
11
|
+
activity :a_test_1_3, :call, :endpoint1
|
12
|
+
end
|
13
|
+
@wf.search WEEL::Position.new(:a_test_1_1, :at)
|
14
|
+
@wf.start.join
|
15
|
+
wf_assert("CALL a_test_1_1:")
|
16
|
+
wf_assert("CALL a_test_1_2:")
|
17
|
+
wf_assert("CALL a_test_1_3:")
|
18
|
+
wf_sassert("|running|Ca_test_1_1Da_test_1_1Ca_test_1_2Da_test_1_2Ca_test_1_3Da_test_1_3|finished|")
|
19
|
+
end
|
20
|
+
#def test_wfdescription_string
|
21
|
+
# ret = @wf.description "activity :b_test_1_1, :call, :endpoint1"
|
22
|
+
# @wf.search WEEL::Position.new(:b_test_1_1, :at)
|
23
|
+
# @wf.start.join
|
24
|
+
# wf_assert("DONE b_test_1_1")
|
25
|
+
# wf_sassert("|running|Cb_test_1_1Db_test_1_1|finished|")
|
26
|
+
#end
|
27
|
+
def test_wfdescription_block
|
28
|
+
ret = @wf.description do
|
29
|
+
activity :c_test_1_1, :call, :endpoint1
|
30
|
+
activity :c_test_1_2, :call, :endpoint1
|
31
|
+
end
|
32
|
+
|
33
|
+
assert(ret.class == Proc, "wf_description should be nil => not available. codeblock was given!")
|
34
|
+
@wf.search WEEL::Position.new(:c_test_1_2, :at)
|
35
|
+
@wf.start.join
|
36
|
+
wf_sassert("|running|Cc_test_1_2Dc_test_1_2|finished|")
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestData < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_check_data
|
8
|
+
data = @wf.data
|
9
|
+
assert(data.is_a?(Hash), "data is not a Hash")
|
10
|
+
assert(data.size == 1, "data has not exactly 1 element, it has #{data.size}")
|
11
|
+
assert(data.keys[0] == :x, "data.keys[0] has not the correct value [#{data.keys[0]}]")
|
12
|
+
assert(data[:x] == "begin_", "data[:x] has not the correct value")
|
13
|
+
end
|
14
|
+
def test_set_data_variable
|
15
|
+
@wf.data[:a] = "test1"
|
16
|
+
data = @wf.data
|
17
|
+
assert(data.is_a?(Hash), "data is not a Hash")
|
18
|
+
assert(data.keys.include?(:a), "data has no key :a")
|
19
|
+
assert(data[:a] == "test1", "data[:a] has not the correct value [#{data[:x]}]")
|
20
|
+
end
|
21
|
+
def test_set_data
|
22
|
+
@wf.data[:x] = "test1"
|
23
|
+
@wf.data[:y] = "test2"
|
24
|
+
data = @wf.data
|
25
|
+
assert(data.is_a?(Hash), "data is not a Hash")
|
26
|
+
assert(data.size == 2, "data has not exactly 1 element, it has #{data.size}")
|
27
|
+
assert(data.keys.include?(:x), "data has no key x")
|
28
|
+
assert(data.keys.include?(:y), "data has no key y")
|
29
|
+
assert(data[:x] == "test1", "data[:x] has not the correct value [#{data[:x]}]")
|
30
|
+
assert(data[:y] == "test2", "data[:y] has not the correct value [#{data[:y]}]")
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestEndpoint < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_check_endpoint
|
8
|
+
ep1 = @wf.endpoints[:endpoint1]
|
9
|
+
assert(ep1.is_a?(String), "Endpoint1 is no string but should be")
|
10
|
+
assert(ep1 == "http://www.heise.de", "Endpoint1 has wrong value [#{ep1}]")
|
11
|
+
end
|
12
|
+
def test_create_endpoint
|
13
|
+
@wf.endpoint :endpoint2 => "http://www.test.at"
|
14
|
+
ep2 = @wf.endpoints[:endpoint2]
|
15
|
+
assert(ep2.is_a?(String), "Endpoint1 is no string but should be")
|
16
|
+
assert(ep2 == "http://www.test.at", "Endpoint1 has wrong value [#{ep2}]")
|
17
|
+
end
|
18
|
+
def test_change_endpoint
|
19
|
+
@wf.endpoint :endpoint1 => "http://www.newpoint.com"
|
20
|
+
ep1 = @wf.endpoints[:endpoint1]
|
21
|
+
assert(ep1.is_a?(String), "Endpoint1 is no string but should be")
|
22
|
+
assert(ep1 == "http://www.newpoint.com", "Endpoint1 has wrong value [#{ep1}]")
|
23
|
+
end
|
24
|
+
def test_change_endpoint2
|
25
|
+
@wf.endpoints[:endpoint1] = "http://www.newpoint2.com"
|
26
|
+
ep1 = @wf.endpoints[:endpoint1]
|
27
|
+
assert(ep1.is_a?(String), "Endpoint1 is no string but should be")
|
28
|
+
assert(ep1 == "http://www.newpoint2.com", "Endpoint1 has wrong value [#{ep1}]")
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_endpoints
|
32
|
+
@wf.endpoint :endpoint2 => "http://www.test.at" # asure that there is endpoint1 & endpoint2
|
33
|
+
@wf.endpoints[:endpoint1]="http://www.test2.com" # asure that ep1 has original value
|
34
|
+
eps = @wf.endpoints
|
35
|
+
assert(eps.is_a?(Hash), "Endpoints should result a Hash but returns a #{eps.class}")
|
36
|
+
assert(eps.size == 3, "Endpoints should have two entries: #{eps.inspect}")
|
37
|
+
assert(eps[:endpoint1] == "http://www.test2.com", "Endpoint 1 has wrong value or does not exist: #{eps.inspect}")
|
38
|
+
assert(eps[:endpoint2] == "http://www.test.at", "Endpoint 2 has wrong value or does not exist: #{eps.inspect}")
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestCaseHandler < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_handler
|
8
|
+
assert_raise RuntimeError do
|
9
|
+
@wf.handlerwrapper = String
|
10
|
+
end
|
11
|
+
assert_nothing_raised do
|
12
|
+
@wf.handlerwrapper = TestHandlerWrapper
|
13
|
+
end
|
14
|
+
end
|
15
|
+
def test_handlerargs
|
16
|
+
@wf.handlerwrapper_args = ["1", "2"]
|
17
|
+
assert(@wf.handlerwrapper_args.is_a?(Array), "Handler arguments is not an array, it is a #{@wf.handlerwrapper_args.inspect}")
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestParallel < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_parallel_simple
|
8
|
+
@wf.description do
|
9
|
+
parallel do
|
10
|
+
parallel_branch do
|
11
|
+
activity :a_1, :call, :endpoint1, :call => Proc.new{ sleep 0.5 }
|
12
|
+
end
|
13
|
+
parallel_branch do
|
14
|
+
activity :a_2, :call, :endpoint1, :call => Proc.new{ sleep 0.5 }
|
15
|
+
end
|
16
|
+
parallel_branch do
|
17
|
+
activity :a_3, :call, :endpoint1, :call => Proc.new{ sleep 0.5 }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
wf = @wf.start
|
22
|
+
sleep(0.25)
|
23
|
+
wf_assert("CALL a_1:")
|
24
|
+
wf_assert("CALL a_2:")
|
25
|
+
wf_assert("CALL a_3:")
|
26
|
+
wf.join
|
27
|
+
wf_assert("DONE a_1")
|
28
|
+
wf_assert("DONE a_2")
|
29
|
+
wf_assert("DONE a_3")
|
30
|
+
end
|
31
|
+
def test_parallel_wait
|
32
|
+
@wf.description do
|
33
|
+
parallel :wait do
|
34
|
+
parallel_branch do
|
35
|
+
activity :a_1, :call, :endpoint1
|
36
|
+
end
|
37
|
+
parallel_branch do
|
38
|
+
activity :a_2, :call, :endpoint1, :call => Proc.new{ sleep 0.5 }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
activity :a_3, :call, :endpoint1
|
42
|
+
end
|
43
|
+
@wf.start.join
|
44
|
+
wf_assert('CALL a_1')
|
45
|
+
wf_assert('DONE a_1')
|
46
|
+
wf_assert('CALL a_2')
|
47
|
+
wf_sassert('Da_2Ca_3Da_3|finished|')
|
48
|
+
end
|
49
|
+
def test_parallel_nowait
|
50
|
+
@wf.description do
|
51
|
+
parallel :wait => 1 do
|
52
|
+
parallel_branch do
|
53
|
+
activity :a_1, :call, :endpoint1
|
54
|
+
end
|
55
|
+
parallel_branch do
|
56
|
+
activity :a_2, :call, :endpoint1, :call => Proc.new{ sleep 8.5 }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
activity :a_3, :call, :endpoint1
|
60
|
+
end
|
61
|
+
@wf.start.join
|
62
|
+
wf_assert('CALL a_1')
|
63
|
+
wf_assert('CALL a_2')
|
64
|
+
wf_sassert('NLNa_2Ca_3Da_3|finished|')
|
65
|
+
end
|
66
|
+
def test_parallel_no_longer_necessary
|
67
|
+
@wf.description do
|
68
|
+
parallel :wait => 1 do
|
69
|
+
parallel_branch do
|
70
|
+
activity :a_1, :call, :endpoint1
|
71
|
+
end
|
72
|
+
parallel_branch do
|
73
|
+
activity :a_2, :call, :endpoint1, :call => Proc.new{ sleep 0.5 }
|
74
|
+
activity :a_2_2, :call, :endpoint1
|
75
|
+
end
|
76
|
+
end
|
77
|
+
activity :a_3, :call, :endpoint1
|
78
|
+
end
|
79
|
+
@wf.start.join
|
80
|
+
wf_assert('CALL a_1')
|
81
|
+
wf_assert('CALL a_2')
|
82
|
+
wf_sassert('NLNa_2Ca_3Da_3|finished|')
|
83
|
+
end
|
84
|
+
def test_parallel_nested
|
85
|
+
# |- :a_1
|
86
|
+
# |-|-|- :a_2_1_1
|
87
|
+
# |-|-|- :a_2_1_2
|
88
|
+
# |-|-|- => :a_2_1_3
|
89
|
+
# |-|- :a_2_2
|
90
|
+
# |-|- :a_2_3
|
91
|
+
# |- => :a_3
|
92
|
+
@wf.description do
|
93
|
+
parallel :wait do
|
94
|
+
parallel_branch do activity :a_1, :call, :endpoint1 end
|
95
|
+
parallel_branch do
|
96
|
+
parallel :wait do
|
97
|
+
parallel_branch do
|
98
|
+
parallel :wait do
|
99
|
+
parallel_branch do activity :a_2_1_1, :call, :endpoint1, :call => Proc.new {sleep 0.2} end
|
100
|
+
parallel_branch do activity :a_2_1_2, :call, :endpoint1, :call => Proc.new {sleep 0.4} end
|
101
|
+
end
|
102
|
+
activity :a_2_1_3, :call, :endpoint1, :call => Proc.new {sleep 0.8}
|
103
|
+
end
|
104
|
+
parallel_branch do activity :a_2_2, :call, :endpoint1, :call => Proc.new {sleep 0.8} end
|
105
|
+
parallel_branch do activity :a_2_3, :call, :endpoint1, :call => Proc.new {sleep 1.0} end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
activity :a_3, :call, :endpoint1
|
110
|
+
end
|
111
|
+
@wf.start.join
|
112
|
+
nump = $long_track.split("\n").delete_if{|e| !(e =~ /^(DONE)/)}
|
113
|
+
assert(nump == ["DONE a_1", "DONE a_2_1_1", "DONE a_2_1_2", "DONE a_2_2", "DONE a_2_3", "DONE a_2_1_3", "DONE a_3"], "not in the right order, sorry")
|
114
|
+
end
|
115
|
+
end
|