beaker-aws 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,17 +7,20 @@ module Beaker
7
7
  # Mock out the call to load_fog_credentials
8
8
  allow_any_instance_of( Beaker::AwsSdk ).
9
9
  to receive(:load_fog_credentials).
10
- and_return({
11
- :access_key => fog_file_contents[:default][:aws_access_key_id],
12
- :secret_key => fog_file_contents[:default][:aws_secret_access_key],
13
- :session_token => fog_file_contents[:default][:aws_session_token],
14
- })
10
+ and_return(Aws::Credentials.new(
11
+ fog_file_contents[:default][:aws_access_key_id],
12
+ fog_file_contents[:default][:aws_secret_access_key],
13
+ fog_file_contents[:default][:aws_session_token],
14
+ ))
15
15
 
16
16
 
17
17
  # This is needed because the EC2 api looks up a local endpoints.json file
18
18
  FakeFS.deactivate!
19
19
  aws = Beaker::AwsSdk.new(@hosts, options)
20
+ aws_partitions_dir = Gem::Specification.find_by_name('aws-partitions').gem_dir
20
21
  FakeFS.activate!
22
+ allow(File).to receive(:exist?).with(File.join(aws_partitions_dir, 'partitions.json'))
23
+ FakeFS::FileSystem.clone(File.join(aws_partitions_dir, 'partitions.json'))
21
24
 
22
25
  aws
23
26
  }
@@ -59,9 +62,11 @@ module Beaker
59
62
 
60
63
  it 'from .fog file' do
61
64
  creds = aws.load_fog_credentials
62
- expect( creds[:access_key] ).to eq("IMANACCESSKEY")
63
- expect( creds[:secret_key] ).to eq("supersekritkey")
64
- expect( creds[:session_token] ).to eq('somecrazylongsupersessiontoken!#%^^*(%$^&@$%#!!#$asd;fjapugfrejklvznb;jdgfjiadvij')
65
+ expect(creds).to have_attributes(
66
+ :access_key_id => 'IMANACCESSKEY',
67
+ :secret_access_key => 'supersekritkey',
68
+ :session_token =>'somecrazylongsupersessiontoken!#%^^*(%$^&@$%#!!#$asd;fjapugfrejklvznb;jdgfjiadvij',
69
+ )
65
70
  end
66
71
 
67
72
 
@@ -70,9 +75,11 @@ module Beaker
70
75
  ENV['AWS_SECRET_ACCESS_KEY'] = "supersekritkey"
71
76
 
72
77
  creds = aws.load_env_credentials
73
- expect( creds[:access_key] ).to eq("IMANACCESSKEY")
74
- expect( creds[:secret_key] ).to eq("supersekritkey")
75
- expect( creds[:session_token] ).to be_nil
78
+ expect(creds).to have_attributes(
79
+ :access_key_id => "IMANACCESSKEY",
80
+ :secret_access_key => "supersekritkey",
81
+ :session_token => nil,
82
+ )
76
83
  end
77
84
 
78
85
  it 'from environment variables with session_token' do
@@ -81,9 +88,11 @@ module Beaker
81
88
  ENV['AWS_SESSION_TOKEN'] = 'somesuperlongsessiontokenspecialcharsblah!#%$#@$^!@qewpofudjsvjm'
82
89
 
83
90
  creds = aws.load_env_credentials
84
- expect( creds[:access_key] ).to eq("IMANACCESSKEY")
85
- expect( creds[:secret_key] ).to eq("supersekritkey")
86
- expect( creds[:session_token] ).to eq('somesuperlongsessiontokenspecialcharsblah!#%$#@$^!@qewpofudjsvjm')
91
+ expect(creds).to have_attributes(
92
+ :access_key_id => "IMANACCESSKEY",
93
+ :secret_access_key => "supersekritkey",
94
+ :session_token => 'somesuperlongsessiontokenspecialcharsblah!#%$#@$^!@qewpofudjsvjm',
95
+ )
87
96
  end
88
97
 
89
98
  end
@@ -91,11 +100,17 @@ module Beaker
91
100
  context 'dont read fog credentials' do
92
101
  let(:options) { make_opts.merge({ 'use_fog_credentials' => false }) }
93
102
 
103
+ before(:each) do
104
+ ENV.delete('AWS_ACCESS_KEY_ID')
105
+ end
106
+
94
107
  it 'not using fog' do
95
108
  creds = aws.load_env_credentials
96
- expect( creds[:access_key] ).to eq(nil)
97
- expect( creds[:secret_key] ).to eq(nil)
98
- expect( options[:use_fog_credentials] ).to eq(false)
109
+ expect(creds).to have_attributes(
110
+ :access_key_id => nil,
111
+ :secret_access_key => nil,
112
+ )
113
+ expect(options[:use_fog_credentials]).to eq(false)
99
114
  end
100
115
  end
101
116
 
@@ -121,11 +136,29 @@ module Beaker
121
136
  end
122
137
 
123
138
  describe '#kill_instances' do
124
- let( :ec2_instance ) { double('ec2_instance', :nil? => false, :exists? => true, :id => "ec2", :terminate => nil) }
125
- let( :vpc_instance ) { double('vpc_instance', :nil? => false, :exists? => true, :id => "vpc", :terminate => nil) }
126
- let( :nil_instance ) { double('vpc_instance', :nil? => true, :exists? => true, :id => "nil", :terminate => nil) }
127
- let( :unreal_instance ) { double('vpc_instance', :nil? => false, :exists? => false, :id => "unreal", :terminate => nil) }
139
+ def mock_instance(id, state)
140
+ instance_double(
141
+ Aws::EC2::Types::Instance,
142
+ :state => instance_double(Aws::EC2::Types::InstanceState, :name => state),
143
+ :instance_id => id,
144
+ )
145
+ end
146
+
147
+ let(:ec2_instance) { mock_instance('ec2', 'running') }
148
+ let(:vpc_instance) { mock_instance('vpc', 'running') }
149
+ let(:nil_instance) { nil }
150
+ let(:unreal_instance) { mock_instance('unreal', 'terminated') }
151
+
128
152
  subject(:kill_instances) { aws.kill_instances(instance_set) }
