fission 0.4.0 → 0.5.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.
Files changed (79) hide show
  1. data/.ruby-gemset +1 -0
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +12 -3
  5. data/README.md +45 -19
  6. data/bin/fission +1 -1
  7. data/fission.gemspec +3 -2
  8. data/lib/fission.rb +15 -0
  9. data/lib/fission/action/shell_executor.rb +37 -0
  10. data/lib/fission/action/snapshot/creator.rb +81 -0
  11. data/lib/fission/action/snapshot/deleter.rb +85 -0
  12. data/lib/fission/action/snapshot/lister.rb +90 -0
  13. data/lib/fission/action/snapshot/reverter.rb +81 -0
  14. data/lib/fission/action/vm/cloner.rb +191 -0
  15. data/lib/fission/action/vm/deleter.rb +73 -0
  16. data/lib/fission/action/vm/lister.rb +138 -0
  17. data/lib/fission/action/vm/starter.rb +88 -0
  18. data/lib/fission/action/vm/stopper.rb +79 -0
  19. data/lib/fission/action/vm/suspender.rb +68 -0
  20. data/lib/fission/cli.rb +21 -117
  21. data/lib/fission/command.rb +39 -0
  22. data/lib/fission/command/clone.rb +11 -6
  23. data/lib/fission/command/delete.rb +11 -6
  24. data/lib/fission/command/info.rb +62 -0
  25. data/lib/fission/command/snapshot_create.rb +9 -3
  26. data/lib/fission/command/snapshot_delete.rb +38 -0
  27. data/lib/fission/command/snapshot_list.rb +9 -3
  28. data/lib/fission/command/snapshot_revert.rb +9 -3
  29. data/lib/fission/command/start.rb +11 -6
  30. data/lib/fission/command/status.rb +9 -1
  31. data/lib/fission/command/stop.rb +9 -3
  32. data/lib/fission/command/suspend.rb +11 -6
  33. data/lib/fission/command_helpers.rb +18 -4
  34. data/lib/fission/command_line_parser.rb +189 -0
  35. data/lib/fission/config.rb +1 -1
  36. data/lib/fission/fusion.rb +3 -4
  37. data/lib/fission/lease.rb +2 -1
  38. data/lib/fission/metadata.rb +6 -1
  39. data/lib/fission/response.rb +17 -9
  40. data/lib/fission/version.rb +1 -1
  41. data/lib/fission/vm.rb +142 -382
  42. data/lib/fission/vm_configuration.rb +79 -0
  43. data/spec/fission/action/execute_shell_command_spec.rb +25 -0
  44. data/spec/fission/action/snapshot/creator_spec.rb +77 -0
  45. data/spec/fission/action/snapshot/deleter_spec.rb +84 -0
  46. data/spec/fission/action/snapshot/lister_spec.rb +67 -0
  47. data/spec/fission/action/snapshot/reverter_spec.rb +76 -0
  48. data/spec/fission/action/vm/cloner_spec.rb +198 -0
  49. data/spec/fission/action/vm/deleter_spec.rb +79 -0
  50. data/spec/fission/action/vm/lister_spec.rb +164 -0
  51. data/spec/fission/action/vm/starter_spec.rb +88 -0
  52. data/spec/fission/action/vm/stopper_spec.rb +71 -0
  53. data/spec/fission/action/vm/suspender_spec.rb +59 -0
  54. data/spec/fission/cli_spec.rb +32 -157
  55. data/spec/fission/command/clone_spec.rb +9 -3
  56. data/spec/fission/command/delete_spec.rb +11 -3
  57. data/spec/fission/command/info_spec.rb +130 -0
  58. data/spec/fission/command/snapshot_create_spec.rb +11 -3
  59. data/spec/fission/command/snapshot_delete_spec.rb +74 -0
  60. data/spec/fission/command/snapshot_list_spec.rb +11 -3
  61. data/spec/fission/command/snapshot_revert_spec.rb +11 -3
  62. data/spec/fission/command/start_spec.rb +11 -3
  63. data/spec/fission/command/status_spec.rb +16 -5
  64. data/spec/fission/command/stop_spec.rb +11 -3
  65. data/spec/fission/command/suspend_spec.rb +11 -3
  66. data/spec/fission/command_helpers_spec.rb +27 -5
  67. data/spec/fission/command_line_parser_spec.rb +267 -0
  68. data/spec/fission/command_spec.rb +16 -1
  69. data/spec/fission/config_spec.rb +3 -3
  70. data/spec/fission/fusion_spec.rb +11 -6
  71. data/spec/fission/lease_spec.rb +81 -45
  72. data/spec/fission/metadata_spec.rb +29 -6
  73. data/spec/fission/response_spec.rb +20 -9
  74. data/spec/fission/ui_spec.rb +1 -1
  75. data/spec/fission/vm_configuration_spec.rb +132 -0
  76. data/spec/fission/vm_spec.rb +393 -750
  77. data/spec/helpers/command_helpers.rb +1 -1
  78. metadata +93 -15
  79. data/.rvmrc +0 -1
