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,37 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestSearch < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_search_impact_single
|
8
|
+
@wf.description do
|
9
|
+
activity :a1_1, :call, :endpoint1
|
10
|
+
activity :a1_2, :call, :endpoint1
|
11
|
+
activity :a1_3, :call, :endpoint1
|
12
|
+
end
|
13
|
+
@wf.search WEEL::Position.new(:a1_2, :at)
|
14
|
+
@wf.start.join
|
15
|
+
wf_sassert("|running|Ca1_2Da1_2Ca1_3Da1_3|finished|")
|
16
|
+
end
|
17
|
+
def test_search_impact_dual
|
18
|
+
@wf.description do
|
19
|
+
activity :a1, :call, :endpoint1
|
20
|
+
parallel do
|
21
|
+
parallel_branch do
|
22
|
+
activity :a2_1, :call, :endpoint1
|
23
|
+
end
|
24
|
+
parallel_branch do
|
25
|
+
activity :a2_2, :call, :endpoint1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
activity :a3, :call, :endpoint1
|
29
|
+
end
|
30
|
+
@wf.search [WEEL::Position.new(:a2_1, :at), WEEL::Position.new(:a2_2, :at)]
|
31
|
+
@wf.start.join
|
32
|
+
wf_assert("DONE a1",false)
|
33
|
+
wf_assert("DONE a2_1",true)
|
34
|
+
wf_assert("DONE a2_2",true)
|
35
|
+
wf_assert("DONE a3",true)
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestState < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_check_state
|
8
|
+
s = @wf.state
|
9
|
+
assert(s.is_a?(Symbol), "state is not a symbol")
|
10
|
+
assert(s == :ready, "state is not set to :ready, it is #{s}")
|
11
|
+
end
|
12
|
+
def test_check_stop_state
|
13
|
+
@wf.start
|
14
|
+
@wf.stop.join
|
15
|
+
assert(@wf.state == :stopped || @wf.state == :finished, "state is not set to :stopped after workflow being stopped, it is #{@wf.state}")
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestWorkflowControl < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_runthrough
|
8
|
+
@wf.start.join
|
9
|
+
wf_assert("DONE a1_1")
|
10
|
+
wf_assert("CALL a2_1_1:")
|
11
|
+
wf_assert("CALL a2_2_1:")
|
12
|
+
wf_assert("DONE a2_1_1")
|
13
|
+
wf_assert("DONE a2_2_1")
|
14
|
+
wf_assert("DONE a3")
|
15
|
+
wf_assert("DONE a4a")
|
16
|
+
assert(@wf.state == :finished, "Stopped workflow has wrong state, #{@wf.state} instead of :stopped")
|
17
|
+
assert(@wf.positions.is_a?(Array) && @wf.positions.empty?, "@wf.positions has wrong type, should be an empty array, it is: #{@wf.positions.inspect}")
|
18
|
+
assert(@wf.data[:x] == "begin_Handler_Dummy_Result_end", "Ending environment not correct, see result=#{@wf.data[:x].inspect}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_stop
|
22
|
+
@wf.description do
|
23
|
+
activity :a_test_1_1, :call, :endpoint1
|
24
|
+
activity :a_test_1_2, :call, :endpoint1, :call => Proc.new{ sleep 0.5 }
|
25
|
+
activity :a_test_1_3, :call, :endpoint1
|
26
|
+
end
|
27
|
+
@wf.search WEEL::Position.new(:a_test_1_1, :at)
|
28
|
+
wf = @wf.start
|
29
|
+
sleep(0.2)
|
30
|
+
@wf.stop.join
|
31
|
+
wf.join
|
32
|
+
wf_assert("DONE a_test_1_1")
|
33
|
+
wf_assert("STOPPED a_test_1_2")
|
34
|
+
wf_assert("DONE a_test_1_2",false)
|
35
|
+
wf_assert("CALL a_test_1_2:")
|
36
|
+
assert(@wf.state == :stopped, "Stopped workflow has wrong state, #{@wf.state} instead of :stopped")
|
37
|
+
assert(@wf.positions.is_a?(Array), "@wf.positions has wrong type, should be an array, it is: #{@wf.positions.inspect}")
|
38
|
+
assert(@wf.positions[0].position == :a_test_1_2, "Stop-position has wrong value: #{@wf.positions[0].position} instead of :a_test_2_1")
|
39
|
+
assert(@wf.positions[0].detail == :at, "Stop-Position is not :at")
|
40
|
+
end
|
41
|
+
def test_continue
|
42
|
+
@wf.description do
|
43
|
+
activity :a_test_1_1, :call, :endpoint1
|
44
|
+
activity :a_test_1_2, :call, :endpoint1, :call => Proc.new{ sleep 0.5 }
|
45
|
+
activity :a_test_1_3, :call, :endpoint1
|
46
|
+
end
|
47
|
+
@wf.start
|
48
|
+
sleep(0.2)
|
49
|
+
@wf.stop.join
|
50
|
+
|
51
|
+
@wf.search @wf.positions
|
52
|
+
|
53
|
+
@wf.start.join
|
54
|
+
wf_sassert('|running|Ca_test_1_1Da_test_1_1Ca_test_1_2|stopping|Sa_test_1_2|stopped||running|Ca_test_1_2Da_test_1_2Ca_test_1_3Da_test_1_3|finished|')
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_continue_after
|
58
|
+
@wf.description do
|
59
|
+
activity :c_test_1_1, :call, :endpoint1
|
60
|
+
activity :c_test_1_2, :call, :endpoint1
|
61
|
+
activity :c_test_1_3, :call, :endpoint1
|
62
|
+
end
|
63
|
+
@wf.search [WEEL::Position.new(:c_test_1_1, :after)]
|
64
|
+
@wf.start.join
|
65
|
+
|
66
|
+
wf_sassert('|running|Cc_test_1_2Dc_test_1_2Cc_test_1_3Dc_test_1_3|finished|')
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestGeneralsynchonizingmergeLoopsearch < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_coopis
|
8
|
+
@wf.data[:hotels] = []
|
9
|
+
@wf.data[:airline] = ''
|
10
|
+
@wf.data[:costs] = 0
|
11
|
+
@wf.data[:persons] = 3
|
12
|
+
@wf.description do
|
13
|
+
activity :a1, :call, :endpoint1 do
|
14
|
+
data.airline = 'Aeroflot'
|
15
|
+
data.costs += 101
|
16
|
+
status.update 1, 'Hotel'
|
17
|
+
end
|
18
|
+
parallel do
|
19
|
+
loop pre_test{data.persons > 0} do
|
20
|
+
parallel_branch data.persons do |p|
|
21
|
+
activity :a2, :call, :endpoint1 do
|
22
|
+
data.hotels << 'Rathaus'
|
23
|
+
data.costs += 200
|
24
|
+
end
|
25
|
+
end
|
26
|
+
activity :a3, :manipulate do
|
27
|
+
data.persons -= 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
choose do
|
32
|
+
alternative data.costs > 400 do
|
33
|
+
activity :a4, :call, :endpoint1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
@wf.start.join
|
38
|
+
|
39
|
+
wf_rsassert('\|running\|Ca1Ma1Da1Ma3Da3Ma3Da3Ma3Da3Ca2.*?Ca2.*?Ca2.*Da2Ca4Da4\|finished\|')
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_coopis_searchmode1
|
43
|
+
@wf.data[:hotels] = ['Marriott']
|
44
|
+
@wf.data[:airline] = 'Ana'
|
45
|
+
@wf.data[:costs] = 802
|
46
|
+
@wf.data[:persons] = 2
|
47
|
+
@wf.description do
|
48
|
+
activity :a1, :call, :endpoint1 do
|
49
|
+
data.airline = 'Aeroflot'
|
50
|
+
data.costs += 101
|
51
|
+
status.update 1, 'Hotel'
|
52
|
+
end
|
53
|
+
parallel do
|
54
|
+
loop pre_test{data.persons > 0} do
|
55
|
+
parallel_branch data.persons do |p|
|
56
|
+
activity :a2, :call, :endpoint1 do
|
57
|
+
data.hotels << 'Rathaus'
|
58
|
+
data.costs += 200
|
59
|
+
end
|
60
|
+
end
|
61
|
+
activity :a3, :manipulate do
|
62
|
+
data.persons -= 1
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
choose do
|
67
|
+
alternative data.costs > 700 do
|
68
|
+
activity :a4, :call, :endpoint1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
@wf.search [WEEL::Position.new(:a3, :at)]
|
73
|
+
@wf.start.join
|
74
|
+
|
75
|
+
wf_rsassert('\|running\|Ma3Da3Ma3Da3Ca2.*?Ca2.*Da2Ca4Da4\|finished\|')
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_coopis_searchmode2
|
79
|
+
@wf.data[:hotels] = ['Marriott']
|
80
|
+
@wf.data[:airline] = 'Ana'
|
81
|
+
@wf.data[:costs] = 802
|
82
|
+
@wf.data[:persons] = 2
|
83
|
+
@wf.description do
|
84
|
+
activity :a1, :call, :endpoint1 do
|
85
|
+
data.airline = 'Aeroflot'
|
86
|
+
data.costs += 101
|
87
|
+
status.update 1, 'Hotel'
|
88
|
+
end
|
89
|
+
parallel do
|
90
|
+
loop pre_test{data.persons > 0} do
|
91
|
+
parallel_branch data.persons do |p|
|
92
|
+
activity :a2, :call, :endpoint1 do
|
93
|
+
data.hotels << 'Rathaus'
|
94
|
+
data.costs += 200
|
95
|
+
end
|
96
|
+
end
|
97
|
+
activity :a3, :manipulate do
|
98
|
+
data.persons -= 1
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
choose do
|
103
|
+
alternative data.costs > 700 do
|
104
|
+
activity :a4, :call, :endpoint1
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
@wf.search [WEEL::Position.new(:a2, :at)]
|
109
|
+
@wf.start.join
|
110
|
+
|
111
|
+
wf_rsassert('\|running\|Ca2Ma2Da2Ca4Da4\|finished\|')
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestParallelStop < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_coopis
|
8
|
+
@wf.data[:hotels] = []
|
9
|
+
@wf.data[:costs] = 0
|
10
|
+
@wf.description do
|
11
|
+
parallel do
|
12
|
+
parallel_branch do
|
13
|
+
activity :a1, :call, :endpoint1 do
|
14
|
+
data.hotels << 'Rathaus'
|
15
|
+
data.costs += 200
|
16
|
+
end
|
17
|
+
activity :a3, :call, :stop
|
18
|
+
end
|
19
|
+
parallel_branch do
|
20
|
+
activity :a2, :call, :endpoint2 do
|
21
|
+
data.hotels << 'Graf Stadion'
|
22
|
+
data.costs += 200
|
23
|
+
end
|
24
|
+
activity :a4, :call, :stop
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@wf.start.join
|
29
|
+
|
30
|
+
wf_rsassert('\|stopped\|')
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestWFPLocalSynchronizingMerge < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_localsyncmerge
|
8
|
+
@wf.data[:cont] = true
|
9
|
+
@wf.description do
|
10
|
+
parallel do
|
11
|
+
parallel_branch do
|
12
|
+
activity :a1_1, :call, :endpoint1, :call => Proc.new{sleep 0.2}
|
13
|
+
end
|
14
|
+
parallel_branch do
|
15
|
+
activity :a1_2, :call, :endpoint1, :call => Proc.new{sleep 0.4}
|
16
|
+
end
|
17
|
+
choose do
|
18
|
+
alternative(true) do
|
19
|
+
loop post_test{puts data.break; data.break} do
|
20
|
+
parallel_branch do
|
21
|
+
activity :a2_1, :call, :endpoint1
|
22
|
+
end
|
23
|
+
activity(:a2_decide, :call, :endpoint1, :result => false) do |e|
|
24
|
+
data.break = e
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
otherwise do
|
29
|
+
activity :a2_2, :call, :endpoint1, :call => Proc.new{sleep 0.1}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
activity :a3, :call, :endpoint1
|
34
|
+
end
|
35
|
+
@wf.start.join
|
36
|
+
wf_sassert('|running|Ca2_decideDa2_decide')
|
37
|
+
wf_assert('CALL a1_1:')
|
38
|
+
wf_assert('CALL a1_2:')
|
39
|
+
wf_assert('CALL a2_1:')
|
40
|
+
wf_assert('DONE a1_1')
|
41
|
+
wf_assert('DONE a1_2')
|
42
|
+
wf_assert('DONE a2_1')
|
43
|
+
wf_sassert('Ca3Da3|finished|')
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestWFPLocalSynchronizingMerge < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_localsyncmerge
|
8
|
+
@wf.description do
|
9
|
+
parallel do
|
10
|
+
parallel_branch do
|
11
|
+
activity :a1_1, :call, :endpoint1, :call => Proc.new{sleep 0.2}
|
12
|
+
end
|
13
|
+
parallel_branch do
|
14
|
+
activity :a1_2, :call, :endpoint1, :call => Proc.new{sleep 0.4}
|
15
|
+
end
|
16
|
+
choose do
|
17
|
+
alternative(false) do
|
18
|
+
parallel_branch do
|
19
|
+
activity :a2_1, :call, :endpoint1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
otherwise do
|
23
|
+
activity :a2_2, :call, :endpoint1, :call => Proc.new{sleep 0.1}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
activity :a3, :call, :endpoint1
|
28
|
+
end
|
29
|
+
@wf.start.join
|
30
|
+
wf_sassert('|running|Ca2_2Da2_2')
|
31
|
+
wf_assert('CALL a1_1:')
|
32
|
+
wf_assert('CALL a1_2:')
|
33
|
+
wf_assert('DONE a1_1')
|
34
|
+
wf_assert('DONE a1_2')
|
35
|
+
wf_sassert('Ca3Da3|finished|')
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
class TestWFPMultiChoice < Test::Unit::TestCase
|
5
|
+
include TestMixin
|
6
|
+
|
7
|
+
def test_multichoice_chained
|
8
|
+
@wf.data :x => 1
|
9
|
+
@wf.description do
|
10
|
+
choose do
|
11
|
+
alternative(data.x == 1) do
|
12
|
+
activity :a1_1, :call, :endpoint1
|
13
|
+
end
|
14
|
+
alternative(data.x > 0) do
|
15
|
+
activity :a1_2, :call, :endpoint1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
activity :a2, :call, :endpoint1
|
19
|
+
end
|
20
|
+
@wf.start.join
|
21
|
+
wf_sassert('|running|Ca1_1Da1_1Ca1_2Da1_2Ca2Da2|finished|')
|
22
|
+
end
|
23
|
+
def test_multichoice_parallel
|
24
|
+
@wf.data :x => 1
|
25
|
+
@wf.description do
|
26
|
+
choose do
|
27
|
+
parallel do
|
28
|
+
parallel_branch do
|
29
|
+
alternative(data.x == 1) do
|
30
|
+
activity :a1_1, :call, :endpoint1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
parallel_branch do
|
34
|
+
alternative(data.x > 0) do
|
35
|
+
activity :a1_2, :call, :endpoint1, :call => Proc.new{sleep 0.1}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
activity :a2, :call, :endpoint1
|
41
|
+
end
|
42
|
+
@wf.start.join
|
43
|
+
wf_assert('CALL a1_1')
|
44
|
+
wf_assert('CALL a1_2')
|
45
|
+
wf_sassert('Da1_1Da1_2Ca2Da2|finished|')
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(::File.dirname(__FILE__) + '/../TestWorkflow')
|
3
|
+
|
4
|
+
# only variant Cancelling Discriminator is implemented, but that's the coolest one 8)
|
5
|
+
class TestWFPStructuredDiscriminator < Test::Unit::TestCase
|
6
|
+
include TestMixin
|
7
|
+
|
8
|
+
def test_cancelling_discriminator
|
9
|
+
@wf.description do
|
10
|
+
parallel :wait => 1 do
|
11
|
+
parallel_branch do
|
12
|
+
activity :a_1_1, :call, :endpoint1
|
13
|
+
end
|
14
|
+
parallel_branch do
|
15
|
+
activity :a_1_2, :call, :endpoint1, :call => Proc.new{sleep 0.2}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
activity :a_2, :call, :endpoint1
|
19
|
+
end
|
20
|
+
t = @wf.start.join
|
21
|
+
wf_assert("CALL a_1_1:")
|
22
|
+
wf_assert("CALL a_1_2:")
|
23
|
+
wf_assert("CALL a_2:")
|
24
|
+
wf_assert("NO_LONGER_NECCESARY a_1_2")
|
25
|
+
wf_assert("DONE a_1_1")
|
26
|
+
wf_assert("DONE a_2")
|
27
|
+
end
|
28
|
+
end
|