153
+ let(:mock_client) { instance_double(Aws::EC2::Client, :terminate_instances => nil) }
154
+
155
+ before(:each) do
156
+ allow(aws).to receive(:client).and_return(mock_client)
157
+ allow(aws).to receive(:instance_by_id).with('ec2').and_return(ec2_instance)
158
+ allow(aws).to receive(:instance_by_id).with('vpc').and_return(vpc_instance)
159
+ allow(aws).to receive(:instance_by_id).with('nil').and_return(nil_instance)
160
+ allow(aws).to receive(:instance_by_id).with('unreal').and_return(unreal_instance)
161
+ end
129
162
 
130
163
  it 'should return nil' do
131
164
  instance_set = [ec2_instance, vpc_instance, nil_instance, unreal_instance]
@@ -138,28 +171,21 @@ module Beaker
138
171
  end
139
172
 
140
173
  context 'in general use' do
141
- let( :instance_set ) { [ec2_instance, vpc_instance] }
174
+ let( :instance_set ) { [ec2_instance, nil_instance, vpc_instance] }
142
175
 
143
176
  it 'terminates each running instance' do
144
- instance_set.each do |instance|
145
- expect(instance).to receive(:terminate).once
146
- end
147
- expect(kill_instances).to be_nil
148
- end
177
+ expect(mock_client).to receive(:terminate_instances).with(
178
+ :instance_ids => [ec2_instance.instance_id, vpc_instance.instance_id],
179
+ )
149
180
 
150
- it 'verifies instances are not nil' do
151
- instance_set.each do |instance|
152
- expect(instance).to receive(:nil?)
153
- allow(instance).to receive(:terminate).once
154
- end
155
181
  expect(kill_instances).to be_nil
156
182
  end
157
183
 
158
184
  it 'verifies instances exist in AWS' do
159
- instance_set.each do |instance|
160
- expect(instance).to receive(:exists?)
161
- allow(instance).to receive(:terminate).once
185
+ instance_set.compact.each do |instance|
186
+ expect(aws).to receive(:instance_by_id).with(instance.instance_id)
162
187
  end
188
+
163
189
  expect(kill_instances).to be_nil
164
190
  end
165
191
  end
@@ -168,25 +194,23 @@ module Beaker
168
194
  let( :instance_set ) { [ec2_instance] }
169
195
 
170
196
  it 'terminates the running instance' do
171
- instance_set.each do |instance|
172
- expect(instance).to receive(:terminate).once
173
- end
174
- expect(kill_instances).to be_nil
175
- end
197
+ expect(mock_client).to receive(:terminate_instances).with(
198
+ :instance_ids => [ec2_instance.instance_id],
199
+ )
176
200
 
177
- it 'verifies instance is not nil' do
178
- instance_set.each do |instance|
179
- expect(instance).to receive(:nil?)
180
- allow(instance).to receive(:terminate).once
181
- end
182
201
  expect(kill_instances).to be_nil
183
202
  end
184
203
 
185
204
  it 'verifies instance exists in AWS' do
186
205
  instance_set.each do |instance|
187
- expect(instance).to receive(:exists?)
188
- allow(instance).to receive(:terminate).once
206
+ expected_state = instance_double(Aws::EC2::Types::InstanceState, :name => 'running')
207
+ expect(instance).to receive(:state).and_return(expected_state)
189
208
  end
209
+
210
+ expect(mock_client).to receive(:terminate_instances).with(
211
+ :instance_ids => [ec2_instance.instance_id],
212
+ )
213
+
190
214
  expect(kill_instances).to be_nil
191
215
  end
192
216
  end
@@ -195,54 +219,47 @@ module Beaker
195
219
  let( :instance_set ) { [unreal_instance] }
196
220
 
197
221
  it 'does not call terminate' do
198
- instance_set.each do |instance|
199
- expect(instance).to receive(:terminate).exactly(0).times
200
- end
222
+ expect(mock_client).not_to receive(:terminate_instances)
201
223
  expect(kill_instances).to be_nil
202
224
  end
203
225
 
204
226
  it 'verifies instance does not exist' do
205
227
  instance_set.each do |instance|
206
- expect(instance).to receive(:exists?).once
207
- allow(instance).to receive(:terminate).exactly(0).times
228
+ expected_state = instance_double(Aws::EC2::Types::InstanceState, :name => 'terminated')
229
+ expect(instance).to receive(:state).and_return(expected_state)
208
230
  end
231
+
232
+ expect(mock_client).not_to receive(:terminate_instances)
209
233
  expect(kill_instances).to be_nil
210
234
  end
211
235
  end
212
236
 
213
237
  context 'when an instance is nil' do
214
- let( :instance_set ) { [nil_instance] }
238
+ let(:instance_set) { [nil_instance] }
215
239
 
216
240
  it 'does not call terminate' do
217
- instance_set.each do |instance|
218
- expect(instance).to receive(:terminate).exactly(0).times
219
- end
220
- expect(kill_instances).to be_nil
221
- end
241
+ expect(mock_client).not_to receive(:terminate_instances)
222
242
 
223
- it 'verifies instance is nil' do
224
- instance_set.each do |instance|
225
- expect(instance).to receive(:nil?).once
226
- allow(instance).to receive(:terminate).exactly(0).times
227
- end
228
243
  expect(kill_instances).to be_nil
229
244
  end
230
245
  end
231
-
232
246
  end
233
247
 
234
248
  describe '#cleanup' do
235
249
  subject(:cleanup) { aws.cleanup }
236
- let( :ec2_instance ) { double('ec2_instance', :nil? => false, :exists? => true, :terminate => nil, :id => 'id') }
250
+ let(:ec2_instance) do
251
+ instance_double(Aws::EC2::Types::Instance,
252
+ :instance_id => 'id',
253
+ :state => instance_double(Aws::EC2::Types::InstanceState, :name => 'running'),
254
+ )
255
+ end
237
256
 
238
257
  context 'with a list of hosts' do
239
258
  before :each do
240
- @hosts.each {|host| host['instance'] = ec2_instance}
241
- expect(aws).to receive( :delete_key_pair_all_regions )
259
+ @hosts.each { |host| host['instance'] = ec2_instance }
260
+ expect(aws).to receive(:delete_key_pair_all_regions)
242
261
  end
243
262
 
244
- it { is_expected.to be_nil }
245
-
246
263
  it 'kills instances' do
247
264
  expect(aws).to receive(:kill_instances).once
248
265
  expect(cleanup).to be_nil
@@ -255,8 +272,6 @@ module Beaker
255
272
  expect(aws).to receive( :delete_key_pair_all_regions )
256
273
  end
257
274
 
258
- it { is_expected.to be_nil }
259
-
260
275
  it 'kills instances' do
