simmer 1.0.0.pre.alpha.3 → 1.0.0.pre.alpha.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +5 -0
- data/lib/simmer.rb +103 -9
- data/lib/simmer/configuration.rb +7 -17
- data/lib/simmer/database.rb +10 -0
- data/lib/simmer/{util → database}/fixture.rb +7 -3
- data/lib/simmer/{util → database}/fixture_set.rb +10 -4
- data/lib/simmer/externals/aws_file_system.rb +30 -23
- data/lib/simmer/externals/mysql_database.rb +17 -10
- data/lib/simmer/externals/spoon_client.rb +5 -19
- data/lib/simmer/runner.rb +2 -2
- data/lib/simmer/specification/act.rb +1 -6
- data/lib/simmer/specification/assert/assertions/table.rb +1 -6
- data/lib/simmer/spoon_mock.rb +35 -0
- data/lib/simmer/suite.rb +49 -43
- data/lib/simmer/{session → suite}/reporter.rb +1 -1
- data/lib/simmer/{session → suite}/result.rb +1 -1
- data/lib/simmer/util.rb +0 -1
- data/lib/simmer/util/evaluator.rb +4 -5
- data/lib/simmer/util/record.rb +2 -0
- data/lib/simmer/util/record_set.rb +5 -1
- data/lib/simmer/util/resolver.rb +2 -2
- data/lib/simmer/util/yaml_reader.rb +9 -12
- data/lib/simmer/version.rb +1 -1
- data/spec/config/simmer.yaml.ci +7 -0
- data/spec/db/database.sql +1 -0
- data/spec/db/tables.sql +20 -0
- data/spec/db_helper.rb +26 -0
- data/spec/fixtures/agent_fixtures.yaml +14 -0
- data/spec/fixtures/configuration.yaml +11 -0
- data/spec/fixtures/noc_list.csv +3 -0
- data/spec/fixtures/specifications/load_noc_list.yaml +30 -0
- data/spec/fixtures/yaml_reader/bar.yaml +2 -0
- data/spec/fixtures/yaml_reader/baz/baz.yaml +2 -0
- data/spec/fixtures/yaml_reader/foo.yaml +2 -0
- data/spec/simmer/configuration_spec.rb +46 -0
- data/spec/simmer/database/fixture_set_spec.rb +75 -0
- data/spec/simmer/database/fixture_spec.rb +57 -0
- data/spec/simmer/externals/aws_file_system_spec.rb +75 -0
- data/spec/simmer/externals/mysql_database_spec.rb +79 -0
- data/spec/simmer/externals/spoon_client_spec.rb +67 -0
- data/spec/simmer/specification/act/params_spec.rb +38 -0
- data/spec/simmer/specification/act_spec.rb +37 -0
- data/spec/simmer/specification/assert_spec.rb +27 -0
- data/spec/simmer/specification/stage_spec.rb +32 -0
- data/spec/simmer/specification_spec.rb +28 -0
- data/spec/simmer/util/evaluator_spec.rb +82 -0
- data/spec/simmer/util/record_set_spec.rb +41 -0
- data/spec/simmer/util/record_spec.rb +218 -0
- data/spec/simmer/util/yaml_reader_spec.rb +49 -0
- data/spec/spec_helper.rb +21 -0
- metadata +60 -8
- data/lib/simmer/externals/spoon_client/mock.rb +0 -39
- data/lib/simmer/session.rb +0 -79
@@ -0,0 +1,30 @@
|
|
1
|
+
name: Declassify Users
|
2
|
+
stage:
|
3
|
+
files:
|
4
|
+
src: noc_list.csv
|
5
|
+
dest: input/noc_list.csv
|
6
|
+
fixtures:
|
7
|
+
- iron_man
|
8
|
+
- hulk
|
9
|
+
act:
|
10
|
+
name: load_noc_list
|
11
|
+
repository: top_secret
|
12
|
+
type: transformation
|
13
|
+
params:
|
14
|
+
files:
|
15
|
+
input_file: noc_list.csv
|
16
|
+
keys:
|
17
|
+
code: 'The secret code is: {codes.the_secret_one}'
|
18
|
+
assert:
|
19
|
+
assertions:
|
20
|
+
- type: table
|
21
|
+
name: agents
|
22
|
+
records:
|
23
|
+
- call_sign: iron_man
|
24
|
+
first: tony
|
25
|
+
last: stark
|
26
|
+
- call_sign: hulk
|
27
|
+
first: bruce
|
28
|
+
last: banner
|
29
|
+
- type: output
|
30
|
+
value: Decoding Agents
|
@@ -0,0 +1,46 @@
|
|
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 'spec_helper'
|
11
|
+
|
12
|
+
describe Simmer::Configuration do
|
13
|
+
let(:path) { File.join('configuration.yaml') }
|
14
|
+
let(:config) { yaml_fixture(path) }
|
15
|
+
let(:simmer_dir) { 'simmer' }
|
16
|
+
|
17
|
+
subject { described_class.new(config, simmer_dir) }
|
18
|
+
|
19
|
+
specify '#mysql_database_config resolves' do
|
20
|
+
expect(subject.mysql_database_config).to eq('mysql_database_key' => 'mysql_database_value')
|
21
|
+
end
|
22
|
+
|
23
|
+
specify '#aws_file_system_config resolves' do
|
24
|
+
expect(subject.aws_file_system_config).to eq('aws_file_system_key' => 'aws_file_system_value')
|
25
|
+
end
|
26
|
+
|
27
|
+
specify '#spoon_client_config resolves' do
|
28
|
+
expect(subject.spoon_client_config).to eq('spoon_client_key' => 'spoon_client_value')
|
29
|
+
end
|
30
|
+
|
31
|
+
specify '#tests_dir resolves' do
|
32
|
+
expect(subject.tests_dir).to eq(File.join(simmer_dir, 'specs'))
|
33
|
+
end
|
34
|
+
|
35
|
+
specify '#fixtures_dir resolves' do
|
36
|
+
expect(subject.fixtures_dir).to eq(File.join(simmer_dir, 'fixtures'))
|
37
|
+
end
|
38
|
+
|
39
|
+
specify '#files_dir resolves' do
|
40
|
+
expect(subject.files_dir).to eq(File.join(simmer_dir, 'files'))
|
41
|
+
end
|
42
|
+
|
43
|
+
specify '#results_dir resolves' do
|
44
|
+
expect(subject.results_dir).to eq(File.join(simmer_dir, 'results'))
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,75 @@
|
|
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 'spec_helper'
|
11
|
+
|
12
|
+
describe Simmer::Database::FixtureSet do
|
13
|
+
let(:config) do
|
14
|
+
{
|
15
|
+
'Some Fixture' => {
|
16
|
+
fields: {
|
17
|
+
first: 'Frank',
|
18
|
+
last: 'Rizzo'
|
19
|
+
},
|
20
|
+
table: 'users'
|
21
|
+
},
|
22
|
+
bozo: {
|
23
|
+
fields: {
|
24
|
+
first: 'Bozo',
|
25
|
+
last: 'The Clown'
|
26
|
+
},
|
27
|
+
table: 'users'
|
28
|
+
}
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
subject { described_class.new(config) }
|
33
|
+
|
34
|
+
describe '#get!' do
|
35
|
+
context 'when name is a string' do
|
36
|
+
it 'returns Fixture if name exists' do
|
37
|
+
name = 'Some Fixture'
|
38
|
+
|
39
|
+
expected = Simmer::Database::Fixture.make(config[name.to_s].merge(name: name))
|
40
|
+
|
41
|
+
expect(subject.get!(name)).to eq(expected)
|
42
|
+
|
43
|
+
name = 'bozo'
|
44
|
+
|
45
|
+
expected = Simmer::Database::Fixture.make(config[name.to_sym].merge(name: name))
|
46
|
+
|
47
|
+
expect(subject.get!(name)).to eq(expected)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'raises ArgumentError if name does not exist' do
|
51
|
+
expect { subject.get!(:doesnt_exist) }.to raise_error(ArgumentError)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when name is a symbol' do
|
56
|
+
it 'returns Fixture if name exists' do
|
57
|
+
name = :'Some Fixture'
|
58
|
+
|
59
|
+
expected = Simmer::Database::Fixture.make(config[name.to_s].merge(name: name))
|
60
|
+
|
61
|
+
expect(subject.get!(name)).to eq(expected)
|
62
|
+
|
63
|
+
name = :bozo
|
64
|
+
|
65
|
+
expected = Simmer::Database::Fixture.make(config[name.to_sym].merge(name: name))
|
66
|
+
|
67
|
+
expect(subject.get!(name)).to eq(expected)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'raises ArgumentError if name does not exist' do
|
71
|
+
expect { subject.get!(:doesnt_exist) }.to raise_error(ArgumentError)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,57 @@
|
|
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 'spec_helper'
|
11
|
+
|
12
|
+
describe Simmer::Database::Fixture do
|
13
|
+
let(:config) do
|
14
|
+
{
|
15
|
+
fields: {
|
16
|
+
first: 'Frank',
|
17
|
+
last: 'Rizzo'
|
18
|
+
},
|
19
|
+
name: 'Some Fixture',
|
20
|
+
table: 'users'
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'initialization' do
|
25
|
+
context 'when using acts_as_hashable' do
|
26
|
+
subject { described_class.make(config) }
|
27
|
+
|
28
|
+
it 'sets fields' do
|
29
|
+
expect(subject.fields).to eq(config[:fields])
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'sets name' do
|
33
|
+
expect(subject.name).to eq(config[:name])
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'sets table' do
|
37
|
+
expect(subject.table).to eq(config[:table])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'equality' do
|
43
|
+
subject { described_class.new(config) }
|
44
|
+
|
45
|
+
specify '#== compares all attributes' do
|
46
|
+
subject2 = described_class.new(config)
|
47
|
+
|
48
|
+
expect(subject).to eq(subject2)
|
49
|
+
end
|
50
|
+
|
51
|
+
specify '#eql? compares all attributes' do
|
52
|
+
subject2 = described_class.new(config)
|
53
|
+
|
54
|
+
expect(subject).to eql(subject2)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,75 @@
|
|
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 'spec_helper'
|
11
|
+
|
12
|
+
describe Simmer::Externals::AwsFileSystem do
|
13
|
+
let(:bucket_store) { {} }
|
14
|
+
let(:bucket_name) { 'test' }
|
15
|
+
let(:encryption) { 'AES256' }
|
16
|
+
let(:files_dir) { File.join('spec', 'fixtures') }
|
17
|
+
let(:specification_path) { File.join('specifications', 'load_noc_list.yaml') }
|
18
|
+
let(:specification_config) { yaml_fixture(specification_path).merge(path: specification_path) }
|
19
|
+
let(:specification) { Simmer::Specification.make(specification_config) }
|
20
|
+
|
21
|
+
let(:aws_s3_client_stub) do
|
22
|
+
Aws::S3::Client.new(stub_responses: true).tap do |client|
|
23
|
+
client.stub_responses(:get_object, lambda { |context|
|
24
|
+
obj = bucket_store[context.params[:key]]
|
25
|
+
obj || 'NoSuchKey'
|
26
|
+
})
|
27
|
+
|
28
|
+
client.stub_responses(:put_object, lambda { |context|
|
29
|
+
bucket_store[context.params[:key]] = { body: context.params[:body] }
|
30
|
+
{}
|
31
|
+
})
|
32
|
+
|
33
|
+
client.stub_responses(:list_objects, lambda { |_context|
|
34
|
+
contents = bucket_store.keys.map { |k| OpenStruct.new(key: k) }
|
35
|
+
|
36
|
+
OpenStruct.new(contents: contents)
|
37
|
+
})
|
38
|
+
|
39
|
+
client.stub_responses(:delete_objects, lambda { |context|
|
40
|
+
keys = context.params.dig(:delete, :objects).map { |k| k[:key] }
|
41
|
+
|
42
|
+
keys.each { |key| bucket_store.delete(key) }
|
43
|
+
})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
subject { described_class.new(aws_s3_client_stub, bucket_name, encryption, files_dir) }
|
48
|
+
|
49
|
+
specify '#write transfers all files' do
|
50
|
+
subject.write!(specification)
|
51
|
+
|
52
|
+
expected = {
|
53
|
+
'input/noc_list.csv' => {
|
54
|
+
body: "call_sign,first,last\niron_man,Tony,Stark\nhulk,Bruce,Banner\n"
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
expect(bucket_store).to eq(expected)
|
59
|
+
end
|
60
|
+
|
61
|
+
specify '#clean! deletes all files' do
|
62
|
+
aws_s3_client_stub.put_object(
|
63
|
+
body: 'Test File',
|
64
|
+
bucket: bucket_name,
|
65
|
+
key: 'test_key.txt',
|
66
|
+
server_side_encryption: encryption
|
67
|
+
)
|
68
|
+
|
69
|
+
subject.clean!
|
70
|
+
|
71
|
+
expected = {}
|
72
|
+
|
73
|
+
expect(bucket_store).to eq(expected)
|
74
|
+
end
|
75
|
+
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 'spec_helper'
|
11
|
+
require 'db_helper'
|
12
|
+
|
13
|
+
describe Simmer::Externals::MysqlDatabase do
|
14
|
+
let(:exclude_tables) { [] }
|
15
|
+
let(:raw_fixtures) { yaml_read('spec', 'fixtures', 'agent_fixtures.yaml') }
|
16
|
+
let(:fixture_set) { Simmer::Database::FixtureSet.new(raw_fixtures) }
|
17
|
+
let(:spec_path) { File.join('specifications', 'load_noc_list.yaml') }
|
18
|
+
let(:spec_config) { yaml_fixture(spec_path).merge(path: spec_path) }
|
19
|
+
let(:specification) { Simmer::Specification.make(spec_config) }
|
20
|
+
|
21
|
+
subject { described_class.new(db_helper_client, exclude_tables, fixture_set) }
|
22
|
+
|
23
|
+
before(:each) do
|
24
|
+
db_helper_clean_schema
|
25
|
+
end
|
26
|
+
|
27
|
+
specify '#seed! adds records' do
|
28
|
+
subject.seed!(specification)
|
29
|
+
|
30
|
+
actual = db_helper_client.query('SELECT * FROM agents ORDER BY call_sign').to_a
|
31
|
+
|
32
|
+
call_signs = actual.map { |r| r['call_sign'] }
|
33
|
+
|
34
|
+
expect(call_signs).to eq(%w[hulk iron_man])
|
35
|
+
end
|
36
|
+
|
37
|
+
specify '#clean! removes all records without worrying about foreign keys' do
|
38
|
+
db_helper_client.query("INSERT INTO agents (id, call_sign) VALUES (1, 'thor')")
|
39
|
+
db_helper_client.query("INSERT INTO notes (agent_id, note) VALUES (1, 'thor')")
|
40
|
+
|
41
|
+
agent_count = db_helper_client.query('SELECT * FROM agents').to_a.length
|
42
|
+
note_count = db_helper_client.query('SELECT * FROM notes').to_a.length
|
43
|
+
|
44
|
+
expect(agent_count).to eq(1)
|
45
|
+
expect(note_count).to eq(1)
|
46
|
+
|
47
|
+
table_count = subject.clean!
|
48
|
+
|
49
|
+
expect(table_count).to eq(2)
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#records' do
|
53
|
+
before(:each) do
|
54
|
+
db_helper_client.query("INSERT INTO agents (id, call_sign) VALUES (1, 'thor')")
|
55
|
+
db_helper_client.query("INSERT INTO agents (id, call_sign) VALUES (2, 'black_widow')")
|
56
|
+
end
|
57
|
+
|
58
|
+
specify 'when fields is empty' do
|
59
|
+
actual = subject.records(:agents)
|
60
|
+
|
61
|
+
expected = [
|
62
|
+
{
|
63
|
+
'id' => 1,
|
64
|
+
'call_sign' => 'thor',
|
65
|
+
'first' => nil,
|
66
|
+
'last' => nil
|
67
|
+
},
|
68
|
+
{
|
69
|
+
'id' => 2,
|
70
|
+
'call_sign' => 'black_widow',
|
71
|
+
'first' => nil,
|
72
|
+
'last' => nil
|
73
|
+
}
|
74
|
+
]
|
75
|
+
|
76
|
+
expect(actual).to eq(expected)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,67 @@
|
|
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 'spec_helper'
|
11
|
+
require 'db_helper'
|
12
|
+
|
13
|
+
describe Simmer::Externals::SpoonClient do
|
14
|
+
class Mock
|
15
|
+
attr_reader :result
|
16
|
+
|
17
|
+
def initialize(result)
|
18
|
+
@result = result
|
19
|
+
end
|
20
|
+
|
21
|
+
def run(*)
|
22
|
+
raise Pdi::Spoon::KitchenError, OpenStruct.new(code: 1) if result == 'KitchenError'
|
23
|
+
raise Pdi::Spoon::PanError, OpenStruct.new(code: 1) if result == 'PanError'
|
24
|
+
|
25
|
+
Pdi::Executor::Result.new(result)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:files_dir) { File.join('spec', 'fixtures') }
|
30
|
+
let(:specification_path) { File.join('specifications', 'load_noc_list.yaml') }
|
31
|
+
let(:specification_config) { yaml_fixture(specification_path).merge(path: specification_path) }
|
32
|
+
let(:specification) { Simmer::Specification.make(specification_config) }
|
33
|
+
|
34
|
+
subject { described_class.new(files_dir, spoon) }
|
35
|
+
|
36
|
+
context 'when PDI executes successfully' do
|
37
|
+
let(:spoon) do
|
38
|
+
Mock.new(
|
39
|
+
args: [],
|
40
|
+
status: {
|
41
|
+
code: 0,
|
42
|
+
err: 'Some error output from PDI',
|
43
|
+
out: 'Some output from PDI',
|
44
|
+
pid: 123
|
45
|
+
}
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
specify '#run is called with the right arguments' do
|
50
|
+
expected_path = File.expand_path(File.join(files_dir, 'noc_list.csv'))
|
51
|
+
|
52
|
+
args = {
|
53
|
+
repository: 'top_secret',
|
54
|
+
name: 'load_noc_list',
|
55
|
+
params: {
|
56
|
+
'input_file' => expected_path,
|
57
|
+
'code' => 'The secret code is: '
|
58
|
+
},
|
59
|
+
type: 'transformation'
|
60
|
+
}
|
61
|
+
|
62
|
+
expect(spoon).to receive(:run).with(args)
|
63
|
+
|
64
|
+
subject.run(specification, simmer_config)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|