oflow 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +182 -0
  4. data/lib/oflow/actor.rb +76 -0
  5. data/lib/oflow/actors/errorhandler.rb +32 -0
  6. data/lib/oflow/actors/ignore.rb +22 -0
  7. data/lib/oflow/actors/log.rb +175 -0
  8. data/lib/oflow/actors/relay.rb +23 -0
  9. data/lib/oflow/actors/timer.rb +126 -0
  10. data/lib/oflow/actors.rb +11 -0
  11. data/lib/oflow/box.rb +195 -0
  12. data/lib/oflow/env.rb +52 -0
  13. data/lib/oflow/errors.rb +74 -0
  14. data/lib/oflow/flow.rb +75 -0
  15. data/lib/oflow/haserrorhandler.rb +48 -0
  16. data/lib/oflow/haslinks.rb +64 -0
  17. data/lib/oflow/haslog.rb +72 -0
  18. data/lib/oflow/hasname.rb +31 -0
  19. data/lib/oflow/hastasks.rb +209 -0
  20. data/lib/oflow/inspector.rb +501 -0
  21. data/lib/oflow/link.rb +43 -0
  22. data/lib/oflow/pattern.rb +8 -0
  23. data/lib/oflow/stamp.rb +39 -0
  24. data/lib/oflow/task.rb +415 -0
  25. data/lib/oflow/test/action.rb +21 -0
  26. data/lib/oflow/test/actorwrap.rb +62 -0
  27. data/lib/oflow/test.rb +8 -0
  28. data/lib/oflow/tracker.rb +109 -0
  29. data/lib/oflow/version.rb +5 -0
  30. data/lib/oflow.rb +23 -0
  31. data/test/actors/log_test.rb +57 -0
  32. data/test/actors/timer_test.rb +56 -0
  33. data/test/actorwrap_test.rb +48 -0
  34. data/test/all_tests.rb +27 -0
  35. data/test/box_test.rb +127 -0
  36. data/test/collector.rb +23 -0
  37. data/test/flow_basic_test.rb +93 -0
  38. data/test/flow_cfg_error_test.rb +94 -0
  39. data/test/flow_log_test.rb +87 -0
  40. data/test/flow_nest_test.rb +215 -0
  41. data/test/flow_rescue_test.rb +133 -0
  42. data/test/flow_tracker_test.rb +82 -0
  43. data/test/stutter.rb +21 -0
  44. data/test/task_test.rb +98 -0
  45. data/test/tracker_test.rb +59 -0
  46. metadata +93 -0
@@ -0,0 +1,5 @@
1
+
2
+ module OFlow
3
+ # Current version of the module.
4
+ VERSION = '0.3.0'
5
+ end
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