261
276
  expect(aws).to receive(:kill_instances).once
262
277
  expect(cleanup).to be_nil
@@ -267,45 +282,32 @@ module Beaker
267
282
  describe '#log_instances', :wip do
268
283
  end
269
284
 
270
- describe '#instance_by_id' do
271
- subject { aws.instance_by_id('my_id') }
272
- it { is_expected.to be_instance_of(AWS::EC2::Instance) }
285
+ describe '#instance_by_id', :wip do
273
286
  end
274
287
 
275
- describe '#instances' do
276
- subject { aws.instances }
277
- it { is_expected.to be_instance_of(AWS::EC2::InstanceCollection) }
288
+ describe '#instances', :wip do
278
289
  end
279
290
 
280
- describe '#vpc_by_id' do
281
- subject { aws.vpc_by_id('my_id') }
282
- it { is_expected.to be_instance_of(AWS::EC2::VPC) }
291
+ describe '#vpc_by_id', :wip do
283
292
  end
284
293
 
285
- describe '#vpcs' do
286
- subject { aws.vpcs }
287
- it { is_expected.to be_instance_of(AWS::EC2::VPCCollection) }
294
+ describe '#vpcs', :wip do
288
295
  end
289
296
 
290
- describe '#security_group_by_id' do
291
- subject { aws.security_group_by_id('my_id') }
292
- it { is_expected.to be_instance_of(AWS::EC2::SecurityGroup) }
297
+ describe '#security_group_by_id', :wip do
293
298
  end
294
299
 
295
- describe '#security_groups' do
296
- subject { aws.security_groups }
297
- it { is_expected.to be_instance_of(AWS::EC2::SecurityGroupCollection) }
300
+ describe '#security_groups', :wip do
298
301
  end
299
302
 
300
303
  describe '#kill_zombies' do
301
304
  it 'calls delete_key_pair_all_regions' do
302
- ec2_mock = Object.new
303
- allow(ec2_mock).to receive( :regions ).and_return( {} )
304
- aws.instance_variable_set( :@ec2, ec2_mock )
305
+ allow(aws).to receive(:regions).and_return([])
305
306
 
306
- expect( aws ).to receive( :delete_key_pair_all_regions ).once
307
+ expect(aws).to receive(:kill_instances).once
308
+ expect(aws).to receive(:delete_key_pair_all_regions).once
307
309
 
308
- aws.kill_zombies()
310
+ aws.kill_zombies
309
311
  end
310
312
  end
311
313
 
@@ -322,21 +324,34 @@ module Beaker
322
324
  end
323
325
 
324
326
  describe '#wait_for_status' do
325
- let( :aws_instance ) { double('aws_instance', :id => "ec2", :terminate => nil) }
326
- let( :instance_set ) { [{:instance => aws_instance}] }
327
+ let( :aws_instance ) { instance_double(Aws::EC2::Types::Instance, :instance_id => "ec2") }
328
+ let( :instance_set ) { [{:instance => aws_instance, :host => instance_double(Beaker::Host, :name => 'test')}] }
327
329
  subject(:wait_for_status) { aws.wait_for_status(:running, instance_set) }
328
330
 
331
+ def mock_instance(state, other = {})
332
+ r = instance_double(
333
+ Aws::EC2::Types::Instance,
334
+ :instance_id => 'ec2',
335
+ :state => instance_double(Aws::EC2::Types::InstanceState, :name => state),
336
+ )
337
+
338
+ other.each do |k, v|
339
+ allow(r).to receive(:[]).with(k).and_return(v)
340
+ end
341
+
342
+ r
343
+ end
344
+
329
345
  context 'single instance' do
330
346
  it 'behaves correctly in typical case' do
331
- allow(aws_instance).to receive(:status).and_return(:waiting, :waiting, :running)
347
+ allow(aws).to receive(:instance_by_id).with('ec2').and_return(mock_instance(:waiting), mock_instance(:waiting), mock_instance(:running))
332
348
  expect(aws).to receive(:backoff_sleep).exactly(3).times
333
349
  expect(wait_for_status).to eq(instance_set)
334
350
  end
335
351
 
336
352
  it 'executes block correctly instead of status if given one' do
337
353
  barn_value = 'did you grow up in a barn?'
338
- allow(aws_instance).to receive( :[] ).with( :barn ) { barn_value }
339
- expect(aws_instance).to receive(:status).exactly(0).times
354
+ expect(aws).to receive(:instance_by_id).and_return(mock_instance(:running, :barn => barn_value))
340
355
  expect(aws).to receive(:backoff_sleep).exactly(1).times
341
356
  aws.wait_for_status(:running, instance_set) do |instance|
342
357
  expect( instance[:barn] ).to be === barn_value
@@ -346,16 +361,35 @@ module Beaker
346
361
  end
347
362
 
348
363
  context 'with multiple instances' do
349
- let( :instance_set ) { [{:instance => aws_instance}, {:instance => aws_instance}] }
364
+ let(:instance_set) do
365
+ [
366
+ { :instance => aws_instance, :host => instance_double(Beaker::Host, :name => 'test1') },
367
+ { :instance => aws_instance, :host => instance_double(Beaker::Host, :name => 'test2') },
368
+ ]
369
+ end
350
370
 
351
371
  it 'returns the instance set passed to it' do
352
- allow(aws_instance).to receive(:status).and_return(:waiting, :waiting, :running, :waiting, :waiting, :running)
372
+ allow(aws).to receive(:instance_by_id).and_return(
373
+ mock_instance(:waiting),
374
+ mock_instance(:waiting),
375
+ mock_instance(:running),
376
+ mock_instance(:waiting),
377
+ mock_instance(:waiting),
378
+ mock_instance(:running)
379
+ )
353
380
  allow(aws).to receive(:backoff_sleep).exactly(6).times
354
381
  expect(wait_for_status).to eq(instance_set)
355
382
  end
356
383
 
357
384
  it 'calls backoff_sleep once per instance.status call' do
358
- allow(aws_instance).to receive(:status).and_return(:waiting, :waiting, :running, :waiting, :waiting, :running)
385
+ allow(aws).to receive(:instance_by_id).and_return(
386
+ mock_instance(:waiting),
387
+ mock_instance(:waiting),
388
+ mock_instance(:running),
389
+ mock_instance(:waiting),
390
+ mock_instance(:waiting),
391
+ mock_instance(:running),
392
+ )
359
393
  expect(aws).to receive(:backoff_sleep).exactly(6).times
