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.
Files changed (50) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.md +3 -0
  3. data/README.md +1 -1
  4. data/lib/fission.rb +5 -6
  5. data/lib/fission/cli.rb +77 -7
  6. data/lib/fission/command.rb +43 -1
  7. data/lib/fission/command/clone.rb +19 -20
  8. data/lib/fission/command/delete.rb +29 -25
  9. data/lib/fission/command/snapshot_create.rb +11 -26
  10. data/lib/fission/command/snapshot_list.rb +13 -19
  11. data/lib/fission/command/snapshot_revert.rb +11 -26
  12. data/lib/fission/command/start.rb +11 -25
  13. data/lib/fission/command/status.rb +26 -10
  14. data/lib/fission/command/stop.rb +10 -21
  15. data/lib/fission/command/suspend.rb +21 -21
  16. data/lib/fission/command_helpers.rb +21 -0
  17. data/lib/fission/config.rb +35 -0
  18. data/lib/fission/fusion.rb +11 -3
  19. data/lib/fission/lease.rb +148 -0
  20. data/lib/fission/metadata.rb +55 -2
  21. data/lib/fission/response.rb +76 -0
  22. data/lib/fission/ui.rb +49 -0
  23. data/lib/fission/version.rb +1 -1
  24. data/lib/fission/vm.rb +653 -75
  25. data/spec/contexts/command.rb +12 -0
  26. data/spec/fission/cli_spec.rb +4 -11
  27. data/spec/fission/command/clone_spec.rb +45 -45
  28. data/spec/fission/command/delete_spec.rb +56 -43
  29. data/spec/fission/command/snapshot_create_spec.rb +29 -51
  30. data/spec/fission/command/snapshot_list_spec.rb +25 -26
  31. data/spec/fission/command/snapshot_revert_spec.rb +27 -53
  32. data/spec/fission/command/start_spec.rb +25 -69
  33. data/spec/fission/command/status_spec.rb +48 -13
  34. data/spec/fission/command/stop_spec.rb +25 -42
  35. data/spec/fission/command/suspend_spec.rb +54 -49
  36. data/spec/fission/command_helpers_spec.rb +30 -0
  37. data/spec/fission/command_spec.rb +19 -0
  38. data/spec/fission/config_spec.rb +24 -0
  39. data/spec/fission/fusion_spec.rb +6 -6
  40. data/spec/fission/lease_spec.rb +176 -0
  41. data/spec/fission/metadata_spec.rb +8 -8
  42. data/spec/fission/response_spec.rb +81 -0
  43. data/spec/fission/vm_spec.rb +869 -193
  44. data/spec/fission_spec.rb +0 -6
  45. data/spec/helpers/command_helpers.rb +12 -0
  46. data/spec/helpers/response_helpers.rb +21 -0
  47. data/spec/matchers/be_a_successful_response.rb +7 -0
  48. data/spec/matchers/be_an_unsuccessful_response.rb +10 -0
  49. data/spec/spec_helper.rb +7 -0
  50. metadata +24 -5
@@ -1,82 +1,87 @@
1
1
  require File.expand_path('../../../spec_helper.rb', __FILE__)
2
2
 
3
3
  describe Fission::Command::Suspend do
4
+ include_context 'command_setup'
5
+
4
6
  before do
5
- @vm_info = ['foo']
6
- @string_io = StringIO.new
7
- Fission.stub!(:ui).and_return(Fission::UI.new(@string_io))
7
+ @target_vm = ['foo']
8
+ Fission::VM.stub(:new).and_return(@vm_mock)
9
+
10
+ @suspend_response_mock = mock('suspend_response')
11
+
12
+ @vm_mock.stub(:name).and_return(@target_vm.first)
8
13
  end
9
14
 
10
15
  describe 'execute' do
11
- it "should output an error and the help when no VM argument is passed in" do
12
- Fission::Command::Suspend.should_receive(:help)
16
+ subject { Fission::Command::Suspend }
13
17
 
14
- lambda {
15
- command = Fission::Command::Suspend.new
16
- command.execute
17
- }.should raise_error SystemExit
18
+ it_should_not_accept_arguments_of [], 'suspend'
18
19
 
