simmer 1.0.0.pre.alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +8 -0
- data/.gitignore +7 -0
- data/.rubocop.yml +25 -0
- data/.ruby-version +1 -0
- data/.travis.yml +25 -0
- data/CHANGELOG.md +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +5 -0
- data/Guardfile +16 -0
- data/LICENSE +7 -0
- data/README.md +5 -0
- data/Rakefile +17 -0
- data/bin/console +18 -0
- data/bin/simmer +11 -0
- data/lib/simmer.rb +50 -0
- data/lib/simmer/configuration.rb +90 -0
- data/lib/simmer/core_ext/hash.rb +21 -0
- data/lib/simmer/externals.rb +12 -0
- data/lib/simmer/externals/aws_file_system.rb +81 -0
- data/lib/simmer/externals/mysql_database.rb +114 -0
- data/lib/simmer/externals/mysql_database/sql_fixture.rb +43 -0
- data/lib/simmer/externals/spoon_client.rb +77 -0
- data/lib/simmer/externals/spoon_client/mock.rb +39 -0
- data/lib/simmer/externals/spoon_client/result.rb +48 -0
- data/lib/simmer/judge.rb +38 -0
- data/lib/simmer/judge/result.rb +34 -0
- data/lib/simmer/runner.rb +125 -0
- data/lib/simmer/runner/result.rb +52 -0
- data/lib/simmer/session.rb +79 -0
- data/lib/simmer/session/reporter.rb +100 -0
- data/lib/simmer/session/result.rb +45 -0
- data/lib/simmer/specification.rb +34 -0
- data/lib/simmer/specification/act.rb +48 -0
- data/lib/simmer/specification/act/params.rb +55 -0
- data/lib/simmer/specification/assert.rb +27 -0
- data/lib/simmer/specification/assert/assertions.rb +27 -0
- data/lib/simmer/specification/assert/assertions/bad_output_assertion.rb +34 -0
- data/lib/simmer/specification/assert/assertions/bad_table_assertion.rb +38 -0
- data/lib/simmer/specification/assert/assertions/output.rb +37 -0
- data/lib/simmer/specification/assert/assertions/table.rb +47 -0
- data/lib/simmer/specification/stage.rb +28 -0
- data/lib/simmer/specification/stage/input_file.rb +33 -0
- data/lib/simmer/suite.rb +73 -0
- data/lib/simmer/util.rb +13 -0
- data/lib/simmer/util/evaluator.rb +32 -0
- data/lib/simmer/util/fixture.rb +32 -0
- data/lib/simmer/util/fixture_set.rb +41 -0
- data/lib/simmer/util/record.rb +54 -0
- data/lib/simmer/util/record_set.rb +51 -0
- data/lib/simmer/util/resolver.rb +28 -0
- data/lib/simmer/util/yaml_reader.rb +61 -0
- data/lib/simmer/version.rb +12 -0
- data/simmer.gemspec +38 -0
- data/spec/simmer/core_ext/hash_spec.rb +16 -0
- data/spec/spec_helper.rb +22 -0
- metadata +284 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2020-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
module Simmer
|
11
|
+
class Runner
|
12
|
+
# Return object from a Runner#run call.
|
13
|
+
class Result
|
14
|
+
extend Forwardable
|
15
|
+
|
16
|
+
attr_reader :id, :judge_result, :specification, :spoon_client_result
|
17
|
+
|
18
|
+
def_delegators :spoon_client_result, :time_in_seconds
|
19
|
+
|
20
|
+
def_delegators :specification, :name
|
21
|
+
|
22
|
+
def initialize(id, judge_result, specification, spoon_client_result)
|
23
|
+
@id = id.to_s
|
24
|
+
@judge_result = judge_result
|
25
|
+
@specification = specification
|
26
|
+
@spoon_client_result = spoon_client_result
|
27
|
+
|
28
|
+
freeze
|
29
|
+
end
|
30
|
+
|
31
|
+
def pass?
|
32
|
+
judge_result&.pass? && spoon_client_result&.pass?
|
33
|
+
end
|
34
|
+
|
35
|
+
def fail?
|
36
|
+
!pass?
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_h
|
40
|
+
{
|
41
|
+
'name' => specification.name,
|
42
|
+
'id' => id,
|
43
|
+
'path' => specification.path,
|
44
|
+
'time_in_seconds' => time_in_seconds,
|
45
|
+
'pass' => pass?,
|
46
|
+
'spoon_client_result' => spoon_client_result.to_h,
|
47
|
+
'judge_result' => judge_result.to_h
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2020-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
require_relative 'session/reporter'
|
11
|
+
require_relative 'session/result'
|
12
|
+
|
13
|
+
module Simmer
|
14
|
+
# Runs a collection of specifications and then writes down the results to disk.
|
15
|
+
class Session
|
16
|
+
def initialize(
|
17
|
+
config:,
|
18
|
+
out:,
|
19
|
+
resolver: Objectable.resolver,
|
20
|
+
results_dir:,
|
21
|
+
runner:
|
22
|
+
)
|
23
|
+
@config = config || {}
|
24
|
+
@out = out
|
25
|
+
@resolver = resolver
|
26
|
+
@results_dir = results_dir
|
27
|
+
@runner = runner
|
28
|
+
|
29
|
+
freeze
|
30
|
+
end
|
31
|
+
|
32
|
+
def run(specifications)
|
33
|
+
runner_results = run_all_specs(specifications)
|
34
|
+
|
35
|
+
Result.new(runner_results).tap do |result|
|
36
|
+
if result.pass?
|
37
|
+
out.puts('Suite ended successfully')
|
38
|
+
else
|
39
|
+
out.puts('Suite ended but was not successful')
|
40
|
+
end
|
41
|
+
|
42
|
+
Reporter.new(result).write!(results_dir)
|
43
|
+
|
44
|
+
out.puts("Results can be viewed at #{results_dir}")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
attr_reader :config, :out, :results_dir, :resolver, :runner
|
51
|
+
|
52
|
+
def run_all_specs(specifications)
|
53
|
+
out.puts('Simmer suite started')
|
54
|
+
|
55
|
+
count = specifications.length
|
56
|
+
|
57
|
+
out.puts("Running #{count} specification(s)")
|
58
|
+
print_line
|
59
|
+
|
60
|
+
specifications.map.with_index(1) do |specification, index|
|
61
|
+
run_single_spec(specification, index, count)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def run_single_spec(specification, index, count)
|
66
|
+
id = SecureRandom.uuid
|
67
|
+
|
68
|
+
out.puts("Test #{index} of #{count}: #{id}")
|
69
|
+
|
70
|
+
runner.run(specification, id: id, config: config).tap do
|
71
|
+
print_line
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def print_line
|
76
|
+
out.puts('-' * 60)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2020-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
module Simmer
|
11
|
+
class Session
|
12
|
+
# Understands how to write a SessionResult instance to disk.
|
13
|
+
class Reporter
|
14
|
+
DATA_FILE = 'data.yaml'
|
15
|
+
PDI_OUT_FILE = 'pdi_out.txt'
|
16
|
+
PDI_ERR_FILE = 'pdi_err.txt'
|
17
|
+
|
18
|
+
def initialize(session_result)
|
19
|
+
raise ArgumentError, 'session_result is required' unless session_result
|
20
|
+
|
21
|
+
@session_result = session_result
|
22
|
+
|
23
|
+
freeze
|
24
|
+
end
|
25
|
+
|
26
|
+
def write!(dir)
|
27
|
+
dir = setup_directory(dir)
|
28
|
+
|
29
|
+
IO.write(data_path(dir), session_result.to_h.to_yaml)
|
30
|
+
|
31
|
+
pdi_out_file = File.open(pdi_out_path(dir), 'w')
|
32
|
+
pdi_err_file = File.open(pdi_err_path(dir), 'w')
|
33
|
+
|
34
|
+
write_part(session_result.runner_results, pdi_out_file, pdi_err_file)
|
35
|
+
|
36
|
+
pdi_out_file.close
|
37
|
+
pdi_err_file.close
|
38
|
+
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_h
|
43
|
+
{
|
44
|
+
'pass' => pass?,
|
45
|
+
'time_in_seconds' => time_in_seconds,
|
46
|
+
'runner_results' => runner_results.map(&:to_h)
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
attr_reader :session_result
|
53
|
+
|
54
|
+
def data_path(dir)
|
55
|
+
File.join(dir, DATA_FILE)
|
56
|
+
end
|
57
|
+
|
58
|
+
def pdi_out_path(dir)
|
59
|
+
File.join(dir, PDI_OUT_FILE)
|
60
|
+
end
|
61
|
+
|
62
|
+
def pdi_err_path(dir)
|
63
|
+
File.join(dir, PDI_ERR_FILE)
|
64
|
+
end
|
65
|
+
|
66
|
+
def setup_directory(dir)
|
67
|
+
File.expand_path(dir).tap do |expanded_dir|
|
68
|
+
FileUtils.mkdir_p(expanded_dir)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def write_part(runner_results, pdi_out_file, pdi_err_file)
|
73
|
+
runner_results.each do |runner_result|
|
74
|
+
name = runner_result.name
|
75
|
+
runner_id = runner_result.id
|
76
|
+
out_contents = runner_result.spoon_client_result.execution_result.out
|
77
|
+
err_contents = runner_result.spoon_client_result.execution_result.err
|
78
|
+
|
79
|
+
write_block(pdi_out_file, name, runner_id, out_contents)
|
80
|
+
write_block(pdi_err_file, name, runner_id, err_contents)
|
81
|
+
end
|
82
|
+
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
|
86
|
+
def write_block(file, name, runner_id, contents)
|
87
|
+
hyphens = '-' * 80
|
88
|
+
|
89
|
+
file.write("#{hyphens}\n")
|
90
|
+
file.write("Name: #{name}\n")
|
91
|
+
file.write("Runner ID: #{runner_id}\n")
|
92
|
+
file.write("#{hyphens}\n")
|
93
|
+
file.write("#{contents}\n")
|
94
|
+
file.write("\n")
|
95
|
+
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2020-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
module Simmer
|
11
|
+
class Session
|
12
|
+
# The return object for a Session#run call.
|
13
|
+
class Result
|
14
|
+
attr_reader :runner_results
|
15
|
+
|
16
|
+
def initialize(runner_results = [])
|
17
|
+
@runner_results = Array(runner_results)
|
18
|
+
|
19
|
+
freeze
|
20
|
+
end
|
21
|
+
|
22
|
+
def pass?
|
23
|
+
!fail?
|
24
|
+
end
|
25
|
+
|
26
|
+
def fail?
|
27
|
+
runner_results.any?(&:fail?)
|
28
|
+
end
|
29
|
+
|
30
|
+
def time_in_seconds
|
31
|
+
runner_results.inject(0.0) do |memo, runner_result|
|
32
|
+
memo + runner_result.time_in_seconds
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_h
|
37
|
+
{
|
38
|
+
'pass' => pass?,
|
39
|
+
'time_in_seconds' => time_in_seconds,
|
40
|
+
'runner_results' => runner_results.map(&:to_h)
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2020-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
require_relative 'specification/act'
|
11
|
+
require_relative 'specification/assert'
|
12
|
+
require_relative 'specification/stage'
|
13
|
+
|
14
|
+
module Simmer
|
15
|
+
# Describes a specification at the highest of levels.
|
16
|
+
class Specification
|
17
|
+
acts_as_hashable
|
18
|
+
|
19
|
+
attr_reader :act, :assert, :name, :path, :stage
|
20
|
+
|
21
|
+
def initialize(act: {}, assert: {}, name:, path:, stage: {})
|
22
|
+
raise ArgumentError, 'name is required' if name.to_s.empty?
|
23
|
+
raise ArgumentError, 'path is required' if path.to_s.empty?
|
24
|
+
|
25
|
+
@act = Act.make(act)
|
26
|
+
@assert = Assert.make(assert)
|
27
|
+
@name = name.to_s
|
28
|
+
@path = path.to_s
|
29
|
+
@stage = Stage.make(stage)
|
30
|
+
|
31
|
+
freeze
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2020-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
require_relative 'act/params'
|
11
|
+
|
12
|
+
module Simmer
|
13
|
+
class Specification
|
14
|
+
# Describes everything necessary to execute Pdi::Spoon.
|
15
|
+
class Act
|
16
|
+
extend Forwardable
|
17
|
+
acts_as_hashable
|
18
|
+
|
19
|
+
module Type
|
20
|
+
JOB = :job
|
21
|
+
TRANSFORMATION = :transformation
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :repository, :name, :type, :params
|
25
|
+
|
26
|
+
def_delegator :params, :compile, :compiled_params
|
27
|
+
|
28
|
+
def initialize(repository:, name:, type:, params: {})
|
29
|
+
assert_presence(repository, 'repository')
|
30
|
+
assert_presence(name, 'name')
|
31
|
+
assert_presence(type, 'type')
|
32
|
+
|
33
|
+
@repository = repository.to_s
|
34
|
+
@name = name.to_s
|
35
|
+
@type = Type.const_get(type.to_s.to_s.upcase.to_sym)
|
36
|
+
@params = Params.make(params)
|
37
|
+
|
38
|
+
freeze
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def assert_presence(value, name)
|
44
|
+
raise ArgumentError, "#{name} is required" if value.to_s.empty?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2020-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
module Simmer
|
11
|
+
class Specification
|
12
|
+
class Act
|
13
|
+
# Understands how to compile a list of files and key value pairs for Pdi::Spoon
|
14
|
+
# consumption.
|
15
|
+
class Params
|
16
|
+
acts_as_hashable
|
17
|
+
|
18
|
+
attr_reader :files, :keys
|
19
|
+
|
20
|
+
def initialize(files: {}, keys: {})
|
21
|
+
@files = files || {}
|
22
|
+
@keys = keys || {}
|
23
|
+
@evaluator = Util::Evaluator.new
|
24
|
+
|
25
|
+
freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
def compile(files_path, config = {})
|
29
|
+
compiled_file_params(files_path, config).merge(compiled_key_params(config))
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :evaluator
|
35
|
+
|
36
|
+
def compiled_file_params(files_path, config)
|
37
|
+
files.map do |key, value|
|
38
|
+
evaluated_value = evaluator.evaluate(value, config)
|
39
|
+
expanded_value = File.expand_path(File.join(files_path, evaluated_value))
|
40
|
+
|
41
|
+
[key, expanded_value]
|
42
|
+
end.to_h
|
43
|
+
end
|
44
|
+
|
45
|
+
def compiled_key_params(config)
|
46
|
+
keys.map do |key, value|
|
47
|
+
evaluated_value = evaluator.evaluate(value, config)
|
48
|
+
|
49
|
+
[key, evaluated_value]
|
50
|
+
end.to_h
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2020-present, Blue Marble Payroll, LLC
|
5
|
+
#
|
6
|
+
# This source code is licensed under the MIT license found in the
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
8
|
+
#
|
9
|
+
|
10
|
+
require_relative 'assert/assertions'
|
11
|
+
|
12
|
+
module Simmer
|
13
|
+
class Specification
|
14
|
+
# Describes what should be expected after a Pdi::Spoon execution.
|
15
|
+
class Assert
|
16
|
+
acts_as_hashable
|
17
|
+
|
18
|
+
attr_reader :assertions
|
19
|
+
|
20
|
+
def initialize(assertions: [])
|
21
|
+
@assertions = Assertions.array(assertions)
|
22
|
+
|
23
|
+
freeze
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|