oflow 0.3.0
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.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +182 -0
- data/lib/oflow/actor.rb +76 -0
- data/lib/oflow/actors/errorhandler.rb +32 -0
- data/lib/oflow/actors/ignore.rb +22 -0
- data/lib/oflow/actors/log.rb +175 -0
- data/lib/oflow/actors/relay.rb +23 -0
- data/lib/oflow/actors/timer.rb +126 -0
- data/lib/oflow/actors.rb +11 -0
- data/lib/oflow/box.rb +195 -0
- data/lib/oflow/env.rb +52 -0
- data/lib/oflow/errors.rb +74 -0
- data/lib/oflow/flow.rb +75 -0
- data/lib/oflow/haserrorhandler.rb +48 -0
- data/lib/oflow/haslinks.rb +64 -0
- data/lib/oflow/haslog.rb +72 -0
- data/lib/oflow/hasname.rb +31 -0
- data/lib/oflow/hastasks.rb +209 -0
- data/lib/oflow/inspector.rb +501 -0
- data/lib/oflow/link.rb +43 -0
- data/lib/oflow/pattern.rb +8 -0
- data/lib/oflow/stamp.rb +39 -0
- data/lib/oflow/task.rb +415 -0
- data/lib/oflow/test/action.rb +21 -0
- data/lib/oflow/test/actorwrap.rb +62 -0
- data/lib/oflow/test.rb +8 -0
- data/lib/oflow/tracker.rb +109 -0
- data/lib/oflow/version.rb +5 -0
- data/lib/oflow.rb +23 -0
- data/test/actors/log_test.rb +57 -0
- data/test/actors/timer_test.rb +56 -0
- data/test/actorwrap_test.rb +48 -0
- data/test/all_tests.rb +27 -0
- data/test/box_test.rb +127 -0
- data/test/collector.rb +23 -0
- data/test/flow_basic_test.rb +93 -0
- data/test/flow_cfg_error_test.rb +94 -0
- data/test/flow_log_test.rb +87 -0
- data/test/flow_nest_test.rb +215 -0
- data/test/flow_rescue_test.rb +133 -0
- data/test/flow_tracker_test.rb +82 -0
- data/test/stutter.rb +21 -0
- data/test/task_test.rb +98 -0
- data/test/tracker_test.rb +59 -0
- metadata +93 -0
data/lib/oflow.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module OFlow
|
3
|
+
end
|
4
|
+
|
5
|
+
require 'oflow/errors'
|
6
|
+
require 'oflow/stamp'
|
7
|
+
require 'oflow/hasname'
|
8
|
+
require 'oflow/hastasks'
|
9
|
+
require 'oflow/haslinks'
|
10
|
+
require 'oflow/haserrorhandler'
|
11
|
+
require 'oflow/haslog'
|
12
|
+
require 'oflow/pattern'
|
13
|
+
require 'oflow/tracker'
|
14
|
+
require 'oflow/box'
|
15
|
+
require 'oflow/actor'
|
16
|
+
require 'oflow/task'
|
17
|
+
require 'oflow/link'
|
18
|
+
require 'oflow/flow'
|
19
|
+
|
20
|
+
require 'oflow/actors'
|
21
|
+
|
22
|
+
require 'oflow/env'
|
23
|
+
require 'oflow/inspector'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
[ File.dirname(__FILE__),
|
5
|
+
File.join(File.dirname(__FILE__), "../../lib"),
|
6
|
+
File.join(File.dirname(__FILE__), "..")
|
7
|
+
].each { |path| $: << path unless $:.include?(path) }
|
8
|
+
|
9
|
+
require 'test/unit'
|
10
|
+
require 'stringio'
|
11
|
+
require 'oflow'
|
12
|
+
|
13
|
+
class LogTest < ::Test::Unit::TestCase
|
14
|
+
|
15
|
+
def test_log
|
16
|
+
stream = StringIO.new()
|
17
|
+
log = ::OFlow::Task.new(nil, 'log', ::OFlow::Actors::Log,
|
18
|
+
:stream => stream,
|
19
|
+
:severity => Logger::INFO,
|
20
|
+
:formatter => proc { |sev, time, prog, msg| "#{sev}: #{msg}\n" })
|
21
|
+
|
22
|
+
log.receive(:fatal, ::OFlow::Box.new(['dead msg', 'Dead']))
|
23
|
+
log.receive(:error, ::OFlow::Box.new(['oops msg', 'Oops']))
|
24
|
+
log.receive(:warn, ::OFlow::Box.new(['duck msg', 'Duck']))
|
25
|
+
log.receive(:info, ::OFlow::Box.new(['something msg', 'Something']))
|
26
|
+
log.receive(:debug, ::OFlow::Box.new(['bugs msg', 'Bugs']))
|
27
|
+
|
28
|
+
log.flush()
|
29
|
+
assert_equal(%{FATAL: dead msg
|
30
|
+
ERROR: oops msg
|
31
|
+
WARN: duck msg
|
32
|
+
INFO: something msg
|
33
|
+
}, stream.string)
|
34
|
+
|
35
|
+
log.shutdown()
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_log_filename
|
39
|
+
filename = 'filename_test.log'
|
40
|
+
%x{rm -f #{filename}}
|
41
|
+
|
42
|
+
log = ::OFlow::Task.new(nil, 'log', ::OFlow::Actors::Log,
|
43
|
+
:filename => filename,
|
44
|
+
:severity => Logger::INFO,
|
45
|
+
:formatter => proc { |sev, time, prog, msg| "#{sev}: #{msg}\n" })
|
46
|
+
|
47
|
+
log.receive(:info, ::OFlow::Box.new(['first entry', 'One']))
|
48
|
+
log.flush()
|
49
|
+
|
50
|
+
output = File.read(filename).split("\n")[1..-1]
|
51
|
+
assert_equal(['INFO: first entry'], output)
|
52
|
+
%x{rm #{filename}}
|
53
|
+
|
54
|
+
log.shutdown()
|
55
|
+
end
|
56
|
+
|
57
|
+
end # LogTest
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
[ File.dirname(__FILE__),
|
5
|
+
File.join(File.dirname(__FILE__), "../../lib"),
|
6
|
+
File.join(File.dirname(__FILE__), "..")
|
7
|
+
].each { |path| $: << path unless $:.include?(path) }
|
8
|
+
|
9
|
+
require 'test/unit'
|
10
|
+
require 'oflow'
|
11
|
+
|
12
|
+
require 'collector'
|
13
|
+
|
14
|
+
class TimerTest < ::Test::Unit::TestCase
|
15
|
+
|
16
|
+
def test_timer_repeat
|
17
|
+
period = 0.1
|
18
|
+
timer = nil
|
19
|
+
collector = nil
|
20
|
+
::OFlow::Env.flow('one-time') { |f|
|
21
|
+
f.task('once', ::OFlow::Actors::Timer, repeat: 4, period: period) { |t|
|
22
|
+
timer = t
|
23
|
+
t.link(:ping, :collector, :tick)
|
24
|
+
}
|
25
|
+
f.task(:collector, Collector) { |t|
|
26
|
+
collector = t.actor
|
27
|
+
}
|
28
|
+
}
|
29
|
+
::OFlow::Env.flush()
|
30
|
+
prev = nil
|
31
|
+
ticks = collector.collection.map do |t|
|
32
|
+
tf = t[2].to_f
|
33
|
+
if prev.nil?
|
34
|
+
tick = [t[1], tf, 0.0]
|
35
|
+
else
|
36
|
+
tick = [t[1], tf, tf - prev]
|
37
|
+
end
|
38
|
+
prev = tf
|
39
|
+
tick
|
40
|
+
end
|
41
|
+
|
42
|
+
ticks.size.times do |i|
|
43
|
+
tick = ticks[i]
|
44
|
+
assert_equal(i + 1, tick[0])
|
45
|
+
next if 0 == i
|
46
|
+
dif = tick[2] - period
|
47
|
+
limit = period / 10 # 10% accuracy
|
48
|
+
assert(-limit < dif && dif < limit, "Verify timer fires are within 10% of expected. (dif: #{dif}, limit: #{limit})")
|
49
|
+
end
|
50
|
+
|
51
|
+
::OFlow::Env.clear()
|
52
|
+
end
|
53
|
+
|
54
|
+
# TBD more tests on start, stop, combinations of options, and error conditions
|
55
|
+
|
56
|
+
end # TimerTest
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
[ File.dirname(__FILE__),
|
5
|
+
File.join(File.dirname(__FILE__), "../lib")
|
6
|
+
].each { |path| $: << path unless $:.include?(path) }
|
7
|
+
|
8
|
+
require 'test/unit'
|
9
|
+
require 'oflow'
|
10
|
+
require 'oflow/test'
|
11
|
+
|
12
|
+
class Nonsense < ::OFlow::Actor
|
13
|
+
def initialize(task, options)
|
14
|
+
super
|
15
|
+
@cnt = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform(op, box)
|
19
|
+
@cnt += 1
|
20
|
+
task.ship(:start, ::OFlow::Box.new(@cnt))
|
21
|
+
task.ship(op, box)
|
22
|
+
task.info("finished #{@cnt}")
|
23
|
+
end
|
24
|
+
|
25
|
+
end # Nonsense
|
26
|
+
|
27
|
+
class ActorWrapTest < ::Test::Unit::TestCase
|
28
|
+
|
29
|
+
def test_actorwrap
|
30
|
+
wrap = ::OFlow::Test::ActorWrap.new('wrapper', Nonsense)
|
31
|
+
|
32
|
+
wrap.receive(:first, ::OFlow::Box.new('word'))
|
33
|
+
history = wrap.history.map { |action| action.to_s }
|
34
|
+
assert_equal(['start: 1', 'first: word', 'log: [:info, "finished 1", ":test:wrapper"]'], history)
|
35
|
+
|
36
|
+
wrap.receive(:second, ::OFlow::Box.new('This is a sentence.'))
|
37
|
+
history = wrap.history.map { |action| action.to_s }
|
38
|
+
assert_equal(['start: 1', 'first: word', 'log: [:info, "finished 1", ":test:wrapper"]',
|
39
|
+
'start: 2', 'second: This is a sentence.', 'log: [:info, "finished 2", ":test:wrapper"]'], history)
|
40
|
+
|
41
|
+
wrap.reset()
|
42
|
+
assert_equal([], wrap.history)
|
43
|
+
wrap.receive(:third, ::OFlow::Box.new('word'))
|
44
|
+
history = wrap.history.map { |action| action.to_s }
|
45
|
+
assert_equal(['start: 3', 'third: word', 'log: [:info, "finished 3", ":test:wrapper"]'], history)
|
46
|
+
end
|
47
|
+
|
48
|
+
end # ActorWrapTest
|
data/test/all_tests.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
[ File.dirname(__FILE__),
|
5
|
+
File.join(File.dirname(__FILE__), "../lib")
|
6
|
+
].each { |path| $: << path unless $:.include?(path) }
|
7
|
+
|
8
|
+
|
9
|
+
require 'test/unit'
|
10
|
+
|
11
|
+
require 'box_test'
|
12
|
+
require 'task_test'
|
13
|
+
require 'tracker_test'
|
14
|
+
require 'actorwrap_test'
|
15
|
+
|
16
|
+
require 'flow_basic_test'
|
17
|
+
require 'flow_rescue_test'
|
18
|
+
require 'flow_log_test'
|
19
|
+
require 'flow_cfg_error_test'
|
20
|
+
require 'flow_rescue_test'
|
21
|
+
require 'flow_nest_test'
|
22
|
+
require 'flow_tracker_test'
|
23
|
+
|
24
|
+
# Actor tests
|
25
|
+
require 'actors/log_test'
|
26
|
+
require 'actors/timer_test'
|
27
|
+
|
data/test/box_test.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
# Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is
|
5
|
+
# required. That can be set in the RUBYOPT environment variable.
|
6
|
+
# export RUBYOPT=-w
|
7
|
+
|
8
|
+
$VERBOSE = true
|
9
|
+
|
10
|
+
$: << File.join(File.dirname(__FILE__), "../lib")
|
11
|
+
|
12
|
+
require 'test/unit'
|
13
|
+
require 'oflow'
|
14
|
+
|
15
|
+
class Access
|
16
|
+
attr_accessor :x, :y
|
17
|
+
def initialize(x, y)
|
18
|
+
@x = x
|
19
|
+
@y = y
|
20
|
+
end
|
21
|
+
end # Access
|
22
|
+
|
23
|
+
class BoxTest < ::Test::Unit::TestCase
|
24
|
+
|
25
|
+
def test_box_new
|
26
|
+
data = { a: [1, 'first'], b: true }
|
27
|
+
t = ::OFlow::Tracker.create('test')
|
28
|
+
box = ::OFlow::Box.new(data, t)
|
29
|
+
|
30
|
+
assert_equal(data, box.contents, 'data should be the same as what was passed in')
|
31
|
+
assert_equal(t, box.tracker, 'tracker should be the same as what was passed in')
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_box_freeze
|
35
|
+
data = { a: [1, 'first'], b: true }
|
36
|
+
t = ::OFlow::Tracker.create('test')
|
37
|
+
box = ::OFlow::Box.new(data, t).freeze()
|
38
|
+
|
39
|
+
assert_equal(true, box.frozen?, 'box should be frozen')
|
40
|
+
assert_equal(true, box.contents.frozen?, 'contents should be frozen')
|
41
|
+
assert_equal(true, box.contents[:a].frozen?, 'members of contents should be frozen')
|
42
|
+
assert_equal(true, box.contents[:a][1].frozen?, 'members of contentes should be frozen all the way down')
|
43
|
+
assert_equal(true, box.tracker.frozen?, 'tracker should be frozen')
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_box_thaw
|
47
|
+
data = { a: [1, 'first'], b: true }
|
48
|
+
t = ::OFlow::Tracker.create('test')
|
49
|
+
box = ::OFlow::Box.new(data, t).freeze()
|
50
|
+
# make sure it is frozen first.
|
51
|
+
assert_equal(true, box.frozen?, 'box should be frozen')
|
52
|
+
box = box.thaw()
|
53
|
+
|
54
|
+
assert_equal(false, box.frozen?, 'box should not be frozen')
|
55
|
+
assert_equal(false, box.contents.frozen?, 'contents not should be frozen')
|
56
|
+
assert_equal(false, box.contents[:a].frozen?, 'members of contents should not be frozen')
|
57
|
+
assert_equal(false, box.contents[:a][1].frozen?, 'members of contentes should not be frozen all the way down')
|
58
|
+
assert_equal(true, box.tracker.frozen?, 'tracker should still be frozen')
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_box_receive
|
62
|
+
data = { a: [1, 'first'], b: true }
|
63
|
+
t = ::OFlow::Tracker.create('test')
|
64
|
+
box = ::OFlow::Box.new(data, t).freeze()
|
65
|
+
# make sure it is frozen first.
|
66
|
+
assert_equal(true, box.frozen?, 'box should be frozen')
|
67
|
+
|
68
|
+
rbox = box.receive('here', 'try')
|
69
|
+
assert_equal(false, rbox.frozen?, 'box should not be frozen')
|
70
|
+
assert_equal(true, box.contents.frozen?, 'contents should be frozen')
|
71
|
+
assert_equal(2, rbox.tracker.track.size, 'track should have 2 entries')
|
72
|
+
assert_equal('test-', rbox.tracker.track[0].where, 'check track entry 0')
|
73
|
+
assert_equal('here-try', rbox.tracker.track[1].where, 'check track entry 1')
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_box_get
|
77
|
+
data = { a: [1, 'first'], b: true, 'c' => 'see', d: Access.new([7, 3], :y) }
|
78
|
+
box = ::OFlow::Box.new(data).freeze()
|
79
|
+
# Hash access
|
80
|
+
assert_equal(true, box.get('b'), 'get b')
|
81
|
+
assert_equal('see', box.get('c'), 'get c')
|
82
|
+
assert_equal(nil, box.get('x'), 'get x')
|
83
|
+
# Array access
|
84
|
+
assert_equal(1, box.get('a:0'), 'get a:0')
|
85
|
+
assert_equal('first', box.get('a:1'), 'get a:1')
|
86
|
+
assert_equal(nil, box.get('a:2'), 'get a:2')
|
87
|
+
# nil path
|
88
|
+
assert_equal(data, box.get(nil), 'get nil')
|
89
|
+
assert_equal(data, box.get(''), 'get nil')
|
90
|
+
# Object
|
91
|
+
assert_equal([7, 3], box.get('d:x'), 'get d:x')
|
92
|
+
assert_equal(7, box.get('d:x:0'), 'get d:x:0')
|
93
|
+
assert_equal(:y, box.get('d:y'), 'get d:y')
|
94
|
+
assert_equal(nil, box.get('d:z'), 'get d:z')
|
95
|
+
# more bad paths
|
96
|
+
assert_equal(nil, box.get('b:0'), 'get b:0')
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_box_set
|
100
|
+
data = { a: [1, 'first'], b: true, 'c' => 'see', d: Access.new([7, 3], :y) }
|
101
|
+
box = ::OFlow::Box.new(data).freeze()
|
102
|
+
|
103
|
+
b2 = box.set('b', false)
|
104
|
+
assert_equal(false, b2.get('b'), 'get b')
|
105
|
+
assert_equal(true, box.contents[:a].frozen?, 'other contents should be frozen')
|
106
|
+
|
107
|
+
b2 = box.set('a:0', 3)
|
108
|
+
assert_equal(3, b2.get('a:0'), 'get a:0')
|
109
|
+
|
110
|
+
b2 = box.set('a:2', 5)
|
111
|
+
assert_equal(5, b2.get('a:2'), 'get a:2')
|
112
|
+
|
113
|
+
b2 = box.set('c', 'mite')
|
114
|
+
assert_equal('mite', b2.get('c'), 'get c')
|
115
|
+
|
116
|
+
b2 = box.set('e:ha', 'new')
|
117
|
+
assert_equal('new', b2.get('e:ha'), 'get e:ha')
|
118
|
+
|
119
|
+
b2 = box.set('f:1', 'new')
|
120
|
+
assert_equal(Array, b2.get('f').class, 'get f class')
|
121
|
+
assert_equal(nil, b2.get('f:0'), 'get f:0')
|
122
|
+
assert_equal('new', b2.get('f:1'), 'get f:1')
|
123
|
+
|
124
|
+
assert_raise(::OFlow::FrozenError) { box.set('d:x:1', 'three') }
|
125
|
+
end
|
126
|
+
|
127
|
+
end # BoxTest
|
data/test/collector.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
[ File.dirname(__FILE__),
|
5
|
+
File.join(File.dirname(__FILE__), "../lib")
|
6
|
+
].each { |path| $: << path unless $:.include?(path) }
|
7
|
+
|
8
|
+
require 'oflow'
|
9
|
+
|
10
|
+
class Collector < ::OFlow::Actor
|
11
|
+
attr_accessor :collection
|
12
|
+
|
13
|
+
def initialize(task, options)
|
14
|
+
super
|
15
|
+
@collection = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform(op, box)
|
19
|
+
@collection << box.contents
|
20
|
+
end
|
21
|
+
|
22
|
+
end # Collector
|
23
|
+
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
[ File.dirname(__FILE__),
|
5
|
+
File.join(File.dirname(__FILE__), "../lib")
|
6
|
+
].each { |path| $: << path unless $:.include?(path) }
|
7
|
+
|
8
|
+
require 'test/unit'
|
9
|
+
require 'oflow'
|
10
|
+
|
11
|
+
require 'collector'
|
12
|
+
|
13
|
+
class Stutter < ::OFlow::Actor
|
14
|
+
|
15
|
+
def initialize(task, options)
|
16
|
+
super
|
17
|
+
@collector = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def perform(op, box)
|
21
|
+
if @collector.nil?
|
22
|
+
@collector = task.ship(:collector, ::OFlow::Box.new([task.full_name, op, box.contents]))
|
23
|
+
else
|
24
|
+
@collector.ship(::OFlow::Box.new([task.full_name, op, box.contents, 'with_link']))
|
25
|
+
end
|
26
|
+
task.ship(op, box)
|
27
|
+
end
|
28
|
+
|
29
|
+
end # Stutter
|
30
|
+
|
31
|
+
class FlowBasicTest < ::Test::Unit::TestCase
|
32
|
+
|
33
|
+
def test_flow_basic
|
34
|
+
trigger = nil
|
35
|
+
collector = nil
|
36
|
+
::OFlow::Env.flow('basic', :opt1 => 1) { |f|
|
37
|
+
# collects results
|
38
|
+
f.task(:collector, Collector) { |t|
|
39
|
+
collector = t.actor
|
40
|
+
}
|
41
|
+
# starts off the process
|
42
|
+
trigger = f.task('trigger', Stutter) { |t|
|
43
|
+
t.link(:collector, 'collector', 'trigger')
|
44
|
+
t.link(:once, 'dub', :twice)
|
45
|
+
}
|
46
|
+
# sends to self and then ends with no other task to ship to
|
47
|
+
f.task('dub', Stutter, :opt1 => 7) { |t|
|
48
|
+
t.link(:collector, 'collector', 'dub')
|
49
|
+
t.link(:twice, 'dub', :once)
|
50
|
+
t.link(:once, 'ignore', nil)
|
51
|
+
}
|
52
|
+
f.task(:ignore, ::OFlow::Actors::Ignore)
|
53
|
+
}
|
54
|
+
# see if the flow was constructed correctly
|
55
|
+
assert_equal(%|OFlow::Env {
|
56
|
+
basic (OFlow::Flow) {
|
57
|
+
collector (Collector) {
|
58
|
+
}
|
59
|
+
trigger (Stutter) {
|
60
|
+
collector => collector:trigger
|
61
|
+
once => dub:twice
|
62
|
+
}
|
63
|
+
dub (Stutter) {
|
64
|
+
collector => collector:dub
|
65
|
+
twice => dub:once
|
66
|
+
once => ignore:
|
67
|
+
}
|
68
|
+
ignore (OFlow::Actors::Ignore) {
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}|, ::OFlow::Env.describe())
|
72
|
+
|
73
|
+
# run it and check the output
|
74
|
+
trigger.receive(:once, ::OFlow::Box.new(7))
|
75
|
+
::OFlow::Env.flush()
|
76
|
+
assert_equal([[':basic:trigger', :once, 7],
|
77
|
+
[':basic:dub', :twice, 7],
|
78
|
+
[':basic:dub', :once, 7, 'with_link'],
|
79
|
+
], collector.collection)
|
80
|
+
|
81
|
+
# run again and make sure all tasks use links
|
82
|
+
collector.collection = []
|
83
|
+
trigger.receive(:once, ::OFlow::Box.new(7))
|
84
|
+
::OFlow::Env.flush()
|
85
|
+
assert_equal([[':basic:trigger', :once, 7, 'with_link'],
|
86
|
+
[':basic:dub', :twice, 7, 'with_link'],
|
87
|
+
[':basic:dub', :once, 7, 'with_link'],
|
88
|
+
], collector.collection)
|
89
|
+
|
90
|
+
::OFlow::Env.clear()
|
91
|
+
end
|
92
|
+
|
93
|
+
end # FlowBasicTest
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
[ File.dirname(__FILE__),
|
5
|
+
File.join(File.dirname(__FILE__), "../lib")
|
6
|
+
].each { |path| $: << path unless $:.include?(path) }
|
7
|
+
|
8
|
+
require 'test/unit'
|
9
|
+
require 'oflow'
|
10
|
+
|
11
|
+
require 'collector'
|
12
|
+
|
13
|
+
class Dummy < ::OFlow::Actor
|
14
|
+
|
15
|
+
def initialize(task, options)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def perform(op, box)
|
20
|
+
task.ship(op, box)
|
21
|
+
end
|
22
|
+
|
23
|
+
end # Dummy
|
24
|
+
|
25
|
+
class Miss < ::OFlow::Actor
|
26
|
+
|
27
|
+
def initialize(task, options)
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def perform(op, box)
|
32
|
+
case op
|
33
|
+
when :one
|
34
|
+
task.ship(:one, box)
|
35
|
+
when :two
|
36
|
+
task.ship(:two, box)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def inputs()
|
41
|
+
[ ::OFlow::Actor::Spec.new(:fixnum, Fixnum),
|
42
|
+
::OFlow::Actor::Spec.new(:float, nil) ]
|
43
|
+
end
|
44
|
+
|
45
|
+
def outputs()
|
46
|
+
[ ::OFlow::Actor::Spec.new(:fixnum, Fixnum),
|
47
|
+
::OFlow::Actor::Spec.new(:float, Float) ]
|
48
|
+
end
|
49
|
+
|
50
|
+
end # Miss
|
51
|
+
|
52
|
+
class FlowCfgErrTest < ::Test::Unit::TestCase
|
53
|
+
|
54
|
+
def test_flow_link_unresolved
|
55
|
+
begin
|
56
|
+
::OFlow::Env.flow('unresolved', :opt1 => 1) { |f|
|
57
|
+
f.task(:one, Dummy) { |t|
|
58
|
+
t.link(:two, :two, nil)
|
59
|
+
}
|
60
|
+
f.task(:three, Dummy) { |t|
|
61
|
+
t.link(:second, :two, nil)
|
62
|
+
}
|
63
|
+
}
|
64
|
+
assert(false, "expected a ValidateError")
|
65
|
+
rescue ::OFlow::ValidateError => ve
|
66
|
+
assert_equal([":unresolved:one: Failed to find task 'two'.",
|
67
|
+
":unresolved:three: Failed to find task 'two'."], ve.problems.map { |p| p.to_s })
|
68
|
+
end
|
69
|
+
::OFlow::Env.clear()
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_flow_link_missing
|
73
|
+
begin
|
74
|
+
::OFlow::Env.flow('miss-me') { |f|
|
75
|
+
f.task(:sort, Miss) { |t|
|
76
|
+
t.link(:fixnum, :fix, nil)
|
77
|
+
}
|
78
|
+
f.task(:fix, Dummy) { |t|
|
79
|
+
t.link(:repeat, :sort, :float)
|
80
|
+
t.link(:wrong, :sort, :complex)
|
81
|
+
}
|
82
|
+
}
|
83
|
+
assert(false, "expected a ValidateError")
|
84
|
+
rescue ::OFlow::ValidateError => ve
|
85
|
+
assert_equal([":miss-me:sort: Missing link for 'float'.",
|
86
|
+
":miss-me:fix: 'complex' not allowed on ':miss-me:sort'."], ve.problems.map { |p| p.to_s })
|
87
|
+
end
|
88
|
+
::OFlow::Env.clear()
|
89
|
+
end
|
90
|
+
|
91
|
+
# TBD missing links for output spec
|
92
|
+
|
93
|
+
|
94
|
+
end # FlowCfgErrTest
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
[ File.dirname(__FILE__),
|
5
|
+
File.join(File.dirname(__FILE__), "../lib")
|
6
|
+
].each { |path| $: << path unless $:.include?(path) }
|
7
|
+
|
8
|
+
require 'test/unit'
|
9
|
+
require 'oflow'
|
10
|
+
|
11
|
+
require 'collector'
|
12
|
+
|
13
|
+
class Noise < ::OFlow::Actor
|
14
|
+
|
15
|
+
def initialize(task, options)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def perform(op, box)
|
20
|
+
task.info("op: #{op}, box: #{box.contents}")
|
21
|
+
end
|
22
|
+
|
23
|
+
end # Noise
|
24
|
+
|
25
|
+
class FlowLogTest < ::Test::Unit::TestCase
|
26
|
+
|
27
|
+
# Make sure the log works and relays to a log task if it exists.
|
28
|
+
def test_flow_log_relay
|
29
|
+
trigger = nil
|
30
|
+
collector = nil
|
31
|
+
::OFlow::Env.flow('log_relay') { |f|
|
32
|
+
trigger = f.task('noise', Noise)
|
33
|
+
f.task(:log, Collector) { |t|
|
34
|
+
collector = t.actor
|
35
|
+
}
|
36
|
+
}
|
37
|
+
trigger.receive(:speak, ::OFlow::Box.new(7))
|
38
|
+
::OFlow::Env.flush()
|
39
|
+
|
40
|
+
assert_equal(collector.collection.size, 1)
|
41
|
+
assert_equal(collector.collection[0][0], 'op: speak, box: 7')
|
42
|
+
assert_equal(collector.collection[0][1], ':log_relay:noise')
|
43
|
+
|
44
|
+
::OFlow::Env.clear()
|
45
|
+
end
|
46
|
+
|
47
|
+
# Make sure the log in the flow var is used.
|
48
|
+
def test_flow_log_var
|
49
|
+
trigger = nil
|
50
|
+
collector = nil
|
51
|
+
::OFlow::Env.flow('log_relay') { |f|
|
52
|
+
trigger = f.task('noise', Noise)
|
53
|
+
f.log = f.task(:collector, Collector) { |t|
|
54
|
+
collector = t.actor
|
55
|
+
}
|
56
|
+
}
|
57
|
+
trigger.receive(:speak, ::OFlow::Box.new(7))
|
58
|
+
::OFlow::Env.flush()
|
59
|
+
|
60
|
+
assert_equal(collector.collection.size, 1)
|
61
|
+
assert_equal(collector.collection[0][0], 'op: speak, box: 7')
|
62
|
+
assert_equal(collector.collection[0][1], ':log_relay:noise')
|
63
|
+
|
64
|
+
::OFlow::Env.clear()
|
65
|
+
end
|
66
|
+
|
67
|
+
# Make sure the log in the Env var is used.
|
68
|
+
def test_flow_log_env
|
69
|
+
trigger = nil
|
70
|
+
collector = nil
|
71
|
+
::OFlow::Env.flow('log_relay') { |f|
|
72
|
+
trigger = f.task('noise', Noise)
|
73
|
+
::OFlow::Env.log = f.task(:collector, Collector) { |t|
|
74
|
+
collector = t.actor
|
75
|
+
}
|
76
|
+
}
|
77
|
+
trigger.receive(:speak, ::OFlow::Box.new(7))
|
78
|
+
::OFlow::Env.flush()
|
79
|
+
|
80
|
+
assert_equal(collector.collection.size, 1)
|
81
|
+
assert_equal(collector.collection[0][0], 'op: speak, box: 7')
|
82
|
+
assert_equal(collector.collection[0][1], ':log_relay:noise')
|
83
|
+
|
84
|
+
::OFlow::Env.clear()
|
85
|
+
end
|
86
|
+
|
87
|
+
end # FlowLogTest
|