19
- @string_io.string.should match /Incorrect arguments for suspend command/
20
- end
20
+ it 'should suspend the vm' do
21
+ @suspend_response_mock.stub_as_successful
21
22
 
22
- it "should output an error and exit if it can't find the vm" do
23
- Fission::VM.should_receive(:exists?).with(@vm_info.first).and_return(false)
23
+ @vm_mock.should_receive(:suspend).and_return(@suspend_response_mock)
24
24
 
25
- lambda {
26
- command = Fission::Command::Suspend.new @vm_info
27
- command.execute
28
- }.should raise_error SystemExit
25
+ command = Fission::Command::Suspend.new @target_vm
26
+ command.execute
29
27
 
30
- @string_io.string.should match /Unable to find the VM #{@vm_info.first}/
28
+ @string_io.string.should match /Suspending '#{@target_vm.first}'/
29
+ @string_io.string.should match /VM '#{@target_vm.first}' suspended/
31
30
  end
32
31
 
32
+ it 'should output an error and exit if there was an error suspending the vm' do
33
+ @suspend_response_mock.stub_as_unsuccessful
33
34
 
34
- it "should output and exit if the vm is not running" do
35
- Fission::VM.should_receive(:exists?).with(@vm_info.first).and_return(true)
36
- Fission::VM.should_receive(:all_running).and_return([])
35
+ @vm_mock.should_receive(:suspend).and_return(@suspend_response_mock)
37
36
 
38
- lambda {
39
- command = Fission::Command::Suspend.new @vm_info
40
- command.execute
41
- }.should raise_error SystemExit
42
-
43
- @string_io.string.should match /VM '#{@vm_info.first}' is not running/
44
- end
45
-
46
- it 'should try to suspend the vm if it is running' do
47
- @vm_mock = mock('vm_mock')
48
- Fission::VM.should_receive(:exists?).with(@vm_info.first).and_return(true)
49
- Fission::VM.should_receive(:all_running).and_return([@vm_info.first])
50
- Fission::VM.should_receive(:new).with(@vm_info.first).and_return(@vm_mock)
51
- @vm_mock.should_receive(:suspend)
52
-
53
- command = Fission::Command::Suspend.new @vm_info
54
- command.execute
37
+ command = Fission::Command::Suspend.new @target_vm
38
+ lambda { command.execute }.should raise_error SystemExit
55
39
 
56
- @string_io.string.should match /Suspending '#{@vm_info.first}'/
40
+ @string_io.string.should match /Suspending '#{@target_vm.first}'/
41
+ @string_io.string.should match /There was an error suspending the VM.+it blew up.+/m
57
42
  end
58
43
 
59
44
  describe 'with --all' do
60
- it 'should suspend all running VMs' do
45
+ before do
61
46
  @vm_mock_1 = mock('vm_mock_1')
62
47
  @vm_mock_2 = mock('vm_mock_2')
63
48
 
