beaker 3.13.0 → 3.14.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 +8 -8
- data/acceptance/tests/subcommands/destroy.rb +49 -0
- data/acceptance/tests/subcommands/exec.rb +33 -0
- data/acceptance/tests/subcommands/init.rb +12 -36
- data/acceptance/tests/subcommands/provision.rb +9 -35
- data/beaker.gemspec +2 -2
- data/bin/beaker +1 -1
- data/docs/how_to/cloning_private_repos.md +3 -0
- data/docs/how_to/enabling_cross_sut_access.md +23 -0
- data/docs/how_to/ssh_agent_forwarding.md +4 -0
- data/lib/beaker/cli.rb +45 -15
- data/lib/beaker/host.rb +1 -1
- data/lib/beaker/hypervisor.rb +2 -1
- data/lib/beaker/network_manager.rb +5 -1
- data/lib/beaker/options/parser.rb +8 -1
- data/lib/beaker/options/subcommand_options_file_parser.rb +20 -0
- data/lib/beaker/ssh_connection.rb +1 -1
- data/lib/beaker/subcommand.rb +140 -28
- data/lib/beaker/subcommands/subcommand_util.rb +12 -125
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/cli_spec.rb +31 -0
- data/spec/beaker/logger_spec.rb +2 -0
- data/spec/beaker/options/parser_spec.rb +14 -1
- data/spec/beaker/options/subcommand_options_parser_spec.rb +33 -0
- data/spec/beaker/subcommand/subcommand_util_spec.rb +31 -204
- data/spec/beaker/subcommand_spec.rb +146 -0
- metadata +27 -20
data/spec/beaker/logger_spec.rb
CHANGED
@@ -5,6 +5,7 @@ module Beaker
|
|
5
5
|
describe Logger do
|
6
6
|
let(:my_io) { StringIO.new }
|
7
7
|
let(:logger) { Logger.new(my_io, :quiet => true) }
|
8
|
+
let(:basic_logger) { Logger.new(:quiet => true) }
|
8
9
|
let(:test_dir) { 'tmp/tests' }
|
9
10
|
let(:dummy_prefix) { 'dummy' }
|
10
11
|
|
@@ -424,5 +425,6 @@ module Beaker
|
|
424
425
|
end
|
425
426
|
|
426
427
|
end
|
428
|
+
|
427
429
|
end
|
428
430
|
end
|
@@ -146,6 +146,7 @@ module Beaker
|
|
146
146
|
:user_known_hosts_file => 'hosts123'
|
147
147
|
}
|
148
148
|
} }
|
149
|
+
let(:subcommand_file) {@subcommand_file || {:level => 'fifth'}}
|
149
150
|
let(:presets) { {:level => 'lowest',
|
150
151
|
:ssh => {
|
151
152
|
:config => 'config123',
|
@@ -173,10 +174,12 @@ module Beaker
|
|
173
174
|
|
174
175
|
allow(OptionsFileParser).to receive(:parse_options_file).and_return(opt_file)
|
175
176
|
allow(parser).to receive(:parse_hosts_options).and_return(host_file)
|
177
|
+
|
178
|
+
allow(SubcommandOptionsParser).to receive(:parse_subcommand_options).and_return(subcommand_file)
|
176
179
|
end
|
177
180
|
|
178
181
|
it 'presets have the lowest priority' do
|
179
|
-
@env = @argv = @host_file = @opt_file = {}
|
182
|
+
@env = @argv = @host_file = @opt_file = @subcommand_file = {}
|
180
183
|
mock_out_parsing
|
181
184
|
|
182
185
|
opts = parser.parse_args([])
|
@@ -185,6 +188,16 @@ module Beaker
|
|
185
188
|
expect(attribution[:level]).to be == 'preset'
|
186
189
|
end
|
187
190
|
|
191
|
+
it 'subcommand_options should have fifth priority' do
|
192
|
+
@env = @argv = @host_file = @opt_file = {}
|
193
|
+
mock_out_parsing
|
194
|
+
|
195
|
+
opts = parser.parse_args([])
|
196
|
+
attribution = parser.attribution
|
197
|
+
expect(opts[:level]).to be == 'fifth'
|
198
|
+
expect(attribution[:level]).to be == 'subcommand'
|
199
|
+
end
|
200
|
+
|
188
201
|
it 'options file has fourth priority' do
|
189
202
|
@env = @argv = @host_file = {}
|
190
203
|
mock_out_parsing
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Beaker
|
4
|
+
module Options
|
5
|
+
describe '#parse_subcommand_options' do
|
6
|
+
let( :parser ) {Beaker::Options::SubcommandOptionsParser.parse_subcommand_options(argv)}
|
7
|
+
let( :argv ) {[]}
|
8
|
+
|
9
|
+
it 'returns an empty OptionsHash if not executing a subcommand' do
|
10
|
+
expect(parser).to be_kind_of(OptionsHash)
|
11
|
+
expect(parser).to be_empty
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'when the subcommand is init' do
|
15
|
+
let( :argv ) {['init']}
|
16
|
+
it 'returns an empty OptionsHash' do
|
17
|
+
expect(parser).to be_kind_of(OptionsHash)
|
18
|
+
expect(parser).to be_empty
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'when the subcommand is not init' do
|
23
|
+
let( :argv ) {['provision']}
|
24
|
+
it 'checks for file existence and loads the YAML file' do
|
25
|
+
expect(Beaker::Subcommands::SubcommandUtil::SUBCOMMAND_OPTIONS).to receive(:exist?).and_return(true)
|
26
|
+
allow(YAML).to receive(:load_file).and_return({})
|
27
|
+
expect(parser).to be_kind_of(Hash)
|
28
|
+
expect(parser).not_to be_kind_of(OptionsHash)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -24,15 +24,37 @@ module Beaker
|
|
24
24
|
double("host")
|
25
25
|
}
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
27
|
+
let(:hypervisors) {
|
28
|
+
double("hypervisors")
|
29
|
+
}
|
30
|
+
|
31
|
+
let(:hosts) {
|
32
|
+
double("hosts")
|
33
|
+
}
|
34
|
+
|
35
|
+
let(:hypervisors_object) {
|
36
|
+
double("hypervisors_object")
|
37
|
+
}
|
38
|
+
|
39
|
+
let(:hosts_object) {
|
40
|
+
double("hosts_object")
|
41
|
+
}
|
42
|
+
|
43
|
+
let(:network_manager){
|
44
|
+
double("network_manager")
|
45
|
+
}
|
46
|
+
|
47
|
+
let(:save_object){
|
48
|
+
double("save_object")
|
49
|
+
}
|
50
|
+
|
51
|
+
let(:load_object){
|
52
|
+
double("load_object")
|
53
|
+
}
|
54
|
+
|
55
|
+
let(:yaml_object){
|
56
|
+
double("yaml_object")
|
57
|
+
}
|
36
58
|
|
37
59
|
describe 'execute_subcommand' do
|
38
60
|
it "determines if we should execute the init subcommand" do
|
@@ -52,15 +74,6 @@ module Beaker
|
|
52
74
|
end
|
53
75
|
end
|
54
76
|
|
55
|
-
describe 'execute_beaker' do
|
56
|
-
it "executes beaker with arguments" do
|
57
|
-
allow(cli).to receive(:execute!).and_return(true)
|
58
|
-
allow(Beaker::CLI).to receive(:new).and_return(cli)
|
59
|
-
expect(subject).to receive(:reset_argv).exactly(1).times
|
60
|
-
expect(cli).to receive(:execute!).exactly(1).times
|
61
|
-
subject.execute_beaker(['args'])
|
62
|
-
end
|
63
|
-
end
|
64
77
|
|
65
78
|
describe 'error_with' do
|
66
79
|
it "the exit value should default to 1" do
|
@@ -91,192 +104,6 @@ module Beaker
|
|
91
104
|
end
|
92
105
|
end
|
93
106
|
|
94
|
-
describe 'init_vmpooler' do
|
95
|
-
it "executes the vmpooler quick task" do
|
96
|
-
expect(subject).to receive(:execute_rake_task).with("beaker_quickstart:gen_hosts[vmpooler]").exactly(1).times
|
97
|
-
subject.init_vmpooler
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
describe 'init_vagrant' do
|
102
|
-
it "executes the vmpooler quick task" do
|
103
|
-
expect(subject).to receive(:execute_rake_task).with("beaker_quickstart:gen_hosts[vagrant]").exactly(1).times
|
104
|
-
subject.init_vagrant
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe 'init_hypervisor' do
|
109
|
-
it "calls init_vagrant" do
|
110
|
-
expect(subject).to receive(:init_vagrant).with(no_args).exactly(1).times
|
111
|
-
expect(subject).to receive(:init_vmpooler).with(no_args).exactly(0).times
|
112
|
-
subject.init_hypervisor('vagrant')
|
113
|
-
end
|
114
|
-
|
115
|
-
it "calls init_vmpooler" do
|
116
|
-
expect(subject).to receive(:init_vagrant).with(no_args).exactly(0).times
|
117
|
-
expect(subject).to receive(:init_vmpooler).with(no_args).exactly(1).times
|
118
|
-
subject.init_hypervisor('vmpooler')
|
119
|
-
end
|
120
|
-
|
121
|
-
it "fails to call init for a hypervisor" do
|
122
|
-
expect(subject).to receive(:init_vagrant).with(no_args).exactly(0).times
|
123
|
-
expect(subject).to receive(:init_vmpooler).with(no_args).exactly(0).times
|
124
|
-
subject.init_hypervisor('invalid')
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
describe 'execute_rake_task' do
|
129
|
-
|
130
|
-
it "executes the rake task" do
|
131
|
-
allow(Rake).to receive(:application).and_return(rake)
|
132
|
-
expect(ARGV).to receive(:clear).exactly(1).times
|
133
|
-
expect(rake).to receive(:init).and_return(true).exactly(1).times
|
134
|
-
expect(rake).to receive(:load_rakefile).and_return(true).exactly(1).times
|
135
|
-
expect(rake).to receive(:invoke_task).with("mytask").exactly(1).times
|
136
|
-
subject.execute_rake_task("mytask")
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
describe "determine_rake_file" do
|
141
|
-
|
142
|
-
it "uses Rakefile if no rakefile exists" do
|
143
|
-
allow(subject).to receive(:rake_app).and_return(rake)
|
144
|
-
allow(rake).to receive(:find_rakefile_location).and_return(nil)
|
145
|
-
expect subject.determine_rake_file == "Rakefile"
|
146
|
-
end
|
147
|
-
|
148
|
-
it "uses Rakefile if Rakefile exists" do
|
149
|
-
allow(subject).to receive(:rake_app).and_return(rake)
|
150
|
-
allow(rake).to receive(:find_rakefile_location).and_return("Rakefile")
|
151
|
-
expect subject.determine_rake_file == "Rakefile"
|
152
|
-
end
|
153
|
-
|
154
|
-
it "uses rakefile if rakefile exists" do
|
155
|
-
allow(subject).to receive(:rake_app).and_return(rake)
|
156
|
-
allow(rake).to receive(:find_rakefile_location).and_return("rakefile")
|
157
|
-
expect subject.determine_rake_file == "rakefile"
|
158
|
-
end
|
159
|
-
|
160
|
-
it "uses Rakefile.rb if Rakefile.rb exists" do
|
161
|
-
allow(subject).to receive(:rake_app).and_return(rake)
|
162
|
-
allow(rake).to receive(:find_rakefile_location).and_return("Rakefile.rb")
|
163
|
-
expect subject.determine_rake_file == "Rakefile.rb"
|
164
|
-
end
|
165
|
-
|
166
|
-
it "uses rakefile.rb if rakefile.rb exists" do
|
167
|
-
allow(subject).to receive(:rake_app).and_return(rake)
|
168
|
-
allow(rake).to receive(:find_rakefile_location).and_return("rakefile.rb")
|
169
|
-
expect subject.determine_rake_file == "rakefile.rb"
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
describe "require_tasks" do
|
174
|
-
it "appends the require if it isn't contained in the Rakefile" do
|
175
|
-
allow(subject).to receive(:determine_rake_file).and_return("Rakefile")
|
176
|
-
allow(File).to receive(:readlines).with("Rakefile").and_return([""])
|
177
|
-
allow(File).to receive(:open).with("Rakefile", "a+").and_yield(file)
|
178
|
-
allow(File).to receive(:puts).with("require 'beaker/tasks/quick_start'").and_return(true)
|
179
|
-
expect(FileUtils).to receive(:touch).with("Rakefile").exactly(1).times
|
180
|
-
expect(File).to receive(:open).with("Rakefile", "a+").and_yield(file).exactly(1).times
|
181
|
-
expect(file).to receive(:puts).with("require 'beaker/tasks/quick_start'").exactly(1).times
|
182
|
-
subject.require_tasks
|
183
|
-
end
|
184
|
-
|
185
|
-
it "does't append the require if it is contained in the Rakefile" do
|
186
|
-
allow(subject).to receive(:determine_rake_file).and_return("Rakefile")
|
187
|
-
allow(File).to receive(:readlines).with("Rakefile").and_return(["require 'beaker/tasks/quick_start'"])
|
188
|
-
allow(File).to receive(:open).with("Rakefile", "a+").and_yield(file)
|
189
|
-
allow(File).to receive(:puts).with("require 'beaker/tasks/quick_start'").and_return(true)
|
190
|
-
expect(FileUtils).to receive(:touch).with("Rakefile").exactly(1).times
|
191
|
-
expect(File).to receive(:open).with("Rakefile", "a+").and_yield(file).exactly(0).times
|
192
|
-
expect(file).to receive(:puts).with("require 'beaker/tasks/quick_start'").exactly(0).times
|
193
|
-
subject.require_tasks
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
describe "init_config" do
|
198
|
-
it "creates a .beaker folder and loads the config" do
|
199
|
-
expect(FileUtils).to receive(:mkdir_p).with(".beaker").exactly(1).times
|
200
|
-
expect(YAML::Store).to receive(:new).with(".beaker/config").exactly(1).times
|
201
|
-
subject.init_config
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
describe "store_config" do
|
206
|
-
before(:each) { SubcommandUtil.class_variable_set :@@store, store}
|
207
|
-
|
208
|
-
it "stores some values in the YAML store" do
|
209
|
-
options = { :hypervisor => "vmpooler", :test => "abc", :provisioned => true}
|
210
|
-
allow(store).to receive(:transaction).and_yield
|
211
|
-
expect(store).to receive(:[]=).with(:hypervisor, "vmpooler").exactly(1).times
|
212
|
-
expect(store).to receive(:[]=).with(:test, "abc").exactly(0).times
|
213
|
-
expect(store).to receive(:[]=).with(:provisioned, true).exactly(1).times
|
214
|
-
subject.store_config(options)
|
215
|
-
end
|
216
|
-
|
217
|
-
it "stores all values in the YAML store" do
|
218
|
-
options = { :hypervisor => "vmpooler", :provisioned => true}
|
219
|
-
allow(store).to receive(:transaction).and_yield
|
220
|
-
expect(store).to receive(:[]=).with(:hypervisor, "vmpooler").exactly(1).times
|
221
|
-
expect(store).to receive(:[]=).with(:provisioned, true).exactly(1).times
|
222
|
-
subject.store_config(options)
|
223
|
-
end
|
224
|
-
|
225
|
-
it "stores no values in the YAML store" do
|
226
|
-
options = {:test => "abc"}
|
227
|
-
allow(store).to receive(:transaction).and_yield
|
228
|
-
expect(store).to receive(:[]=).with(:hypervisor, anything).exactly(0).times
|
229
|
-
expect(store).to receive(:[]=).with(:provisioned, anything).exactly(0).times
|
230
|
-
subject.store_config(options)
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
describe "delete_config" do
|
235
|
-
before(:each) { SubcommandUtil.class_variable_set :@@store, store}
|
236
|
-
it "deletes keys from the YAML store" do
|
237
|
-
keys = [ :hypervisor, :test, :provisioned ]
|
238
|
-
allow(store).to receive(:transaction).and_yield
|
239
|
-
expect(store).to receive(:delete).with(:hypervisor).exactly(1).times
|
240
|
-
expect(store).to receive(:delete).with(:test).exactly(1).times
|
241
|
-
expect(store).to receive(:delete).with(:provisioned).exactly(1).times
|
242
|
-
subject.delete_config(keys)
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
describe "provision" do
|
247
|
-
it "provisions, validates, and configures with vmpooler" do
|
248
|
-
options = {:validate => true, :configure => true}
|
249
|
-
expect(cli).to receive(:provision).and_return(true)
|
250
|
-
expect(cli).to receive(:preserve_hosts_file).exactly(1).times
|
251
|
-
allow(Beaker::CLI).to receive(:new).and_return(cli)
|
252
|
-
allow(cli).to receive(:parse_options).and_return(cli)
|
253
|
-
hypervisor = "vmpooler"
|
254
|
-
expect(subject).to receive(:reset_argv).with(["--hosts",".beaker/acceptance/config/default_#{hypervisor}_hosts.yaml", "--validate", true, "--configure", true]).exactly(1).times
|
255
|
-
subject.provision(hypervisor, options)
|
256
|
-
end
|
257
|
-
|
258
|
-
it "provisions and validates with vmpooler" do
|
259
|
-
options = {:validate => true, :configure => false }
|
260
|
-
expect(cli).to receive(:provision).and_return(true)
|
261
|
-
expect(cli).to receive(:preserve_hosts_file).exactly(1).times
|
262
|
-
allow(Beaker::CLI).to receive(:new).and_return(cli)
|
263
|
-
allow(cli).to receive(:parse_options).and_return(cli)
|
264
|
-
hypervisor = "vmpooler"
|
265
|
-
expect(subject).to receive(:reset_argv).with(["--hosts",".beaker/acceptance/config/default_#{hypervisor}_hosts.yaml", "--validate", true, "--configure", false]).exactly(1).times
|
266
|
-
subject.provision(hypervisor, options)
|
267
|
-
end
|
268
|
-
|
269
|
-
it "only provisions with vmpooler" do
|
270
|
-
options = {:validate => false, :configure => false }
|
271
|
-
expect(cli).to receive(:provision).and_return(true)
|
272
|
-
expect(cli).to receive(:preserve_hosts_file).exactly(1).times
|
273
|
-
allow(Beaker::CLI).to receive(:new).and_return(cli)
|
274
|
-
allow(cli).to receive(:parse_options).and_return(cli)
|
275
|
-
hypervisor = "vmpooler"
|
276
|
-
expect(subject).to receive(:reset_argv).with(["--hosts",".beaker/acceptance/config/default_#{hypervisor}_hosts.yaml", "--validate", false, "--configure", false]).exactly(1).times
|
277
|
-
subject.provision(hypervisor, options)
|
278
|
-
end
|
279
|
-
end
|
280
107
|
end
|
281
108
|
end
|
282
109
|
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Beaker
|
4
|
+
SubcommandUtil = Beaker::Subcommands::SubcommandUtil
|
5
|
+
describe Subcommand do
|
6
|
+
let( :subcommand ) {
|
7
|
+
Beaker::Subcommand.new
|
8
|
+
}
|
9
|
+
|
10
|
+
context '#initialize' do
|
11
|
+
it 'creates a cli object' do
|
12
|
+
expect(Beaker::CLI).to receive(:new).once
|
13
|
+
subcommand
|
14
|
+
end
|
15
|
+
describe 'File operation initialization for subcommands' do
|
16
|
+
it 'checks to ensure subcommand file resources exist' do
|
17
|
+
expect(FileUtils).to receive(:mkdir_p).with(SubcommandUtil::CONFIG_DIR)
|
18
|
+
expect(SubcommandUtil::SUBCOMMAND_OPTIONS).to receive(:exist?).and_return(true)
|
19
|
+
expect(SubcommandUtil::SUBCOMMAND_STATE).to receive(:exist?).and_return(true)
|
20
|
+
subcommand
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'touches the files when they do not exist' do
|
24
|
+
expect(FileUtils).to receive(:mkdir_p).with(SubcommandUtil::CONFIG_DIR)
|
25
|
+
allow(SubcommandUtil::SUBCOMMAND_OPTIONS).to receive(:exist?).and_return(false)
|
26
|
+
allow(SubcommandUtil::SUBCOMMAND_STATE).to receive(:exist?).and_return(false)
|
27
|
+
expect(FileUtils).to receive(:touch).with(SubcommandUtil::SUBCOMMAND_OPTIONS)
|
28
|
+
expect(FileUtils).to receive(:touch).with(SubcommandUtil::SUBCOMMAND_STATE)
|
29
|
+
subcommand
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context '#init' do
|
36
|
+
let( :cli ) { subcommand.instance_variable_get(:@cli) }
|
37
|
+
let( :mock_options ) { {:timestamp => 'noon', :other_key => 'cordite'}}
|
38
|
+
let( :yaml_store_mock ) { double('yaml_store_mock') }
|
39
|
+
it 'calculates options and writes them to disk and deletes the' do
|
40
|
+
expect(cli).to receive(:parse_options)
|
41
|
+
allow(cli).to receive(:configured_options).and_return(mock_options)
|
42
|
+
|
43
|
+
allow(File).to receive(:open)
|
44
|
+
allow(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
|
45
|
+
allow(yaml_store_mock).to receive(:transaction).and_yield
|
46
|
+
expect(yaml_store_mock).to receive(:[]=).with('provisioned', false)
|
47
|
+
subcommand.init
|
48
|
+
expect(mock_options).not_to have_key(:timestamp)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context '#provision' do
|
53
|
+
let ( :cli ) { subcommand.instance_variable_get(:@cli) }
|
54
|
+
let( :yaml_store_mock ) { double('yaml_store_mock') }
|
55
|
+
let ( :host_hash ) { {'mynode.net' => {:name => 'mynode', :platform => Beaker::Platform.new('centos-6-x86_64')}}}
|
56
|
+
let ( :cleaned_hosts ) {double()}
|
57
|
+
let ( :yielded_host_hash ) {double()}
|
58
|
+
let ( :yielded_host_name) {double()}
|
59
|
+
let ( :network_manager) {double('network_manager')}
|
60
|
+
let ( :hosts) {double('hosts')}
|
61
|
+
let ( :hypervisors) {double('hypervisors')}
|
62
|
+
let (:options) {double ('options')}
|
63
|
+
it 'provisions the host and saves the host info' do
|
64
|
+
expect(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
|
65
|
+
allow(yaml_store_mock).to receive(:[]).and_return(false)
|
66
|
+
allow(cli).to receive(:preserve_hosts_file).and_return("/path/to/ho")
|
67
|
+
allow(cli).to receive(:network_manager).and_return(network_manager)
|
68
|
+
allow(cli).to receive(:options).and_return(options)
|
69
|
+
allow(options).to receive(:[]).with(:hosts_preserved_yaml_file).and_return("/path/to/hosts")
|
70
|
+
allow(network_manager).to receive(:hosts).and_return(hosts)
|
71
|
+
allow(network_manager).to receive(:hypervisors).and_return(hypervisors)
|
72
|
+
expect(cli).to receive(:parse_options).and_return(cli)
|
73
|
+
expect(cli).to receive(:provision)
|
74
|
+
expect(cli).to receive(:combined_instance_and_options_hosts).and_return(host_hash)
|
75
|
+
expect(SubcommandUtil).to receive(:sanitize_options_for_save).and_return(cleaned_hosts)
|
76
|
+
expect(cleaned_hosts).to receive(:each).and_yield(yielded_host_name, yielded_host_hash)
|
77
|
+
expect(yielded_host_hash).to receive(:[]=).with('provision', false)
|
78
|
+
expect(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_OPTIONS).and_return(yaml_store_mock)
|
79
|
+
|
80
|
+
expect(yaml_store_mock).to receive(:transaction).and_yield.exactly(3).times
|
81
|
+
expect(yaml_store_mock).to receive(:[]=).with('HOSTS', cleaned_hosts)
|
82
|
+
expect(yaml_store_mock).to receive(:[]=).with('hosts_preserved_yaml_file', "/path/to/hosts")
|
83
|
+
|
84
|
+
expect(yaml_store_mock).to receive(:[]=).with('provisioned', true)
|
85
|
+
subcommand.provision
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
context 'exec' do
|
91
|
+
it 'calls execute! when no resource is given' do
|
92
|
+
expect_any_instance_of(Pathname).to_not receive(:directory?)
|
93
|
+
expect_any_instance_of(Pathname).to_not receive(:exist?)
|
94
|
+
expect_any_instance_of(Beaker::CLI).to receive(:parse_options).once
|
95
|
+
expect_any_instance_of(Beaker::CLI).to receive(:initialize_network_manager).once
|
96
|
+
expect_any_instance_of(Beaker::CLI).to receive(:execute!).once
|
97
|
+
expect{subcommand.exec}.to_not raise_error
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'checks to to see if the resource is a file_resource' do
|
101
|
+
|
102
|
+
expect_any_instance_of(Pathname).to receive(:exist?).and_return(true)
|
103
|
+
expect_any_instance_of(Pathname).to receive(:directory?).and_return(false)
|
104
|
+
expect_any_instance_of(Pathname).to receive(:expand_path).once
|
105
|
+
expect_any_instance_of(Beaker::CLI).to receive(:execute!).once
|
106
|
+
expect{subcommand.exec('resource')}.to_not raise_error
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'checks to see if the resource is a directory' do
|
110
|
+
expect_any_instance_of(Pathname).to receive(:exist?).and_return(true)
|
111
|
+
expect_any_instance_of(Pathname).to receive(:directory?).and_return(true)
|
112
|
+
expect(Dir).to receive(:glob)
|
113
|
+
expect_any_instance_of(Pathname).to receive(:expand_path).once
|
114
|
+
expect_any_instance_of(Beaker::CLI).to receive(:execute!).once
|
115
|
+
expect{subcommand.exec('resource')}.to_not raise_error
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'allows a hard coded suite name to be specified' do
|
119
|
+
|
120
|
+
allow_any_instance_of(Pathname).to receive(:exist?).and_return(false)
|
121
|
+
expect_any_instance_of(Beaker::CLI).to receive(:execute!).once
|
122
|
+
expect{subcommand.exec('tests')}.to_not raise_error
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'errors when a resource is neither a valid file resource or suite name' do
|
126
|
+
allow_any_instance_of(Pathname).to receive(:exist?).and_return(false)
|
127
|
+
expect{subcommand.exec('blahblahblah')}.to raise_error(ArgumentError)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'destroy' do
|
132
|
+
let( :cli ) { subcommand.instance_variable_get(:@cli) }
|
133
|
+
let( :mock_options ) { {:timestamp => 'noon', :other_key => 'cordite'}}
|
134
|
+
let( :yaml_store_mock ) { double('yaml_store_mock') }
|
135
|
+
it 'calls destroy and updates the yaml store' do
|
136
|
+
expect(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
|
137
|
+
allow(SubcommandUtil).to receive(:cleanup).with(cli).and_return(true)
|
138
|
+
allow(yaml_store_mock).to receive(:transaction).and_yield
|
139
|
+
allow(yaml_store_mock).to receive(:[]).with('provisioned').and_return(true)
|
140
|
+
allow(yaml_store_mock).to receive(:delete).with('provisioned').and_return(true)
|
141
|
+
expect(SubcommandUtil).to receive(:error_with).with("Please provision an environment").exactly(0).times
|
142
|
+
subcommand.destroy
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|