360
394
  expect(wait_for_status).to eq(instance_set)
361
395
  end
@@ -364,7 +398,12 @@ module Beaker
364
398
  barn_value = 'did you grow up in a barn?'
365
399
  not_barn_value = 'notabarn'
366
400
  allow(aws_instance).to receive( :[] ).with( :barn ).and_return(not_barn_value, barn_value, not_barn_value, barn_value)
367
- allow(aws_instance).to receive(:status).and_return(:waiting)
401
+ allow(aws).to receive(:instance_by_id).and_return(
402
+ mock_instance(:waiting, :barn => not_barn_value),
403
+ mock_instance(:waiting, :barn => barn_value),
404
+ mock_instance(:waiting, :barn => not_barn_value),
405
+ mock_instance(:waiting, :barn => barn_value),
406
+ )
368
407
  expect(aws).to receive(:backoff_sleep).exactly(4).times
369
408
  aws.wait_for_status(:running, instance_set) do |instance|
370
409
  instance[:barn] == barn_value
@@ -374,148 +413,197 @@ module Beaker
374
413
 
375
414
  context 'after 10 tries' do
376
415
  it 'raises RuntimeError' do
377
- expect(aws_instance).to receive(:status).and_return(:waiting).exactly(10).times
416
+ expect(aws).to receive(:instance_by_id).and_return(mock_instance(:waiting)).exactly(10).times
378
417
  expect(aws).to receive(:backoff_sleep).exactly(9).times
379
418
  expect { wait_for_status }.to raise_error('Instance never reached state running')
380
419
  end
381
420
 
382
421
  it 'still raises RuntimeError if given a block' do
383
- expect(aws_instance).to receive(:status).and_return(:waiting).exactly(10).times
422
+ expect(aws).to receive(:instance_by_id).and_return(mock_instance(:waiting)).exactly(10).times
384
423
  expect(aws).to receive(:backoff_sleep).exactly(9).times
385
424
  expect { wait_for_status { false } }.to raise_error('Instance never reached state running')
386
425
  end
387
426
  end
388
-
389
- context 'with an invalid instance' do
390
- it 'raises AWS::EC2::Errors::InvalidInstanceID::NotFound' do
391
- expect(aws_instance).to receive(:status).and_raise(AWS::EC2::Errors::InvalidInstanceID::NotFound).exactly(10).times
392
- allow(aws).to receive(:backoff_sleep).at_most(10).times
393
- expect(wait_for_status).to eq(instance_set)
394
- end
395
- end
396
427
  end
397
428
 
398
429
  describe '#add_tags' do
399
- let( :aws_instance ) { double('aws_instance', :add_tag => nil) }
430
+ let(:aws_instance) { instance_double(Aws::EC2::Types::Instance, :instance_id => 'id-123') }
431
+ let(:mock_client) { instance_double(Aws::EC2::Client) }
432
+
400
433
  subject(:add_tags) { aws.add_tags }
401
434
 
402
- it 'returns nil' do
403
- @hosts.each {|host| host['instance'] = aws_instance}
404
- expect(add_tags).to be_nil
435
+ before(:each) do
436
+ allow(aws).to receive(:client).and_return(mock_client)
437
+ allow(mock_client).to receive(:create_tags)
405
438
  end
406
439
 
407
- it 'handles a single host' do
408
- @hosts[0]['instance'] = aws_instance
409
- @hosts = [@hosts[0]]
440
+ it 'returns nil' do
441
+ @hosts.each {|host| host['instance'] = aws_instance}
410
442
  expect(add_tags).to be_nil
411
443
  end
412
444
 
413
445
  context 'with multiple hosts' do
414
446
  before :each do
415
- @hosts.each {|host| host['instance'] = aws_instance}
447
+ @hosts.each_with_index do |host, i|
448
+ host['instance'] = instance_double(Aws::EC2::Types::Instance, :instance_id => "id-#{i}")
449
+ end
416
450
  end
417
451
 
418
452
  it 'handles host_tags hash on host object' do
419
453
  # set :host_tags on first host
420
- aws.instance_eval {
421
- @hosts[0][:host_tags] = {'test_tag' => 'test_value'}
422
- }
423
- expect(aws_instance).to receive(:add_tag).with('test_tag', hash_including(:value => 'test_value')).at_least(:once)
454
+ @hosts[0][:host_tags] = {'test_tag' => 'test_value'}
455
+
456
+ expect(mock_client).to receive(:create_tags).with(
457
+ :resources => [@hosts[0]['instance'].instance_id],
458
+ :tags => include(
459
+ {
460
+ :key => 'test_tag',
461
+ :value => 'test_value',
462
+ },
463
+ ),
464
+ ).once
465
+
424
466
  expect(add_tags).to be_nil
425
467
  end
426
468
 
427
469
  it 'adds tag for jenkins_build_url' do
428
470
  aws.instance_eval('@options[:jenkins_build_url] = "my_build_url"')
429
- expect(aws_instance).to receive(:add_tag).with('jenkins_build_url', hash_including(:value => 'my_build_url')).at_least(:once)
471
+
472
+ expect(mock_client).to receive(:create_tags).with(
473
+ :resources => anything,
474
+ :tags => include(
475
+ {
476
+ :key => 'jenkins_build_url',
477
+ :value => 'my_build_url',
478
+ },
479
+ ),
480
+ ).at_least(:once)
481
+
430
482
  expect(add_tags).to be_nil
431
483
  end
432
484
 
433
485
  it 'adds tag for Name' do
434
- expect(aws_instance).to receive(:add_tag).with('Name', hash_including(:value => /vm/)).at_least(@hosts.size).times
486
+ expect(mock_client).to receive(:create_tags).with(
487
+ :resources => anything,
488
+ :tags => include(
489
+ {
490
+ :key => 'Name',
491
+ :value => a_string_matching(/vm/),
492
+ },
493
+ ),
494
+ ).at_least(:once)
495
+
435
496
  expect(add_tags).to be_nil
436
497
  end
437
498
 
438
499
  it 'adds tag for department' do
439
500
  aws.instance_eval('@options[:department] = "my_department"')
440
- expect(aws_instance).to receive(:add_tag).with('department', hash_including(:value => 'my_department')).at_least(:once)
501
+
502
+ expect(mock_client).to receive(:create_tags).with(
503
+ :resources => anything,
504
+ :tags => include(
505
+ {
506
+ :key => 'department',
507
+ :value => 'my_department',
508
+ },
509
+ ),
510
+ ).at_least(:once)
511
+
441
512
  expect(add_tags).to be_nil
