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