64
- vm_items = {'vm_1' => @vm_mock_1,
65
- 'vm_2' => @vm_mock_2
49
+ @vm_mock_1.stub(:name).and_return('vm_1')
50
+ @vm_mock_2.stub(:name).and_return('vm_2')
51
+
52
+ @vm_items = {'vm_1' => @vm_mock_1,
53
+ 'vm_2' => @vm_mock_2
66
54
  }
55
+ end
56
+
57
+ it 'should output an error and exit if there was an error getting the list of running vms' do
58
+ @all_running_response_mock.stub_as_unsuccessful
59
+
60
+ Fission::VM.should_receive(:all_running).and_return(@all_running_response_mock)
61
+
62
+ command = Fission::Command::Suspend.new ['--all']
63
+ lambda { command.execute }.should raise_error SystemExit
64
+
65
+ @string_io.string.should match /There was an error getting the list of running VMs.+it blew up.+/m
66
+ end
67
67
 
68
- Fission::VM.should_receive(:all_running).and_return(vm_items.keys)
68
+ it 'should suspend all running VMs' do
69
+ @all_running_response_mock.stub_as_successful @vm_items.values
70
+ @suspend_response_mock.stub_as_successful
71
+
72
+ Fission::VM.should_receive(:all_running).and_return(@all_running_response_mock)
69
73
 
70
- vm_items.each_pair do |name, mock|
71
- Fission::VM.should_receive(:new).with(name).and_return(mock)
72
- mock.should_receive(:suspend)
74
+ @vm_items.each_pair do |name, mock|
75
+ mock.should_receive(:suspend).and_return(@suspend_response_mock)
73
76
  end
74
77
 
75
78
  command = Fission::Command::Suspend.new ['--all']
76
79
  command.execute
77
80
 
78
- @string_io.string.should match /Suspending 'vm_1'/
79
- @string_io.string.should match /Suspending 'vm_2'/
81
+ @vm_items.keys.each do |vm|
82
+ @string_io.string.should match /Suspending '#{vm}'/
83
+ @string_io.string.should match /VM '#{vm}' suspended/
84
+ end
80
85
  end
81
86
  end
82
87
 
@@ -86,7 +91,7 @@ describe Fission::Command::Suspend do
86
91
  it 'should output info for this command' do
87
92
  output = Fission::Command::Suspend.help
88
93
 
89
- output.should match /suspend \[vm \| --all\]/
94
+ output.should match /suspend \[vm_name \| --all\]/
90
95
  end
91
96
  end
92
97
  end
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../../spec_helper.rb', __FILE__)
2
+
3
+ describe Fission::CommandHelpers do
4
+ include_context 'command_setup'
5
+
6
+ before do
7
+ @object = Object.new
8
+ @object.extend Fission::CommandHelpers
9
+ end
10
+
11
+ describe 'incorrect_arguments' do
12
+ before do
13
+ @object.class.should_receive(:help).and_return('foo help')
14
+ @object.stub(:output)
15
+ @object.stub(:output_and_exit)
16
+ end
17
+
18
+ it "should output the command's help text" do
19
+ @object.should_receive(:output).with("foo help\n")
20
+ @object.incorrect_arguments 'delete'
21
+ end
22
+
23
+ it 'should output that the argumets are incorrect and exit' do
24
+ @object.should_receive(:output_and_exit).
25
+ with('Incorrect arguments for delete command', 1)
26
+ @object.incorrect_arguments 'delete'
27
+ end
28
+ end
29
+
30
+ end
@@ -22,4 +22,23 @@ describe Fission::Command do
22
22
  end
23
23
  end
24
24
 
25
+ describe 'ui' do
26
+ it 'should load a ui object' do
27
+ Fission::Command.new.ui.should be_a Fission::UI
28
+ end
29
+
30
+ [:output, :output_and_exit, :output_printf].each do |item|
31
+ it "should delegate '#{item.to_s}' to the ui instance" do
32
+ @ui_mock = mock('ui')
33
+ @ui_mock.should_receive(item)
34
+
35
+ Fission::UI.stub!(:new).and_return(@ui_mock)
36
+
37
+ @cmd_instance = Fission::Command.new
38
+ @cmd_instance.send item, 'foo'
39
+ end
40
+ end
41
+
42
+ end
43
+
25
44
  end
@@ -42,6 +42,30 @@ describe Fission::Config do
42
42
  end
43
43
  end
44
44
 
45
+ it 'should use the fusion default lease file' do
46
+ @config = Fission::Config.new
47
+ @config.attributes['lease_file'].should == '/var/db/vmware/vmnet-dhcpd-vmnet8.leases'
48
+ end
49
+
50
+ end
51
+
52
+ describe '[]' do
53
+ before do
54
+ @config_items = { 'vmrun_bin' => '/foo/bar/vmrun',
55
+ 'vmrun_cmd' => '/foo/bar/vmrun -T fusion',
56
+ 'plist_file' => '/foo/bar/plist',
57
+ 'gui_bin' => '/foo/bar/gui',
58
+ 'vm_dir' => '/foo/bar/vms'}
59
+ @config = Fission::Config.new
60
+ @config.attributes = @config_items
61
+ end
62
+
63
+ it 'should return the value for specifed key' do
64
+ @config_items.each_pair do |k, v|
65
+ @config[k].should == v
66
+ end
67
+ end
68
+
45
69
  end
46
70
 
47
71
  end
@@ -1,22 +1,22 @@
1
1
  require File.expand_path('../../spec_helper.rb', __FILE__)
2
2
 
3
3
  describe Fission::Fusion do
4
- describe 'self.is_running?' do
4
+ describe 'self.running?' do
5
5
  before do
6
6
  @cmd = "ps -ef | grep -v grep | "
7
- @cmd << "grep -c #{Fission.config.attributes['gui_bin'].gsub(' ', '\ ')} 2>&1"
7
+ @cmd << "grep -c #{Fission.config['gui_bin'].gsub(' ', '\ ')} 2>&1"
8
8
  end
9
9
 
10
- it 'should return true if the fusion app is running' do
10
+ it 'should return a successful response and true if the fusion app is running' do
11
11
  Fission::Fusion.should_receive(:`).with(@cmd).
12
12
  and_return("1\n")
13
- Fission::Fusion.is_running?.should == true
13
+ Fission::Fusion.running?.should == true
14
14
  end
15
15
 
16
- it 'should return false if the fusion app is not running' do
16
+ it 'should return a successful response and false if the fusion app is not running' do
17
17
  Fission::Fusion.should_receive(:`).with(@cmd).
18
18
  and_return("0\n")
19
- Fission::Fusion.is_running?.should == false
19
+ Fission::Fusion.running?.should == false
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,176 @@
1
+ require File.expand_path('../../spec_helper.rb', __FILE__)
2
+
3
+ describe Fission::Lease do
4
+ before do
5
+ @lease_info = [ { :ip_address => '172.16.248.197',
6
+ :mac_address => '00:0c:29:2b:af:50',
7
+ :start => '2011/10/11 01:50:58',
8
+ :end => '2011/10/11 02:20:58' },
9
+ { :ip_address => '172.16.248.132',
10
+ :mac_address => '00:0c:29:10:23:57',
11
+ :start => '2010/07/12 21:31:28',
12
+ :end => '2010/07/12 22:01:28' },
13
+ { :ip_address => '172.16.248.130',
14
+ :mac_address => '00:0c:29:b3:63:d0',
15
+ :start => '2010/05/27 00:54:52',
16
+ :end => '2010/05/27 01:24:52' },
17
+ { :ip_address => '172.16.248.129',
18
+ :mac_address => '00:0c:29:0a:e9:b3',
19
+ :start => '2010/02/16 23:16:05',
20
+ :end => '2010/02/16 23:46:05' } ]
21
+
22
+ @lease_file_content = '# This is a comment
23
+ # And here is another
24
+ lease 172.16.248.197 {
25
+ starts 2 2011/10/11 01:50:58;
26
+ ends 2 2011/10/11 02:20:58;
27
+ hardware ethernet 00:0c:29:2b:af:50;
28
+ }
29
+ lease 172.16.248.132 {
30
+ starts 1 2010/07/12 21:31:28;
31
+ ends 1 2010/07/12 22:01:28;
32
+ hardware ethernet 00:0c:29:10:23:57;
33
+ }
34
+ lease 172.16.248.130 {
35
+ starts 4 2010/05/27 00:54:52;
36
+ ends 4 2010/05/27 01:24:52;
37
+ hardware ethernet 00:0c:29:b3:63:d0;
38
+ }
39
+ lease 172.16.248.129 {
40
+ starts 2 2010/02/16 23:16:05;
41
+ ends 2 2010/02/16 23:46:05;
42
+ hardware ethernet 00:0c:29:0a:e9:b3;
43
+ }'
44
+ end
45
+
46
+ describe 'new' do
47
+ { :ip_address => '127.0.0.1',
48
+ :mac_address => '00:00:00:00:00:00',
49
+ :start => '2004/07/25 17:18:00',
50
+ :end => '2004/07/25 18:18:00' }
51
+ it 'should set the ip address' do
52
+ lease = Fission::Lease.new :ip_address => '127.0.0.1'
53
+ lease.ip_address.should == '127.0.0.1'
54
+ end
55
+
56
+ it 'should set the mac address' do
57
+ lease = Fission::Lease.new :mac_address => '00:00:00:00:00:00'
58
+ lease.mac_address.should == '00:00:00:00:00:00'
59
+ end
60
+
61
+ it 'should set the lease start date/time' do
62
+ date_time = DateTime.parse('2000/01/01 17:00:00')
63
+ lease = Fission::Lease.new :start => date_time
64
+ lease.start.should == date_time
65
+ end
66
+
67
+ it 'should set the lease end date/time' do
68
+ date_time = DateTime.parse('2000/01/01 17:00:00')
69
+ lease = Fission::Lease.new :end => date_time
70
+ lease.end.should == date_time
71
+ end
72
+ end
73
+
74
+ describe 'expired?' do
75
+ it 'should return true if the lease is expired' do
76
+ lease = Fission::Lease.new :end => DateTime.now - 1
77
+ lease.expired?.should == true
78
+ end
79
+
80
+ it 'should return false if the lease has not expired' do
81
+ lease = Fission::Lease.new :end => DateTime.now + 1
82
+ lease.expired?.should == false
83
+ end
84
+ end
85
+
86
+ describe 'self.all' do
87
+ it 'should query the configured lease file' do
88
+ File.should_receive(:read).with(Fission.config['lease_file']).
89
+ and_return('')
90
+
91
+ Fission::Lease.all
92
+ end
93
+
94
+ it 'should return a successful response with the list of the found leases' do
95
+ File.should_receive(:read).with(Fission.config['lease_file']).
96
+ and_return(@lease_file_content)
97
+
98
+ example_leases = @lease_info.collect do |lease|
99
+ Fission::Lease.new :ip_address => lease[:ip_address],
100
+ :mac_address => lease[:mac_address],
101
+ :start => DateTime.parse(lease[:start]),
102
+ :end => DateTime.parse(lease[:end])
103
+
104
+ end
105
+
106
+ response = Fission::Lease.all
107
+ response.should be_a_successful_response
108
+
109
+ response.data.each do |lease|
110
+ example_lease = example_leases.select { |l| l.ip_address == lease.ip_address }
111
+
112
+ [:ip_address, :mac_address, :start, :end].each do |attrib|
113
+ lease.send(attrib).should == example_lease.first.send(attrib)
114
+ end
115
+ end
116
+
117
+ end
118
+
119
+ it 'should return a successful response with an empty list if there are no leases found' do
120
+ File.should_receive(:read).with(Fission.config['lease_file']).
121
+ and_return('')
122
+ response = Fission::Lease.all
123
+ response.should be_a_successful_response
124
+ response.data.should == []
125
+ end
126
+
127
+ it 'should return an unsuccessful response if the configured lease file does not exist' do
128
+ File.should_receive(:file?).with(Fission.config['lease_file']).
129
+ and_return(false)
130
+ response = Fission::Lease.all
131
+ error_string = "Unable to find the lease file '#{Fission.config['lease_file']}'"
132
+ response.should be_an_unsuccessful_response(error_string)
133
+ end
134
+
135
+ end
136
+
137
+ describe 'self.find_by_mac_address' do
138
+ describe 'when able to get all of the leases' do
139
+ before do
140
+ File.should_receive(:read).with(Fission.config['lease_file']).
141
+ and_return(@lease_file_content)
142
+ end
143
+
144
+ it 'should return a response with the lease associated with the provided mac address' do
145
+
146
+ response = Fission::Lease.find_by_mac_address '00:0c:29:10:23:57'
147
+
148
+ response.should be_a_successful_response
149
+
150
+ response.data.ip_address.should == '172.16.248.132'
151
+ response.data.mac_address.should == '00:0c:29:10:23:57'
152
+ response.data.start.should == DateTime.parse('2010/07/12 21:31:28')
153
+ response.data.end.should == DateTime.parse('2010/07/12 22:01:28')
154
+ end
155
+
156
+ it "should return a response with nil if the mac address can't be found" do
157
+ response = Fission::Lease.find_by_mac_address('00:11:22:33:44:55')
158
+
159
+ response.should be_a_successful_response
160
+ response.data.should be_nil
161
+ end
162
+ end
163
+
164
+ it 'should return an unsuccessful response if there was an error getting all of the leases' do
165
+ @all_response_mock = mock('all_response')
166
+ @all_response_mock.stub_as_unsuccessful
167
+
168
+ Fission::Lease.stub(:all).and_return(@all_response_mock)
169
+
170
+ response = Fission::Lease.find_by_mac_address('00:11:22:33:44:55')
171
+
172
+ response.should be_an_unsuccessful_response
173
+ end
174
+ end
175
+
176
+ end
@@ -3,7 +3,7 @@ require File.expand_path('../../spec_helper.rb', __FILE__)
3
3
  describe Fission::Metadata do
4
4
  before do
5
5
  @plist_mock = mock('plist_mock')
6
- @plist_file_path = Fission.config.attributes['plist_file']
6
+ @plist_file_path = Fission.config['plist_file']
7
7
  @metadata = Fission::Metadata.new
8
8
  end
9
9
 
@@ -28,19 +28,19 @@ describe Fission::Metadata do
28
28
  end
29
29
 
30
30
  it 'should remove the vm item from the list if the vm path is in the list' do
31
- @metadata.delete_vm_restart_document(Fission::VM.path('foo'))
31
+ @metadata.delete_vm_restart_document(Fission::VM.new('foo').path)
32
32
  @metadata.content.should == { 'PLRestartDocumentPaths' => ['/vm/bar.vmwarevm']}
33
33
  end
34
34
 
35
35
  it 'should not doing anything if the vm is not in the list' do
36
- @metadata.delete_vm_restart_document(Fission::VM.path('baz'))
36
+ @metadata.delete_vm_restart_document(Fission::VM.new('baz').path)
37
37
  @metadata.content.should == @data
38
38
  end
39
39
 
40
40
  it 'should not do anything if the restart document list does not exist' do
41
41
  other_data = { 'OtherConfigItem' => ['foo', 'bar']}
42
42
  @metadata.content = other_data
43
- @metadata.delete_vm_restart_document(Fission::VM.path('foo'))
43
+ @metadata.delete_vm_restart_document(Fission::VM.new('foo').path)
44
44
  @metadata.content.should == other_data
45
45
  end
46
46
  end
@@ -52,12 +52,12 @@ describe Fission::Metadata do
52
52
  end
53
53
 
54
54
  it 'should remove the vm item from the list' do
55
- @metadata.delete_vm_favorite_entry(Fission::VM.path('foo'))
55
+ @metadata.delete_vm_favorite_entry(Fission::VM.new('foo').path)
56
56
  @metadata.content.should == { 'VMFavoritesListDefaults2' => [] }
57
57
  end
58
58
 
59
59
  it 'should not do anything if the vm is not in the list' do
60
- @metadata.delete_vm_favorite_entry(Fission::VM.path('bar'))
60
+ @metadata.delete_vm_favorite_entry(Fission::VM.new('bar').path)
61
61
  @metadata.content.should == @data
62
62
  end
63
63
  end
@@ -73,13 +73,13 @@ describe Fission::Metadata do
73
73
  it 'should remove the vm from the restart document list' do
74
74
  @md_mock.should_receive(:delete_vm_restart_document).with('/vm/foo.vmwarevm')
75
75
  @md_mock.stub!(:delete_vm_favorite_entry)
76
- Fission::Metadata.delete_vm_info(Fission::VM.path('foo'))
76
+ Fission::Metadata.delete_vm_info(Fission::VM.new('foo').path)
77
77
  end
78
78
 
79
79
  it 'should remove the vm from the favorite list' do
80
80
  @md_mock.should_receive(:delete_vm_favorite_entry).with('/vm/foo.vmwarevm')
81
81
  @md_mock.stub!(:delete_vm_restart_document)
82
- Fission::Metadata.delete_vm_info(Fission::VM.path('foo'))
82
+ Fission::Metadata.delete_vm_info(Fission::VM.new('foo').path)
83
83
  end
84
84
  end
85
85