beaker-vmware 0.3.0 → 2.0.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 +5 -5
- data/.github/dependabot.yml +17 -0
- data/.github/workflows/release.yml +32 -0
- data/.github/workflows/test.yml +56 -0
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +266 -0
- data/.simplecov +1 -1
- data/CHANGELOG.md +62 -0
- data/Gemfile +6 -21
- data/README.md +43 -9
- data/Rakefile +34 -119
- data/beaker-vmware.gemspec +20 -30
- data/bin/beaker-vmware +1 -3
- data/lib/beaker/hypervisor/fusion.rb +21 -23
- data/lib/beaker/hypervisor/vsphere.rb +23 -24
- data/lib/beaker/hypervisor/vsphere_helper.rb +78 -81
- data/lib/beaker-vmware/version.rb +1 -1
- data/spec/beaker/hypervisor/fusion_spec.rb +14 -16
- data/spec/beaker/hypervisor/vsphere_helper_spec.rb +120 -124
- data/spec/beaker/hypervisor/vsphere_spec.rb +28 -40
- data/spec/mock_fission.rb +63 -0
- data/spec/mock_vsphere.rb +284 -0
- data/spec/mock_vsphere_helper.rb +167 -0
- data/spec/spec_helper.rb +28 -3
- metadata +65 -59
@@ -3,12 +3,12 @@ require 'rbvmomi'
|
|
3
3
|
require 'beaker/logger'
|
4
4
|
|
5
5
|
class VsphereHelper
|
6
|
-
def initialize
|
6
|
+
def initialize(vInfo)
|
7
7
|
@logger = vInfo[:logger] || Beaker::Logger.new
|
8
|
-
@connection = RbVmomi::VIM.connect :
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
8
|
+
@connection = RbVmomi::VIM.connect host: vInfo[:server],
|
9
|
+
user: vInfo[:user],
|
10
|
+
password: vInfo[:pass],
|
11
|
+
insecure: true
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.load_config(dot_fog = '.fog')
|
@@ -19,121 +19,121 @@ class VsphereHelper
|
|
19
19
|
vsphere_credentials[:user] = default[:vsphere_username]
|
20
20
|
vsphere_credentials[:pass] = default[:vsphere_password]
|
21
21
|
|
22
|
-
|
22
|
+
vsphere_credentials
|
23
23
|
end
|
24
24
|
|
25
|
-
def find_snapshot
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
raise "vm #{vm.name} has no snapshots to revert to"
|
30
|
-
end
|
25
|
+
def find_snapshot(vm, snapname)
|
26
|
+
raise "vm #{vm.name} has no snapshots to revert to" unless vm.snapshot
|
27
|
+
|
28
|
+
search_child_snaps vm.snapshot.rootSnapshotList, snapname
|
31
29
|
end
|
32
30
|
|
33
|
-
def search_child_snaps
|
31
|
+
def search_child_snaps(tree, snapname)
|
34
32
|
snapshot = nil
|
35
33
|
tree.each do |child|
|
36
|
-
if child.name == snapname
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
snapshot ||= if child.name == snapname
|
35
|
+
child.snapshot
|
36
|
+
else
|
37
|
+
search_child_snaps child.childSnapshotList, snapname
|
38
|
+
end
|
41
39
|
end
|
42
40
|
snapshot
|
43
41
|
end
|
44
42
|
|
45
|
-
def find_customization
|
43
|
+
def find_customization(name)
|
46
44
|
csm = @connection.serviceContent.customizationSpecManager
|
47
45
|
|
48
46
|
begin
|
49
|
-
customizationSpec = csm.GetCustomizationSpec({:name
|
50
|
-
rescue
|
47
|
+
customizationSpec = csm.GetCustomizationSpec({ name: name }).spec
|
48
|
+
rescue StandardError
|
51
49
|
customizationSpec = nil
|
52
50
|
end
|
53
51
|
|
54
|
-
|
52
|
+
customizationSpec
|
55
53
|
end
|
56
54
|
|
57
55
|
# an easier wrapper around the horrid PropertyCollector interface,
|
58
56
|
# necessary for searching VMs in all Datacenters that may be nested
|
59
57
|
# within folders of arbitrary depth
|
60
58
|
# returns a hash array of <name> => <VirtualMachine ManagedObjects>
|
61
|
-
def find_vms
|
62
|
-
names = names.is_a?(Array)
|
59
|
+
def find_vms(names, connection = @connection)
|
60
|
+
names = [names] unless names.is_a?(Array)
|
63
61
|
containerView = get_base_vm_container_from connection
|
64
62
|
propertyCollector = connection.propertyCollector
|
65
63
|
|
66
64
|
objectSet = [{
|
67
|
-
:
|
68
|
-
:
|
69
|
-
:
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
65
|
+
obj: containerView,
|
66
|
+
skip: true,
|
67
|
+
selectSet: [RbVmomi::VIM::TraversalSpec.new({
|
68
|
+
name: 'gettingTheVMs',
|
69
|
+
path: 'view',
|
70
|
+
skip: false,
|
71
|
+
type: 'ContainerView',
|
72
|
+
})],
|
75
73
|
}]
|
76
74
|
|
77
75
|
propSet = [{
|
78
|
-
:
|
79
|
-
:
|
76
|
+
pathSet: ['name'],
|
77
|
+
type: 'VirtualMachine',
|
80
78
|
}]
|
81
79
|
|
82
80
|
results = propertyCollector.RetrievePropertiesEx({
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
81
|
+
specSet: [{
|
82
|
+
objectSet: objectSet,
|
83
|
+
propSet: propSet,
|
84
|
+
}],
|
85
|
+
options: { maxObjects: nil },
|
86
|
+
})
|
89
87
|
|
90
88
|
vms = {}
|
91
89
|
results.objects.each do |result|
|
92
90
|
name = result.propSet.first.val
|
93
91
|
next unless names.include? name
|
92
|
+
|
94
93
|
vms[name] = result.obj
|
95
94
|
end
|
96
95
|
|
97
|
-
while results.token
|
98
|
-
results = propertyCollector.ContinueRetrievePropertiesEx({:
|
96
|
+
while results.token
|
97
|
+
results = propertyCollector.ContinueRetrievePropertiesEx({ token: results.token })
|
99
98
|
results.objects.each do |result|
|
100
99
|
name = result.propSet.first.val
|
101
100
|
next unless names.include? name
|
101
|
+
|
102
102
|
vms[name] = result.obj
|
103
103
|
end
|
104
104
|
end
|
105
105
|
vms
|
106
106
|
end
|
107
107
|
|
108
|
-
def find_datastore(dc,datastorename)
|
108
|
+
def find_datastore(dc, datastorename)
|
109
109
|
datacenter = @connection.serviceInstance.find_datacenter(dc)
|
110
110
|
datacenter.find_datastore(datastorename)
|
111
111
|
end
|
112
112
|
|
113
|
-
def find_folder(dc,foldername)
|
113
|
+
def find_folder(dc, foldername)
|
114
114
|
datacenter = @connection.serviceInstance.find_datacenter(dc)
|
115
115
|
base = datacenter.vmFolder.traverse(foldername)
|
116
|
-
if base
|
117
|
-
base
|
118
|
-
else
|
116
|
+
if base.nil?
|
119
117
|
abort "Failed to find folder #{foldername}"
|
118
|
+
else
|
119
|
+
base
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
def find_pool(dc,poolname)
|
123
|
+
def find_pool(dc, poolname)
|
124
124
|
datacenter = @connection.serviceInstance.find_datacenter(dc)
|
125
125
|
base = datacenter.hostFolder
|
126
126
|
pools = poolname.split('/')
|
127
127
|
pools.each do |pool|
|
128
128
|
case base
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
129
|
+
when RbVmomi::VIM::Folder
|
130
|
+
base = base.childEntity.find { |f| f.name == pool }
|
131
|
+
when RbVmomi::VIM::ClusterComputeResource
|
132
|
+
base = base.resourcePool.resourcePool.find { |f| f.name == pool }
|
133
|
+
when RbVmomi::VIM::ResourcePool
|
134
|
+
base = base.resourcePool.find { |f| f.name == pool }
|
135
|
+
else
|
136
|
+
abort "Unexpected object type encountered (#{base.class}) while finding resource pool"
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
@@ -141,43 +141,41 @@ class VsphereHelper
|
|
141
141
|
base
|
142
142
|
end
|
143
143
|
|
144
|
-
def get_base_vm_container_from
|
144
|
+
def get_base_vm_container_from(connection)
|
145
145
|
viewManager = connection.serviceContent.viewManager
|
146
146
|
viewManager.CreateContainerView({
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
147
|
+
container: connection.serviceContent.rootFolder,
|
148
|
+
recursive: true,
|
149
|
+
type: ['VirtualMachine'],
|
150
|
+
})
|
151
151
|
end
|
152
152
|
|
153
|
-
def wait_for_tasks
|
154
|
-
obj_set = tasks.map { |task| { :
|
153
|
+
def wait_for_tasks(tasks, try, attempts)
|
154
|
+
obj_set = tasks.map { |task| { obj: task } }
|
155
155
|
filter = @connection.propertyCollector.CreateFilter(
|
156
|
-
:
|
157
|
-
:
|
158
|
-
|
159
|
-
|
160
|
-
:
|
156
|
+
spec: {
|
157
|
+
propSet: [{ type: 'Task',
|
158
|
+
all: false,
|
159
|
+
pathSet: ['info.state'], }],
|
160
|
+
objectSet: obj_set,
|
161
161
|
},
|
162
|
-
:
|
162
|
+
partialUpdates: false,
|
163
163
|
)
|
164
164
|
ver = ''
|
165
165
|
while true
|
166
|
-
result = @connection.propertyCollector.WaitForUpdates(:
|
166
|
+
result = @connection.propertyCollector.WaitForUpdates(version: ver)
|
167
167
|
ver = result.version
|
168
168
|
complete = 0
|
169
169
|
tasks.each do |task|
|
170
|
-
if [
|
171
|
-
complete += 1
|
172
|
-
end
|
173
|
-
end
|
174
|
-
break if (complete == tasks.length)
|
175
|
-
if try <= attempts
|
176
|
-
sleep 5
|
177
|
-
try += 1
|
178
|
-
else
|
179
|
-
raise "unable to complete Vsphere tasks before timeout"
|
170
|
+
complete += 1 if %w[success error].member? task.info.state
|
180
171
|
end
|
172
|
+
break if complete == tasks.length
|
173
|
+
|
174
|
+
raise 'unable to complete Vsphere tasks before timeout' unless try <= attempts
|
175
|
+
|
176
|
+
sleep 5
|
177
|
+
try += 1
|
178
|
+
|
181
179
|
end
|
182
180
|
|
183
181
|
filter.DestroyPropertyFilter
|
@@ -188,4 +186,3 @@ class VsphereHelper
|
|
188
186
|
@connection.close
|
189
187
|
end
|
190
188
|
end
|
191
|
-
|
@@ -2,40 +2,38 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Beaker
|
4
4
|
describe Fusion do
|
5
|
-
let(
|
6
|
-
|
7
|
-
before
|
8
|
-
|
9
|
-
@hosts = make_hosts
|
10
|
-
MockFission.presets(
|
11
|
-
allow_any_instance_of(
|
12
|
-
fusion.instance_variable_set(
|
5
|
+
let(:fusion) { Beaker::Fusion.new(@hosts, make_opts) }
|
6
|
+
|
7
|
+
before do
|
8
|
+
stub_const('Fission::VM', true)
|
9
|
+
@hosts = make_hosts
|
10
|
+
MockFission.presets(@hosts)
|
11
|
+
allow_any_instance_of(Fusion).to receive(:require).with('fission').and_return(true)
|
12
|
+
fusion.instance_variable_set(:@fission, MockFission)
|
13
13
|
end
|
14
14
|
|
15
|
-
it
|
15
|
+
it 'can interoperate with the fission library to provision hosts' do
|
16
16
|
fusion.provision
|
17
17
|
end
|
18
18
|
|
19
|
-
it
|
19
|
+
it 'raises an error if unknown snapshot name is used' do
|
20
20
|
@hosts[0][:snapshot] = 'unknown'
|
21
|
-
expect{ fusion.provision }.to raise_error
|
21
|
+
expect { fusion.provision }.to raise_error
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'raises an error if snapshots is nil' do
|
25
25
|
MockFissionVM.set_snapshots(nil)
|
26
|
-
expect{ fusion.provision }.to raise_error(/No snapshots available/)
|
26
|
+
expect { fusion.provision }.to raise_error(/No snapshots available/)
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'raises an error if snapshots are empty' do
|
30
30
|
MockFissionVM.set_snapshots([])
|
31
|
-
expect{ fusion.provision }.to raise_error(/No snapshots available/)
|
31
|
+
expect { fusion.provision }.to raise_error(/No snapshots available/)
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'host fails init with nil snapshot' do
|
35
35
|
@hosts[0][:snapshot] = nil
|
36
|
-
expect{ Beaker::Fusion.new(
|
36
|
+
expect { Beaker::Fusion.new(@hosts, make_opts) }.to raise_error(/specify a snapshot/)
|
37
37
|
end
|
38
|
-
|
39
38
|
end
|
40
|
-
|
41
39
|
end
|
@@ -2,162 +2,158 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Beaker
|
4
4
|
describe VsphereHelper do
|
5
|
-
let(
|
6
|
-
let(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
5
|
+
let(:logger) { double('logger').as_null_object }
|
6
|
+
let(:vInfo) do
|
7
|
+
{ server: 'vsphere.labs.net', user: 'vsphere@labs.com', pass: 'supersekritpassword' }
|
8
|
+
end
|
9
|
+
let(:vsphere_helper) { VsphereHelper.new(vInfo.merge({ logger: logger })) }
|
10
|
+
let(:snaplist) do
|
11
|
+
{ 'snap1' => { 'snap1sub1' => nil,
|
12
|
+
'snap1sub2' => nil, },
|
13
|
+
'snap2' => nil,
|
14
|
+
'snap3' => { 'snap3sub1' => nil,
|
15
|
+
'snap3sub2' => nil,
|
16
|
+
'snap3sub3' => nil, }, }
|
17
|
+
end
|
18
|
+
let(:vms) do
|
19
|
+
[MockRbVmomiVM.new('mockvm1', snaplist),
|
20
|
+
MockRbVmomiVM.new('mockvm2', snaplist),
|
21
|
+
MockRbVmomiVM.new('mockvm3', snaplist),]
|
20
22
|
end
|
21
23
|
|
22
|
-
|
24
|
+
before do
|
25
|
+
stub_const('RbVmomi', MockRbVmomi)
|
26
|
+
end
|
23
27
|
|
28
|
+
describe '#load_config' do
|
24
29
|
it 'can load a .fog file' do
|
25
|
-
allow(
|
26
|
-
allow(
|
27
|
-
|
28
|
-
expect( VsphereHelper.load_config ).to be === vInfo
|
30
|
+
allow(File).to receive(:exist?).and_return(true)
|
31
|
+
allow(YAML).to receive(:load_file).and_return(fog_file_contents)
|
29
32
|
|
33
|
+
expect(VsphereHelper.load_config).to be === vInfo
|
30
34
|
end
|
31
35
|
|
32
36
|
it 'raises an error when the .fog file is missing' do
|
33
|
-
allow(
|
34
|
-
|
35
|
-
expect{ VsphereHelper.load_config }.to raise_error( ArgumentError )
|
37
|
+
allow(File).to receive(:exist?).and_return(false)
|
36
38
|
|
39
|
+
expect { VsphereHelper.load_config }.to raise_error(ArgumentError)
|
37
40
|
end
|
38
|
-
|
39
41
|
end
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
expect( vsphere_helper.find_snapshot( mockvm, 'snap2' ) ).to be === mockvm.get_snapshot( 'snap2' )
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
43
|
+
describe '#find_snapshot' do
|
44
|
+
it 'can find a given snapshot name' do
|
45
|
+
mockvm = MockRbVmomiVM.new('mockvm', snaplist)
|
50
46
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
expect( vsphere_helper.find_customization( 'name' ) ).to be === true
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
describe "#find_vms" do
|
61
|
-
it 'finds the list of vms' do
|
62
|
-
connection = vsphere_helper.instance_variable_get( :@connection )
|
63
|
-
connection.set_info( vms )
|
64
|
-
|
65
|
-
expect( vsphere_helper.find_vms( 'mockvm1' ) ).to be === {vms[0].name => vms[0]}
|
66
|
-
end
|
47
|
+
expect(vsphere_helper.find_snapshot(mockvm, 'snap2')).to be === mockvm.get_snapshot('snap2')
|
48
|
+
end
|
49
|
+
end
|
67
50
|
|
68
|
-
|
69
|
-
|
70
|
-
|
51
|
+
describe '#find_customization' do
|
52
|
+
it 'returns the customization spec' do
|
53
|
+
expect(vsphere_helper.find_customization('name')).to be === true
|
54
|
+
end
|
55
|
+
end
|
71
56
|
|
72
|
-
|
73
|
-
|
57
|
+
describe '#find_vms' do
|
58
|
+
it 'finds the list of vms' do
|
59
|
+
connection = vsphere_helper.instance_variable_get(:@connection)
|
60
|
+
connection.set_info(vms)
|
74
61
|
|
75
|
-
|
62
|
+
expect(vsphere_helper.find_vms('mockvm1')).to be === { vms[0].name => vms[0] }
|
63
|
+
end
|
76
64
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
dc = connection.serviceInstance.find_datacenter('testdc')
|
81
|
-
expect(vsphere_helper.find_datastore( dc,'datastorename' ) ).to be === true
|
82
|
-
end
|
65
|
+
it 'returns {} when no vm is found' do
|
66
|
+
connection = vsphere_helper.instance_variable_get(:@connection)
|
67
|
+
connection.set_info(vms)
|
83
68
|
|
84
|
-
|
69
|
+
expect(vsphere_helper.find_vms('novm')).to be === {}
|
70
|
+
end
|
71
|
+
end
|
85
72
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
73
|
+
describe '#find_datastore' do
|
74
|
+
it 'finds the datastore from the connection object' do
|
75
|
+
connection = vsphere_helper.instance_variable_get(:@connection)
|
76
|
+
dc = connection.serviceInstance.find_datacenter('testdc')
|
77
|
+
expect(vsphere_helper.find_datastore(dc, 'datastorename')).to be === true
|
78
|
+
end
|
79
|
+
end
|
91
80
|
|
92
|
-
|
81
|
+
describe '#find_folder' do
|
82
|
+
it 'can find a folder in the datacenter' do
|
83
|
+
connection = vsphere_helper.instance_variable_get(:@connection)
|
84
|
+
expect(vsphere_helper.find_folder('testdc',
|
85
|
+
'root')).to be === connection.serviceInstance.find_datacenter('testdc').vmFolder
|
86
|
+
end
|
87
|
+
end
|
93
88
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
89
|
+
describe '#find_pool' do
|
90
|
+
it 'can find a pool in a folder in the datacenter' do
|
91
|
+
connection = vsphere_helper.instance_variable_get(:@connection)
|
92
|
+
dc = connection.serviceInstance.find_datacenter('testdc')
|
93
|
+
dc.hostFolder = MockRbVmomi::VIM::Folder.new
|
94
|
+
dc.hostFolder.name = '/root'
|
100
95
|
|
101
|
-
|
96
|
+
expect(vsphere_helper.find_pool('testdc',
|
97
|
+
'root')).to be === connection.serviceInstance.find_datacenter('testdc').hostFolder
|
98
|
+
end
|
102
99
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
dc.hostFolder.name = "/root"
|
100
|
+
it 'can find a pool in a clustercomputeresource in the datacenter' do
|
101
|
+
connection = vsphere_helper.instance_variable_get(:@connection)
|
102
|
+
dc = connection.serviceInstance.find_datacenter('testdc')
|
103
|
+
dc.hostFolder = MockRbVmomi::VIM::ClusterComputeResource.new
|
104
|
+
dc.hostFolder.name = '/root'
|
109
105
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
connection = vsphere_helper.instance_variable_get( :@connection )
|
114
|
-
dc = connection.serviceInstance.find_datacenter('testdc')
|
115
|
-
dc.hostFolder = MockRbVmomi::VIM::ResourcePool.new
|
116
|
-
dc.hostFolder.name = "/root"
|
106
|
+
expect(vsphere_helper.find_pool('testdc',
|
107
|
+
'root')).to be === connection.serviceInstance.find_datacenter('testdc').hostFolder
|
108
|
+
end
|
117
109
|
|
118
|
-
|
119
|
-
|
110
|
+
it 'can find a pool in a resourcepool in the datacenter' do
|
111
|
+
connection = vsphere_helper.instance_variable_get(:@connection)
|
112
|
+
dc = connection.serviceInstance.find_datacenter('testdc')
|
113
|
+
dc.hostFolder = MockRbVmomi::VIM::ResourcePool.new
|
114
|
+
dc.hostFolder.name = '/root'
|
120
115
|
|
121
|
-
|
116
|
+
expect(vsphere_helper.find_pool('testdc',
|
117
|
+
'root')).to be === connection.serviceInstance.find_datacenter('testdc').hostFolder
|
118
|
+
end
|
119
|
+
end
|
122
120
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
121
|
+
describe '#wait_for_tasks' do
|
122
|
+
it 'can wait for tasks to error' do
|
123
|
+
allow(vsphere_helper).to receive(:sleep).and_return(true)
|
124
|
+
vms.each do |vm|
|
125
|
+
vm.info.state = 'error'
|
126
|
+
end
|
129
127
|
|
130
|
-
|
131
|
-
|
128
|
+
expect(vsphere_helper.wait_for_tasks(vms, 0, 5)).to be === vms
|
129
|
+
end
|
132
130
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
131
|
+
it 'can wait for tasks to succeed' do
|
132
|
+
allow(vsphere_helper).to receive(:sleep).and_return(true)
|
133
|
+
vms.each do |vm|
|
134
|
+
vm.info.state = 'success'
|
135
|
+
end
|
138
136
|
|
139
|
-
|
140
|
-
|
137
|
+
expect(vsphere_helper.wait_for_tasks(vms, 0, 5)).to be === vms
|
138
|
+
end
|
141
139
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
140
|
+
it 'errors when tasks fail to error/success before timing out' do
|
141
|
+
allow(vsphere_helper).to receive(:sleep).and_return(true)
|
142
|
+
vms.each do |vm|
|
143
|
+
vm.info.state = 'nope'
|
144
|
+
end
|
147
145
|
|
148
|
-
|
149
|
-
|
146
|
+
expect { vsphere_helper.wait_for_tasks(vms, 0, 5) }.to raise_error
|
147
|
+
end
|
148
|
+
end
|
150
149
|
|
151
|
-
|
150
|
+
describe '#close' do
|
151
|
+
it 'closes the connection' do
|
152
|
+
connection = vsphere_helper.instance_variable_get(:@connection)
|
153
|
+
expect(connection).to receive(:close).once
|
152
154
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
vsphere_helper.close
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
end
|
155
|
+
vsphere_helper.close
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
163
159
|
end
|