442
513
  end
443
514
 
444
515
  it 'adds tag for project' do
445
516
  aws.instance_eval('@options[:project] = "my_project"')
446
- expect(aws_instance).to receive(:add_tag).with('project', hash_including(:value => 'my_project')).at_least(:once)
517
+
518
+ expect(mock_client).to receive(:create_tags).with(
519
+ :resources => anything,
520
+ :tags => include(
521
+ {
522
+ :key => 'project',
523
+ :value => 'my_project',
524
+ },
525
+ ),
526
+ ).at_least(:once)
527
+
447
528
  expect(add_tags).to be_nil
448
529
  end
449
530
 
450
531
  it 'adds tag for created_by' do
451
532
  aws.instance_eval('@options[:created_by] = "my_created_by"')
452
- expect(aws_instance).to receive(:add_tag).with('created_by', hash_including(:value => 'my_created_by')).at_least(:once)
533
+
534
+ expect(mock_client).to receive(:create_tags).with(
535
+ :resources => anything,
536
+ :tags => include(
537
+ {
538
+ :key => 'created_by',
539
+ :value => 'my_created_by',
540
+ },
541
+ ),
542
+ ).at_least(:once)
543
+
453
544
  expect(add_tags).to be_nil
454
545
  end
455
546
  end
456
547
  end
457
548
 
458
549
  describe '#populate_dns' do
459
- let( :vpc_instance ) { {ip_address: nil, private_ip_address: "vpc_private_ip", dns_name: "vpc_dns_name"} }
460
- let( :ec2_instance ) { {ip_address: "ec2_public_ip", private_ip_address: "ec2_private_ip", dns_name: "ec2_dns_name"} }
550
+ let( :vpc_instance ) do
551
+ instance_double(Aws::EC2::Types::Instance, public_ip_address: nil, private_ip_address: "vpc_private_ip", public_dns_name: "vpc_dns_name")
552
+ end
553
+ let( :ec2_instance ) do
554
+ instance_double(Aws::EC2::Types::Instance, public_ip_address: "ec2_public_ip", private_ip_address: "ec2_private_ip", public_dns_name: "ec2_dns_name")
555
+ end
461
556
  subject(:populate_dns) { aws.populate_dns }
557
+ subject(:hosts) { aws.instance_variable_get(:@hosts) }
462
558
 
463
559
  context 'on a public EC2 instance' do
464
560
  before :each do
465
- @hosts.each {|host| host['instance'] = make_instance ec2_instance}
466
- end
561
+ @hosts.each { |host| host['instance'] = ec2_instance }
467
562
 
468
- it 'sets host ip to instance.ip_address' do
469
563
  populate_dns
470
- hosts = aws.instance_variable_get( :@hosts )
564
+ end
565
+
566
+ it 'sets host ip to instance.public_ip_address' do
471
567
  hosts.each do |host|
472
- expect(host['ip']).to eql(ec2_instance[:ip_address])
568
+ expect(host['ip']).to eql(ec2_instance.public_ip_address)
473
569
  end
474
570
  end
475
571
 
476
572
  it 'sets host private_ip to instance.private_ip_address' do
477
- populate_dns
478
- hosts = aws.instance_variable_get( :@hosts )
479
573
  hosts.each do |host|
480
- expect(host['private_ip']).to eql(ec2_instance[:private_ip_address])
574
+ expect(host['private_ip']).to eql(ec2_instance.private_ip_address)
481
575
  end
482
576
  end
483
577
 
484
- it 'sets host dns_name to instance.dns_name' do
485
- populate_dns
486
- hosts = aws.instance_variable_get( :@hosts )
578
+ it 'sets host dns_name to instance.public_dns_name' do
487
579
  hosts.each do |host|
488
- expect(host['dns_name']).to eql(ec2_instance[:dns_name])
580
+ expect(host['dns_name']).to eql(ec2_instance.public_dns_name)
489
581
  end
490
582
  end
491
583
  end
492
584
 
493
585
  context 'on a VPC based instance' do
494
586
  before :each do
495
- @hosts.each {|host| host['instance'] = make_instance vpc_instance}
587
+ @hosts.each { |host| host['instance'] = vpc_instance }
588
+
589
+ populate_dns
496
590
  end
497
591
 
498
592
  it 'sets host ip to instance.private_ip_address' do
499
- populate_dns
500
- hosts = aws.instance_variable_get( :@hosts )
501
593
  hosts.each do |host|
502
- expect(host['ip']).to eql(vpc_instance[:private_ip_address])
594
+ expect(host['ip']).to eql(vpc_instance.private_ip_address)
503
595
  end
504
596
  end
505
597
 
506
598
  it 'sets host private_ip to instance.private_ip_address' do
507
- populate_dns
508
- hosts = aws.instance_variable_get( :@hosts )
509
599
  hosts.each do |host|
510
- expect(host['private_ip']).to eql(vpc_instance[:private_ip_address])
600
+ expect(host['private_ip']).to eql(vpc_instance.private_ip_address)
511
601
  end
512
602
  end
513
603
 
514
- it 'sets host dns_name to instance.dns_name' do
515
- populate_dns
516
- hosts = aws.instance_variable_get( :@hosts )
604
+ it 'sets host dns_name to instance.public_dns_name' do
517
605
  hosts.each do |host|
518
- expect(host['dns_name']).to eql(vpc_instance[:dns_name])
606
+ expect(host['dns_name']).to eql(vpc_instance.public_dns_name)
519
607
  end
520
608
  end
521
609
  end
@@ -608,13 +696,11 @@ module Beaker
608
696
  end
609
697
 
610
698
  describe '#enable_root_netscaler' do
611
- let( :ns_host ) { @hosts[5] }
699
+ let(:ns_host) { @hosts[5] }
612
700
  subject(:enable_root_netscaler) { aws.enable_root_netscaler(ns_host) }
613
701
 
614
702
  it 'set password to instance id of the host' do
615
- instance_mock = Object.new
616
- allow( instance_mock ).to receive(:id).and_return("i-842018")
617
- ns_host["instance"]=instance_mock
703
+ ns_host["instance"] = instance_double(Aws::EC2::Types::Instance, :instance_id => 'i-842018')
618
704
  enable_root_netscaler
619
705
  expect(ns_host['ssh'][:password]).to eql("i-842018")
620
706
  end
@@ -701,6 +787,8 @@ module Beaker
701
787
  end
