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.
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