ntl-orchestra 0.9.4 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -4
- data/lib/orchestra.rb +1 -13
- data/lib/orchestra/conductor.rb +8 -5
- data/lib/orchestra/dsl/operations.rb +1 -11
- data/lib/orchestra/errors.rb +7 -1
- data/lib/orchestra/execution.rb +6 -3
- data/lib/orchestra/recording.rb +25 -8
- data/lib/orchestra/recording/node.rb +54 -0
- data/lib/orchestra/run_list.rb +5 -3
- data/lib/orchestra/util.rb +0 -12
- data/lib/orchestra/version.rb +1 -1
- data/orchestra.gemspec +1 -1
- data/test/examples/fizz_buzz.rb +19 -3
- data/test/examples/invitation_service.rb +1 -1
- data/test/integration/recording_telemetry_test.rb +4 -4
- data/test/integration/replayable_operation_test.rb +9 -3
- data/test/unit/dsl_test.rb +13 -5
- data/test/unit/node_test.rb +6 -2
- data/test/unit/operation_test.rb +18 -0
- data/test/unit/run_list_test.rb +23 -0
- data/test/unit/step_test.rb +2 -2
- data/test/unit/util_test.rb +0 -14
- metadata +7 -7
- data/lib/orchestra/node.rb +0 -52
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c1897824735843933375a596888e93eb404fe49
|
4
|
+
data.tar.gz: d29cfbda3e69e845132c79b2cc7784c410851b39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f870d33006961640028804fb1103a04815a81d631dc11ea1ac71801fb22da9ca1a87e56cce78de5e9d3488dc73c532d3737164dace444ba3eecb72e8f6b75a2f
|
7
|
+
data.tar.gz: 6dbcb3009f801d14e81447d00a86793c61253284f7f8ac863a06e6d113de53811da672867382ab3e59b41040ca6c19cbe08fd2307b44f60eac01dda4060381af
|
data/README.md
CHANGED
@@ -491,13 +491,13 @@ recording.output # <-- the usual output is attached to the recording itself
|
|
491
491
|
And a recording can be replayed:
|
492
492
|
|
493
493
|
```ruby
|
494
|
-
|
494
|
+
recording.replay InvitationService
|
495
495
|
```
|
496
496
|
|
497
497
|
You can override the inputs passed in when replaying:
|
498
498
|
|
499
499
|
```ruby
|
500
|
-
|
500
|
+
recording.replay InvitationService, :account_name => "dhh"
|
501
501
|
```
|
502
502
|
|
503
503
|
If you want to serialize/persist the recording, just use `JSON.dump`:
|
@@ -511,8 +511,8 @@ You can replay the recording using `JSON.load`:
|
|
511
511
|
|
512
512
|
```ruby
|
513
513
|
json = File.read "tmp/recording.json"
|
514
|
-
recording = JSON.load json
|
515
|
-
|
514
|
+
recording = Orchestra::Recording(JSON.load json, symbolize_names: true)
|
515
|
+
recording.replay InvitationService
|
516
516
|
```
|
517
517
|
|
518
518
|
## Installation
|
data/lib/orchestra.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require "forwardable"
|
2
2
|
require "invokr"
|
3
3
|
require "observer"
|
4
|
-
require "securerandom"
|
5
4
|
|
6
5
|
module Orchestra
|
7
6
|
extend self
|
@@ -14,16 +13,5 @@ module Orchestra
|
|
14
13
|
Conductor.new.execute operation, inputs
|
15
14
|
end
|
16
15
|
|
17
|
-
|
18
|
-
store = Util.recursively_symbolize store
|
19
|
-
input = input.merge store[:input]
|
20
|
-
svc_recordings = store[:service_recordings]
|
21
|
-
Recording.replay operation, input, svc_recordings
|
22
|
-
end
|
23
|
-
|
24
|
-
load File.expand_path('../orchestra/errors.rb', __FILE__)
|
25
|
-
end
|
26
|
-
|
27
|
-
Dir[File.expand_path '../orchestra/**/*.rb', __FILE__].each do |rb_file|
|
28
|
-
load rb_file
|
16
|
+
Dir[File.expand_path '../orchestra/**/*.rb', __FILE__].each &method(:load)
|
29
17
|
end
|
data/lib/orchestra/conductor.rb
CHANGED
@@ -7,6 +7,9 @@ module Orchestra
|
|
7
7
|
@thread_pool = ThreadPool.new
|
8
8
|
@observers = Set.new
|
9
9
|
self.thread_count = Configuration.thread_count
|
10
|
+
if block_given?
|
11
|
+
raise ArgumentError, "Supplied block to Conductor.new; did you mean to invoke Orchestra::Operation.new do … end?"
|
12
|
+
end
|
10
13
|
end
|
11
14
|
|
12
15
|
def execute operation, input = {}
|
@@ -17,7 +20,7 @@ module Orchestra
|
|
17
20
|
end
|
18
21
|
|
19
22
|
def record *args
|
20
|
-
recording = Recording.
|
23
|
+
recording = Recording.fresh
|
21
24
|
add_observer recording
|
22
25
|
execute *args do |execution|
|
23
26
|
execution.add_observer recording
|
@@ -91,10 +94,10 @@ module Orchestra
|
|
91
94
|
alias_method :__getobj__, :service
|
92
95
|
alias_method :__setobj__, :service=
|
93
96
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
97
|
+
def initialize service, recording
|
98
|
+
super service
|
99
|
+
@recording = recording
|
100
|
+
end
|
98
101
|
|
99
102
|
def kind_of? klass
|
100
103
|
super or service.kind_of? klass
|
@@ -20,7 +20,6 @@ module Orchestra
|
|
20
20
|
|
21
21
|
def add_step name_or_object, args = {}, &block
|
22
22
|
name, step = case name_or_object
|
23
|
-
when nil then build_anonymous_step block
|
24
23
|
when Operation then build_embedded_operation_step name_or_object
|
25
24
|
when ::String, ::Symbol then build_inline_step name_or_object, block
|
26
25
|
else build_object_step name_or_object, args
|
@@ -37,15 +36,6 @@ module Orchestra
|
|
37
36
|
step.freeze
|
38
37
|
end
|
39
38
|
|
40
|
-
def build_anonymous_step block
|
41
|
-
step = Step::InlineStep.build &block
|
42
|
-
unless step.provisions.size == 1
|
43
|
-
raise ArgumentError, "Could not infer name for step from a provision"
|
44
|
-
end
|
45
|
-
name = step.provisions.fetch 0
|
46
|
-
[name, step]
|
47
|
-
end
|
48
|
-
|
49
39
|
def build_embedded_operation_step operation
|
50
40
|
name = object_name operation
|
51
41
|
[name || operation.result, operation]
|
@@ -92,7 +82,7 @@ module Orchestra
|
|
92
82
|
end
|
93
83
|
|
94
84
|
def result *args, &block
|
95
|
-
args <<
|
85
|
+
args << :result if args.empty?
|
96
86
|
step = @builder.add_step *args, &block
|
97
87
|
name ||= step.provisions.fetch 0
|
98
88
|
self.result = name
|
data/lib/orchestra/errors.rb
CHANGED
@@ -13,12 +13,18 @@ module Orchestra
|
|
13
13
|
end
|
14
14
|
|
15
15
|
class MissingProvisionError < Error
|
16
|
+
attr_writer :name
|
17
|
+
|
16
18
|
def initialize missing_provisions
|
17
19
|
@missing_provisions = missing_provisions
|
18
20
|
end
|
19
21
|
|
22
|
+
def name
|
23
|
+
@name ||= "<anonymous>"
|
24
|
+
end
|
25
|
+
|
20
26
|
def to_s
|
21
|
-
"failed to supply output: #{list_out @missing_provisions}"
|
27
|
+
"Node `#{name}' failed to supply output: #{list_out @missing_provisions}"
|
22
28
|
end
|
23
29
|
end
|
24
30
|
|
data/lib/orchestra/execution.rb
CHANGED
@@ -4,12 +4,12 @@ module Orchestra
|
|
4
4
|
|
5
5
|
def build operation, conductor, input = {}
|
6
6
|
run_list = RunList.build operation.steps, operation.result, input.keys
|
7
|
-
node = Node.new run_list, operation.name, input
|
7
|
+
node = Recording::Node.new run_list, operation.name, input
|
8
8
|
Operation.new conductor, run_list, input, node
|
9
9
|
end
|
10
10
|
|
11
11
|
def execute_step step, input
|
12
|
-
node = Node.new step, 'anonymous', input
|
12
|
+
node = Recording::Node.new step, 'anonymous', input
|
13
13
|
operation_execution = Operation.new Conductor.new, {}, input, node
|
14
14
|
Step.execute step, node.name, operation_execution
|
15
15
|
end
|
@@ -50,6 +50,9 @@ module Orchestra
|
|
50
50
|
def process name, step
|
51
51
|
output = Step.execute step, name, self
|
52
52
|
state.merge! output
|
53
|
+
rescue MissingProvisionError => error
|
54
|
+
error.name = name.inspect
|
55
|
+
raise error
|
53
56
|
end
|
54
57
|
|
55
58
|
def ensure_inputs_are_present!
|
@@ -95,7 +98,7 @@ module Orchestra
|
|
95
98
|
end
|
96
99
|
|
97
100
|
def execute
|
98
|
-
@node = Node.new step, name, input
|
101
|
+
@node = Recording::Node.new step, name, input
|
99
102
|
operation_execution.publish :step_entered, node, node.input
|
100
103
|
output = step.process invoke
|
101
104
|
operation_execution.publish :step_exited, node, output
|
data/lib/orchestra/recording.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
module Orchestra
|
2
2
|
class Recording
|
3
|
-
|
3
|
+
def self.fresh
|
4
|
+
services = Hash.new do |hsh, service_name| hsh[service_name] = [] end
|
5
|
+
new services
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_accessor :input, :output
|
9
|
+
attr :services
|
4
10
|
|
5
|
-
def initialize
|
6
|
-
@services =
|
11
|
+
def initialize services
|
12
|
+
@services = services
|
7
13
|
end
|
8
14
|
|
9
15
|
def update event_name, *args
|
@@ -19,10 +25,14 @@ module Orchestra
|
|
19
25
|
end
|
20
26
|
end
|
21
27
|
|
28
|
+
def [] attr
|
29
|
+
to_h[attr]
|
30
|
+
end
|
31
|
+
|
22
32
|
def to_h
|
23
33
|
{
|
24
|
-
:input
|
25
|
-
:output
|
34
|
+
:input => input,
|
35
|
+
:output => output,
|
26
36
|
:service_recordings => services,
|
27
37
|
}
|
28
38
|
end
|
@@ -31,13 +41,20 @@ module Orchestra
|
|
31
41
|
generator.generate to_h
|
32
42
|
end
|
33
43
|
|
34
|
-
def
|
44
|
+
def replay operation, override_input = {}
|
35
45
|
replayed_services = {}
|
36
|
-
|
46
|
+
services.each do |svc, service_recording|
|
37
47
|
replayed_services[svc] = Playback.build service_recording
|
38
48
|
end
|
39
49
|
conductor = Conductor.new replayed_services
|
40
|
-
conductor.execute operation, input
|
50
|
+
conductor.execute operation, input.merge(override_input)
|
41
51
|
end
|
42
52
|
end
|
53
|
+
|
54
|
+
def Recording serialized_recording
|
55
|
+
recording = Recording.new serialized_recording[:service_recordings]
|
56
|
+
recording.input = serialized_recording[:input]
|
57
|
+
recording.output = serialized_recording[:output]
|
58
|
+
recording.freeze
|
59
|
+
end
|
43
60
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Orchestra
|
2
|
+
class Recording
|
3
|
+
# Reader object to expose operations and steps to the outside world
|
4
|
+
class Node
|
5
|
+
attr :input, :name
|
6
|
+
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegators :@node, :provisions, :dependencies, :optional_dependencies,
|
10
|
+
:required_dependencies
|
11
|
+
|
12
|
+
def initialize step_or_operation, name, input
|
13
|
+
@name = name
|
14
|
+
@node = step_or_operation
|
15
|
+
@input = format_input input
|
16
|
+
freeze
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_h
|
20
|
+
{
|
21
|
+
dependencies: dependencies,
|
22
|
+
input: input,
|
23
|
+
name: name,
|
24
|
+
optional_dependencies: optional_dependencies,
|
25
|
+
provisions: provisions,
|
26
|
+
required_dependencies: required_dependencies,
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def inspect
|
31
|
+
params = to_h.each_with_object [] do |(key, val), list|
|
32
|
+
list << "#{key}=#{val.inspect}"
|
33
|
+
end
|
34
|
+
"#<Orchestra::Node #{params.join ', '}>"
|
35
|
+
end
|
36
|
+
|
37
|
+
def operation?
|
38
|
+
@node.is_a? Operation
|
39
|
+
end
|
40
|
+
|
41
|
+
def step?
|
42
|
+
not operation?
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def format_input input
|
48
|
+
@node.dependencies.each_with_object Hash.new do |dep, hsh|
|
49
|
+
hsh[dep] = input[dep] if input.has_key? dep
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/orchestra/run_list.rb
CHANGED
@@ -61,7 +61,7 @@ module Orchestra
|
|
61
61
|
def initialize result, input_names = []
|
62
62
|
@input_names = input_names
|
63
63
|
@steps_hash = {}
|
64
|
-
@required = [result]
|
64
|
+
@required = Set.new [result]
|
65
65
|
@result = result
|
66
66
|
freeze
|
67
67
|
end
|
@@ -109,8 +109,10 @@ module Orchestra
|
|
109
109
|
|
110
110
|
def require step
|
111
111
|
supplied_by_input = input_names.method :include?
|
112
|
-
|
113
|
-
@required.
|
112
|
+
required_deps = step.required_dependencies.reject &supplied_by_input
|
113
|
+
@required.merge required_deps
|
114
|
+
required = @required.method :include?
|
115
|
+
@required.merge step.optional_dependencies.reject &required
|
114
116
|
true
|
115
117
|
end
|
116
118
|
|
data/lib/orchestra/util.rb
CHANGED
@@ -23,18 +23,6 @@ module Orchestra
|
|
23
23
|
[hsh, ary]
|
24
24
|
end
|
25
25
|
|
26
|
-
def recursively_symbolize obj
|
27
|
-
case obj
|
28
|
-
when Array
|
29
|
-
obj.map &method(:recursively_symbolize)
|
30
|
-
when Hash then
|
31
|
-
obj.each_with_object Hash.new do |(k, v), out_hsh|
|
32
|
-
out_hsh[k.to_sym] = recursively_symbolize v
|
33
|
-
end
|
34
|
-
else obj
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
26
|
def to_lazy_thunk obj
|
39
27
|
if obj.respond_to? :to_proc and not obj.is_a? Symbol
|
40
28
|
obj
|
data/lib/orchestra/version.rb
CHANGED
data/orchestra.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^test/})
|
19
19
|
spec.require_paths = %w(lib)
|
20
20
|
|
21
|
-
spec.add_dependency "invokr"
|
21
|
+
spec.add_dependency "invokr", "~> 0.9.7"
|
22
22
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.6"
|
24
24
|
spec.add_development_dependency "pry"
|
data/test/examples/fizz_buzz.rb
CHANGED
@@ -21,12 +21,28 @@ module Examples
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
finally
|
25
|
-
depends_on :
|
24
|
+
finally do
|
25
|
+
depends_on :stdout
|
26
26
|
iterates_over :fizzbuzz
|
27
27
|
execute do |str|
|
28
|
-
|
28
|
+
stdout.puts str
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
InteractiveFizzBuzz = Orchestra::Operation.new do
|
34
|
+
step :prompt_user do
|
35
|
+
depends_on :stdin, :stdout
|
36
|
+
provides :up_to
|
37
|
+
execute do
|
38
|
+
stdout.puts "How high would you like to go?"
|
39
|
+
stdout.print " => "
|
40
|
+
stdout.flush
|
41
|
+
value = stdin.gets
|
42
|
+
value.to_i
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
finally Examples::FizzBuzz
|
47
|
+
end
|
32
48
|
end
|
@@ -46,7 +46,7 @@ class RecordingTelemetryTest < Minitest::Test
|
|
46
46
|
],
|
47
47
|
},
|
48
48
|
},
|
49
|
-
:
|
49
|
+
:__finally__ => {
|
50
50
|
:input => {
|
51
51
|
:fizzbuzz => [
|
52
52
|
"1",
|
@@ -66,15 +66,15 @@ class RecordingTelemetryTest < Minitest::Test
|
|
66
66
|
"FizzBuzz",
|
67
67
|
],
|
68
68
|
},
|
69
|
-
:output => { :
|
69
|
+
:output => { :__finally__ => [] },
|
70
70
|
}
|
71
71
|
},
|
72
72
|
:output => [],
|
73
73
|
}
|
74
74
|
end
|
75
75
|
|
76
|
-
def execute_with_telemetry telemetry,
|
77
|
-
conductor = Orchestra::Conductor.new :
|
76
|
+
def execute_with_telemetry telemetry, stdout
|
77
|
+
conductor = Orchestra::Conductor.new :stdout => stdout
|
78
78
|
|
79
79
|
conductor.add_observer TelemetryRecorder.new telemetry
|
80
80
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
1
3
|
class ReplayableOperationTest < Minitest::Test
|
2
4
|
include Examples::InvitationService::TestSetup
|
3
5
|
|
@@ -6,16 +8,20 @@ class ReplayableOperationTest < Minitest::Test
|
|
6
8
|
recording = execute_for_real
|
7
9
|
|
8
10
|
# Write the recording out to a file. In this case, a StringIO is used for
|
9
|
-
# simplicity, and we serialize into JSON
|
11
|
+
# simplicity, and we serialize into JSON. The to_h is important as
|
12
|
+
# hashes can be coerced back into Recording objects.
|
10
13
|
file = StringIO.new
|
11
14
|
file.write JSON.dump recording
|
12
15
|
file.rewind
|
13
16
|
|
17
|
+
# Re-load the recording from JSON using Orchestra::Recording()
|
18
|
+
parsed_json = JSON.parse file.read, symbolize_names: true
|
19
|
+
recording = Orchestra::Recording(parsed_json)
|
20
|
+
|
14
21
|
# Replay the operation, directing SMTP to an alternative service object
|
15
22
|
smtp_service = build_example_smtp
|
16
|
-
|
23
|
+
recording.replay(
|
17
24
|
Examples::InvitationService,
|
18
|
-
JSON.load(file.read),
|
19
25
|
:smtp => smtp_service,
|
20
26
|
)
|
21
27
|
|
data/test/unit/dsl_test.rb
CHANGED
@@ -33,12 +33,10 @@ class DSLTest < Minitest::Test
|
|
33
33
|
end
|
34
34
|
assert_equal :foo, operation.result
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
result do execute do 'foo' end end
|
39
|
-
end
|
36
|
+
operation = Orchestra::Operation.new do
|
37
|
+
result do execute do 'foo' end end
|
40
38
|
end
|
41
|
-
assert_equal
|
39
|
+
assert_equal :result, operation.result
|
42
40
|
|
43
41
|
operation = Orchestra::Operation.new do
|
44
42
|
result do
|
@@ -119,4 +117,14 @@ class DSLTest < Minitest::Test
|
|
119
117
|
|
120
118
|
assert_equal "Must supply at least one step", error.message
|
121
119
|
end
|
120
|
+
|
121
|
+
def test_cannot_accidentally_try_to_define_a_conductor_with_dsl
|
122
|
+
error = assert_raises ArgumentError do
|
123
|
+
Orchestra::Conductor.new do
|
124
|
+
self.result = :foo
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
assert_equal "Supplied block to Conductor.new; did you mean to invoke Orchestra::Operation.new do … end?", error.message
|
129
|
+
end
|
122
130
|
end
|
data/test/unit/node_test.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
class NodeTest < Minitest::Test
|
2
2
|
def test_inspect
|
3
|
-
node = Orchestra::Node.new
|
3
|
+
node = Orchestra::Recording::Node.new(
|
4
|
+
Examples::FizzBuzz,
|
5
|
+
"Examples::FizzBuzz",
|
6
|
+
{},
|
7
|
+
)
|
4
8
|
|
5
9
|
assert_equal(
|
6
|
-
"#<Orchestra::Node dependencies=[:array, :fizzbuzz, :
|
10
|
+
"#<Orchestra::Node dependencies=[:array, :fizzbuzz, :stdout, :up_to], input={}, name=\"Examples::FizzBuzz\", optional_dependencies=[], provisions=[:__finally__, :array, :fizzbuzz], required_dependencies=[:stdout, :up_to]>",
|
7
11
|
node.inspect,
|
8
12
|
)
|
9
13
|
end
|
data/test/unit/operation_test.rb
CHANGED
@@ -19,6 +19,24 @@ module OperationTest
|
|
19
19
|
assert_equal %(Missing input :sentence), error.message
|
20
20
|
end
|
21
21
|
|
22
|
+
def test_adds_name_to_missing_provision_error
|
23
|
+
operation = Orchestra::Operation.new do
|
24
|
+
result :foo do
|
25
|
+
provides :bar, :baz
|
26
|
+
execute do nil end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
error = assert_raises Orchestra::MissingProvisionError do
|
31
|
+
operation.execute
|
32
|
+
end
|
33
|
+
|
34
|
+
assert_equal(
|
35
|
+
"Node `:foo' failed to supply output: :bar and :baz",
|
36
|
+
error.message,
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
22
40
|
def test_mutating_inputs
|
23
41
|
operation = build_mutator
|
24
42
|
|
data/test/unit/run_list_test.rb
CHANGED
@@ -16,6 +16,29 @@ class RunListTest < Minitest::Test
|
|
16
16
|
assert_equal %w(foo⇒bar bar⇒baz baz⇒qux qux⇒res), run_list.step_names
|
17
17
|
end
|
18
18
|
|
19
|
+
def test_does_not_discard_steps_that_would_override_defaults
|
20
|
+
steps = {
|
21
|
+
'foo' => OpenStruct.new(
|
22
|
+
:optional_dependencies => [],
|
23
|
+
:required_dependencies => [:bar],
|
24
|
+
:provisions => [:baz],
|
25
|
+
),
|
26
|
+
'qux' => OpenStruct.new(
|
27
|
+
:optional_dependencies => [:baz],
|
28
|
+
:required_dependencies => [],
|
29
|
+
:provisions => [:res],
|
30
|
+
),
|
31
|
+
}
|
32
|
+
builder = assemble_builder steps
|
33
|
+
builder.input_names.concat [:bar]
|
34
|
+
|
35
|
+
builder.sort!
|
36
|
+
builder.prune!
|
37
|
+
run_list = builder.build
|
38
|
+
|
39
|
+
assert_equal %w(foo qux), run_list.step_names
|
40
|
+
end
|
41
|
+
|
19
42
|
def test_supplying_dependencies
|
20
43
|
builder.input_names << :baz
|
21
44
|
|
data/test/unit/step_test.rb
CHANGED
@@ -78,7 +78,7 @@ class StepTest < Minitest::Test
|
|
78
78
|
error = assert_raises Orchestra::MissingProvisionError do step.execute end
|
79
79
|
|
80
80
|
assert_equal(
|
81
|
-
"failed to supply output: :foo, :bar and :baz",
|
81
|
+
"Node `<anonymous>' failed to supply output: :foo, :bar and :baz",
|
82
82
|
error.message,
|
83
83
|
)
|
84
84
|
end
|
@@ -92,7 +92,7 @@ class StepTest < Minitest::Test
|
|
92
92
|
error = assert_raises Orchestra::MissingProvisionError do step.execute end
|
93
93
|
|
94
94
|
assert_equal(
|
95
|
-
"failed to supply output: :foo",
|
95
|
+
"Node `<anonymous>' failed to supply output: :foo",
|
96
96
|
error.message,
|
97
97
|
)
|
98
98
|
end
|
data/test/unit/util_test.rb
CHANGED
@@ -3,18 +3,4 @@ class UtilTest < Minitest::Test
|
|
3
3
|
assert_equal "foo/bar", Orchestra::Util.to_snake_case("Foo::Bar")
|
4
4
|
assert_equal "foo_bar", Orchestra::Util.to_snake_case("FOOBar")
|
5
5
|
end
|
6
|
-
|
7
|
-
def test_recursive_symbolizing
|
8
|
-
expected_hsh = {
|
9
|
-
foo: [{
|
10
|
-
bar: { baz: 'qux' },
|
11
|
-
},{
|
12
|
-
ping: ['pong'],
|
13
|
-
}],
|
14
|
-
}
|
15
|
-
|
16
|
-
actual_hsh = Orchestra::Util.recursively_symbolize JSON.load JSON.dump expected_hsh
|
17
|
-
|
18
|
-
assert_equal expected_hsh, actual_hsh
|
19
|
-
end
|
20
6
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ntl-orchestra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ntl
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01
|
11
|
+
date: 2015-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: invokr
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 0.9.7
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 0.9.7
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,9 +90,9 @@ files:
|
|
90
90
|
- lib/orchestra/dsl/steps.rb
|
91
91
|
- lib/orchestra/errors.rb
|
92
92
|
- lib/orchestra/execution.rb
|
93
|
-
- lib/orchestra/node.rb
|
94
93
|
- lib/orchestra/operation.rb
|
95
94
|
- lib/orchestra/recording.rb
|
95
|
+
- lib/orchestra/recording/node.rb
|
96
96
|
- lib/orchestra/recording/playback.rb
|
97
97
|
- lib/orchestra/run_list.rb
|
98
98
|
- lib/orchestra/step.rb
|
data/lib/orchestra/node.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
module Orchestra
|
2
|
-
# Reader object to expose operations and steps to the outside world
|
3
|
-
class Node
|
4
|
-
attr :input, :name
|
5
|
-
|
6
|
-
extend Forwardable
|
7
|
-
|
8
|
-
def_delegators :@node, :provisions, :dependencies, :optional_dependencies,
|
9
|
-
:required_dependencies
|
10
|
-
|
11
|
-
def initialize step_or_operation, name, input
|
12
|
-
@name = name
|
13
|
-
@node = step_or_operation
|
14
|
-
@input = format_input input
|
15
|
-
freeze
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_h
|
19
|
-
{
|
20
|
-
dependencies: dependencies,
|
21
|
-
input: input,
|
22
|
-
name: name,
|
23
|
-
optional_dependencies: optional_dependencies,
|
24
|
-
provisions: provisions,
|
25
|
-
required_dependencies: required_dependencies,
|
26
|
-
}
|
27
|
-
end
|
28
|
-
|
29
|
-
def inspect
|
30
|
-
params = to_h.each_with_object [] do |(key, val), list|
|
31
|
-
list << "#{key}=#{val.inspect}"
|
32
|
-
end
|
33
|
-
"#<Orchestra::Node #{params.join ', '}>"
|
34
|
-
end
|
35
|
-
|
36
|
-
def operation?
|
37
|
-
@node.is_a? Operation
|
38
|
-
end
|
39
|
-
|
40
|
-
def step?
|
41
|
-
not operation?
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def format_input input
|
47
|
-
@node.dependencies.each_with_object Hash.new do |dep, hsh|
|
48
|
-
hsh[dep] = input[dep] if input.has_key? dep
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|