702
788
 
703
789
  it "should return an error if the files do not exist" do
790
+ allow(File).to receive(:exist?).with(/id_[dr]sa.pub/) { false }
791
+ allow(File).to receive(:exist?).with(/id_[dr]sa/) { false }
704
792
  expect { public_key }.to raise_error(RuntimeError, /Expected to find a public key/)
705
793
  end
706
794
 
@@ -761,124 +849,133 @@ module Beaker
761
849
  end
762
850
 
763
851
  describe '#delete_key_pair_all_regions' do
852
+ before(:each) do
853
+ allow(aws).to receive(:my_key_pairs).and_return(region_keypairs)
854
+ end
855
+
856
+ after(:each) do
857
+ aws.delete_key_pair_all_regions
858
+ end
859
+
860
+ let(:region_keypairs) do
861
+ {
862
+ 'test1' => ['key1', 'key2', 'key3'],
863
+ 'test2' => ['key4', 'key5', 'key6'],
864
+ }
865
+ end
866
+
764
867
  it 'calls delete_key_pair over all regions' do
765
- key_name = 'kname_test1538'
766
- allow(aws).to receive( :key_name ).and_return(key_name)
767
- regions = []
768
- regions << double('region', :key_pairs => 'pair1', :name => 'name1')
769
- regions << double('region', :key_pairs => 'pair2', :name => 'name2')
770
- ec2_mock = Object.new
771
- allow(ec2_mock).to receive( :regions ).and_return(regions)
772
- aws.instance_variable_set( :@ec2, ec2_mock )
773
- region_keypairs_hash_mock = {}
774
- region_keypairs_hash_mock[double('region')] = ['key1', 'key2', 'key3']
775
- region_keypairs_hash_mock[double('region')] = ['key4', 'key5', 'key6']
776
- allow( aws ).to receive( :my_key_pairs ).and_return( region_keypairs_hash_mock )
777
-
778
- region_keypairs_hash_mock.each_pair do |region, keyname_array|
868
+ region_keypairs.each do |region, keyname_array|
779
869
  keyname_array.each do |keyname|
780
- expect( aws ).to receive( :delete_key_pair ).with( region, keyname )
870
+ expect(aws).to receive(:delete_key_pair).with(region, keyname)
781
871
  end
782
872
  end
783
- aws.delete_key_pair_all_regions
784
873
  end
785
874
  end
786
875
 
787
876
  describe '#my_key_pairs' do
788
- let( :region ) { double('region', :name => 'test_region_name') }
877
+ let(:regions) { ['name1', 'name2'] }
878
+ let(:mock_clients) { regions.map { |r| [r, instance_double(Aws::EC2::Client)] }.to_h }
879
+ let(:default_key_name) { 'test_pair_6193' }
880
+
881
+ before(:each) do
882
+ allow(aws).to receive(:regions).and_return(regions)
883
+ allow(aws).to receive(:key_name).and_return(default_key_name)
884
+
885
+ regions.each do |region|
886
+ allow(aws).to receive(:client).with(region).and_return(mock_clients[region])
887
+ end
888
+ end
789
889
 
790
890
  it 'uses the default keyname if no filter is given' do
791
- default_keyname_answer = 'test_pair_6193'
792
- allow( aws ).to receive( :key_name ).and_return( default_keyname_answer )
793
-
794
- kp_mock_1 = double('keypair')
795
- kp_mock_2 = double('keypair')
796
- regions = []
797
- regions << double('region', :key_pairs => kp_mock_1, :name => 'name1')
798
- regions << double('region', :key_pairs => kp_mock_2, :name => 'name2')
799
- ec2_mock = Object.new
800
- allow( ec2_mock ).to receive( :regions ).and_return( regions )
801
- aws.instance_variable_set( :@ec2, ec2_mock )
802
-
803
- kp_mock = double('keypair')
804
- allow( region ).to receive( :key_pairs ).and_return( kp_mock )
805
- expect( kp_mock_1 ).to receive( :filter ).with( 'key-name', default_keyname_answer ).and_return( [] )
806
- expect( kp_mock_2 ).to receive( :filter ).with( 'key-name', default_keyname_answer ).and_return( [] )
891
+ regions.each do |region|
892
+ expect(mock_clients[region]).to receive(:describe_key_pairs).with(
893
+ :filters => [{ :name => 'key-name', :values => [default_key_name] }]
894
+ ).and_return(instance_double(Aws::EC2::Types::DescribeKeyPairsResult, :key_pairs => []))
895
+ end
807
896
 
808
897
  aws.my_key_pairs()
809
898
  end
810
899
 
811
900
  it 'uses the filter passed if given' do
812
- default_keyname_answer = 'test_pair_6194'
813
- allow( aws ).to receive( :key_name ).and_return( default_keyname_answer )
814
901
  name_filter = 'filter_pair_1597'
815
- filter_star = "#{name_filter}-*"
816
-
817
- kp_mock_1 = double('keypair')
818
- kp_mock_2 = double('keypair')
819
- regions = []
820
- regions << double('region', :key_pairs => kp_mock_1, :name => 'name1')
821
- regions << double('region', :key_pairs => kp_mock_2, :name => 'name2')
822
- ec2_mock = Object.new
823
- allow( ec2_mock ).to receive( :regions ).and_return( regions )
824
- aws.instance_variable_set( :@ec2, ec2_mock )
825
-
826
- kp_mock = double('keypair')
827
- allow( region ).to receive( :key_pairs ).and_return( kp_mock )
828
- expect( kp_mock_1 ).to receive( :filter ).with( 'key-name', filter_star ).and_return( [] )
829
- expect( kp_mock_2 ).to receive( :filter ).with( 'key-name', filter_star ).and_return( [] )
902
+ filter_pattern = "#{name_filter}-*"
903
+
904
+ regions.each do |region|
905
+ expect(mock_clients[region]).to receive(:describe_key_pairs).with(
906
+ :filters => [{ :name => 'key-name', :values => [filter_pattern] }]
907
+ ).and_return(instance_double(Aws::EC2::Types::DescribeKeyPairsResult, :key_pairs => []))
908
+ end
830
909
 
831
910
  aws.my_key_pairs(name_filter)
832
911
  end
833
912
  end
834
913
 
835
914
  describe '#delete_key_pair' do
836
- let( :region ) { double('region', :name => 'test_region_name') }
915
+ let(:region) { 'test_region_name' }
916
+ let(:mock_client) { instance_double(Aws::EC2::Client) }
917
+ let(:pair_name) { 'pair1' }
837
918
 