@@ -0,0 +1,79 @@
1
+ module Fission
2
+
3
+ class VMConfiguration
4
+
5
+ # Internal: Creates a new VMConfiguration object. This accepts a VM object
6
+ #
7
+ # vm - An instance of VM
8
+ #
9
+ # Examples:
10
+ #
11
+ # Fission::VMConfiguration.new @my_vm
12
+ #
13
+ # Returns a new VMConfiguration object
14
+ def initialize(vm)
15
+ @vm = vm
16
+ end
17
+
18
+ # Internal: Gathers the the configuration data for the VM. This essentially
19
+ # parses the key/value pairs from the configuration file (.vmx) into a Hash.
20
+ #
21
+ # Exaples:
22
+ #
23
+ # @vm_config.config_data.data
24
+ # # => { 'memsize' => '384', 'ethernet0.present' => 'TRUE',... }
25
+ #
26
+ # Returns a Response object with the result.
27
+ # If successful, the Response's data attribute will be a Hash. All keys and
28
+ # values are represented as a String (even when the value in the
29
+ # configuration file is 'TRUE'). If a value is an empty string in the
30
+ # configuration file, it will be represented in the Hash as an empty String.
31
+ # If there is an error, an unsuccessful Response will be returned.
32
+ def config_data
33
+ return Response.new :code => 1, :message => 'VM does not exist' unless @vm.exists?
34
+
35
+ conf_file_response = @vm.conf_file
36
+ return conf_file_response unless conf_file_response.successful?
37
+
38
+ @conf_file_location = conf_file_response.data
39
+
40
+ Response.new :code => 0, :data => parse_vm_config_file
41
+ end
42
+
43
+ private
44
+ # Internal: Parses the configuration file (i.e. '.vmx')
45
+ #
46
+ # Examples:
47
+ #
48
+ # @vm_config.parse_vm_config_file
49
+ # # => { 'memsize' => '384', 'ethernet0.present' => 'TRUE',... }
50
+ #
51
+ # Returns a Hash.
52
+ # All keys and values are represented as a String (even when the value in
53
+ # the conf file is 'TRUE'). If a value is an empty string in the
54
+ # configuration file, it will be represented in the Hash as an empty String.
55
+ def parse_vm_config_file
56
+ File.readlines(@conf_file_location).inject({}) do |result, line|
57
+ data = parse_line_data(line)
58
+ result[data[0]] = (data[1].nil? ? '' : data[1])
59
+ result
60
+ end
61
+ end
62
+
63
+ # Internal: Splits and formats a single line from a VM configuration file
64
+ # into an Array.
65
+ #
66
+ # Examples:
67
+ #
68
+ # @vm_config.parse_line_data('foo = "bar"')
69
+ #
70
+ # Returns an Array. The first item will be the left side of the '=' and the
71
+ # second item will be the right side. This will also strip any whitespace
72
+ # characters from the beginning or end of the provided line.
73
+ def parse_line_data(line)
74
+ line.strip.gsub('"', '').split ' = '
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fission::Action::ShellExecutor do
4
+
5
+ describe 'execute' do
6
+ before do
7
+ @cmd = 'ls /var/log'
8
+ @executor = Fission::Action::ShellExecutor.new @cmd
9
+ end
10
+
11
+ it 'should execute the shell command' do
12
+ @executor.should_receive(:`).with(@cmd)
13
+ @executor.execute
14
+ end
15
+
16
+ it 'should return a hash of the output and Process::Status object' do
17
+ result = @executor.execute
18
+ result['output'].should be_a String
19
+ result['output'].empty?.should be_false
20
+ result['process_status'].should be_a Process::Status
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fission::Action::Snapshot::Creator do
4
+ describe 'create_snapshot' do
5
+ before do
6
+ @vm = Fission::VM.new 'foo'
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
+ @snapshots_response_mock = mock 'snapshots'
11
+ @running_response_mock = mock 'running?'
12
+
13
+ @running_response_mock.stub_as_successful true
14
+ @conf_file_response_mock.stub_as_successful @conf_file_path
15
+ @snapshots_response_mock.stub_as_successful []
16
+
17
+ @vm.stub(:exists?).and_return(true)
18
+ @vm.stub(:snapshots).and_return(@snapshots_response_mock)
19
+ @vm.stub(:running?).and_return(@running_response_mock)
20
+ @vm.stub(:conf_file).and_return(@conf_file_response_mock)
21
+ @creator = Fission::Action::Snapshot::Creator.new @vm
22
+ end
23
+
24
+ it "should return an unsuccessful response if the vm doesn't exist" do
25
+ @vm.stub(:exists?).and_return(false)
26
+ @creator.create_snapshot('snap_1').should be_an_unsuccessful_response 'VM does not exist'
27
+ end
28
+
29
+ it 'should return an unsuccessful response if the vm is not running' do
30
+ @running_response_mock.stub_as_successful false
31
+
32
+ response = @creator.create_snapshot 'snap_1'
33
+ error_message = 'The VM must be running in order to take a snapshot.'
34
+ response.should be_an_unsuccessful_response error_message
35
+ end
36
+
37
+ it 'should return an unsuccessful response if unable to determine if running' do
38
+ @running_response_mock.stub_as_unsuccessful
39
+ @creator.create_snapshot('snap_1').should be_an_unsuccessful_response
40
+ end
41
+
42
+ it 'should return an unsuccessful response if unable to figure out the conf file' do
43
+ @conf_file_response_mock.stub_as_unsuccessful
44
+ @creator.create_snapshot('snap_1').should be_an_unsuccessful_response
45
+ end
46
+
47
+ it 'should return a response when creating the snapshot' do
48
+ executor_mock = mock 'executor'
49
+ response = stub
50
+ cmd = "#{@vmrun_cmd} snapshot "
51
+ cmd << "'#{@conf_file_path}' \"bar\" 2>&1"
52
+
53
+ executor_mock.should_receive(:execute).and_return(executor_mock)
54
+ Fission::Action::ShellExecutor.should_receive(:new).
55
+ with(cmd).
56
+ and_return(executor_mock)
57
+ Fission::Response.should_receive(:from_shell_executor).
58
+ with(executor_mock).
59
+ and_return(response)
60
+
61
+ @creator.create_snapshot('bar').should == response
62
+ end
63
+
64
+ it 'should return an unsuccessful response if the snapshot name is a duplicate' do
65
+ @snapshots_response_mock.stub_as_successful ['snap_1']
66
+ response = @creator.create_snapshot 'snap_1'
67
+ response.should be_an_unsuccessful_response "There is already a snapshot named 'snap_1'."
68
+ end
69
+
70
+ it 'should return an unsuccessful response if there was a problem listing the existing snapshots' do
71
+ @snapshots_response_mock.stub_as_unsuccessful
72
+ @creator.create_snapshot('snap_1').should be_an_unsuccessful_response
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fission::Action::Snapshot::Deleter do
4
+
5
+ describe 'delete_snapshot' do
6
+ before do
7
+ @vm = Fission::VM.new 'foo'
8
+ @conf_file_path = File.join @vm.path, 'foo.vmx'
9
+ @vmrun_cmd = Fission.config['vmrun_cmd']
10
+ @conf_file_response_mock = mock 'conf_file_response'
11
+ @snapshots_response_mock = mock 'snapshots'
12
+ @running_response_mock = mock 'running?'
13
+
14
+ @running_response_mock.stub_as_successful true
15
+ @conf_file_response_mock.stub_as_successful @conf_file_path
16
+ @snapshots_response_mock.stub_as_successful ['snap_1']
17
+
18
+ @vm.stub(:exists?).and_return(true)
19
+ @vm.stub(:snapshots).and_return(@snapshots_response_mock)
20
+ @vm.stub(:running?).and_return(@running_response_mock)
21
+ @vm.stub(:conf_file).and_return(@conf_file_response_mock)
22
+ Fission::Fusion.stub(:running?).and_return(false)
23
+ @deleter = Fission::Action::Snapshot::Deleter.new @vm
24
+ end
25
+
26
+ it "should return an unsuccessful response if the vm doesn't exist" do
27
+ @vm.stub(:exists?).and_return(false)
28
+ @deleter.delete_snapshot('snap_1').should be_an_unsuccessful_response 'VM does not exist'
29
+ end
30
+
31
+ it 'should return an unsuccessful response if unable to figure out the conf file' do
32
+ @conf_file_response_mock.stub_as_unsuccessful
33
+ @deleter.delete_snapshot('snap_1').should be_an_unsuccessful_response
34
+ end
35
+
36
+ it 'should return an unsuccessful response if the snapshot does not exist' do
37
+ @snapshots_response_mock.stub_as_successful []
38
+ response = @deleter.delete_snapshot 'snap_1'
39
+ response.should be_an_unsuccessful_response "Unable to find a snapshot named 'snap_1'."
40
+ end
41
+
42
+ it 'should return an unsuccessful response if there was a problem listing the existing snapshots' do
43
+ @snapshots_response_mock.stub_as_unsuccessful
44
+ @deleter.delete_snapshot('snap_1').should be_an_unsuccessful_response
45
+ end
46
+
47
+ it 'should return a response when deleting the snapshot' do
48
+ executor_mock = mock 'executor'
49
+ response = stub
50
+ cmd = "#{@vmrun_cmd} deleteSnapshot "
51
+ cmd << "'#{@conf_file_path}' \"snap_1\" 2>&1"
52
+
53
+ executor_mock.should_receive(:execute).and_return(executor_mock)
54
+ Fission::Action::ShellExecutor.should_receive(:new).
55
+ with(cmd).
56
+ and_return(executor_mock)
57
+ Fission::Response.should_receive(:from_shell_executor).
58
+ with(executor_mock).
59
+ and_return(response)
60
+
61
+ @deleter.delete_snapshot('snap_1').should == response
62
+ end
63
+
64
+ context 'when the gui is running' do
65
+ before do
66
+ Fission::Fusion.stub(:running?).and_return(true)
67
+ end
68
+
69
+ it 'should return an unsuccessful response if the vm is not running' do
70
+ @running_response_mock.stub_as_successful false
71
+ response = @deleter.delete_snapshot 'snap_1'
72
+ error_message = 'A snapshot cannot be deleted when the GUI is running and the VM is not running.'
73
+ response.should be_an_unsuccessful_response error_message
74
+ end
75
+
76
+ it 'should return an unsuccessful response if unable to determine if running' do
77
+ @running_response_mock.stub_as_unsuccessful
78
+ @deleter.delete_snapshot('snap_1').should be_an_unsuccessful_response
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fission::Action::Snapshot::Lister do
4
+ before do
5
+ @vm = Fission::VM.new 'foo'
6
+ @conf_file_path = File.join @vm.path, 'foo.vmx'
7
+ @vmrun_cmd = Fission.config['vmrun_cmd']
8
+ @conf_file_response_mock = mock 'conf_file_response'
9
+ @vm.stub(:conf_file).and_return(@conf_file_response_mock)
10
+ end
11
+
12
+ describe 'snapshots' do
13
+ before do
14
+ @vm.stub(:exists?).and_return(true)
15
+ @conf_file_response_mock.stub_as_successful @conf_file_path
16
+ @lister = Fission::Action::Snapshot::Lister.new @vm
17
+ end
18
+
19
+ it "should return an unsuccessful repsonse when the vm doesn't exist" do
20
+ @vm.stub(:exists?).and_return(false)
21
+ @lister.snapshots.should be_an_unsuccessful_response 'VM does not exist'
22
+ end
23
+
24
+ it 'should return an unsuccessful response if unable to figure out the conf file' do
25
+ @conf_file_response_mock.stub_as_unsuccessful
26
+ @lister.snapshots.should be_an_unsuccessful_response
27
+ end
28
+
29
+ it 'should return a response when listing the snapshots' do
30
+ executor_mock = mock 'executor'
31
+ process_mock = stub :exitstatus => 0
32
+ cmd = "#{@vmrun_cmd} listSnapshots "
33
+ cmd << "'#{@conf_file_path}' 2>&1"
34
+
35
+ output_text = "Total snapshots: 3\nsnap foo\nsnap bar\nsnap baz\n"
36
+ executor_mock.should_receive(:execute).
37
+ and_return({'output' => output_text,
38
+ 'process_status' => process_mock})
39
+
40
+ Fission::Action::ShellExecutor.should_receive(:new).
41
+ with(cmd).
42
+ and_return(executor_mock)
43
+
44
+ response = @lister.snapshots
45
+ response.should be_a_successful_response
46
+ response.data.should == ['snap foo', 'snap bar', 'snap baz']
47
+ end
48
+
49
+ it 'should return an unsuccessful response if there was a problem listing the snapshots' do
50
+ executor_mock = mock 'executor'
51
+ process_mock = stub :exitstatus => 1
52
+ cmd = "#{@vmrun_cmd} listSnapshots "
53
+ cmd << "'#{@conf_file_path}' 2>&1"
54
+
55
+ executor_mock.should_receive(:execute).
56
+ and_return({'output' => 'it blew up',
57
+ 'process_status' => process_mock})
58
+
59
+ Fission::Action::ShellExecutor.should_receive(:new).
60
+ with(cmd).
61
+ and_return(executor_mock)
62
+
63
+ @lister.snapshots.should be_an_unsuccessful_response
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fission::Action::Snapshot::Reverter do
4
+
5
+ describe 'revert_snapshot' do
6
+ before do
7
+ @vm = Fission::VM.new 'foo'
8
+ @conf_file_path = File.join @vm.path, 'foo.vmx'
9
+ @vmrun_cmd = Fission.config['vmrun_cmd']
10
+ @conf_file_response_mock = mock 'conf_file_response'
11
+ @snapshots_response_mock = mock 'snapshots'
12
+
13
+ @conf_file_response_mock.stub_as_successful @conf_file_path
14
+ @snapshots_response_mock.stub_as_successful []
15
+
16
+ @vm.stub(:exists?).and_return(true)
17
+ @vm.stub(:snapshots).and_return(@snapshots_response_mock)
18
+ @vm.stub(:conf_file).and_return(@conf_file_response_mock)
19
+ @snapshots_response_mock.stub_as_successful ['snap_1']
20
+ Fission::Fusion.stub(:running?).and_return(false)
21
+ @reverter = Fission::Action::Snapshot::Reverter.new @vm
22
+ end
23
+
24
+ it "should return an unsuccessful response if the vm doesn't exist" do
25
+ @vm.stub(:exists?).and_return(false)
26
+ @reverter.revert_to_snapshot('snap_1').should be_an_unsuccessful_response 'VM does not exist'
27
+ end
28
+
29
+ it 'should return an unsuccessful response if the Fusion GUI is running' do
30
+ Fission::Fusion.stub(:running?).and_return(true)
31
+
32
+ response = @reverter.revert_to_snapshot 'snap_1'
33
+
34
+ error_string = 'It looks like the Fusion GUI is currently running. '
35
+ error_string << 'A VM cannot be reverted to a snapshot when the Fusion GUI is running.'
36
+ error_string << ' Exit the Fusion GUI and try again.'
37
+
38
+ response.should be_an_unsuccessful_response error_string
39
+ end
40
+
41
+ it 'should return an unsuccessful response if unable to figure out the conf file' do
42
+ @conf_file_response_mock.stub_as_unsuccessful
43
+ @reverter.revert_to_snapshot('snap_1').should be_an_unsuccessful_response
44
+ end
45
+
46
+ it 'should return a response when reverting to the snapshot' do
47
+ executor_mock = mock 'executor'
48
+ response = stub
49
+ cmd = "#{@vmrun_cmd} revertToSnapshot "
50
+ cmd << "'#{@conf_file_path}' \"snap_1\" 2>&1"
51
+
52
+ executor_mock.should_receive(:execute).and_return(executor_mock)
53
+ Fission::Action::ShellExecutor.should_receive(:new).
54
+ with(cmd).
55
+ and_return(executor_mock)
56
+ Fission::Response.should_receive(:from_shell_executor).
57
+ with(executor_mock).
58
+ and_return(response)
59
+
60
+ @reverter.revert_to_snapshot('snap_1').should == response
61
+ end
62
+
63
+ it 'should return an unsuccessful response if the snapshot cannot be found' do
64
+ @snapshots_response_mock.stub_as_successful []
65
+ response = @reverter.revert_to_snapshot 'snap_1'
66
+ response.should be_an_unsuccessful_response "Unable to find a snapshot named 'snap_1'."
67
+ end
68
+
69
+ it 'should return an unsuccessful response if unable to list the existing snapshots' do
70
+ @snapshots_response_mock.stub_as_unsuccessful
71
+ @reverter.revert_to_snapshot('snap_1').should be_an_unsuccessful_response
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,198 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fission::Action::VM::Cloner do
4
+
5
+ describe 'clone' do
6
+ before do
7
+ @source_vm = Fission::VM.new 'foo'
8
+ @target_vm = Fission::VM.new 'bar'
9
+ @source_path = @source_vm.path
10
+ @target_path = @target_vm.path
11
+
12
+ @clone_response_mock = mock('clone_response')
13
+ @vm_files = ['.vmx', '.vmxf', '.vmdk', '-s001.vmdk', '-s002.vmdk', '.vmsd']
14
+
15
+ FakeFS.activate!
16
+
17
+ FileUtils.mkdir_p @source_path
18
+
19
+ @vm_files.each do |file|
20
+ FileUtils.touch "#{@source_path}/#{@source_vm.name}#{file}"
21
+ end
22
+
23
+ ['.vmx', '.vmxf', '.vmdk'].each do |ext|
24
+ File.open("#{@source_path}/foo#{ext}", 'w') { |f| f.write 'foo.vmdk'}
25
+ end
26
+
27
+ @source_vm.stub(:exists?).and_return(true)
28
+ @target_vm.stub(:exists?).and_return(false)
29
+
30
+ Fission::VM.stub(:new).with(@source_vm.name).
31
+ and_return(@source_vm)
32
+ Fission::VM.stub(:new).with(@target_vm.name).
33
+ and_return(@target_vm)
34
+
35
+ vmx_content = 'ide1:0.deviceType = "cdrom-image"
36
+ nvram = "foo.nvram"
37
+ ethernet0.present = "TRUE"
38
+ ethernet1.address = "00:0c:29:1d:6a:75"
39
+ ethernet0.connectionType = "nat"
40
+ ethernet0.generatedAddress = "00:0c:29:1d:6a:64"
41
+ ethernet0.virtualDev = "e1000"
42
+ tools.remindInstall = "TRUE"
43
+ ethernet0.wakeOnPcktRcv = "FALSE"
44
+ ethernet0.addressType = "generated"
45
+ uuid.action = "keep"
46
+ ethernet0.linkStatePropagation.enable = "TRUE"
47
+ ethernet0.generatedAddressenable = "TRUE"
48
+ ethernet1.generatedAddressenable = "TRUE"'
49
+
50
+ File.open("#{@source_path}/#{@source_vm.name}.vmx", 'w') do |f|
51
+ f.write vmx_content
52
+ end
53
+
54
+ ['.vmx', '.vmxf'].each do |ext|
55
+ File.stub(:binary?).
56
+ with("#{@target_path}/#{@target_vm.name}#{ext}").
57
+ and_return(false)
58
+ end
59
+
60
+ File.stub(:binary?).
61
+ with("#{@target_path}/#{@target_vm.name}.vmdk").
62
+ and_return(true)
63
+ @cloner = Fission::Action::VM::Cloner.new @source_vm, @target_vm
64
+ end
65
+
66
+ after do
67
+ FakeFS.deactivate!
68
+ FakeFS::FileSystem.clear
69
+ end
70
+
71
+ it "should return an unsuccessful response if the source vm doesn't exist" do
72
+ @source_vm.stub(:exists?).and_return(false)
73
+ response = @cloner.clone
74
+ response.should be_an_unsuccessful_response 'VM does not exist'
75
+ end
76
+
77
+ it "should return an unsuccessful response if the target vm exists" do
78
+ @target_vm.stub(:exists?).and_return(true)
79
+ response = @cloner.clone
80
+ response.should be_an_unsuccessful_response 'VM already exists'
81
+ end
82
+
83
+ it 'should copy the vm files to the target' do
84
+ @cloner.clone
85
+
86
+ File.directory?(@target_path).should == true
87
+
88
+ @vm_files.each do |file|
89
+ File.file?("#{@target_path}/bar#{file}").should == true
90
+ end
91
+ end
92
+
93
+ it "should copy the vm files to the target if a file name doesn't match the directory" do
94
+ FileUtils.touch "#{@source_path}/other_name.nvram"
95
+
96
+ @cloner.clone
97
+
98
+ File.directory?(@target_path).should == true
99
+
100
+ @vm_files.each do |file|
101
+ File.file?("#{@target_path}/#{@target_vm.name}#{file}").should == true
102
+ end
103
+
104
+ File.file?("#{@target_path}/bar.nvram").should == true
105
+ end
106
+
107
+ it "should copy the vm files to the target if a sparse disk file name doesn't match the directory" do
108
+ FileUtils.touch "#{@source_path}/other_name-s003.vmdk"
109
+
110
+ @cloner.clone
111
+
112
+ File.directory?(@target_path).should == true
113
+
114
+ @vm_files.each do |file|
115
+ File.file?("#{@target_path}/#{@target_vm.name}#{file}").should == true
116
+ end
117
+
118
+ File.file?("#{@target_path}/bar-s003.vmdk").should == true
119
+ end
120
+
121
+ it 'should update the target vm config files' do
122
+ @cloner.clone
123
+
124
+ ['.vmx', '.vmxf'].each do |ext|
125
+ File.read("#{@target_path}/bar#{ext}").should_not match /foo/
126
+ File.read("#{@target_path}/bar#{ext}").should match /bar/
127
+ end
128
+ end
129
+
130
+ it 'should disable VMware tools warning in the conf file' do
131
+ @cloner.clone
132
+ pattern = /^tools\.remindInstall = "FALSE"/
133
+ File.read("#{@target_path}/bar.vmx").should match pattern
134
+ end
135
+
136
+ it 'should remove auto generated MAC addresses from the conf file' do
137
+ @cloner.clone
138
+ pattern = /^ethernet\.+generatedAddress.+/
139
+ File.read("#{@target_path}/bar.vmx").should_not match pattern
140
+ end
141
+
142
+ it 'should setup the conf file to generate a new uuid' do
143
+ @cloner.clone
144
+ pattern = /^uuid\.action = "create"/
145
+ File.read("#{@target_path}/bar.vmx").scan(pattern).count.should == 1
146
+ end
147
+
148
+ context 'when uuid.action already exists in the source conf file' do
149
+ before do
150
+ File.open("#{@source_path}/#{@source_vm.name}.vmx", 'a') do |f|
151
+ f.write "\nuuid.action = \"create\""
152
+ end
153
+ end
154
+
155
+ it 'should not add another entry for uuid.action' do
156
+ @cloner.clone
157
+ pattern = /^uuid\.action = "create"/
158
+ File.read("#{@target_path}/bar.vmx").scan(pattern).count.should == 1
159
+ end
160
+ end
161
+
162
+ context 'when tools.remindInstall already exists in the source conf file' do
163
+ before do
164
+ File.open("#{@source_path}/#{@source_vm.name}.vmx", 'w') do |f|
165
+ f.write "\ntools.remindInstall = \"FALSE\""
166
+ end
167
+ end
168
+
169
+ it 'should not add another entry for tools.remindInstall' do
170
+ @cloner.clone
171
+ pattern = /^tools\.remindInstall = "FALSE"/
172
+ File.read("#{@target_path}/bar.vmx").scan(pattern).count.should == 1
173
+ end
174
+ end
175
+
176
+ it "should not try to update the vmdk file if it's not a sparse disk" do
177
+ @cloner.clone
178
+ File.read("#{@target_path}/bar.vmdk").should match /foo/
179
+ end
180
+
181
+ it 'should return a successful response if clone was successful' do
182
+ @cloner.clone.should be_a_successful_response
183
+ end
184
+
185
+ context 'when a sparse disk is found' do
186
+ it "should update the vmdk" do
187
+ File.rspec_reset
188
+ File.stub(:binary?).and_return(false)
189
+
190
+ @cloner.clone
191
+
192
+ File.read("#{@target_path}/bar.vmdk").should match /bar/
193
+ end
194
+ end
195
+
196
+ end
197
+
198
+ end