weel 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|