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.
@@ -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
- describe 'reset_argv' do
28
- it "resets argv" do
29
- args = ["test1", "test2"]
30
- expect(ARGV).to receive(:clear).exactly(1).times
31
- subject.reset_argv(args)
32
- expect(ARGV[0]).to eq(args[0])
33
- expect(ARGV[1]).to eq(args[1])
34
- end
35
- end
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