fission 0.3.0 → 0.4.0.beta.1
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.
- data/.gitignore +1 -0
- data/CHANGELOG.md +3 -0
- data/README.md +1 -1
- data/lib/fission.rb +5 -6
- data/lib/fission/cli.rb +77 -7
- data/lib/fission/command.rb +43 -1
- data/lib/fission/command/clone.rb +19 -20
- data/lib/fission/command/delete.rb +29 -25
- data/lib/fission/command/snapshot_create.rb +11 -26
- data/lib/fission/command/snapshot_list.rb +13 -19
- data/lib/fission/command/snapshot_revert.rb +11 -26
- data/lib/fission/command/start.rb +11 -25
- data/lib/fission/command/status.rb +26 -10
- data/lib/fission/command/stop.rb +10 -21
- data/lib/fission/command/suspend.rb +21 -21
- data/lib/fission/command_helpers.rb +21 -0
- data/lib/fission/config.rb +35 -0
- data/lib/fission/fusion.rb +11 -3
- data/lib/fission/lease.rb +148 -0
- data/lib/fission/metadata.rb +55 -2
- data/lib/fission/response.rb +76 -0
- data/lib/fission/ui.rb +49 -0
- data/lib/fission/version.rb +1 -1
- data/lib/fission/vm.rb +653 -75
- data/spec/contexts/command.rb +12 -0
- data/spec/fission/cli_spec.rb +4 -11
- data/spec/fission/command/clone_spec.rb +45 -45
- data/spec/fission/command/delete_spec.rb +56 -43
- data/spec/fission/command/snapshot_create_spec.rb +29 -51
- data/spec/fission/command/snapshot_list_spec.rb +25 -26
- data/spec/fission/command/snapshot_revert_spec.rb +27 -53
- data/spec/fission/command/start_spec.rb +25 -69
- data/spec/fission/command/status_spec.rb +48 -13
- data/spec/fission/command/stop_spec.rb +25 -42
- data/spec/fission/command/suspend_spec.rb +54 -49
- data/spec/fission/command_helpers_spec.rb +30 -0
- data/spec/fission/command_spec.rb +19 -0
- data/spec/fission/config_spec.rb +24 -0
- data/spec/fission/fusion_spec.rb +6 -6
- data/spec/fission/lease_spec.rb +176 -0
- data/spec/fission/metadata_spec.rb +8 -8
- data/spec/fission/response_spec.rb +81 -0
- data/spec/fission/vm_spec.rb +869 -193
- data/spec/fission_spec.rb +0 -6
- data/spec/helpers/command_helpers.rb +12 -0
- data/spec/helpers/response_helpers.rb +21 -0
- data/spec/matchers/be_a_successful_response.rb +7 -0
- data/spec/matchers/be_an_unsuccessful_response.rb +10 -0
- data/spec/spec_helper.rb +7 -0
- metadata +24 -5
@@ -0,0 +1,81 @@
|
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
describe Fission::Response do
|
4
|
+
describe 'initialize' do
|
5
|
+
it 'should allow you to set the code' do
|
6
|
+
Fission::Response.new(:code => 1).code.should == 1
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should set the code to 1 if not provided' do
|
10
|
+
Fission::Response.new.code.should == 1
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should allow you to set the message' do
|
14
|
+
Fission::Response.new(:message => 'foobar').message.should == 'foobar'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should set the message to an empty string if not provided' do
|
18
|
+
Fission::Response.new.message.should == ''
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should set the data to nil if not provided' do
|
22
|
+
Fission::Response.new.data.should be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'code' do
|
28
|
+
it 'should allow you to set the code' do
|
29
|
+
@response = Fission::Response.new
|
30
|
+
@response.code = 4
|
31
|
+
@response.code.should == 4
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'successful?' do
|
36
|
+
it 'should return true if the code is 0' do
|
37
|
+
Fission::Response.new(:code => 0).successful?.should == true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should return false if the code is not 0' do
|
41
|
+
Fission::Response.new(:code => 1).successful?.should == false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'message' do
|
46
|
+
it 'should allow you to set the message' do
|
47
|
+
@response = Fission::Response.new
|
48
|
+
@response.message = 'foobar'
|
49
|
+
@response.message.should == 'foobar'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'data' do
|
54
|
+
it 'should allow you to set the data' do
|
55
|
+
@response = Fission::Response.new
|
56
|
+
@response.data = [1, 2, 3]
|
57
|
+
@response.data.should == [1, 2, 3]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'self.from_command' do
|
62
|
+
it 'should return a response object' do
|
63
|
+
Fission::Response.from_command('').should be_a Fission::Response
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should set the code to the exit status' do
|
67
|
+
$?.should_receive(:exitstatus).and_return(55)
|
68
|
+
Fission::Response.from_command('').code.should == 55
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should set the message if the command was unsuccessful' do
|
72
|
+
$?.should_receive(:exitstatus).and_return(55)
|
73
|
+
Fission::Response.from_command('foo').message.should == 'foo'
|
74
|
+
end
|
75
|
+
it 'should not set the message if the command was successful' do
|
76
|
+
$?.should_receive(:exitstatus).and_return(0)
|
77
|
+
Fission::Response.from_command('foo').message.should == ''
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
data/spec/fission/vm_spec.rb
CHANGED
@@ -2,11 +2,11 @@ require File.expand_path('../../spec_helper.rb', __FILE__)
|
|
2
2
|
|
3
3
|
describe Fission::VM do
|
4
4
|
before do
|
5
|
-
@string_io = StringIO.new
|
6
|
-
Fission.stub!(:ui).and_return(Fission::UI.new(@string_io))
|
7
5
|
@vm = Fission::VM.new('foo')
|
8
|
-
@vm.stub!(:conf_file).and_return(File.join(
|
9
|
-
@
|
6
|
+
@vm.stub!(:conf_file).and_return(File.join(@vm.path, 'foo.vmx'))
|
7
|
+
@conf_file_path = File.join(@vm.path, 'foo.vmx')
|
8
|
+
@vmrun_cmd = Fission.config['vmrun_cmd']
|
9
|
+
@conf_file_response_mock = mock('conf_file_response')
|
10
10
|
end
|
11
11
|
|
12
12
|
describe 'new' do
|
@@ -16,148 +16,724 @@ describe Fission::VM do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
describe 'start' do
|
19
|
-
|
20
|
-
|
21
|
-
@vm.should_receive(:`).
|
22
|
-
with("#{@vmrun_cmd} start #{@vm.conf_file.gsub(' ', '\ ')} gui 2>&1").
|
23
|
-
and_return("it's all good")
|
24
|
-
@vm.start
|
19
|
+
before do
|
20
|
+
@running_response_mock = mock('running?')
|
25
21
|
|
26
|
-
@
|
22
|
+
@vm.stub(:exists?).and_return(true)
|
23
|
+
@vm.stub(:running?).and_return(@running_response_mock)
|
24
|
+
@vm.stub(:conf_file).and_return(@conf_file_response_mock)
|
25
|
+
@running_response_mock.stub_as_successful false
|
26
|
+
@conf_file_response_mock.stub_as_successful @conf_file_path
|
27
27
|
end
|
28
28
|
|
29
|
-
it
|
30
|
-
|
31
|
-
@vm.
|
32
|
-
|
33
|
-
and_return("it's all good")
|
34
|
-
@vm.start(:headless => true)
|
29
|
+
it "should return an unsuccessful response if the vm doesn't exist" do
|
30
|
+
@vm.stub(:exists?).and_return(false)
|
31
|
+
@vm.start.should be_an_unsuccessful_response 'VM does not exist'
|
32
|
+
end
|
35
33
|
|
36
|
-
|
34
|
+
it 'should return an unsuccessful response if the vm is already running' do
|
35
|
+
@running_response_mock.stub_as_successful true
|
36
|
+
@vm.start.should be_an_unsuccessful_response 'VM is already running'
|
37
37
|
end
|
38
38
|
|
39
|
-
it 'should
|
40
|
-
|
41
|
-
@vm.
|
42
|
-
|
43
|
-
and_return("it blew up")
|
44
|
-
@vm.start
|
39
|
+
it 'should return an unsuccessful response if unable to determine if running' do
|
40
|
+
@running_response_mock.stub_as_unsuccessful
|
41
|
+
@vm.start.should be_an_unsuccessful_response
|
42
|
+
end
|
45
43
|
|
46
|
-
|
44
|
+
it 'should return an unsuccessful response if unable to figure out the conf file' do
|
45
|
+
@conf_file_response_mock.stub_as_unsuccessful
|
46
|
+
@vm.start.should be_an_unsuccessful_response
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'when the fusion gui is not running' do
|
50
|
+
before do
|
51
|
+
Fission::Fusion.stub(:running?).and_return(false)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should start the VM and return a successful response' do
|
55
|
+
$?.should_receive(:exitstatus).and_return(0)
|
56
|
+
@vm.should_receive(:`).
|
57
|
+
with("#{@vmrun_cmd} start #{@conf_file_path.gsub(' ', '\ ')} gui 2>&1").
|
58
|
+
and_return("it's all good")
|
59
|
+
|
60
|
+
@vm.start.should be_a_successful_response
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should successfully start the vm headless' do
|
64
|
+
$?.should_receive(:exitstatus).and_return(0)
|
65
|
+
@vm.should_receive(:`).
|
66
|
+
with("#{@vmrun_cmd} start #{@conf_file_path.gsub(' ', '\ ')} nogui 2>&1").
|
67
|
+
and_return("it's all good")
|
68
|
+
|
69
|
+
@vm.start(:headless => true).should be_a_successful_response
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should return an unsuccessful response if there was an error starting the VM' do
|
73
|
+
$?.should_receive(:exitstatus).and_return(1)
|
74
|
+
@vm.should_receive(:`).
|
75
|
+
with("#{@vmrun_cmd} start #{@conf_file_path.gsub(' ', '\ ')} gui 2>&1").
|
76
|
+
and_return("it blew up")
|
77
|
+
|
78
|
+
@vm.start.should be_an_unsuccessful_response
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'when the fusion gui is running' do
|
83
|
+
before do
|
84
|
+
Fission::Fusion.stub(:running?).and_return(true)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should return an unsuccessful response if starting headless' do
|
88
|
+
response = @vm.start :headless => true
|
89
|
+
|
90
|
+
error_string = 'It looks like the Fusion GUI is currently running. '
|
91
|
+
error_string << 'A VM cannot be started in headless mode when the Fusion GUI is running. '
|
92
|
+
error_string << 'Exit the Fusion GUI and try again.'
|
93
|
+
|
94
|
+
response.should be_an_unsuccessful_response error_string
|
95
|
+
end
|
47
96
|
end
|
48
97
|
|
49
98
|
end
|
50
99
|
|
51
100
|
describe 'stop' do
|
52
|
-
|
101
|
+
before do
|
102
|
+
@running_response_mock = mock('running?')
|
103
|
+
|
104
|
+
@vm.stub(:exists?).and_return(true)
|
105
|
+
@vm.stub(:running?).and_return(@running_response_mock)
|
106
|
+
@vm.stub(:conf_file).and_return(@conf_file_response_mock)
|
107
|
+
@running_response_mock.stub_as_successful true
|
108
|
+
@conf_file_response_mock.stub_as_successful @conf_file_path
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should return an unsuccessful response if the vm doesn't exist" do
|
112
|
+
@vm.stub(:exists?).and_return(false)
|
113
|
+
@vm.stop.should be_an_unsuccessful_response 'VM does not exist'
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should return an unsuccessful response if the vm is not running' do
|
117
|
+
@running_response_mock.stub_as_successful false
|
118
|
+
@vm.stop.should be_an_unsuccessful_response 'VM is not running'
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should return an unsuccessful response if unable to determine if running' do
|
122
|
+
@running_response_mock.stub_as_unsuccessful
|
123
|
+
@vm.stop.should be_an_unsuccessful_response
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should return an unsuccessful response if unable to figure out the conf file' do
|
127
|
+
@conf_file_response_mock.stub_as_unsuccessful
|
128
|
+
@vm.stop.should be_an_unsuccessful_response
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should return a successful response and stop the vm' do
|
132
|
+
$?.should_receive(:exitstatus).and_return(0)
|
133
|
+
@vm.should_receive(:`).
|
134
|
+
with("#{@vmrun_cmd} stop #{@conf_file_path.gsub ' ', '\ '} 2>&1").
|
135
|
+
and_return("it's all good")
|
136
|
+
|
137
|
+
@vm.stop.should be_a_successful_response
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'should return a suscessful response and hard stop the vm' do
|
53
141
|
$?.should_receive(:exitstatus).and_return(0)
|
54
142
|
@vm.should_receive(:`).
|
55
|
-
with("#{@vmrun_cmd} stop #{@
|
143
|
+
with("#{@vmrun_cmd} stop #{@conf_file_path.gsub ' ', '\ '} hard 2>&1").
|
56
144
|
and_return("it's all good")
|
57
|
-
@vm.stop
|
58
145
|
|
59
|
-
@
|
146
|
+
@vm.stop(:hard => true).should be_a_successful_response
|
60
147
|
end
|
61
148
|
|
62
|
-
it 'it should
|
149
|
+
it 'it should return an unsuccessful response if unable to stop the vm' do
|
63
150
|
$?.should_receive(:exitstatus).and_return(1)
|
64
151
|
@vm.should_receive(:`).
|
65
|
-
with("#{@vmrun_cmd} stop #{@
|
152
|
+
with("#{@vmrun_cmd} stop #{@conf_file_path.gsub ' ', '\ '} 2>&1").
|
66
153
|
and_return("it blew up")
|
67
|
-
@vm.stop
|
68
154
|
|
69
|
-
@
|
155
|
+
@vm.stop.should be_an_unsuccessful_response
|
70
156
|
end
|
71
157
|
end
|
72
158
|
|
73
159
|
describe 'suspend' do
|
74
|
-
|
160
|
+
before do
|
161
|
+
@running_response_mock = mock('running?')
|
162
|
+
|
163
|
+
@vm.stub(:exists?).and_return(true)
|
164
|
+
@vm.stub(:running?).and_return(@running_response_mock)
|
165
|
+
@vm.stub(:conf_file).and_return(@conf_file_response_mock)
|
166
|
+
@running_response_mock.stub_as_successful true
|
167
|
+
@conf_file_response_mock.stub_as_successful @conf_file_path
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should return an unsuccessful response if the vm doesn't exist" do
|
171
|
+
@vm.stub(:exists?).and_return(false)
|
172
|
+
@vm.suspend.should be_an_unsuccessful_response 'VM does not exist'
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should return an unsuccessful response if the vm is not running' do
|
176
|
+
@running_response_mock.stub_as_successful false
|
177
|
+
@vm.suspend.should be_an_unsuccessful_response 'VM is not running'
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'should return an unsuccessful response if unable to determine if running' do
|
181
|
+
@running_response_mock.stub_as_unsuccessful
|
182
|
+
@vm.suspend.should be_an_unsuccessful_response
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should return an unsuccessful response if unable to figure out the conf file' do
|
186
|
+
@conf_file_response_mock.stub_as_unsuccessful
|
187
|
+
@vm.suspend.should be_an_unsuccessful_response
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should return a successful response' do
|
75
191
|
$?.should_receive(:exitstatus).and_return(0)
|
76
192
|
@vm.should_receive(:`).
|
77
|
-
with("#{@vmrun_cmd} suspend #{@
|
193
|
+
with("#{@vmrun_cmd} suspend #{@conf_file_path.gsub ' ', '\ '} 2>&1").
|
78
194
|
and_return("it's all good")
|
79
|
-
@vm.suspend
|
80
195
|
|
81
|
-
@
|
196
|
+
@vm.suspend.should be_a_successful_response
|
82
197
|
end
|
83
198
|
|
84
|
-
it 'it should
|
199
|
+
it 'it should return an unsuccessful response if unable to suspend the vm' do
|
85
200
|
$?.should_receive(:exitstatus).and_return(1)
|
86
201
|
@vm.should_receive(:`).
|
87
|
-
with("#{@vmrun_cmd} suspend #{@
|
202
|
+
with("#{@vmrun_cmd} suspend #{@conf_file_path.gsub ' ', '\ '} 2>&1").
|
88
203
|
and_return("it blew up")
|
89
|
-
@vm.suspend
|
90
204
|
|
91
|
-
@
|
205
|
+
@vm.suspend.should be_an_unsuccessful_response
|
92
206
|
end
|
93
207
|
end
|
94
208
|
|
95
209
|
describe 'snapshots' do
|
96
|
-
|
210
|
+
before do
|
211
|
+
@vm.stub(:exists?).and_return(true)
|
212
|
+
@vm.stub(:conf_file).and_return(@conf_file_response_mock)
|
213
|
+
@conf_file_response_mock.stub_as_successful @conf_file_path
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should return an unsuccessful repsonse when the vm doesn't exist" do
|
217
|
+
@vm.stub(:exists?).and_return(false)
|
218
|
+
@vm.snapshots.should be_an_unsuccessful_response 'VM does not exist'
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should return a successful response with the list of snapshots' do
|
97
222
|
$?.should_receive(:exitstatus).and_return(0)
|
98
223
|
@vm.should_receive(:`).
|
99
|
-
with("#{@vmrun_cmd} listSnapshots #{@
|
224
|
+
with("#{@vmrun_cmd} listSnapshots #{@conf_file_path.gsub ' ', '\ '} 2>&1").
|
100
225
|
and_return("Total snapshots: 3\nsnap foo\nsnap bar\nsnap baz\n")
|
101
|
-
|
226
|
+
|
227
|
+
response = @vm.snapshots
|
228
|
+
response.should be_a_successful_response
|
229
|
+
response.data.should == ['snap foo', 'snap bar', 'snap baz']
|
102
230
|
end
|
103
231
|
|
104
|
-
it 'should
|
232
|
+
it 'should return an unsuccessful response if unable to figure out the conf file' do
|
233
|
+
@conf_file_response_mock.stub_as_unsuccessful
|
234
|
+
@vm.snapshots.should be_an_unsuccessful_response
|
235
|
+
end
|
236
|
+
|
237
|
+
it 'should return an unsuccessful response if there was a problem getting the list of snapshots' do
|
105
238
|
$?.should_receive(:exitstatus).and_return(1)
|
106
239
|
@vm.should_receive(:`).
|
107
|
-
with("#{@vmrun_cmd} listSnapshots #{@
|
108
|
-
and_return("it blew up
|
109
|
-
|
110
|
-
@
|
111
|
-
@string_io.string.should match /error was.+it blew up/m
|
240
|
+
with("#{@vmrun_cmd} listSnapshots #{@conf_file_path.gsub ' ', '\ '} 2>&1").
|
241
|
+
and_return("it blew up")
|
242
|
+
|
243
|
+
@vm.snapshots.should be_an_unsuccessful_response
|
112
244
|
end
|
113
245
|
end
|
114
246
|
|
115
247
|
describe 'create_snapshot' do
|
116
|
-
|
248
|
+
before do
|
249
|
+
@snapshots_response_mock = mock('snapshots')
|
250
|
+
@running_response_mock = mock('running?')
|
251
|
+
|
252
|
+
@running_response_mock.stub_as_successful true
|
253
|
+
@conf_file_response_mock.stub_as_successful @conf_file_path
|
254
|
+
@snapshots_response_mock.stub_as_successful []
|
255
|
+
|
256
|
+
@vm.stub(:exists?).and_return(true)
|
257
|
+
@vm.stub(:snapshots).and_return(@snapshots_response_mock)
|
258
|
+
@vm.stub(:running?).and_return(@running_response_mock)
|
259
|
+
@vm.stub(:conf_file).and_return(@conf_file_response_mock)
|
260
|
+
end
|
261
|
+
|
262
|
+
it "should return an unsuccessful response if the vm doesn't exist" do
|
263
|
+
@vm.stub(:exists?).and_return(false)
|
264
|
+
@vm.create_snapshot('snap_1').should be_an_unsuccessful_response 'VM does not exist'
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'should return an unsuccessful response if the vm is not running' do
|
268
|
+
@running_response_mock.stub_as_successful false
|
269
|
+
|
270
|
+
response = @vm.create_snapshot 'snap_1'
|
271
|
+
error_message = 'The VM must be running in order to take a snapshot.'
|
272
|
+
response.should be_an_unsuccessful_response error_message
|
273
|
+
end
|
274
|
+
|
275
|
+
it 'should return an unsuccessful response if unable to determine if running' do
|
276
|
+
@running_response_mock.stub_as_unsuccessful
|
277
|
+
@vm.create_snapshot('snap_1').should be_an_unsuccessful_response
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'should return an unsuccessful response if unable to figure out the conf file' do
|
281
|
+
@conf_file_response_mock.stub_as_unsuccessful
|
282
|
+
@vm.create_snapshot('snap_1').should be_an_unsuccessful_response
|
283
|
+
end
|
284
|
+
it 'should return a successful response and create a snapshot' do
|
117
285
|
$?.should_receive(:exitstatus).and_return(0)
|
118
286
|
@vm.should_receive(:`).
|
119
|
-
with("#{@vmrun_cmd} snapshot #{@
|
287
|
+
with("#{@vmrun_cmd} snapshot #{@conf_file_path.gsub ' ', '\ '} \"bar\" 2>&1").
|
120
288
|
and_return("")
|
121
|
-
|
122
|
-
@
|
289
|
+
|
290
|
+
@vm.create_snapshot('bar').should be_a_successful_response
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'should return an unsuccessful response if the snapshot name is a duplicate' do
|
294
|
+
@snapshots_response_mock.stub_as_successful ['snap_1']
|
295
|
+
response = @vm.create_snapshot 'snap_1'
|
296
|
+
response.should be_an_unsuccessful_response "There is already a snapshot named 'snap_1'."
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'should return an unsuccessful response if there was a problem listing the existing snapshots' do
|
300
|
+
@snapshots_response_mock.stub_as_unsuccessful
|
301
|
+
@vm.create_snapshot('snap_1').should be_an_unsuccessful_response
|
123
302
|
end
|
124
303
|
|
125
|
-
it 'should
|
304
|
+
it 'should return and unsuccessful response if there was a problem creating the snapshot' do
|
126
305
|
$?.should_receive(:exitstatus).and_return(1)
|
127
306
|
@vm.should_receive(:`).
|
128
|
-
with("#{@vmrun_cmd} snapshot #{@
|
307
|
+
with("#{@vmrun_cmd} snapshot #{@conf_file_path.gsub ' ', '\ '} \"bar\" 2>&1").
|
129
308
|
and_return("it blew up")
|
130
|
-
|
131
|
-
@
|
132
|
-
@string_io.string.should match /error was.+it blew up/m
|
309
|
+
|
310
|
+
@vm.create_snapshot('bar').should be_an_unsuccessful_response
|
133
311
|
end
|
134
312
|
end
|
135
313
|
|
136
314
|
describe 'revert_to_snapshot' do
|
137
|
-
|
315
|
+
before do
|
316
|
+
@snapshots_response_mock = mock('snapshots')
|
317
|
+
|
318
|
+
@conf_file_response_mock.stub_as_successful @conf_file_path
|
319
|
+
@snapshots_response_mock.stub_as_successful ['snap_1']
|
320
|
+
|
321
|
+
@vm.stub(:exists?).and_return(true)
|
322
|
+
@vm.stub(:snapshots).and_return(@snapshots_response_mock)
|
323
|
+
@vm.stub(:conf_file).and_return(@conf_file_response_mock)
|
324
|
+
Fission::Fusion.stub(:running?).and_return(false)
|
325
|
+
end
|
326
|
+
|
327
|
+
it "should return an unsuccessful response if the vm doesn't exist" do
|
328
|
+
@vm.stub(:exists?).and_return(false)
|
329
|
+
@vm.revert_to_snapshot('snap_1').should be_an_unsuccessful_response 'VM does not exist'
|
330
|
+
end
|
331
|
+
|
332
|
+
it 'should return an unsuccessful response if the Fusion GUI is running' do
|
333
|
+
Fission::Fusion.stub(:running?).and_return(true)
|
334
|
+
|
335
|
+
response = @vm.revert_to_snapshot 'snap_1'
|
336
|
+
|
337
|
+
error_string = 'It looks like the Fusion GUI is currently running. '
|
338
|
+
error_string << 'A VM cannot be reverted to a snapshot when the Fusion GUI is running. '
|
339
|
+
error_string << 'Exit the Fusion GUI and try again.'
|
340
|
+
|
341
|
+
response.should be_an_unsuccessful_response error_string
|
342
|
+
end
|
343
|
+
|
344
|
+
it 'should return an unsuccessful response if unable to figure out the conf file' do
|
345
|
+
@conf_file_response_mock.stub_as_unsuccessful
|
346
|
+
@vm.revert_to_snapshot('snap_1').should be_an_unsuccessful_response
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'should return a successful response and revert to the provided snapshot' do
|
138
350
|
$?.should_receive(:exitstatus).and_return(0)
|
139
351
|
@vm.should_receive(:`).
|
140
|
-
with("#{@vmrun_cmd} revertToSnapshot #{@
|
352
|
+
with("#{@vmrun_cmd} revertToSnapshot #{@conf_file_path.gsub ' ', '\ '} \"snap_1\" 2>&1").
|
141
353
|
and_return("")
|
142
|
-
|
143
|
-
@
|
354
|
+
|
355
|
+
@vm.revert_to_snapshot('snap_1').should be_a_successful_response
|
144
356
|
end
|
145
357
|
|
146
|
-
it
|
358
|
+
it 'should return an unsuccessful response if the snapshot cannot be found' do
|
359
|
+
@snapshots_response_mock.stub_as_successful []
|
360
|
+
response = @vm.revert_to_snapshot 'snap_1'
|
361
|
+
response.should be_an_unsuccessful_response "Unable to find a snapshot named 'snap_1'."
|
362
|
+
end
|
363
|
+
|
364
|
+
it 'should return an unsuccessful response if unable to list the existing snapshots' do
|
365
|
+
@snapshots_response_mock.stub_as_unsuccessful
|
366
|
+
@vm.revert_to_snapshot('snap_1').should be_an_unsuccessful_response
|
367
|
+
end
|
368
|
+
|
369
|
+
it 'should return and unsuccessful response if unable to revert to the snapshot' do
|
147
370
|
$?.should_receive(:exitstatus).and_return(1)
|
148
371
|
@vm.should_receive(:`).
|
149
|
-
with("#{@vmrun_cmd} revertToSnapshot #{@
|
372
|
+
with("#{@vmrun_cmd} revertToSnapshot #{@conf_file_path.gsub ' ', '\ '} \"snap_1\" 2>&1").
|
150
373
|
and_return("it blew up")
|
151
|
-
|
152
|
-
@
|
153
|
-
|
374
|
+
|
375
|
+
@vm.revert_to_snapshot('snap_1').should be_an_unsuccessful_response
|
376
|
+
end
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
describe 'exists?' do
|
381
|
+
before do
|
382
|
+
@conf_file_response = mock('exists')
|
383
|
+
@vm.stub(:conf_file).and_return(@conf_file_response)
|
384
|
+
end
|
385
|
+
|
386
|
+
it 'should return true if the VM exists' do
|
387
|
+
@conf_file_response.stub_as_successful '/vms/foo/foo.vmx'
|
388
|
+
@vm.exists?.should == true
|
389
|
+
end
|
390
|
+
|
391
|
+
it 'should return false if the VM does not exist' do
|
392
|
+
@conf_file_response.stub_as_unsuccessful
|
393
|
+
@vm.exists?.should == false
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
describe 'mac_addresses' do
|
398
|
+
before do
|
399
|
+
@network_info_mock = mock('network_info')
|
400
|
+
@vm.should_receive(:network_info).and_return(@network_info_mock)
|
401
|
+
end
|
402
|
+
|
403
|
+
it 'should return a successful response with the list of mac addresses' do
|
404
|
+
network_data = { 'ethernet0' => { 'mac_address' => '00:0c:29:1d:6a:64',
|
405
|
+
'ip_address' => '127.0.0.1' },
|
406
|
+
'ethernet1' => { 'mac_address' => '00:0c:29:1d:6a:75',
|
407
|
+
'ip_address' => '127.0.0.2' } }
|
408
|
+
@network_info_mock.stub_as_successful network_data
|
409
|
+
|
410
|
+
response = @vm.mac_addresses
|
411
|
+
|
412
|
+
response.should be_a_successful_response
|
413
|
+
response.data.should == ['00:0c:29:1d:6a:64', '00:0c:29:1d:6a:75']
|
414
|
+
end
|
415
|
+
|
416
|
+
it 'should return a successful response with an empty list if no mac addresses were found' do
|
417
|
+
@network_info_mock.stub_as_successful Hash.new
|
418
|
+
|
419
|
+
response = @vm.mac_addresses
|
420
|
+
|
421
|
+
response.should be_a_successful_response
|
422
|
+
response.data.should == []
|
423
|
+
end
|
424
|
+
|
425
|
+
it 'should return an unsuccessful response if there was an error getting the mac addresses' do
|
426
|
+
@network_info_mock.stub_as_unsuccessful
|
427
|
+
|
428
|
+
response = @vm.mac_addresses
|
429
|
+
|
430
|
+
response.should be_an_unsuccessful_response
|
431
|
+
response.data.should be_nil
|
432
|
+
end
|
433
|
+
|
434
|
+
end
|
435
|
+
|
436
|
+
describe 'network_info' do
|
437
|
+
before do
|
438
|
+
@conf_file_response_mock.stub_as_successful @conf_file_path
|
439
|
+
|
440
|
+
@vm.should_receive(:conf_file).and_return(@conf_file_response_mock)
|
441
|
+
@conf_file_io = StringIO.new
|
442
|
+
@lease_1_response_mock = mock('lease_1_response')
|
443
|
+
@lease_2_response_mock = mock('lease_1_response')
|
444
|
+
end
|
445
|
+
|
446
|
+
it 'should return a successful response with the list of interfaces, macs, and ips' do
|
447
|
+
@conf_file_response_mock.stub_as_successful @conf_file_path
|
448
|
+
|
449
|
+
@lease_1 = Fission::Lease.new :ip_address => '127.0.0.1',
|
450
|
+
:mac_address => '00:0c:29:1d:6a:64'
|
451
|
+
@lease_1_response_mock.stub_as_successful @lease_1
|
452
|
+
|
453
|
+
@lease_2 = Fission::Lease.new :ip_address => '127.0.0.2',
|
454
|
+
:mac_address => '00:0c:29:1d:6a:75'
|
455
|
+
@lease_2_response_mock.stub_as_successful @lease_2
|
456
|
+
|
457
|
+
vmx_content = 'ide1:0.deviceType = "cdrom-image"
|
458
|
+
ethernet0.present = "TRUE"
|
459
|
+
ethernet1.address = "00:0c:29:1d:6a:75"
|
460
|
+
ethernet0.connectionType = "nat"
|
461
|
+
ethernet0.generatedAddress = "00:0c:29:1d:6a:64"
|
462
|
+
ethernet0.virtualDev = "e1000"
|
463
|
+
ethernet0.wakeOnPcktRcv = "FALSE"
|
464
|
+
ethernet0.addressType = "generated"
|
465
|
+
ethernet0.linkStatePropagation.enable = "TRUE"
|
466
|
+
ethernet0.generatedAddressenable = "TRUE"
|
467
|
+
ethernet1.generatedAddressenable = "TRUE"'
|
468
|
+
|
469
|
+
@conf_file_io.string = vmx_content
|
470
|
+
|
471
|
+
File.should_receive(:open).with(@conf_file_path, 'r').
|
472
|
+
and_yield(@conf_file_io)
|
473
|
+
|
474
|
+
Fission::Lease.should_receive(:find_by_mac_address).
|
475
|
+
with('00:0c:29:1d:6a:64').
|
476
|
+
and_return(@lease_1_response_mock)
|
477
|
+
Fission::Lease.should_receive(:find_by_mac_address).
|
478
|
+
with('00:0c:29:1d:6a:75').
|
479
|
+
and_return(@lease_2_response_mock)
|
480
|
+
|
481
|
+
response = @vm.network_info
|
482
|
+
response.should be_a_successful_response
|
483
|
+
response.data.should == { 'ethernet0' => { 'mac_address' => '00:0c:29:1d:6a:64',
|
484
|
+
'ip_address' => '127.0.0.1' },
|
485
|
+
'ethernet1' => { 'mac_address' => '00:0c:29:1d:6a:75',
|
486
|
+
'ip_address' => '127.0.0.2' } }
|
487
|
+
end
|
488
|
+
|
489
|
+
it 'should return a successful response with an empty list if there are no macs' do
|
490
|
+
|
491
|
+
vmx_content = 'ide1:0.deviceType = "cdrom-image"
|
492
|
+
pciBridge7.virtualDev = "pcieRootPort"
|
493
|
+
pciBridge7.functions = "8"
|
494
|
+
vmci0.present = "TRUE"
|
495
|
+
roamingVM.exitBehavior = "go"
|
496
|
+
tools.syncTime = "TRUE"'
|
497
|
+
|
498
|
+
@conf_file_io.string = vmx_content
|
499
|
+
|
500
|
+
File.should_receive(:open).with(@conf_file_path, 'r').
|
501
|
+
and_yield(@conf_file_io)
|
502
|
+
|
503
|
+
response = @vm.network_info
|
504
|
+
response.should be_a_successful_response
|
505
|
+
response.data.should == {}
|
506
|
+
end
|
507
|
+
|
508
|
+
it 'should return a successful response without ip addresses if none were found' do
|
509
|
+
@lease_1_response_mock.stub_as_successful nil
|
510
|
+
@lease_2_response_mock.stub_as_successful nil
|
511
|
+
|
512
|
+
vmx_content = 'ide1:0.deviceType = "cdrom-image"
|
513
|
+
ethernet0.present = "TRUE"
|
514
|
+
ethernet1.address = "00:0c:29:1d:6a:75"
|
515
|
+
ethernet0.connectionType = "nat"
|
516
|
+
ethernet0.generatedAddress = "00:0c:29:1d:6a:64"
|
517
|
+
ethernet0.virtualDev = "e1000"
|
518
|
+
ethernet0.wakeOnPcktRcv = "FALSE"
|
519
|
+
ethernet0.addressType = "generated"
|
520
|
+
ethernet0.linkStatePropagation.enable = "TRUE"
|
521
|
+
ethernet0.generatedAddressenable = "TRUE"
|
522
|
+
ethernet1.generatedAddressenable = "TRUE"'
|
523
|
+
|
524
|
+
@conf_file_io.string = vmx_content
|
525
|
+
|
526
|
+
File.should_receive(:open).with(@conf_file_path, 'r').
|
527
|
+
and_yield(@conf_file_io)
|
528
|
+
|
529
|
+
Fission::Lease.should_receive(:find_by_mac_address).
|
530
|
+
with('00:0c:29:1d:6a:64').
|
531
|
+
and_return(@lease_1_response_mock)
|
532
|
+
Fission::Lease.should_receive(:find_by_mac_address).
|
533
|
+
with('00:0c:29:1d:6a:75').
|
534
|
+
and_return(@lease_2_response_mock)
|
535
|
+
|
536
|
+
response = @vm.network_info
|
537
|
+
response.should be_a_successful_response
|
538
|
+
response.data.should == { 'ethernet0' => { 'mac_address' => '00:0c:29:1d:6a:64',
|
539
|
+
'ip_address' => nil },
|
540
|
+
'ethernet1' => { 'mac_address' => '00:0c:29:1d:6a:75',
|
541
|
+
'ip_address' => nil } }
|
542
|
+
end
|
543
|
+
|
544
|
+
it 'should return an unsuccessful response with an error if no conf file was found' do
|
545
|
+
@conf_file_response_mock.stub_as_unsuccessful
|
546
|
+
|
547
|
+
File.should_not_receive(:open)
|
548
|
+
|
549
|
+
@vm.network_info.should be_an_unsuccessful_response
|
550
|
+
end
|
551
|
+
|
552
|
+
it 'should return an unsuccessful response if there was an error getting the ip information' do
|
553
|
+
@lease_1_response_mock.stub_as_unsuccessful
|
554
|
+
@lease_2_response_mock.stub_as_successful nil
|
555
|
+
|
556
|
+
vmx_content = 'ide1:0.deviceType = "cdrom-image"
|
557
|
+
ethernet0.present = "TRUE"
|
558
|
+
ethernet1.address = "00:0c:29:1d:6a:75"
|
559
|
+
ethernet0.connectionType = "nat"
|
560
|
+
ethernet0.generatedAddress = "00:0c:29:1d:6a:64"
|
561
|
+
ethernet0.virtualDev = "e1000"
|
562
|
+
ethernet0.wakeOnPcktRcv = "FALSE"
|
563
|
+
ethernet0.addressType = "generated"
|
564
|
+
ethernet0.linkStatePropagation.enable = "TRUE"
|
565
|
+
ethernet0.generatedAddressenable = "TRUE"
|
566
|
+
ethernet1.generatedAddressenable = "TRUE"'
|
567
|
+
|
568
|
+
@conf_file_io.string = vmx_content
|
569
|
+
|
570
|
+
File.should_receive(:open).with(@conf_file_path, 'r').
|
571
|
+
and_yield(@conf_file_io)
|
572
|
+
|
573
|
+
Fission::Lease.should_receive(:find_by_mac_address).
|
574
|
+
with('00:0c:29:1d:6a:64').
|
575
|
+
and_return(@lease_1_response_mock)
|
576
|
+
Fission::Lease.should_receive(:find_by_mac_address).
|
577
|
+
with('00:0c:29:1d:6a:75').
|
578
|
+
and_return(@lease_2_response_mock)
|
579
|
+
|
580
|
+
@vm.network_info.should be_an_unsuccessful_response
|
581
|
+
end
|
582
|
+
end
|
583
|
+
|
584
|
+
describe 'path' do
|
585
|
+
it 'should return the path of the VM' do
|
586
|
+
vm_path = File.join(Fission.config['vm_dir'], 'foo.vmwarevm').gsub '\\', ''
|
587
|
+
Fission::VM.new('foo').path.should == vm_path
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
describe 'state' do
|
592
|
+
before do
|
593
|
+
@vm_1 = Fission::VM.new 'foo'
|
594
|
+
@vm_2 = Fission::VM.new 'bar'
|
595
|
+
|
596
|
+
@all_running_response_mock = mock('all_running')
|
597
|
+
@suspended_response_mock = mock('suspended')
|
598
|
+
|
599
|
+
Fission::VM.stub(:all_running).and_return(@all_running_response_mock)
|
600
|
+
@all_running_response_mock.stub_as_successful [@vm_2]
|
601
|
+
end
|
602
|
+
|
603
|
+
it "should return a successful response and 'not running' when the VM is off" do
|
604
|
+
response = @vm.state
|
605
|
+
response.should be_a_successful_response
|
606
|
+
response.data.should == 'not running'
|
607
|
+
end
|
608
|
+
|
609
|
+
it "should return a successful resopnse and 'running' when the VM is running" do
|
610
|
+
@all_running_response_mock.stub_as_successful [@vm_1, @vm_2]
|
611
|
+
|
612
|
+
response = @vm.state
|
613
|
+
response.should be_a_successful_response
|
614
|
+
response.data.should == 'running'
|
615
|
+
end
|
616
|
+
|
617
|
+
it "should return a successful response and 'suspended' when the VM is suspended" do
|
618
|
+
@suspended_response_mock.stub_as_successful true
|
619
|
+
|
620
|
+
@vm.stub(:suspended?).and_return(@suspended_response_mock)
|
621
|
+
|
622
|
+
response = @vm.state
|
623
|
+
response.should be_a_successful_response
|
624
|
+
response.data.should == 'suspended'
|
625
|
+
end
|
626
|
+
|
627
|
+
it 'should return an unsuccessful response if there was an error getting the running VMs' do
|
628
|
+
@all_running_response_mock.stub_as_unsuccessful
|
629
|
+
@vm.state.should be_an_unsuccessful_response
|
630
|
+
end
|
631
|
+
|
632
|
+
it 'should return an unsuccessful repsonse if there was an error determining if the VM is suspended' do
|
633
|
+
@suspended_response_mock.stub_as_unsuccessful
|
634
|
+
@vm.stub(:suspended?).and_return(@suspended_response_mock)
|
635
|
+
@vm.state.should be_an_unsuccessful_response
|
636
|
+
end
|
637
|
+
end
|
638
|
+
|
639
|
+
describe 'running?' do
|
640
|
+
before do
|
641
|
+
@all_running_response_mock = mock('all_running')
|
642
|
+
|
643
|
+
Fission::VM.stub(:all_running).and_return(@all_running_response_mock)
|
644
|
+
end
|
645
|
+
|
646
|
+
it 'should return a successful response and false when the vm is not running' do
|
647
|
+
@all_running_response_mock.stub_as_successful []
|
648
|
+
response = @vm.running?
|
649
|
+
response.should be_a_successful_response
|
650
|
+
response.data.should == false
|
651
|
+
end
|
652
|
+
|
653
|
+
it 'should return a successful response and true if the vm is running' do
|
654
|
+
@all_running_response_mock.stub_as_successful [Fission::VM.new('foo')]
|
655
|
+
|
656
|
+
response = @vm.running?
|
657
|
+
response.should be_a_successful_response
|
658
|
+
response.data.should == true
|
659
|
+
end
|
660
|
+
|
661
|
+
it 'should return an unsuccessful repsponse if there is an error getting the list of running vms' do
|
662
|
+
@all_running_response_mock.stub_as_unsuccessful
|
663
|
+
@vm.running?.should be_an_unsuccessful_response
|
664
|
+
end
|
665
|
+
|
666
|
+
end
|
667
|
+
|
668
|
+
describe 'suspend_file_exists?' do
|
669
|
+
before do
|
670
|
+
FakeFS.activate!
|
671
|
+
FileUtils.mkdir_p @vm.path
|
672
|
+
end
|
673
|
+
|
674
|
+
after do
|
675
|
+
FakeFS.deactivate!
|
676
|
+
FakeFS::FileSystem.clear
|
154
677
|
end
|
678
|
+
|
679
|
+
it 'should return true if the suspend file exists' do
|
680
|
+
FileUtils.touch(File.join(@vm.path, "#{@vm.name}.vmem"))
|
681
|
+
@vm.suspend_file_exists?.should == true
|
682
|
+
end
|
683
|
+
|
684
|
+
it 'should return false if the suspend file does not exist' do
|
685
|
+
@vm.suspend_file_exists?.should == false
|
686
|
+
end
|
687
|
+
|
688
|
+
end
|
689
|
+
|
690
|
+
describe 'suspended?' do
|
691
|
+
before do
|
692
|
+
@running_response_mock = mock('running?')
|
693
|
+
@vm.stub(:running?).and_return(@running_response_mock)
|
694
|
+
end
|
695
|
+
|
696
|
+
describe 'when the vm is not running' do
|
697
|
+
before do
|
698
|
+
@running_response_mock.stub_as_successful false
|
699
|
+
end
|
700
|
+
|
701
|
+
it 'should return a successful response and true if a .vmem file exists in the vm dir' do
|
702
|
+
@vm.stub(:suspend_file_exists?).and_return(true)
|
703
|
+
|
704
|
+
response = @vm.suspended?
|
705
|
+
response.should be_a_successful_response
|
706
|
+
response.data.should == true
|
707
|
+
end
|
708
|
+
|
709
|
+
it 'should return a successful response and false if a .vmem file is not found in the vm dir' do
|
710
|
+
@vm.stub(:suspend_file_exists?).and_return(false)
|
711
|
+
|
712
|
+
response = @vm.suspended?
|
713
|
+
response.should be_a_successful_response
|
714
|
+
response.data.should == false
|
715
|
+
end
|
716
|
+
end
|
717
|
+
|
718
|
+
it 'should return a successful response and false if the vm is running' do
|
719
|
+
@running_response_mock.stub_as_successful true
|
720
|
+
|
721
|
+
response = @vm.suspended?
|
722
|
+
response.should be_a_successful_response
|
723
|
+
response.data.should == false
|
724
|
+
end
|
725
|
+
|
726
|
+
it 'should return an unsuccessful repsponse if there is an error getting the list of running vms' do
|
727
|
+
@running_response_mock.stub_as_unsuccessful
|
728
|
+
@vm.suspended?.should be_an_unsuccessful_response
|
729
|
+
end
|
730
|
+
|
155
731
|
end
|
156
732
|
|
157
733
|
describe 'conf_file' do
|
158
734
|
before do
|
159
735
|
FakeFS.activate!
|
160
|
-
@vm_root_dir = Fission::VM.
|
736
|
+
@vm_root_dir = Fission::VM.new('foo').path
|
161
737
|
FileUtils.mkdir_p(@vm_root_dir)
|
162
738
|
end
|
163
739
|
|
@@ -166,71 +742,85 @@ describe Fission::VM do
|
|
166
742
|
FakeFS::FileSystem.clear
|
167
743
|
end
|
168
744
|
|
169
|
-
it 'should return the path to the conf file' do
|
745
|
+
it 'should return a successful response with the path to the conf file' do
|
170
746
|
file_path = File.join(@vm_root_dir, 'foo.vmx')
|
171
747
|
FileUtils.touch(file_path)
|
172
|
-
Fission::VM.new('foo').conf_file.should == file_path
|
173
|
-
end
|
174
748
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
}.should raise_error SystemExit
|
749
|
+
response = Fission::VM.new('foo').conf_file
|
750
|
+
response.should be_a_successful_response
|
751
|
+
response.data.should == file_path
|
752
|
+
end
|
180
753
|
|
181
|
-
|
754
|
+
it 'should return an unsuccessful response with an error if no vmx file was found' do
|
755
|
+
response = Fission::VM.new('foo').conf_file
|
756
|
+
response.successful?.should == false
|
757
|
+
response.message.should match /Unable to find a config file for VM 'foo' \(in '#{File.join(@vm_root_dir, '\*\.vmx')}'\)/m
|
182
758
|
end
|
183
759
|
|
184
760
|
describe 'when the VM name and conf file name do not match' do
|
185
761
|
it 'should return the path to the conf file' do
|
186
762
|
file_path = File.join(@vm_root_dir, 'bar.vmx')
|
187
763
|
FileUtils.touch(file_path)
|
188
|
-
|
764
|
+
|
765
|
+
response = Fission::VM.new('foo').conf_file
|
766
|
+
response.should be_a_successful_response
|
767
|
+
response.data.should == file_path
|
189
768
|
end
|
190
769
|
end
|
191
770
|
|
192
771
|
describe 'if multiple vmx files are found' do
|
193
|
-
|
194
|
-
FileUtils.mkdir_p(@vm_root_dir)
|
195
|
-
end
|
196
|
-
|
197
|
-
it 'should use the conf file which matches the VM name if it exists' do
|
772
|
+
it 'should use return a successful response with the conf file which matches the VM name if it exists' do
|
198
773
|
['foo.vmx', 'bar.vmx'].each do |file|
|
199
774
|
FileUtils.touch(File.join(@vm_root_dir, file))
|
200
775
|
end
|
201
|
-
|
776
|
+
|
777
|
+
response = Fission::VM.new('foo').conf_file
|
778
|
+
response.should be_a_successful_response
|
779
|
+
response.data.should == File.join(@vm_root_dir, 'foo.vmx')
|
202
780
|
end
|
203
781
|
|
204
|
-
it 'should
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
Fission::VM.new('foo').conf_file
|
210
|
-
}.should raise_error SystemExit
|
782
|
+
it 'should return an unsuccessful object if none of the conf files matches the VM name' do
|
783
|
+
['bar.vmx', 'baz.vmx'].each do |file|
|
784
|
+
FileUtils.touch(File.join(@vm_root_dir, file))
|
785
|
+
end
|
786
|
+
Fission::VM.new('foo').conf_file
|
211
787
|
|
212
|
-
|
788
|
+
response = Fission::VM.new('foo').conf_file
|
789
|
+
response.successful?.should == false
|
790
|
+
error_regex = /Multiple config files found for VM 'foo' \('bar\.vmx', 'baz\.vmx' in '#{@vm_root_dir}'/m
|
791
|
+
response.message.should match error_regex
|
213
792
|
end
|
214
793
|
end
|
215
794
|
|
216
795
|
end
|
217
796
|
|
218
797
|
describe "self.all" do
|
219
|
-
|
220
|
-
|
798
|
+
before do
|
799
|
+
@vm_1_mock = mock('vm_1')
|
800
|
+
@vm_2_mock = mock('vm_2')
|
801
|
+
end
|
802
|
+
|
803
|
+
it "should return a successful object with the list of VM objects" do
|
804
|
+
vm_root = Fission.config['vm_dir']
|
221
805
|
Dir.should_receive(:[]).
|
222
806
|
and_return(["#{File.join vm_root, 'foo.vmwarevm' }", "#{File.join vm_root, 'bar.vmwarevm' }"])
|
223
807
|
|
224
|
-
vm_root = Fission.config
|
808
|
+
vm_root = Fission.config['vm_dir']
|
225
809
|
File.should_receive(:directory?).with("#{File.join vm_root, 'foo.vmwarevm'}").
|
226
810
|
and_return(true)
|
227
811
|
File.should_receive(:directory?).with("#{File.join vm_root, 'bar.vmwarevm'}").
|
228
812
|
and_return(true)
|
229
|
-
|
813
|
+
|
814
|
+
Fission::VM.should_receive(:new).with('foo').and_return(@vm_1_mock)
|
815
|
+
Fission::VM.should_receive(:new).with('bar').and_return(@vm_2_mock)
|
816
|
+
|
817
|
+
response = Fission::VM.all
|
818
|
+
response.should be_a_successful_response
|
819
|
+
response.data.should == [@vm_1_mock, @vm_2_mock]
|
230
820
|
end
|
231
821
|
|
232
|
-
it "should not return an item in the list if it isn't a directory" do
|
233
|
-
vm_root = Fission.config
|
822
|
+
it "should return a successful object and not return an item in the list if it isn't a directory" do
|
823
|
+
vm_root = Fission.config['vm_dir']
|
234
824
|
Dir.should_receive(:[]).
|
235
825
|
and_return((['foo', 'bar', 'baz'].map { |i| File.join vm_root, "#{i}.vmwarevm"}))
|
236
826
|
File.should_receive(:directory?).
|
@@ -239,11 +829,17 @@ describe Fission::VM do
|
|
239
829
|
with("#{File.join vm_root, 'bar.vmwarevm'}").and_return(true)
|
240
830
|
File.should_receive(:directory?).
|
241
831
|
with("#{File.join vm_root, 'baz.vmwarevm'}").and_return(false)
|
242
|
-
|
832
|
+
|
833
|
+
Fission::VM.should_receive(:new).with('foo').and_return(@vm_1_mock)
|
834
|
+
Fission::VM.should_receive(:new).with('bar').and_return(@vm_2_mock)
|
835
|
+
|
836
|
+
response = Fission::VM.all
|
837
|
+
response.should be_a_successful_response
|
838
|
+
response.data.should == [@vm_1_mock, @vm_2_mock]
|
243
839
|
end
|
244
840
|
|
245
841
|
it "should only query for items with an extension of .vmwarevm" do
|
246
|
-
dir_arg = File.join Fission.config
|
842
|
+
dir_arg = File.join Fission.config['vm_dir'], '*.vmwarevm'
|
247
843
|
Dir.should_receive(:[]).with(dir_arg).
|
248
844
|
and_return(['foo.vmwarevm', 'bar.vmwarevm'])
|
249
845
|
Fission::VM.all
|
@@ -251,7 +847,14 @@ describe Fission::VM do
|
|
251
847
|
end
|
252
848
|
|
253
849
|
describe 'self.all_running' do
|
254
|
-
|
850
|
+
before do
|
851
|
+
@vm_1 = Fission::VM.new 'foo'
|
852
|
+
@vm_2 = Fission::VM.new 'bar'
|
853
|
+
@vm_3 = Fission::VM.new 'baz'
|
854
|
+
@vm_names_and_objs = { 'foo' => @vm_1, 'bar' => @vm_2, 'baz' => @vm_3 }
|
855
|
+
end
|
856
|
+
|
857
|
+
it 'should return a successful response with the list of running vms' do
|
255
858
|
list_output = "Total running VMs: 2\n/vm/foo.vmwarevm/foo.vmx\n"
|
256
859
|
list_output << "/vm/bar.vmwarevm/bar.vmx\n/vm/baz.vmwarevm/baz.vmx\n"
|
257
860
|
|
@@ -262,18 +865,25 @@ describe Fission::VM do
|
|
262
865
|
[ 'foo', 'bar', 'baz'].each do |vm|
|
263
866
|
File.should_receive(:exists?).with("/vm/#{vm}.vmwarevm/#{vm}.vmx").
|
264
867
|
and_return(true)
|
868
|
+
|
869
|
+
Fission::VM.should_receive(:new).with(vm).
|
870
|
+
and_return(@vm_names_and_objs[vm])
|
265
871
|
end
|
266
872
|
|
267
|
-
Fission::VM.all_running
|
873
|
+
response = Fission::VM.all_running
|
874
|
+
response.should be_a_successful_response
|
875
|
+
response.data.should == [@vm_1, @vm_2, @vm_3]
|
268
876
|
end
|
269
877
|
|
270
|
-
it 'should
|
878
|
+
it 'should return a successful response with the VM dir name if it differs from the .vmx file name' do
|
271
879
|
vm_dir_file = { 'foo' => 'foo', 'bar' => 'diff', 'baz' => 'baz'}
|
272
880
|
list_output = "Total running VMs: 3\n"
|
273
881
|
vm_dir_file.each_pair do |dir, file|
|
274
882
|
list_output << "/vm/#{dir}.vmwarevm/#{file}.vmx\n"
|
275
883
|
File.should_receive(:exists?).with("/vm/#{dir}.vmwarevm/#{file}.vmx").
|
276
884
|
and_return(true)
|
885
|
+
Fission::VM.should_receive(:new).with(dir).
|
886
|
+
and_return(@vm_names_and_objs[dir])
|
277
887
|
end
|
278
888
|
|
279
889
|
$?.should_receive(:exitstatus).and_return(0)
|
@@ -281,70 +891,80 @@ describe Fission::VM do
|
|
281
891
|
with("#{@vmrun_cmd} list").
|
282
892
|
and_return(list_output)
|
283
893
|
|
284
|
-
Fission::VM.all_running
|
894
|
+
response = Fission::VM.all_running
|
895
|
+
response.should be_a_successful_response
|
896
|
+
response.data.should == [@vm_1, @vm_2, @vm_3]
|
285
897
|
end
|
286
898
|
|
287
|
-
it 'should
|
899
|
+
it 'should return an unsuccessful response if unable to get the list of running vms' do
|
288
900
|
$?.should_receive(:exitstatus).and_return(1)
|
289
901
|
Fission::VM.should_receive(:`).
|
290
902
|
with("#{@vmrun_cmd} list").
|
291
903
|
and_return("it blew up")
|
292
904
|
Fission.stub!(:ui).and_return(Fission::UI.new(@string_io))
|
293
905
|
|
294
|
-
|
295
|
-
Fission::VM.all_running
|
296
|
-
}.should raise_error SystemExit
|
297
|
-
|
298
|
-
@string_io.string.should match /Unable to determine the list of running VMs/
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
describe "self.path" do
|
303
|
-
it "should return the path of the vm" do
|
304
|
-
vm_path = File.join(Fission.config.attributes['vm_dir'], 'foo.vmwarevm').gsub '\\', ''
|
305
|
-
Fission::VM.path('foo').should == vm_path
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
describe "self.exists?" do
|
310
|
-
it "should return true if the vm exists" do
|
311
|
-
FakeFS do
|
312
|
-
FileUtils.mkdir_p(Fission::VM.path('foo'))
|
313
|
-
Fission::VM.exists?('foo').should == true
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
it 'should return false if the vm does not exist' do
|
318
|
-
FakeFS do
|
319
|
-
FileUtils.rm_r(Fission::VM.path('foo'))
|
320
|
-
Fission::VM.exists?('foo').should == false
|
321
|
-
end
|
906
|
+
Fission::VM.all_running.should be_an_unsuccessful_response
|
322
907
|
end
|
323
908
|
end
|
324
909
|
|
325
910
|
describe "self.clone" do
|
326
911
|
before do
|
327
|
-
@source_vm = 'foo'
|
328
|
-
@target_vm = 'bar'
|
912
|
+
@source_vm = Fission::VM.new 'foo'
|
913
|
+
@target_vm = Fission::VM.new 'bar'
|
914
|
+
@source_path = @source_vm.path
|
915
|
+
@target_path = @target_vm.path
|
916
|
+
|
917
|
+
@clone_response_mock = mock('clone_response')
|
329
918
|
@vm_files = ['.vmx', '.vmxf', '.vmdk', '-s001.vmdk', '-s002.vmdk', '.vmsd']
|
330
919
|
|
331
920
|
FakeFS.activate!
|
332
921
|
|
333
|
-
FileUtils.mkdir_p
|
922
|
+
FileUtils.mkdir_p @source_path
|
334
923
|
|
335
924
|
@vm_files.each do |file|
|
336
|
-
FileUtils.touch
|
925
|
+
FileUtils.touch "#{@source_path}/#{@source_vm.name}#{file}"
|
337
926
|
end
|
338
927
|
|
339
928
|
['.vmx', '.vmxf', '.vmdk'].each do |ext|
|
340
|
-
File.open(
|
929
|
+
File.open("#{@source_path}/foo#{ext}", 'w') { |f| f.write 'foo.vmdk'}
|
930
|
+
end
|
931
|
+
|
932
|
+
@source_vm.stub(:exists?).and_return(true)
|
933
|
+
@target_vm.stub(:exists?).and_return(false)
|
934
|
+
|
935
|
+
Fission::VM.stub(:new).with(@source_vm.name).
|
936
|
+
and_return(@source_vm)
|
937
|
+
Fission::VM.stub(:new).with(@target_vm.name).
|
938
|
+
and_return(@target_vm)
|
939
|
+
|
940
|
+
vmx_content = 'ide1:0.deviceType = "cdrom-image"
|
941
|
+
nvram = "foo.nvram"
|
942
|
+
ethernet0.present = "TRUE"
|
943
|
+
ethernet1.address = "00:0c:29:1d:6a:75"
|
944
|
+
ethernet0.connectionType = "nat"
|
945
|
+
ethernet0.generatedAddress = "00:0c:29:1d:6a:64"
|
946
|
+
ethernet0.virtualDev = "e1000"
|
947
|
+
tools.remindInstall = "TRUE"
|
948
|
+
ethernet0.wakeOnPcktRcv = "FALSE"
|
949
|
+
ethernet0.addressType = "generated"
|
950
|
+
uuid.action = "keep"
|
951
|
+
ethernet0.linkStatePropagation.enable = "TRUE"
|
952
|
+
ethernet0.generatedAddressenable = "TRUE"
|
953
|
+
ethernet1.generatedAddressenable = "TRUE"'
|
954
|
+
|
955
|
+
File.open("#{@source_path}/#{@source_vm.name}.vmx", 'w') do |f|
|
956
|
+
f.write vmx_content
|
341
957
|
end
|
342
958
|
|
343
959
|
['.vmx', '.vmxf'].each do |ext|
|
344
|
-
File.
|
345
|
-
with(
|
960
|
+
File.stub(:binary?).
|
961
|
+
with("#{@target_path}/#{@target_vm.name}#{ext}").
|
346
962
|
and_return(false)
|
347
963
|
end
|
964
|
+
|
965
|
+
File.stub(:binary?).
|
966
|
+
with("#{@target_path}/#{@target_vm.name}.vmdk").
|
967
|
+
and_return(true)
|
348
968
|
end
|
349
969
|
|
350
970
|
after do
|
@@ -352,100 +972,129 @@ describe Fission::VM do
|
|
352
972
|
FakeFS::FileSystem.clear
|
353
973
|
end
|
354
974
|
|
975
|
+
it "should return an unsuccessful response if the source vm doesn't exist" do
|
976
|
+
@source_vm.stub(:exists?).and_return(false)
|
977
|
+
response = Fission::VM.clone @source_vm.name, @target_vm.name
|
978
|
+
response.should be_an_unsuccessful_response 'VM does not exist'
|
979
|
+
end
|
980
|
+
|
981
|
+
it "should return an unsuccessful response if the target vm exists" do
|
982
|
+
@target_vm.stub(:exists?).and_return(true)
|
983
|
+
response = Fission::VM.clone @source_vm.name, @target_vm.name
|
984
|
+
response.should be_an_unsuccessful_response 'VM already exists'
|
985
|
+
end
|
986
|
+
|
355
987
|
it 'should copy the vm files to the target' do
|
356
|
-
|
357
|
-
with(File.join(Fission::VM.path('bar'), "bar.vmdk")).
|
358
|
-
and_return(true)
|
359
|
-
Fission::VM.clone @source_vm, @target_vm
|
988
|
+
Fission::VM.clone @source_vm.name, @target_vm.name
|
360
989
|
|
361
|
-
File.directory?(
|
990
|
+
File.directory?(@target_path).should == true
|
362
991
|
|
363
992
|
@vm_files.each do |file|
|
364
|
-
File.file?(
|
993
|
+
File.file?("#{@target_path}/bar#{file}").should == true
|
365
994
|
end
|
366
995
|
end
|
367
996
|
|
368
997
|
it "should copy the vm files to the target if a file name doesn't match the directory" do
|
369
|
-
FileUtils.touch
|
370
|
-
|
371
|
-
|
372
|
-
and_return(true)
|
373
|
-
Fission::VM.clone @source_vm, @target_vm
|
998
|
+
FileUtils.touch "#{@source_path}/other_name.nvram"
|
999
|
+
|
1000
|
+
Fission::VM.clone @source_vm.name, @target_vm.name
|
374
1001
|
|
375
|
-
File.directory?(
|
1002
|
+
File.directory?(@target_path).should == true
|
376
1003
|
|
377
1004
|
@vm_files.each do |file|
|
378
|
-
File.file?(
|
1005
|
+
File.file?("#{@target_path}/#{@target_vm.name}#{file}").should == true
|
379
1006
|
end
|
380
1007
|
|
381
|
-
File.file?(
|
1008
|
+
File.file?("#{@target_path}/bar.nvram").should == true
|
382
1009
|
end
|
383
1010
|
|
384
|
-
|
385
1011
|
it "should copy the vm files to the target if a sparse disk file name doesn't match the directory" do
|
386
|
-
FileUtils.touch
|
387
|
-
|
388
|
-
|
389
|
-
and_return(true)
|
390
|
-
Fission::VM.clone @source_vm, @target_vm
|
1012
|
+
FileUtils.touch "#{@source_path}/other_name-s003.vmdk"
|
1013
|
+
|
1014
|
+
Fission::VM.clone @source_vm.name, @target_vm.name
|
391
1015
|
|
392
|
-
File.directory?(
|
1016
|
+
File.directory?(@target_path).should == true
|
393
1017
|
|
394
1018
|
@vm_files.each do |file|
|
395
|
-
File.file?(
|
1019
|
+
File.file?("#{@target_path}/#{@target_vm.name}#{file}").should == true
|
396
1020
|
end
|
397
1021
|
|
398
|
-
File.file?(
|
1022
|
+
File.file?("#{@target_path}/bar-s003.vmdk").should == true
|
399
1023
|
end
|
400
1024
|
|
401
1025
|
it 'should update the target vm config files' do
|
402
|
-
|
403
|
-
with(File.join(Fission::VM.path('bar'), "bar.vmdk")).
|
404
|
-
and_return(true)
|
405
|
-
Fission::VM.clone @source_vm, @target_vm
|
1026
|
+
Fission::VM.clone @source_vm.name, @target_vm.name
|
406
1027
|
|
407
1028
|
['.vmx', '.vmxf'].each do |ext|
|
408
|
-
File.read(
|
409
|
-
File.read(
|
1029
|
+
File.read("#{@target_path}/bar#{ext}").should_not match /foo/
|
1030
|
+
File.read("#{@target_path}/bar#{ext}").should match /bar/
|
410
1031
|
end
|
411
1032
|
end
|
412
1033
|
|
413
|
-
it
|
414
|
-
|
415
|
-
|
416
|
-
|
1034
|
+
it 'should disable VMware tools warning in the conf file' do
|
1035
|
+
Fission::VM.clone @source_vm.name, @target_vm.name
|
1036
|
+
|
1037
|
+
pattern = /^tools\.remindInstall = "FALSE"/
|
417
1038
|
|
418
|
-
File.read(
|
1039
|
+
File.read("#{@target_path}/bar.vmx").should match pattern
|
419
1040
|
end
|
420
1041
|
|
421
|
-
it
|
422
|
-
|
423
|
-
|
424
|
-
|
1042
|
+
it 'should remove auto generated MAC addresses from the conf file' do
|
1043
|
+
Fission::VM.clone @source_vm.name, @target_vm.name
|
1044
|
+
|
1045
|
+
pattern = /^ethernet\.+generatedAddress.+/
|
1046
|
+
|
1047
|
+
File.read("#{@target_path}/bar.vmx").should_not match pattern
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
it 'should setup the conf file to generate a new uuid' do
|
1051
|
+
Fission::VM.clone @source_vm.name, @target_vm.name
|
1052
|
+
|
1053
|
+
pattern = /^uuid\.action = "create"/
|
1054
|
+
|
1055
|
+
File.read("#{@target_path}/bar.vmx").should match pattern
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
it "should not try to update the vmdk file if it's not a sparse disk" do
|
1059
|
+
Fission::VM.clone @source_vm.name, @target_vm.name
|
1060
|
+
|
1061
|
+
File.read("#{@target_path}/bar.vmdk").should match /foo/
|
1062
|
+
end
|
425
1063
|
|
426
|
-
|
1064
|
+
it 'should return a successful response if clone was successful' do
|
1065
|
+
Fission::VM.clone(@source_vm.name, @target_vm.name).should be_a_successful_response
|
427
1066
|
end
|
428
1067
|
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
1068
|
+
describe 'when a sparse disk is found' do
|
1069
|
+
it "should update the vmdk" do
|
1070
|
+
File.rspec_reset
|
1071
|
+
File.stub(:binary?).and_return(false)
|
433
1072
|
|
434
|
-
|
435
|
-
|
1073
|
+
Fission::VM.clone @source_vm.name, @target_vm.name
|
1074
|
+
|
1075
|
+
File.read("#{@target_path}/bar.vmdk").should match /bar/
|
1076
|
+
end
|
436
1077
|
end
|
1078
|
+
|
437
1079
|
end
|
438
1080
|
|
439
|
-
describe
|
1081
|
+
describe 'delete' do
|
440
1082
|
before do
|
1083
|
+
@running_response_mock = mock('running?')
|
1084
|
+
@running_response_mock.stub_as_successful false
|
1085
|
+
|
1086
|
+
@vm.stub(:exists?).and_return(true)
|
1087
|
+
@vm.stub(:running?).and_return(@running_response_mock)
|
1088
|
+
@vm.stub(:conf_file).and_return(@conf_file_response_mock)
|
1089
|
+
|
441
1090
|
@target_vm = 'foo'
|
442
1091
|
@vm_files = %w{ .vmx .vmxf .vmdk -s001.vmdk -s002.vmdk .vmsd }
|
443
1092
|
FakeFS.activate!
|
444
1093
|
|
445
|
-
FileUtils.mkdir_p Fission::VM.
|
1094
|
+
FileUtils.mkdir_p Fission::VM.new(@target_vm).path
|
446
1095
|
|
447
1096
|
@vm_files.each do |file|
|
448
|
-
FileUtils.touch File.join(Fission::VM.
|
1097
|
+
FileUtils.touch File.join(Fission::VM.new(@target_vm).path, "#{@target_vm}#{file}")
|
449
1098
|
end
|
450
1099
|
end
|
451
1100
|
|
@@ -453,18 +1102,45 @@ describe Fission::VM do
|
|
453
1102
|
FakeFS.deactivate!
|
454
1103
|
end
|
455
1104
|
|
1105
|
+
it "should return an unsuccessful response if the vm doesn't exist" do
|
1106
|
+
@vm.stub(:exists?).and_return(false)
|
1107
|
+
|
1108
|
+
response = @vm.delete
|
1109
|
+
response.should be_an_unsuccessful_response 'VM does not exist'
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
it 'should return an unsuccessful response if the vm is running' do
|
1113
|
+
@running_response_mock.stub_as_successful true
|
1114
|
+
|
1115
|
+
response = @vm.delete
|
1116
|
+
response.should be_an_unsuccessful_response 'The VM must not be running in order to delete it.'
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
it 'should return an unsuccessful response if unable to determine if running' do
|
1120
|
+
@running_response_mock.stub_as_unsuccessful
|
1121
|
+
|
1122
|
+
response = @vm.delete
|
1123
|
+
response.should be_an_unsuccessful_response
|
1124
|
+
end
|
1125
|
+
|
456
1126
|
it "should delete the target vm files" do
|
457
1127
|
Fission::Metadata.stub!(:delete_vm_info)
|
458
|
-
|
1128
|
+
|
1129
|
+
@vm.delete
|
1130
|
+
|
459
1131
|
@vm_files.each do |file|
|
460
|
-
File.exists?(File.join(Fission::VM.
|
1132
|
+
File.exists?(File.join(Fission::VM.new(@target_vm).path, "#{@target_vm}#{file}")).should == false
|
461
1133
|
end
|
462
|
-
@string_io.string.should match /Deleting vm #{@target_vm}/
|
463
1134
|
end
|
464
1135
|
|
465
1136
|
it 'should delete the target vm metadata' do
|
466
1137
|
Fission::Metadata.should_receive(:delete_vm_info)
|
467
|
-
|
1138
|
+
@vm.delete
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
it 'should return a successful reponsse object' do
|
1142
|
+
Fission::Metadata.stub!(:delete_vm_info)
|
1143
|
+
@vm.delete.should be_a_successful_response
|
468
1144
|
end
|
469
1145
|
|
470
1146
|
end
|