838
- it 'calls delete on a keypair if it exists' do
839
- pair_name = 'pair1'
840
- kp_mock = double('keypair', :exists? => true)
841
- expect( kp_mock ).to receive( :delete ).once
842
- pairs = { pair_name => kp_mock }
843
- allow( region ).to receive( :key_pairs ).and_return( pairs )
844
- aws.delete_key_pair(region, pair_name)
919
+ before(:each) do
920
+ allow(aws).to receive(:client).with(region).and_return(mock_client)
921
+ allow(mock_client).to receive(:describe_key_pairs).with(
922
+ :key_names => [pair_name]
923
+ ).and_return(instance_double(Aws::EC2::Types::DescribeKeyPairsResult, :key_pairs => result))
845
924
  end
846
925
 
847
- it 'skips delete on a keypair if it does not exist' do
848
- pair_name = 'pair1'
849
- kp_mock = double('keypair', :exists? => false)
850
- expect( kp_mock ).to receive( :delete ).never
851
- pairs = { pair_name => kp_mock }
852
- allow( region ).to receive( :key_pairs ).and_return( pairs )
926
+ after(:each) do
853
927
  aws.delete_key_pair(region, pair_name)
854
928
  end
929
+
930
+ context 'when the keypair exists' do
931
+ let(:result) { [instance_double(Aws::EC2::Types::KeyPairInfo)] }
932
+
933
+ it 'deletes the keypair' do
934
+ expect(mock_client).to receive(:delete_key_pair).with(:key_name => pair_name)
935
+ end
936
+ end
937
+
938
+ context 'when the keypair does not exist' do
939
+ let(:result) { [] }
940
+
941
+ it 'does not try to delete the keypair' do
942
+ expect(mock_client).not_to receive(:delete_key_pair)
943
+ end
944
+ end
855
945
  end
856
946
 
857
947
  describe '#create_new_key_pair' do
858
- let(:region) { double('region', :name => 'test_region_name') }
948
+ let(:region) { 'test_region_name' }
859
949
  let(:ssh_string) { 'ssh_string_test_0867' }
860
- let(:pairs) { double('keypairs') }
861
- let(:pair) { double('keypair') }
950
+ let(:pair) { instance_double(Aws::EC2::Types::KeyPairInfo) }
862
951
  let(:pair_name) { 'pair_name_1555432' }
952
+ let(:mock_client) { instance_double(Aws::EC2::Client) }
863
953
 
864
954
  before :each do
955
+ allow(aws).to receive(:client).with(region).and_return(mock_client)
865
956
  allow(aws).to receive(:public_key).and_return(ssh_string)
866
- expect(pairs).to receive(:import).with(pair_name, ssh_string)
867
- expect(pairs).to receive(:[]).with(pair_name).and_return(pair)
868
- expect(region).to receive(:key_pairs).and_return(pairs).twice
957
+ allow(mock_client).to receive(:import_key_pair).with(
958
+ :key_name => pair_name,
959
+ :public_key_material => ssh_string,
960
+ )
961
+ allow(mock_client).to receive(:wait_until).with(:key_pair_exists, any_args)
869
962
  end
870
963
 
871
964
  it 'imports the key given from public_key' do
872
- expect(pair).to receive(:exists?).and_return(true)
965
+ expect(mock_client).to receive(:import_key_pair).with(
966
+ :key_name => pair_name,
967
+ :public_key_material => ssh_string,
968
+ )
969
+
873
970
  aws.create_new_key_pair(region, pair_name)
874
971
  end
875
972
 
876
973
  it 'raises an exception if subsequent keypair check is false' do
877
- expect(pair).to receive(:exists?).and_return(false).exactly(5).times
878
- expect(aws).to receive(:backoff_sleep).exactly(5).times
879
- expect { aws.create_new_key_pair(region, pair_name) }.
880
- to raise_error(RuntimeError,
881
- "AWS key pair #{pair_name} can not be queried, even after import")
974
+ allow(mock_client).to receive(:wait_until).with(:key_pair_exists, any_args).and_raise(Aws::Waiters::Errors::WaiterFailed)
975
+ expect {
976
+ aws.create_new_key_pair(region, pair_name)
977
+ }.to raise_error(RuntimeError,
978
+ "AWS key pair #{pair_name} can not be queried, even after import")
882
979
  end
883
980
  end
884
981
 
@@ -893,84 +990,96 @@ module Beaker
893
990
  end
894
991
 
895
992
  describe '#ensure_group' do
896
- let( :vpc ) { double('vpc') }
897
- let( :ports ) { [22, 80, 8080] }
993
+ let(:vpc) { instance_double(Aws::EC2::Types::Vpc, :vpc_id => 1) }
994
+ let(:ports) { [22, 80, 8080] }
898
995
  subject(:ensure_group) { aws.ensure_group(vpc, ports) }
899
996
 
997
+ let(:mock_client) { instance_double(Aws::EC2::Client) }
998
+
999
+ before :each do
1000
+ allow(aws).to receive(:client).and_return(mock_client)
1001
+ end
1002
+
1003
+ let(:security_group_result) do
1004
+ instance_double(Aws::EC2::Types::DescribeSecurityGroupsResult, :security_groups => [group])
1005
+ end
1006
+
900
1007
  context 'for an existing group' do
901
- before :each do
902
- @group = double(:nil? => false)
903
- end
1008
+ let(:group) { instance_double(Aws::EC2::Types::SecurityGroup, :group_name => 'Beaker-1521896090') }
904
1009
 
905
1010
  it 'returns group from vpc lookup' do
906
- expect(vpc).to receive_message_chain('security_groups.filter.first').and_return(@group)
907
- expect(ensure_group).to eq(@group)
1011
+ allow(mock_client).to receive(:describe_security_groups).with(any_args).and_return(security_group_result)
1012
+ expect(ensure_group).to eq(group)
908
1013
  end
909
1014
 
910
1015
  context 'during group lookup' do
911
1016
  it 'performs group_id lookup for ports' do
912
1017
  expect(aws).to receive(:group_id).with(ports)
913
- expect(vpc).to receive_message_chain('security_groups.filter.first').and_return(@group)
914
- expect(ensure_group).to eq(@group)
1018
+ allow(mock_client).to receive(:describe_security_groups).with(any_args).and_return(security_group_result)
1019
+ expect(ensure_group).to eq(group)
915
1020
  end
