dop_common 0.13.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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +176 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +177 -0
- data/README.md +48 -0
- data/Rakefile +49 -0
- data/Vagrantfile +25 -0
- data/bin/dop-puppet-autosign +56 -0
- data/doc/examples/example_deploment_plan_v0.0.1.yaml +302 -0
- data/doc/plan_format_v0.0.1.md +919 -0
- data/doc/plan_format_v0.0.2_snippets.md +56 -0
- data/dop_common.gemspec +44 -0
- data/lib/dop_common/affinity_group.rb +57 -0
- data/lib/dop_common/cli/global_options.rb +37 -0
- data/lib/dop_common/cli/log.rb +51 -0
- data/lib/dop_common/cli/node_selection.rb +62 -0
- data/lib/dop_common/command.rb +125 -0
- data/lib/dop_common/config/helper.rb +39 -0
- data/lib/dop_common/config.rb +66 -0
- data/lib/dop_common/configuration.rb +37 -0
- data/lib/dop_common/credential.rb +152 -0
- data/lib/dop_common/data_disk.rb +62 -0
- data/lib/dop_common/dns.rb +55 -0
- data/lib/dop_common/hash_parser.rb +241 -0
- data/lib/dop_common/hooks.rb +81 -0
- data/lib/dop_common/infrastructure.rb +160 -0
- data/lib/dop_common/infrastructure_properties.rb +185 -0
- data/lib/dop_common/interface.rb +113 -0
- data/lib/dop_common/log.rb +78 -0
- data/lib/dop_common/network.rb +85 -0
- data/lib/dop_common/node/config.rb +159 -0
- data/lib/dop_common/node.rb +442 -0
- data/lib/dop_common/node_filter.rb +74 -0
- data/lib/dop_common/plan.rb +188 -0
- data/lib/dop_common/plan_cache.rb +83 -0
- data/lib/dop_common/plan_store.rb +263 -0
- data/lib/dop_common/pre_processor.rb +73 -0
- data/lib/dop_common/run_options.rb +56 -0
- data/lib/dop_common/signal_handler.rb +58 -0
- data/lib/dop_common/state_store.rb +95 -0
- data/lib/dop_common/step.rb +200 -0
- data/lib/dop_common/step_set.rb +41 -0
- data/lib/dop_common/thread_context_logger.rb +77 -0
- data/lib/dop_common/utils.rb +106 -0
- data/lib/dop_common/validator.rb +53 -0
- data/lib/dop_common/version.rb +3 -0
- data/lib/dop_common.rb +32 -0
- data/lib/hiera/backend/dop_backend.rb +94 -0
- data/lib/hiera/dop_logger.rb +20 -0
- data/spec/data/fake_hook_file_invalid +1 -0
- data/spec/data/fake_hook_file_valid +5 -0
- data/spec/data/fake_keyfile +1 -0
- data/spec/dop-puppet-autosign_spec_disable.rb +33 -0
- data/spec/dop_common/affinity_group_spec.rb +41 -0
- data/spec/dop_common/command_spec.rb +83 -0
- data/spec/dop_common/credential_spec.rb +73 -0
- data/spec/dop_common/data_disk_spec.rb +165 -0
- data/spec/dop_common/dns_spec.rb +33 -0
- data/spec/dop_common/hash_parser_spec.rb +181 -0
- data/spec/dop_common/hooks_spec.rb +33 -0
- data/spec/dop_common/infrastructure_properties_spec.rb +224 -0
- data/spec/dop_common/infrastructure_spec.rb +77 -0
- data/spec/dop_common/interface_spec.rb +192 -0
- data/spec/dop_common/network_spec.rb +92 -0
- data/spec/dop_common/node_filter_spec.rb +70 -0
- data/spec/dop_common/node_spec.rb +623 -0
- data/spec/dop_common/plan_cache_spec.rb +46 -0
- data/spec/dop_common/plan_spec.rb +136 -0
- data/spec/dop_common/plan_store_spec.rb +194 -0
- data/spec/dop_common/pre_processor_spec.rb +27 -0
- data/spec/dop_common/run_options_spec.rb +65 -0
- data/spec/dop_common/signal_handler_spec.rb +31 -0
- data/spec/dop_common/step_set_spec.rb +21 -0
- data/spec/dop_common/step_spec.rb +175 -0
- data/spec/dop_common/utils_spec.rb +27 -0
- data/spec/dop_common/validator_spec.rb +47 -0
- data/spec/example_plans_spec.rb +16 -0
- data/spec/fixtures/example_ssh_key +27 -0
- data/spec/fixtures/example_ssh_key.pub +1 -0
- data/spec/fixtures/incl/root_part.yaml +1 -0
- data/spec/fixtures/incl/some_list.yaml +2 -0
- data/spec/fixtures/other_plan_same_nodes.yaml +19 -0
- data/spec/fixtures/simple_include.yaml +6 -0
- data/spec/fixtures/simple_include_with_errors.yaml +4 -0
- data/spec/fixtures/simple_plan.yaml +19 -0
- data/spec/fixtures/simple_plan_invalid.yaml +18 -0
- data/spec/fixtures/simple_plan_modified.yaml +21 -0
- data/spec/spec_helper.rb +106 -0
- metadata +381 -0
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DopCommon::Plan do
|
4
|
+
|
5
|
+
describe '#name' do
|
6
|
+
it 'will return a hash if no name is defined' do
|
7
|
+
plan = DopCommon::Plan.new({})
|
8
|
+
if RUBY_VERSION <= '1.8.7'
|
9
|
+
expect(plan.name).to eq 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
10
|
+
else
|
11
|
+
expect(plan.name).to eq '44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
it 'will return the correct value if name is defined' do
|
15
|
+
plan = DopCommon::Plan.new({:name => 'myplan'})
|
16
|
+
expect(plan.name).to eq 'myplan'
|
17
|
+
plan = DopCommon::Plan.new({:name => 'my-plan'})
|
18
|
+
expect(plan.name).to eq 'my-plan'
|
19
|
+
end
|
20
|
+
it 'will throw and exception if the value is not a String' do
|
21
|
+
plan = DopCommon::Plan.new({:name => 2})
|
22
|
+
expect{plan.name}.to raise_error DopCommon::PlanParsingError
|
23
|
+
end
|
24
|
+
it 'will throw and exception if the value contais illegal chars' do
|
25
|
+
plan = DopCommon::Plan.new({:name => 'my(plan'})
|
26
|
+
expect{plan.name}.to raise_error DopCommon::PlanParsingError
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#infrastructures' do
|
31
|
+
it 'will throw and exception if the infrastructures key is not defined' do
|
32
|
+
plan = DopCommon::Plan.new({})
|
33
|
+
expect{plan.infrastructures}.to raise_error DopCommon::PlanParsingError
|
34
|
+
end
|
35
|
+
it 'will throw and exception if the infrastructures value is not a Hash' do
|
36
|
+
plan = DopCommon::Plan.new({:infrastructures => 'foo'})
|
37
|
+
expect{plan.infrastructures}.to raise_error DopCommon::PlanParsingError
|
38
|
+
end
|
39
|
+
it 'will throw and exception if the infrastructures hash is empty' do
|
40
|
+
plan = DopCommon::Plan.new({:infrastructures => {}})
|
41
|
+
expect{plan.infrastructures}.to raise_error DopCommon::PlanParsingError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#nodes' do
|
46
|
+
it 'will return a list of nodes' do
|
47
|
+
plan = DopCommon::Plan.new({:infrastructures => {:management => {}}, :nodes => {'mynode{i}.example.com' =>{:range => '1..10', :digits => 3}}})
|
48
|
+
expect(plan.nodes.length).to be 10
|
49
|
+
expect(plan.nodes[0].name).to eq 'mynode001.example.com'
|
50
|
+
expect(plan.nodes[9].name).to eq 'mynode010.example.com'
|
51
|
+
end
|
52
|
+
it 'will throw and exception if the nodes key is not defined' do
|
53
|
+
plan = DopCommon::Plan.new({})
|
54
|
+
expect{plan.nodes}.to raise_error DopCommon::PlanParsingError
|
55
|
+
end
|
56
|
+
it 'will throw and exception if the nodes value is not a Hash' do
|
57
|
+
plan = DopCommon::Plan.new({:nodes => 'foo'})
|
58
|
+
expect{plan.nodes}.to raise_error DopCommon::PlanParsingError
|
59
|
+
end
|
60
|
+
it 'will throw and exception if the nodes hash is empty' do
|
61
|
+
plan = DopCommon::Plan.new({:nodes => {}})
|
62
|
+
expect{plan.nodes}.to raise_error DopCommon::PlanParsingError
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#step_sets' do
|
67
|
+
it 'will return an empty array if the steps key is not defined' do
|
68
|
+
plan = DopCommon::Plan.new({})
|
69
|
+
expect(plan.step_sets).to eq([])
|
70
|
+
end
|
71
|
+
it 'will return a StepSet object if the stepset is specified correctly' do
|
72
|
+
plan = DopCommon::Plan.new({:steps => []})
|
73
|
+
expect(plan.step_sets.all?{|s| s.kind_of?(DopCommon::StepSet)}).to be true
|
74
|
+
plan = DopCommon::Plan.new({:steps => {'foo' => []}})
|
75
|
+
expect(plan.step_sets.all?{|s| s.kind_of?(DopCommon::StepSet)}).to be true
|
76
|
+
end
|
77
|
+
it 'will throw and exception if the value is not an Array or Hash' do
|
78
|
+
plan = DopCommon::Plan.new({:steps => 'foo'})
|
79
|
+
expect{plan.step_sets}.to raise_error DopCommon::PlanParsingError
|
80
|
+
end
|
81
|
+
it 'will throw and exception if the hash is empty' do
|
82
|
+
plan = DopCommon::Plan.new({:steps => {}})
|
83
|
+
expect{plan.step_sets}.to raise_error DopCommon::PlanParsingError
|
84
|
+
end
|
85
|
+
it 'will throw and exception if the hash is invalid' do
|
86
|
+
plan = DopCommon::Plan.new({:steps => {2 => {}}})
|
87
|
+
expect{plan.step_sets}.to raise_error DopCommon::PlanParsingError
|
88
|
+
plan = DopCommon::Plan.new({:steps => {'foo' => 2}})
|
89
|
+
expect{plan.step_sets}.to raise_error DopCommon::PlanParsingError
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '#credentials' do
|
94
|
+
it 'will return an empty Hash of credentials if nothing is specified' do
|
95
|
+
plan = DopCommon::Plan.new({})
|
96
|
+
expect(plan.credentials).to eq({})
|
97
|
+
end
|
98
|
+
it 'will return a Hash of credentials if correctly specified' do
|
99
|
+
plan = DopCommon::Plan.new({:credentials => {'test' => {
|
100
|
+
:type => :username_password,
|
101
|
+
:username => 'a',
|
102
|
+
:password => 'b'
|
103
|
+
}}})
|
104
|
+
expect(plan.credentials.key?('test')).to be true
|
105
|
+
expect(plan.credentials['test']).to be_a ::DopCommon::Credential
|
106
|
+
end
|
107
|
+
it 'will raise an exception if the the key is not valid' do
|
108
|
+
plan = DopCommon::Plan.new({:credentials => {2 => {}}})
|
109
|
+
expect{plan.credentials}.to raise_error DopCommon::PlanParsingError
|
110
|
+
end
|
111
|
+
it 'will raise an exception if the value is not a hash' do
|
112
|
+
plan = DopCommon::Plan.new({:credentials => {'test' => 2}})
|
113
|
+
expect{plan.credentials}.to raise_error DopCommon::PlanParsingError
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#hooks' do
|
118
|
+
it 'will return hooks object if specified properly' do
|
119
|
+
plan = ::DopCommon::Plan.new({})
|
120
|
+
expect(plan.hooks).to be_a(::DopCommon::Hooks)
|
121
|
+
%w(create update destroy).each do |action|
|
122
|
+
%w(pre post).each do |prefix|
|
123
|
+
hook_name = "#{prefix}_#{action}_vm"
|
124
|
+
plan = ::DopCommon::Plan.new({'hooks' => {hook_name => []}})
|
125
|
+
expect(plan.hooks).to be_an_instance_of(::DopCommon::Hooks)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
it 'will raise an error if not specified correctly' do
|
130
|
+
plan = ::DopCommon::Plan.new({'hooks' => {}})
|
131
|
+
expect { plan.hooks }.to raise_error ::DopCommon::PlanParsingError
|
132
|
+
plan = ::DopCommon::Plan.new({'hooks' => {'invalid' => ['/foo/bar/baz']}})
|
133
|
+
expect { plan.hooks }.to raise_error ::DopCommon::PlanParsingError
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DopCommon::PlanStore do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@tmpdir = Dir.mktmpdir
|
7
|
+
@plan_store = DopCommon::PlanStore.new(@tmpdir)
|
8
|
+
end
|
9
|
+
|
10
|
+
after :each do
|
11
|
+
FileUtils.remove_entry_secure(@tmpdir)
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:plan) { 'spec/fixtures/simple_plan.yaml' }
|
15
|
+
let(:plan_name) { 'simple_plan' }
|
16
|
+
let(:plan_dir) { File.join(@tmpdir, plan_name) }
|
17
|
+
let(:versions_dir) { File.join(plan_dir, 'versions') }
|
18
|
+
|
19
|
+
describe '#add' do
|
20
|
+
subject { @plan_store.add(plan) }
|
21
|
+
|
22
|
+
context 'The plan file is correct' do
|
23
|
+
it { is_expected.to eq('simple_plan') }
|
24
|
+
it { subject; expect(Dir[versions_dir + '/*.yaml'].length).to be 1 }
|
25
|
+
end
|
26
|
+
context 'The plan is in hash form' do
|
27
|
+
let(:plan) { YAML.load_file('spec/fixtures/simple_plan.yaml') }
|
28
|
+
it { is_expected.to eq('simple_plan') }
|
29
|
+
it { subject; expect(Dir[versions_dir + '/*.yaml'].length).to be 1 }
|
30
|
+
end
|
31
|
+
context 'The plan is invalid' do
|
32
|
+
let(:plan) { 'spec/fixtures/simple_plan_invalid.yaml' }
|
33
|
+
it { expect{subject}.to raise_error StandardError }
|
34
|
+
end
|
35
|
+
context 'The plan was already added' do
|
36
|
+
before { @plan_store.add(plan) }
|
37
|
+
it { expect{subject}.to raise_error StandardError }
|
38
|
+
end
|
39
|
+
context 'A node is already present' do
|
40
|
+
before { @plan_store.add('spec/fixtures/other_plan_same_nodes.yaml') }
|
41
|
+
it { expect{subject}.to raise_error StandardError }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#update' do
|
46
|
+
before do |example|
|
47
|
+
@plan_store.add(plan) unless example.metadata[:skip_before]
|
48
|
+
end
|
49
|
+
subject { @plan_store.update(plan) }
|
50
|
+
|
51
|
+
context 'The plan file is correct' do
|
52
|
+
it { is_expected.to eq('simple_plan') }
|
53
|
+
it { subject; expect(Dir[versions_dir + '/*.yaml'].length).to be 2 }
|
54
|
+
end
|
55
|
+
context 'The plan is in hash form' do
|
56
|
+
let(:plan) { YAML.load_file('spec/fixtures/simple_plan.yaml') }
|
57
|
+
it { is_expected.to eq('simple_plan') }
|
58
|
+
it { subject; expect(Dir[versions_dir + '/*.yaml'].length).to be 2 }
|
59
|
+
end
|
60
|
+
context 'The plan is invalid' do
|
61
|
+
let(:invalid_plan) { 'spec/fixtures/simple_plan_invalid.yaml' }
|
62
|
+
subject { @plan_store.update(invalid_plan) }
|
63
|
+
it { expect{subject}.to raise_error StandardError }
|
64
|
+
end
|
65
|
+
context 'The plan was not already added', :skip_before => true do
|
66
|
+
it { expect{subject}.to raise_error StandardError }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#remove' do
|
71
|
+
before :example do
|
72
|
+
@plan_store.add(plan)
|
73
|
+
end
|
74
|
+
let(:dopi_state) { File.join(plan_dir, 'dopi.yaml') }
|
75
|
+
let(:dopv_state) { File.join(plan_dir, 'dopv.yaml') }
|
76
|
+
|
77
|
+
context 'plan exists and default state remove options' do
|
78
|
+
subject { @plan_store.remove(plan_name) }
|
79
|
+
it { is_expected.to eq('simple_plan') }
|
80
|
+
it { subject; expect(File.exists?(versions_dir)).to be false }
|
81
|
+
it { subject; expect(File.exists?(dopi_state)).to be false }
|
82
|
+
it { subject; expect(File.exists?(dopv_state)).to be true }
|
83
|
+
it { subject; expect(File.exists?(plan_dir)).to be true }
|
84
|
+
end
|
85
|
+
context 'plan exists and keep dopi state' do
|
86
|
+
subject { @plan_store.remove(plan_name, false) }
|
87
|
+
it { is_expected.to eq('simple_plan') }
|
88
|
+
it { subject; expect(File.exists?(versions_dir)).to be false }
|
89
|
+
it { subject; expect(File.exists?(dopi_state)).to be true }
|
90
|
+
it { subject; expect(File.exists?(dopv_state)).to be true }
|
91
|
+
it { subject; expect(File.exists?(plan_dir)).to be true }
|
92
|
+
end
|
93
|
+
context 'plan exists and remove dopv state' do
|
94
|
+
subject { @plan_store.remove(plan_name, true, true) }
|
95
|
+
it { is_expected.to eq('simple_plan') }
|
96
|
+
it { subject; expect(File.exists?(versions_dir)).to be false }
|
97
|
+
it { subject; expect(File.exists?(dopi_state)).to be false }
|
98
|
+
it { subject; expect(File.exists?(dopv_state)).to be false }
|
99
|
+
it { subject; expect(File.exists?(plan_dir)).to be false }
|
100
|
+
end
|
101
|
+
context 'plan does not exist' do
|
102
|
+
let(:plan_name) { 'not_existing_plan' }
|
103
|
+
it { expect{subject}.to raise_error StandardError }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#list' do
|
108
|
+
before { @plan_store.add(plan) }
|
109
|
+
subject { @plan_store.list }
|
110
|
+
|
111
|
+
context 'one plan is in the store' do
|
112
|
+
it { is_expected.to be_an Array }
|
113
|
+
it { is_expected.to have_exactly(1).items }
|
114
|
+
it { is_expected.to include plan_name }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#show_versions' do
|
119
|
+
before do |example|
|
120
|
+
@plan_store.add(plan) unless example.metadata[:skip_before]
|
121
|
+
end
|
122
|
+
subject { @plan_store.show_versions(plan_name) }
|
123
|
+
|
124
|
+
context 'the plan is in the store' do
|
125
|
+
it { is_expected.to be_an Array }
|
126
|
+
it { is_expected.to have_exactly(1).items }
|
127
|
+
end
|
128
|
+
context 'the plan is not in the store', :skip_before => true do
|
129
|
+
it { expect{subject}.to raise_error StandardError }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe '#get_plan_hash' do
|
134
|
+
before do |example|
|
135
|
+
@plan_store.add(plan) unless example.metadata[:skip_before]
|
136
|
+
end
|
137
|
+
subject { @plan_store.get_plan_hash(plan_name) }
|
138
|
+
|
139
|
+
context 'the plan is in the store' do
|
140
|
+
it { is_expected.to be_a Hash }
|
141
|
+
it { is_expected.to have_key 'name' }
|
142
|
+
end
|
143
|
+
context 'the plan is not in the store', :skip_before => true do
|
144
|
+
it { expect{subject}.to raise_error StandardError }
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe '#get_plan_hash_diff' do
|
149
|
+
before do |example|
|
150
|
+
unless example.metadata[:skip_before]
|
151
|
+
@plan_store.add(plan)
|
152
|
+
@plan_store.update('spec/fixtures/simple_plan_modified.yaml')
|
153
|
+
end
|
154
|
+
end
|
155
|
+
let(:old_version) { @plan_store.show_versions(plan_name).first }
|
156
|
+
subject { @plan_store.get_plan_hash_diff(plan_name, old_version) }
|
157
|
+
|
158
|
+
context 'the plan is in the store' do
|
159
|
+
it { is_expected.to be_an Array }
|
160
|
+
end
|
161
|
+
context 'the plan is not in the store', :skip_before => true do
|
162
|
+
it { expect{subject}.to raise_error StandardError }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe '#get_plan' do
|
167
|
+
before do |example|
|
168
|
+
@plan_store.add(plan) unless example.metadata[:skip_before]
|
169
|
+
end
|
170
|
+
subject { @plan_store.get_plan(plan_name) }
|
171
|
+
|
172
|
+
context 'the plan is in the store' do
|
173
|
+
it { is_expected.to be_a DopCommon::Plan }
|
174
|
+
it { expect(subject.name).to eq(plan_name) }
|
175
|
+
end
|
176
|
+
context 'the plan is not in the store', :skip_before => true do
|
177
|
+
it { expect{subject}.to raise_error StandardError }
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe '#run_lock' do
|
182
|
+
pending
|
183
|
+
end
|
184
|
+
|
185
|
+
describe '#run_lock?' do
|
186
|
+
pending
|
187
|
+
end
|
188
|
+
|
189
|
+
describe '#state_store' do
|
190
|
+
pending
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DopCommon::PreProcessor do
|
4
|
+
|
5
|
+
describe '#load_plan' do
|
6
|
+
subject{ DopCommon::PreProcessor.load_plan(file) }
|
7
|
+
|
8
|
+
context 'All the include files are present and correct' do
|
9
|
+
let(:file) { 'spec/fixtures/simple_include.yaml' }
|
10
|
+
it{ is_expected.to be_a String }
|
11
|
+
it do
|
12
|
+
expect(YAML.load(subject)).to eq({
|
13
|
+
'name' => 'simple_include_test',
|
14
|
+
'some_root_key' => 'some_value',
|
15
|
+
'some_key' => ['an_item', 'another_item'],
|
16
|
+
})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'Included files are missing' do
|
21
|
+
let(:file) { 'spec/fixtures/simple_include_with_errors.yaml' }
|
22
|
+
it{ expect{subject}.to raise_error DopCommon::PlanParsingError }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class RunOptionsTestKlass
|
4
|
+
include DopCommon::RunOptions
|
5
|
+
def initialize(hash); @hash = hash; end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe DopCommon::RunOptions do
|
9
|
+
|
10
|
+
describe '#max_in_flight' do
|
11
|
+
it 'will return nil if max_in_flight is not defined' do
|
12
|
+
run_options = RunOptionsTestKlass.new({})
|
13
|
+
expect(run_options.max_in_flight).to be nil
|
14
|
+
end
|
15
|
+
it 'will return the correct value if max_in_flight is defined' do
|
16
|
+
run_options = RunOptionsTestKlass.new({:max_in_flight => 10})
|
17
|
+
expect(run_options.max_in_flight).to be 10
|
18
|
+
end
|
19
|
+
it 'will throw and exception if the value is not a Fixnum' do
|
20
|
+
run_options = RunOptionsTestKlass.new({:max_in_flight => 'foo'})
|
21
|
+
expect{run_options.max_in_flight}.to raise_error DopCommon::PlanParsingError
|
22
|
+
end
|
23
|
+
it 'will throw and exception if the value is < -1' do
|
24
|
+
run_options = RunOptionsTestKlass.new({:max_in_flight => -2})
|
25
|
+
expect{run_options.max_in_flight}.to raise_error DopCommon::PlanParsingError
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#max_per_role' do
|
30
|
+
it 'will return nil if max_per_role is not defined' do
|
31
|
+
run_options = RunOptionsTestKlass.new({})
|
32
|
+
expect(run_options.max_per_role).to be nil
|
33
|
+
end
|
34
|
+
it 'will return the correct value if max_per_role is defined' do
|
35
|
+
run_options = RunOptionsTestKlass.new({:max_per_role => 10})
|
36
|
+
expect(run_options.max_per_role).to be 10
|
37
|
+
end
|
38
|
+
it 'will throw and exception if the value is not a Fixnum' do
|
39
|
+
run_options = RunOptionsTestKlass.new({:max_per_role => 'foo'})
|
40
|
+
expect{run_options.max_per_role}.to raise_error DopCommon::PlanParsingError
|
41
|
+
end
|
42
|
+
it 'will throw and exception if the value is < -1' do
|
43
|
+
run_options = RunOptionsTestKlass.new({:max_per_role => -2})
|
44
|
+
expect{run_options.max_per_role}.to raise_error DopCommon::PlanParsingError
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#canary_host' do
|
49
|
+
it 'returns false if the key is missing' do
|
50
|
+
run_options = RunOptionsTestKlass.new({})
|
51
|
+
expect(run_options.canary_host).to eq false
|
52
|
+
end
|
53
|
+
it 'returns the correct result if the key is set' do
|
54
|
+
run_options = RunOptionsTestKlass.new({:canary_host => true})
|
55
|
+
expect(run_options.canary_host).to eq true
|
56
|
+
run_options = RunOptionsTestKlass.new({:canary_host => false})
|
57
|
+
expect(run_options.canary_host).to eq false
|
58
|
+
end
|
59
|
+
it 'throws an exception if the value is not a boolean' do
|
60
|
+
run_options = RunOptionsTestKlass.new({:canary_host => 'foo'})
|
61
|
+
expect{run_options.canary_host}.to raise_error DopCommon::PlanParsingError
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# Test the SignalHandler class
|
3
|
+
#
|
4
|
+
# This test was created with the help of the very useful blog post at
|
5
|
+
# http://timuruski.net/blog/2014/testing-signal-handlers/
|
6
|
+
#
|
7
|
+
require 'spec_helper'
|
8
|
+
|
9
|
+
describe DopCommon::SignalHandler do
|
10
|
+
|
11
|
+
it 'receives the signal, executes the block and then exits' do
|
12
|
+
pipe_reader, pipe_writer = IO.pipe
|
13
|
+
|
14
|
+
ruby = fork do
|
15
|
+
pipe_reader.close
|
16
|
+
DopCommon::SignalHandler.new.handle_signals(:INT) do
|
17
|
+
pipe_writer.puts('received')
|
18
|
+
raise 'signal received'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
pipe_writer.close
|
23
|
+
sleep(0.1)
|
24
|
+
Process.kill(:INT, ruby)
|
25
|
+
expect(pipe_reader.gets).to eq("received\n")
|
26
|
+
pid, status = Process.waitpid2(ruby)
|
27
|
+
expect(status.success?).to be true
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DopCommon::StepSet do
|
4
|
+
|
5
|
+
describe '#steps' do
|
6
|
+
it 'will return an array of steps if correctly specified' do
|
7
|
+
step_set = DopCommon::StepSet.new('foo', [{:name => 'foo'}])
|
8
|
+
expect(step_set.steps).to be_a Array
|
9
|
+
expect(step_set.steps.first).to be_a ::DopCommon::Step
|
10
|
+
end
|
11
|
+
it 'will raise an error if the array is empty' do
|
12
|
+
step_set = DopCommon::StepSet.new('foo', [])
|
13
|
+
expect{step_set.steps}.to raise_error DopCommon::PlanParsingError
|
14
|
+
end
|
15
|
+
it 'will raise an error if the array contains something other than hashes' do
|
16
|
+
step_set = DopCommon::StepSet.new('foo', [{}, 1])
|
17
|
+
expect{step_set.steps}.to raise_error DopCommon::PlanParsingError
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DopCommon::Step do
|
4
|
+
|
5
|
+
describe '#name' do
|
6
|
+
it 'returns the name if it is specified correctly' do
|
7
|
+
step = DopCommon::Step.new({:name => 'foo'})
|
8
|
+
expect(step.name).to eq 'foo'
|
9
|
+
end
|
10
|
+
it 'throws an exception if the key is missing' do
|
11
|
+
step = DopCommon::Step.new({})
|
12
|
+
expect{step.name}.to raise_error DopCommon::PlanParsingError
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
[:nodes, :exclude_nodes, :roles, :exclude_roles].each do |method_name|
|
18
|
+
describe '#' + method_name.to_s do
|
19
|
+
it 'returns an array with entries if correctly specified' do
|
20
|
+
step = DopCommon::Step.new({:name => 'foo', method_name => ['foo']})
|
21
|
+
expect(step.send(method_name)).to eq(['foo'])
|
22
|
+
end
|
23
|
+
it 'returns an empty array if the key is missing' do
|
24
|
+
step = DopCommon::Step.new({:name => 'foo'})
|
25
|
+
expect(step.send(method_name)).to eq([])
|
26
|
+
end
|
27
|
+
it 'returns an array with one element if the value is a string' do
|
28
|
+
step = DopCommon::Step.new({:name => 'foo', method_name => 'foo'})
|
29
|
+
expect(step.send(method_name)).to eq(['foo'])
|
30
|
+
end
|
31
|
+
it 'throws an exception if the value is something other than an array or a string' do
|
32
|
+
step = DopCommon::Step.new({:name => 'foo', method_name => 1})
|
33
|
+
expect{step.send(method_name)}.to raise_error DopCommon::PlanParsingError
|
34
|
+
end
|
35
|
+
it 'throws an exception if the array contains something other than a string' do
|
36
|
+
step = DopCommon::Step.new({:name => 'foo', method_name => ['foo', 1]})
|
37
|
+
expect{step.send(method_name)}.to raise_error DopCommon::PlanParsingError
|
38
|
+
end
|
39
|
+
it 'throws an exception if the array contains an invalid regexp' do
|
40
|
+
step = DopCommon::Step.new({:name => 'foo', method_name => ['/][/']})
|
41
|
+
expect{step.send(method_name)}.to raise_error DopCommon::PlanParsingError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
[:nodes_by_config, :exclude_nodes_by_config].each do |method_name|
|
47
|
+
describe '#' + method_name.to_s do
|
48
|
+
it 'returns a Hash if correctly specified' do
|
49
|
+
step = DopCommon::Step.new({:name => 'foo', method_name => {'my_alias' => 'foo'}})
|
50
|
+
expect(step.send(method_name)).to eq({'my_alias' => ['foo']})
|
51
|
+
end
|
52
|
+
it 'returns an empty hash if the key is missing' do
|
53
|
+
step = DopCommon::Step.new({:name => 'foo'})
|
54
|
+
expect(step.send(method_name)).to eq({})
|
55
|
+
end
|
56
|
+
it 'throws an exception if the value is something other than a hash' do
|
57
|
+
step = DopCommon::Step.new({:name => 'foo', method_name => 1})
|
58
|
+
expect{step.send(method_name)}.to raise_error DopCommon::PlanParsingError
|
59
|
+
end
|
60
|
+
it 'throws an exception if the hash contains something other than a string as a key' do
|
61
|
+
step = DopCommon::Step.new({:name => 'foo', method_name => {1 => 'foo'}})
|
62
|
+
expect{step.send(method_name)}.to raise_error DopCommon::PlanParsingError
|
63
|
+
end
|
64
|
+
it 'throws an exception if the hash contains something other than a string as a value' do
|
65
|
+
step = DopCommon::Step.new({:name => 'foo', method_name => {'my_alias' => 1}})
|
66
|
+
expect{step.send(method_name)}.to raise_error DopCommon::PlanParsingError
|
67
|
+
end
|
68
|
+
it 'throws an exception if the hash contains an invalid regexp' do
|
69
|
+
step = DopCommon::Step.new({:name => 'foo', method_name => {'my_alias' => '/][/'}})
|
70
|
+
expect{step.send(method_name)}.to raise_error DopCommon::PlanParsingError
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#commands' do
|
76
|
+
it 'returns the command objects if a command hash is specified' do
|
77
|
+
step = DopCommon::Step.new({:name => 'foo', :command => {:plugin => 'dummy'}})
|
78
|
+
expect(step.commands).to be_an Array
|
79
|
+
expect(step.commands.all?{|c| c.kind_of?(DopCommon::Command)}).to be true
|
80
|
+
end
|
81
|
+
it 'returns the command objects if a command hash is specified' do
|
82
|
+
step = DopCommon::Step.new({:name => 'foo', :commands => [{:plugin => 'dummy'}, 'dummy']})
|
83
|
+
expect(step.commands).to be_an Array
|
84
|
+
expect(step.commands.all?{|c| c.kind_of?(DopCommon::Command)}).to be true
|
85
|
+
end
|
86
|
+
it 'throws an exception if the command is not specified' do
|
87
|
+
step = DopCommon::Step.new({:name => 'foo'})
|
88
|
+
expect{step.commands}.to raise_error DopCommon::PlanParsingError
|
89
|
+
end
|
90
|
+
it 'throws an exception if the value for command is something other than a String or a Hash' do
|
91
|
+
step = DopCommon::Step.new({:name => 'foo', :command => 1})
|
92
|
+
expect{step.commands}.to raise_error DopCommon::PlanParsingError
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#set_plugin_defaults' do
|
97
|
+
it 'returns an Array if correctly specified (normal plugin string)' do
|
98
|
+
step = DopCommon::Step.new({:name => 'foo', :set_plugin_defaults => [{ :plugin => 'ssh/custom', :credentials => 'my_cred'}]})
|
99
|
+
expect(step.set_plugin_defaults).to eq([{:plugins => ['ssh/custom'], :credentials => 'my_cred'}])
|
100
|
+
end
|
101
|
+
it 'returns an Array if correctly specified (plugins :all)' do
|
102
|
+
step = DopCommon::Step.new({:name => 'foo', :set_plugin_defaults => [{ :plugins => :all, :credentials => 'my_cred'}]})
|
103
|
+
expect(step.set_plugin_defaults).to eq([{:plugins => :all, :credentials => 'my_cred'}])
|
104
|
+
end
|
105
|
+
it 'returns an Array if correctly specified (plugins array)' do
|
106
|
+
step = DopCommon::Step.new({:name => 'foo', :set_plugin_defaults => [{ :plugins => ['ssh/custom', 'ssh/something'], :credentials => 'my_cred'}]})
|
107
|
+
expect(step.set_plugin_defaults).to eq([{:plugins => ['ssh/custom', 'ssh/something'], :credentials => 'my_cred'}])
|
108
|
+
end
|
109
|
+
it 'returns an Array if correctly specified (plugins array)' do
|
110
|
+
step = DopCommon::Step.new({:name => 'foo', :set_plugin_defaults => [{ :plugins => '/^ssh/', :credentials => 'my_cred'}]})
|
111
|
+
expect(step.set_plugin_defaults).to eq([{:plugins => [Regexp.new('^ssh')], :credentials => 'my_cred'}])
|
112
|
+
end
|
113
|
+
it 'returns an empty Array if the key is missing' do
|
114
|
+
step = DopCommon::Step.new({:name => 'foo'})
|
115
|
+
expect(step.set_plugin_defaults).to eq([])
|
116
|
+
end
|
117
|
+
it 'throws an exception if the value is something other than an array' do
|
118
|
+
step = DopCommon::Step.new({:name => 'foo', :set_plugin_defaults => 1})
|
119
|
+
expect{step.set_plugin_defaults}.to raise_error DopCommon::PlanParsingError
|
120
|
+
end
|
121
|
+
it 'throws an exception if an entry is not a hash' do
|
122
|
+
step = DopCommon::Step.new({:name => 'foo', :set_plugin_defaults => [1]})
|
123
|
+
expect{step.set_plugin_defaults}.to raise_error DopCommon::PlanParsingError
|
124
|
+
end
|
125
|
+
it 'throws an exception if no plugins key is present' do
|
126
|
+
step = DopCommon::Step.new({:name => 'foo', :set_plugin_defaults => {}})
|
127
|
+
expect{step.set_plugin_defaults}.to raise_error DopCommon::PlanParsingError
|
128
|
+
end
|
129
|
+
it 'throws an exception if the plugins value is not valid' do
|
130
|
+
step = DopCommon::Step.new({:name => 'foo', :set_plugin_defaults => {:plugins => 1}})
|
131
|
+
expect{step.set_plugin_defaults}.to raise_error DopCommon::PlanParsingError
|
132
|
+
end
|
133
|
+
it 'throws an exception if the plugins value is an invalid Regexp' do
|
134
|
+
step = DopCommon::Step.new({:name => 'foo', :set_plugin_defaults => {:plugins => '/][/'}})
|
135
|
+
expect{step.set_plugin_defaults}.to raise_error DopCommon::PlanParsingError
|
136
|
+
end
|
137
|
+
it 'throws an exception if one of the keys is not a string or symbol' do
|
138
|
+
step = DopCommon::Step.new({:name => 'foo', :set_plugin_defaults => {:plugins => 'ssh/custom', 1 => 2}})
|
139
|
+
expect{step.set_plugin_defaults}.to raise_error DopCommon::PlanParsingError
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe '#delete_plugin_defaults' do
|
144
|
+
it 'returns an Array if correctly specified (normal plugin string)' do
|
145
|
+
step = DopCommon::Step.new({:name => 'foo', :delete_plugin_defaults => [{:plugin => 'ssh/custom', :delete_keys => ['credentials']}]})
|
146
|
+
expect(step.delete_plugin_defaults).to eq([{:plugins => ['ssh/custom'], :delete_keys => ['credentials']}])
|
147
|
+
end
|
148
|
+
it 'returns an Array if correctly specified (singular)' do
|
149
|
+
step = DopCommon::Step.new({:name => 'foo', :delete_plugin_defaults => [{:plugin => 'ssh/custom', :delete_key => 'credentials'}]})
|
150
|
+
expect(step.delete_plugin_defaults).to eq([{:plugins => ['ssh/custom'], :delete_keys => ['credentials']}])
|
151
|
+
end
|
152
|
+
it 'returns an Array if correctly specified (delete all for plugin)' do
|
153
|
+
step = DopCommon::Step.new({:name => 'foo', :delete_plugin_defaults => [{:plugin => 'ssh/custom', :delete_keys => :all}]})
|
154
|
+
expect(step.delete_plugin_defaults).to eq([{:plugins => ['ssh/custom'], :delete_keys => :all}])
|
155
|
+
end
|
156
|
+
it 'returns :all if correctly specified (delete all)' do
|
157
|
+
step = DopCommon::Step.new({:name => 'foo', :delete_plugin_defaults => :all})
|
158
|
+
expect(step.delete_plugin_defaults).to eq(:all)
|
159
|
+
end
|
160
|
+
it 'returns an empty Array if the key is missing' do
|
161
|
+
step = DopCommon::Step.new({:name => 'foo'})
|
162
|
+
expect(step.delete_plugin_defaults).to eq([])
|
163
|
+
end
|
164
|
+
it 'throws an exception if the delete_keys is invalid' do
|
165
|
+
step = DopCommon::Step.new({:name => 'foo', :delete_plugin_defaults => [{:plugin => 'ssh/custom', :delete_keys => 2}]})
|
166
|
+
expect{step.delete_plugin_defaults}.to raise_error DopCommon::PlanParsingError
|
167
|
+
end
|
168
|
+
it 'throws an exception if an element in delete_keys is invalid' do
|
169
|
+
step = DopCommon::Step.new({:name => 'foo', :delete_plugin_defaults => [{:plugin => 'ssh/custom', :delete_keys => ['foo', 2]}]})
|
170
|
+
expect{step.delete_plugin_defaults}.to raise_error DopCommon::PlanParsingError
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DopCommon::Utils::DataSize do
|
4
|
+
describe '#size' do
|
5
|
+
{
|
6
|
+
1000 => 1000,
|
7
|
+
'1000K' => 1000*1024,
|
8
|
+
'512M' => 512*1024*1024,
|
9
|
+
'1000G' => 1000*1024*1024*1024,
|
10
|
+
'1KB' => 1000,
|
11
|
+
'1000MB' => 1000*1000*1000,
|
12
|
+
'2500GB' => 2500*1000*1000*1000,
|
13
|
+
}.each do |k, v|
|
14
|
+
it 'will return size in bytes if specified properly' do
|
15
|
+
size = DopCommon::Utils::DataSize.new(k)
|
16
|
+
expect(size).to be_an_instance_of(DopCommon::Utils::DataSize)
|
17
|
+
expect(size.bytes).to eq v
|
18
|
+
end
|
19
|
+
end
|
20
|
+
[nil, [], 2.4, '2500m', '1000'].each do |input|
|
21
|
+
it 'will raise an exception if not specified properly' do
|
22
|
+
size = DopCommon::Utils::DataSize.new(input)
|
23
|
+
expect{size.bytes}.to raise_error DopCommon::PlanParsingError
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|