916
1021
 
917
1022
  it 'filters on group_id' do
918
- expect(vpc).to receive(:security_groups).and_return(vpc)
919
- expect(vpc).to receive(:filter).with('group-name', 'Beaker-1521896090').and_return(vpc)
920
- expect(vpc).to receive(:first).and_return(@group)
921
- expect(ensure_group).to eq(@group)
1023
+ allow(mock_client).to receive(:describe_security_groups).with(:filters => include({:name => 'group-name', :values => ['Beaker-1521896090']})).and_return(security_group_result)
1024
+ expect(ensure_group).to eq(group)
922
1025
  end
923
1026
  end
924
1027
  end
925
1028
 
926
1029
  context 'when group does not exist' do
1030
+ let(:group) { nil }
1031
+
927
1032
  it 'creates group if group.nil?' do
928
- group = double(:nil? => true)
929
1033
  expect(aws).to receive(:create_group).with(vpc, ports).and_return(group)
930
- expect(vpc).to receive_message_chain('security_groups.filter.first').and_return(group)
1034
+ allow(mock_client).to receive(:describe_security_groups).with(any_args).and_return(security_group_result)
931
1035
  expect(ensure_group).to eq(group)
932
1036
  end
933
1037
  end
934
1038
  end
935
1039
 
936
1040
  describe '#create_group' do
937
- let( :rv ) { double('rv') }
938
- let( :ports ) { [22, 80, 8080] }
1041
+ let(:rv) { double('rv') }
1042
+ let(:ports) { [22, 80, 8080] }
939
1043
  subject(:create_group) { aws.create_group(rv, ports) }
940
1044
 
941
- before :each do
942
- @group = double(:nil? => false)
1045
+ let(:group) { instance_double(Aws::EC2::Types::SecurityGroup, :group_id => 1) }
1046
+ let(:mock_client) { instance_double(Aws::EC2::Client) }
1047
+
1048
+ before(:each) do
1049
+ allow(aws).to receive(:client).and_return(mock_client)
943
1050
  end
944
1051
 
945
1052
  it 'returns a newly created group' do
946
- allow(rv).to receive_message_chain('security_groups.create').and_return(@group)
947
- allow(@group).to receive(:authorize_ingress).at_least(:once)
948
- expect(create_group).to eq(@group)
1053
+ allow(mock_client).to receive(:create_security_group).with(any_args).and_return(group)
1054
+ allow(mock_client).to receive(:authorize_security_group_ingress).with(include(:group_id => group.group_id)).at_least(:once)
1055
+ expect(create_group).to eq(group)
949
1056
  end
950
1057
 
951
1058
  it 'requests group_id for ports given' do
952
1059
  expect(aws).to receive(:group_id).with(ports)
953
- allow(rv).to receive_message_chain('security_groups.create').and_return(@group)
954
- allow(@group).to receive(:authorize_ingress).at_least(:once)
955
- expect(create_group).to eq(@group)
1060
+ allow(mock_client).to receive(:create_security_group).with(any_args).and_return(group)
1061
+ allow(mock_client).to receive(:authorize_security_group_ingress).with(include(:group_id => group.group_id)).at_least(:once)
1062
+ expect(create_group).to eq(group)
956
1063
  end
957
1064
 
958
1065
  it 'creates group with expected arguments' do
959
1066
  group_name = "Beaker-1521896090"
960
1067
  group_desc = "Custom Beaker security group for #{ports.to_a}"
961
- expect(rv).to receive_message_chain('security_groups.create')
962
- .with(group_name, :description => group_desc)
963
- .and_return(@group)
964
- allow(@group).to receive(:authorize_ingress).at_least(:once)
965
- expect(create_group).to eq(@group)
1068
+ expect(mock_client).to receive(:create_security_group).with(
1069
+ :group_name => group_name,
1070
+ :description => group_desc,
1071
+ ).and_return(group)
1072
+ allow(mock_client).to receive(:authorize_security_group_ingress).with(include(:group_id => group.group_id)).at_least(:once)
1073
+ expect(create_group).to eq(group)
966
1074
  end
967
1075
 
968
1076
  it 'authorizes requested ports for group' do
969
- expect(rv).to receive_message_chain('security_groups.create').and_return(@group)
1077
+ allow(mock_client).to receive(:create_security_group).with(any_args).and_return(group)
1078
+
970
1079
  ports.each do |port|
971
- expect(@group).to receive(:authorize_ingress).with(:tcp, port).once
1080
+ expect(mock_client).to receive(:authorize_security_group_ingress).with(include(:to_port => port)).once
972
1081
  end
973
- expect(create_group).to eq(@group)
1082
+ expect(create_group).to eq(group)
974
1083
  end
975
1084
  end
976
1085
 
@@ -980,19 +1089,19 @@ module Beaker
980
1089
  subject(:load_fog_credentials) { aws.load_fog_credentials(dot_fog) }
981
1090
 
982
1091
  it 'returns loaded fog credentials' do
983
- creds = {:access_key => 'awskey', :secret_key => 'awspass', :session_token => nil}
1092
+ creds = {:access_key_id => 'awskey', :secret_access_key => 'awspass', :session_token => nil}
984
1093
  fog_hash = {:default => {:aws_access_key_id => 'awskey', :aws_secret_access_key => 'awspass'}}
985
1094
  expect(aws).to receive(:load_fog_credentials).and_call_original
986
1095
  expect(YAML).to receive(:load_file).and_return(fog_hash)
987
- expect(load_fog_credentials).to eq(creds)
1096
+ expect(load_fog_credentials).to have_attributes(creds)
988
1097
  end
989
1098
 
990
1099
  it 'returns loaded fog credentials with session token' do
991
- creds = {:access_key => 'awskey', :secret_key => 'awspass', :session_token => 'sometoken'}
1100
+ creds = {:access_key_id => 'awskey', :secret_access_key => 'awspass', :session_token => 'sometoken'}
992
1101
  fog_hash = {:default => {:aws_access_key_id => 'awskey', :aws_secret_access_key => 'awspass', :aws_session_token => 'sometoken'}}
993
1102
  expect(aws).to receive(:load_fog_credentials).and_call_original
994
1103
  expect(YAML).to receive(:load_file).and_return(fog_hash)
995
- expect(load_fog_credentials).to eq(creds)
1104
+ expect(load_fog_credentials).to have_attributes(creds)
996
1105
  end
997
1106
 
998
1107
  context 'raises errors' do