virtualbox 0.5.4 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. data/.gitignore +2 -1
  2. data/Gemfile +1 -1
  3. data/Rakefile +1 -1
  4. data/Readme.md +5 -21
  5. data/VERSION +1 -1
  6. data/docs/WhatsNew.md +9 -47
  7. data/lib/virtualbox.rb +7 -30
  8. data/lib/virtualbox/abstract_model.rb +25 -5
  9. data/lib/virtualbox/abstract_model/attributable.rb +5 -1
  10. data/lib/virtualbox/abstract_model/dirty.rb +2 -0
  11. data/lib/virtualbox/abstract_model/interface_attributes.rb +96 -0
  12. data/lib/virtualbox/abstract_model/relatable.rb +19 -8
  13. data/lib/virtualbox/appliance.rb +59 -0
  14. data/lib/virtualbox/audio_adapter.rb +44 -0
  15. data/lib/virtualbox/bios.rb +44 -0
  16. data/lib/virtualbox/com.rb +23 -0
  17. data/lib/virtualbox/com/abstract_enum.rb +42 -0
  18. data/lib/virtualbox/com/abstract_implementer.rb +43 -0
  19. data/lib/virtualbox/com/abstract_interface.rb +165 -0
  20. data/lib/virtualbox/com/ffi/interface.rb +141 -0
  21. data/lib/virtualbox/com/ffi/interfaces.rb +42 -0
  22. data/lib/virtualbox/com/ffi/util.rb +101 -0
  23. data/lib/virtualbox/com/ffi/vboxxpcomc.rb +31 -0
  24. data/lib/virtualbox/com/ffi_interface.rb +65 -0
  25. data/lib/virtualbox/com/implementer/base.rb +52 -0
  26. data/lib/virtualbox/com/implementer/ffi.rb +350 -0
  27. data/lib/virtualbox/com/implementer/mscom.rb +165 -0
  28. data/lib/virtualbox/com/implementer/nil.rb +10 -0
  29. data/lib/virtualbox/com/interface/appliance.rb +20 -0
  30. data/lib/virtualbox/com/interface/audio_adapter.rb +13 -0
  31. data/lib/virtualbox/com/interface/audio_controller_type.rb +9 -0
  32. data/lib/virtualbox/com/interface/audio_driver_type.rb +9 -0
  33. data/lib/virtualbox/com/interface/bios_boot_menu_mode.rb +9 -0
  34. data/lib/virtualbox/com/interface/bios_settings.rb +19 -0
  35. data/lib/virtualbox/com/interface/clipboard_mode.rb +9 -0
  36. data/lib/virtualbox/com/interface/console.rb +48 -0
  37. data/lib/virtualbox/com/interface/cpu_property_type.rb +9 -0
  38. data/lib/virtualbox/com/interface/device_type.rb +9 -0
  39. data/lib/virtualbox/com/interface/dhcp_server.rb +20 -0
  40. data/lib/virtualbox/com/interface/firmware_type.rb +9 -0
  41. data/lib/virtualbox/com/interface/guest_os_type.rb +21 -0
  42. data/lib/virtualbox/com/interface/host.rb +40 -0
  43. data/lib/virtualbox/com/interface/host_network_interface.rb +28 -0
  44. data/lib/virtualbox/com/interface/host_network_interface_medium_type.rb +9 -0
  45. data/lib/virtualbox/com/interface/host_network_interface_status.rb +9 -0
  46. data/lib/virtualbox/com/interface/host_network_interface_type.rb +9 -0
  47. data/lib/virtualbox/com/interface/host_usb_device.rb +11 -0
  48. data/lib/virtualbox/com/interface/host_usb_device_filter.rb +11 -0
  49. data/lib/virtualbox/com/interface/hw_virt_ex_property_type.rb +9 -0
  50. data/lib/virtualbox/com/interface/machine.rb +103 -0
  51. data/lib/virtualbox/com/interface/machine_state.rb +12 -0
  52. data/lib/virtualbox/com/interface/medium.rb +48 -0
  53. data/lib/virtualbox/com/interface/medium_attachment.rb +16 -0
  54. data/lib/virtualbox/com/interface/medium_format.rb +16 -0
  55. data/lib/virtualbox/com/interface/medium_state.rb +9 -0
  56. data/lib/virtualbox/com/interface/medium_type.rb +9 -0
  57. data/lib/virtualbox/com/interface/medium_variant.rb +9 -0
  58. data/lib/virtualbox/com/interface/network_adapter.rb +28 -0
  59. data/lib/virtualbox/com/interface/network_adapter_type.rb +9 -0
  60. data/lib/virtualbox/com/interface/network_attachment_type.rb +9 -0
  61. data/lib/virtualbox/com/interface/nsiexception.rb +21 -0
  62. data/lib/virtualbox/com/interface/nsisupports.rb +13 -0
  63. data/lib/virtualbox/com/interface/parallel_port.rb +15 -0
  64. data/lib/virtualbox/com/interface/port_mode.rb +9 -0
  65. data/lib/virtualbox/com/interface/progress.rb +58 -0
  66. data/lib/virtualbox/com/interface/serial_port.rb +17 -0
  67. data/lib/virtualbox/com/interface/session.rb +16 -0
  68. data/lib/virtualbox/com/interface/session_state.rb +9 -0
  69. data/lib/virtualbox/com/interface/session_type.rb +9 -0
  70. data/lib/virtualbox/com/interface/shared_folder.rb +15 -0
  71. data/lib/virtualbox/com/interface/snapshot.rb +18 -0
  72. data/lib/virtualbox/com/interface/storage_bus.rb +9 -0
  73. data/lib/virtualbox/com/interface/storage_controller.rb +21 -0
  74. data/lib/virtualbox/com/interface/storage_controller_type.rb +9 -0
  75. data/lib/virtualbox/com/interface/system_properties.rb +35 -0
  76. data/lib/virtualbox/com/interface/usb_controller.rb +18 -0
  77. data/lib/virtualbox/com/interface/usb_device.rb +22 -0
  78. data/lib/virtualbox/com/interface/usb_device_filter.rb +21 -0
  79. data/lib/virtualbox/com/interface/usb_device_filter_action.rb +9 -0
  80. data/lib/virtualbox/com/interface/usb_device_state.rb +9 -0
  81. data/lib/virtualbox/com/interface/virtual_box_error_info.rb +15 -0
  82. data/lib/virtualbox/com/interface/virtual_system_description.rb +17 -0
  83. data/lib/virtualbox/com/interface/virtual_system_description_type.rb +12 -0
  84. data/lib/virtualbox/com/interface/virtual_system_description_value_type.rb +9 -0
  85. data/lib/virtualbox/com/interface/virtualbox.rb +54 -0
  86. data/lib/virtualbox/com/interface/vrdp_auth_type.rb +9 -0
  87. data/lib/virtualbox/com/interface/vrdp_server.rb +17 -0
  88. data/lib/virtualbox/com/mscom_interface.rb +22 -0
  89. data/lib/virtualbox/com/util.rb +18 -0
  90. data/lib/virtualbox/dvd.rb +7 -94
  91. data/lib/virtualbox/exceptions.rb +24 -0
  92. data/lib/virtualbox/ext/glob_loader.rb +22 -0
  93. data/lib/virtualbox/ext/logger.rb +38 -0
  94. data/lib/virtualbox/ext/platform.rb +1 -1
  95. data/lib/virtualbox/extra_data.rb +25 -37
  96. data/lib/virtualbox/forwarded_port.rb +35 -13
  97. data/lib/virtualbox/global.rb +22 -80
  98. data/lib/virtualbox/hard_drive.rb +30 -97
  99. data/lib/virtualbox/lib.rb +82 -0
  100. data/lib/virtualbox/media.rb +7 -6
  101. data/lib/virtualbox/medium.rb +138 -0
  102. data/lib/virtualbox/medium_attachment.rb +61 -0
  103. data/lib/virtualbox/network_adapter.rb +134 -0
  104. data/lib/virtualbox/shared_folder.rb +53 -78
  105. data/lib/virtualbox/storage_controller.rb +76 -20
  106. data/lib/virtualbox/system_properties.rb +74 -0
  107. data/lib/virtualbox/usb_controller.rb +55 -0
  108. data/lib/virtualbox/version.rb +15 -0
  109. data/lib/virtualbox/virtual_system_description.rb +47 -0
  110. data/lib/virtualbox/vm.rb +160 -272
  111. data/test/test_helper.rb +0 -108
  112. data/test/virtualbox/abstract_model/attributable_test.rb +7 -1
  113. data/test/virtualbox/abstract_model/dirty_test.rb +1 -1
  114. data/test/virtualbox/abstract_model/interface_attributes_test.rb +169 -0
  115. data/test/virtualbox/abstract_model/relatable_test.rb +20 -0
  116. data/test/virtualbox/abstract_model_test.rb +40 -5
  117. data/test/virtualbox/appliance_test.rb +152 -0
  118. data/test/virtualbox/audio_adapter_test.rb +83 -0
  119. data/test/virtualbox/bios_test.rb +83 -0
  120. data/test/virtualbox/com/abstract_enum_test.rb +48 -0
  121. data/test/virtualbox/com/abstract_implementer_test.rb +39 -0
  122. data/test/virtualbox/com/abstract_interface_test.rb +139 -0
  123. data/test/virtualbox/com/ffi/interface_test.rb +249 -0
  124. data/test/virtualbox/com/ffi/util_test.rb +86 -0
  125. data/test/virtualbox/com/ffi_interface_test.rb +42 -0
  126. data/test/virtualbox/com/implementer/base_test.rb +37 -0
  127. data/test/virtualbox/com/implementer/ffi_test.rb +519 -0
  128. data/test/virtualbox/com/implementer/mscom_test.rb +208 -0
  129. data/test/virtualbox/com/mscom_interface_test.rb +17 -0
  130. data/test/virtualbox/com/util_test.rb +17 -0
  131. data/test/virtualbox/dvd_test.rb +4 -95
  132. data/test/virtualbox/ext/platform_test.rb +8 -0
  133. data/test/virtualbox/extra_data_test.rb +78 -102
  134. data/test/virtualbox/forwarded_port_test.rb +57 -7
  135. data/test/virtualbox/global_test.rb +25 -115
  136. data/test/virtualbox/hard_drive_test.rb +49 -212
  137. data/test/virtualbox/lib_test.rb +93 -0
  138. data/test/virtualbox/medium_attachment_test.rb +147 -0
  139. data/test/virtualbox/medium_test.rb +192 -0
  140. data/test/virtualbox/network_adapter_test.rb +160 -0
  141. data/test/virtualbox/shared_folder_test.rb +144 -160
  142. data/test/virtualbox/storage_controller_test.rb +166 -45
  143. data/test/virtualbox/system_properties_test.rb +87 -0
  144. data/test/virtualbox/usb_controller_test.rb +104 -0
  145. data/test/virtualbox/version_test.rb +34 -0
  146. data/test/virtualbox/virtual_system_description_test.rb +61 -0
  147. data/test/virtualbox/vm_test.rb +288 -322
  148. data/test/virtualbox_test.rb +1 -9
  149. data/virtualbox.gemspec +139 -23
  150. metadata +143 -27
  151. data/lib/virtualbox/attached_device.rb +0 -249
  152. data/lib/virtualbox/command.rb +0 -109
  153. data/lib/virtualbox/image.rb +0 -137
  154. data/lib/virtualbox/nic.rb +0 -111
  155. data/lib/virtualbox/system_property.rb +0 -55
  156. data/lib/virtualbox/usb.rb +0 -72
  157. data/test/virtualbox/attached_device_test.rb +0 -303
  158. data/test/virtualbox/command_test.rb +0 -152
  159. data/test/virtualbox/image_test.rb +0 -190
  160. data/test/virtualbox/nic_test.rb +0 -76
  161. data/test/virtualbox/system_property_test.rb +0 -71
  162. data/test/virtualbox/usb_test.rb +0 -35
@@ -0,0 +1,87 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class SystemPropertiesTest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::SystemProperties
6
+ @interface = mock("interface")
7
+ end
8
+
9
+ context "initializing" do
10
+ should "load attributes from the machine" do
11
+ @klass.any_instance.expects(:initialize_attributes).with(@interface).once
12
+ @klass.new(@interface)
13
+ end
14
+ end
15
+
16
+ context "initializing attributes" do
17
+ setup do
18
+ @klass.any_instance.stubs(:load_interface_attributes)
19
+ end
20
+
21
+ should "load interface attribtues" do
22
+ @klass.any_instance.expects(:load_interface_attributes).with(@interface).once
23
+ @klass.new(@interface)
24
+ end
25
+
26
+ should "setup the interface" do
27
+ instance = @klass.new(@interface)
28
+ assert_equal @interface, instance.interface
29
+ end
30
+
31
+ should "not be dirty" do
32
+ @instance = @klass.new(@interface)
33
+ assert !@instance.changed?
34
+ end
35
+
36
+ should "be existing record" do
37
+ @instance = @klass.new(@interface)
38
+ assert !@instance.new_record?
39
+ end
40
+ end
41
+
42
+ context "class methods" do
43
+ context "populating relationship" do
44
+ setup do
45
+ @instance = mock("instance")
46
+
47
+ @klass.stubs(:new).returns(@instance)
48
+ end
49
+
50
+ should "return a SystemProperties instance" do
51
+ result = @klass.populate_relationship(nil, @interface)
52
+ assert_equal @instance, result
53
+ end
54
+
55
+ should "call new for every shared folder" do
56
+ @klass.expects(:new).with(@interface).returns(@instance)
57
+ result = @klass.populate_relationship(nil, @interface)
58
+ assert_equal @instance, result
59
+ end
60
+ end
61
+
62
+ context "saving relationship" do
63
+ setup do
64
+ @item = mock("item")
65
+ end
66
+
67
+ should "just call save on the item" do
68
+ @item.expects(:save)
69
+ @klass.save_relationship(nil, @item)
70
+ end
71
+ end
72
+ end
73
+
74
+ context "instance methods" do
75
+ setup do
76
+ @klass.any_instance.stubs(:load_interface_attributes)
77
+ @instance = @klass.new(@interface)
78
+ end
79
+
80
+ context "saving" do
81
+ should "save changed interface attributes" do
82
+ @instance.expects(:save_changed_interface_attributes).with(@interface)
83
+ @instance.save
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,104 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class USBControllerTest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::USBController
6
+ @interface = mock("interface")
7
+ end
8
+
9
+ context "initializing" do
10
+ should "load attributes from the machine" do
11
+ @klass.any_instance.expects(:initialize_attributes).with(@parent, @interface).once
12
+ @klass.new(@parent, @interface)
13
+ end
14
+ end
15
+
16
+ context "initializing attributes" do
17
+ setup do
18
+ @klass.any_instance.stubs(:load_interface_attributes)
19
+ end
20
+
21
+ should "load interface attribtues" do
22
+ @klass.any_instance.expects(:load_interface_attributes).with(@interface).once
23
+ @klass.new(@parent, @interface)
24
+ end
25
+
26
+ should "setup the parent" do
27
+ instance = @klass.new(@parent, @interface)
28
+ assert_equal @parent, instance.parent
29
+ end
30
+
31
+ should "setup the interface" do
32
+ instance = @klass.new(@parent, @interface)
33
+ assert_equal @interface, instance.interface
34
+ end
35
+
36
+ should "not be dirty" do
37
+ @instance = @klass.new(@parent, @interface)
38
+ assert !@instance.changed?
39
+ end
40
+
41
+ should "be existing record" do
42
+ @instance = @klass.new(@parent, @interface)
43
+ assert !@instance.new_record?
44
+ end
45
+ end
46
+
47
+ context "class methods" do
48
+ context "populating relationship" do
49
+ setup do
50
+ @instance = mock("instance")
51
+
52
+ @klass.stubs(:new).returns(@instance)
53
+
54
+ @controller_interface = mock("controller_interface")
55
+ @interface.stubs(:usb_controller).returns(@controller_interface)
56
+ end
57
+
58
+ should "return a USBController instance" do
59
+ result = @klass.populate_relationship(nil, @interface)
60
+ assert_equal @instance, result
61
+ end
62
+
63
+ should "call new with the interface" do
64
+ @klass.expects(:new).with(@parent, @controller_interface).returns(@instance)
65
+ result = @klass.populate_relationship(nil, @interface)
66
+ assert_equal @instance, result
67
+ end
68
+ end
69
+
70
+ context "saving relationship" do
71
+ setup do
72
+ @item = mock("item")
73
+ end
74
+
75
+ should "just call save on the item" do
76
+ @item.expects(:save)
77
+ @klass.save_relationship(nil, @item)
78
+ end
79
+ end
80
+ end
81
+
82
+ context "instance methods" do
83
+ setup do
84
+ @klass.any_instance.stubs(:load_interface_attributes)
85
+ @instance = @klass.new(@parent, @interface)
86
+ end
87
+
88
+ context "saving" do
89
+ setup do
90
+ @session = mock("session")
91
+ @machine = mock("machine")
92
+ @usb_controller = mock("usb_controller")
93
+ @session.stubs(:machine).returns(@machine)
94
+ @machine.stubs(:usb_controller).returns(@usb_controller)
95
+ @parent.stubs(:with_open_session).yields(@session)
96
+ end
97
+
98
+ should "save on the locked interface" do
99
+ @instance.expects(:save_changed_interface_attributes).with(@usb_controller).once
100
+ @instance.save
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,34 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class VersionTest < Test::Unit::TestCase
4
+ module VersionTestMod
5
+ extend VirtualBox::Version
6
+ end
7
+
8
+ setup do
9
+ @lib = mock("lib")
10
+ @vbox = mock("vbox")
11
+
12
+ VirtualBox::Lib.stubs(:lib).returns(@lib)
13
+ @lib.stubs(:virtualbox).returns(@vbox)
14
+
15
+ @module = VersionTestMod
16
+ end
17
+
18
+ should "return the version" do
19
+ version = mock("version")
20
+ @vbox.expects(:version).returns(version)
21
+ assert_equal version, @module.version
22
+ end
23
+
24
+ should "return nil if an error occurs" do
25
+ @vbox.expects(:version).raises(LoadError)
26
+ assert @module.version.nil?
27
+ end
28
+
29
+ should "return the revision" do
30
+ revision = mock("revision")
31
+ @vbox.expects(:revision).returns(revision)
32
+ assert_equal revision, @module.revision
33
+ end
34
+ end
@@ -0,0 +1,61 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class VirtualSystemDescriptionTest < Test::Unit::TestCase
4
+ setup do
5
+ @klass = VirtualBox::VirtualSystemDescription
6
+ @interface = mock("interface")
7
+ end
8
+
9
+ context "class methods" do
10
+ context "populating relationship" do
11
+ setup do
12
+ @instance = mock("instance")
13
+
14
+ @klass.stubs(:new).returns(@instance)
15
+ end
16
+
17
+ should "return a proxied collection" do
18
+ result = @klass.populate_relationship(nil, [])
19
+ assert result.is_a?(VirtualBox::Proxies::Collection)
20
+ end
21
+
22
+ should "call new for every description" do
23
+ interfaces = []
24
+ 5.times { |i| interfaces << mock("i#{i}") }
25
+
26
+ expected_result = []
27
+ new_seq = sequence("new_seq")
28
+ interfaces.each do |interface|
29
+ expected_value = "instance-#{interface.inspect}"
30
+ @klass.expects(:new).with(interface).in_sequence(new_seq).returns(expected_value)
31
+ expected_result << expected_value
32
+ end
33
+
34
+ assert_equal expected_result, @klass.populate_relationship(nil, interfaces)
35
+ end
36
+ end
37
+ end
38
+
39
+ context "initializing" do
40
+ should "load attributes from the machine" do
41
+ @klass.any_instance.expects(:initialize_attributes).with(@interface).once
42
+ @klass.new(@interface)
43
+ end
44
+ end
45
+
46
+ context "initializing attributes" do
47
+ setup do
48
+ @interface.stubs(:get_values_by_type).returns(nil)
49
+ end
50
+
51
+ should "not be dirty" do
52
+ @instance = @klass.new(@interface)
53
+ assert !@instance.changed?
54
+ end
55
+
56
+ should "be existing record" do
57
+ @instance = @klass.new(@interface)
58
+ assert !@instance.new_record?
59
+ end
60
+ end
61
+ end
@@ -2,421 +2,387 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
2
 
3
3
  class VMTest < Test::Unit::TestCase
4
4
  setup do
5
- @raw_xml = mock_xml
6
- @raw_xml_doc = mock_xml_doc
7
-
8
- @name = "foo"
9
-
10
- # Just to be sure nothing is executed
11
- VirtualBox::Command.stubs(:execute).returns('')
12
- end
13
-
14
- def create_vm
15
- VirtualBox::Command.expects(:parse_xml).returns(@raw_xml_doc)
16
- vm = VirtualBox::VM.load_from_xml(@name)
17
- assert vm
18
- vm
5
+ @klass = VirtualBox::VM
6
+ @interface = mock("interface")
19
7
  end
20
8
 
21
- context "reading the VM state" do
22
- setup do
23
- @vm = create_vm
24
- end
25
-
26
- should "lazy load the state" do
27
- @vm.expects(:load_attribute).with(:state).once
28
- @vm.state
29
- end
30
-
31
- should "reload the state if true is passed as a parameter" do
32
- VirtualBox::VM.expects(:raw_info).returns({ :vmstate => "on" })
33
- assert_equal "on", @vm.state(true)
34
- assert_equal "on", @vm.state
35
- end
36
-
37
- should "never have state as dirty" do
38
- VirtualBox::VM.expects(:raw_info).returns({ :vmstate => "on" })
39
- @vm.expects(:clear_dirty!).with(:state).once
40
- @vm.state(true)
9
+ context "class methods" do
10
+ context "retrieving all machines" do
11
+ should "return an array of VM objects" do
12
+ vms = mock("vms")
13
+ global = mock("global")
14
+ global.expects(:vms).returns(vms)
15
+ VirtualBox::Global.expects(:global).returns(global)
16
+ assert_equal vms, VirtualBox::VM.all
17
+ end
41
18
  end
42
19
 
43
- should "provide conveniance methods for determining VM state" do
44
- VirtualBox::VM.expects(:raw_info).returns({ :vmstate => "poweroff" })
45
- assert_equal "poweroff", @vm.state(true)
46
- assert @vm.powered_off?
47
-
48
- VirtualBox::VM.expects(:raw_info).returns({ :vmstate => "running" })
49
- assert_equal "running", @vm.state(true)
50
- assert @vm.running?
51
-
52
- VirtualBox::VM.expects(:raw_info).returns({ :vmstate => "paused" })
53
- assert_equal "paused", @vm.state(true)
54
- assert @vm.paused?
55
-
56
- VirtualBox::VM.expects(:raw_info).returns({ :vmstate => "saved" })
57
- assert_equal "saved", @vm.state(true)
58
- assert @vm.saved?
59
-
60
- VirtualBox::VM.expects(:raw_info).returns({ :vmstate => "aborted" })
61
- assert_equal "aborted", @vm.state(true)
62
- assert @vm.aborted?
63
- end
64
- end
20
+ context "finding a VM" do
21
+ setup do
22
+ @all = []
23
+ @klass.stubs(:all).returns(@all)
24
+ end
65
25
 
66
- context "exporting a VM" do
67
- setup do
68
- @vm = create_vm
69
- end
26
+ def mock_vm(uuid, name=nil)
27
+ vm = mock("vm-#{uuid}")
28
+ vm.stubs(:uuid).returns(uuid)
29
+ vm.stubs(:name).returns(name)
30
+ vm
31
+ end
70
32
 
71
- should "export the VM with no options if none are passed" do
72
- VirtualBox::Command.expects(:vboxmanage).with("export", @name, "-o", "foo")
73
- @vm.export("foo")
74
- end
33
+ should "return nil if it doesn't exist" do
34
+ @all << mock_vm("foo")
35
+ assert_nil @klass.find("bar")
36
+ end
75
37
 
76
- should "export the VM with specified options" do
77
- VirtualBox::Command.expects(:vboxmanage).with("export", @name, "-o", "foo", "--vsys", "0", "--foo", :bar)
78
- @vm.export("foo", :foo => :bar)
79
- end
38
+ should "return the matching vm if it is found" do
39
+ vm = mock_vm("foo")
40
+ @all << mock_vm("bar")
41
+ @all << vm
42
+ assert_equal vm, @klass.find("foo")
43
+ end
80
44
 
81
- should "shell escape all the options" do
82
- VirtualBox::Command.expects(:vboxmanage).with("export", @name, "-o", "foo", "--vsys", "0", "--foo", "a space")
83
- @vm.export("foo", :foo => "a space")
45
+ should "return if matching name is found" do
46
+ vm = mock_vm(nil, "foo")
47
+ @all << vm
48
+ assert_equal vm, @klass.find("foo")
49
+ end
84
50
  end
85
51
 
86
- should "return true if the export succeeded" do
87
- VirtualBox::Command.expects(:vboxmanage).once
88
- assert @vm.export("foo")
89
- end
52
+ context "importing" do
53
+ setup do
54
+ @path = "foo.rb"
55
+ @appliance = mock("appliance")
56
+ @virtual_system = mock("virtual_system")
57
+ @appliance.stubs(:virtual_systems).returns([@virtual_system])
58
+
59
+ @name = :foo
60
+ @virtual_system.stubs(:descriptions).returns({
61
+ :name => { :auto => @name }
62
+ })
63
+ end
90
64
 
91
- should "return false if the export failed" do
92
- VirtualBox::Command.stubs(:vboxmanage).raises(VirtualBox::Exceptions::CommandFailedException)
93
- assert !@vm.export("foo")
94
- end
65
+ should "create a new appliance with path, import, and return VM" do
66
+ result = mock("result")
67
+ proc = mock("proc")
68
+ VirtualBox::Appliance.expects(:new).with(@path).returns(@appliance)
69
+ @appliance.expects(:import).yields(proc)
70
+ @klass.expects(:find).with(@name).returns(result)
71
+ proc.expects(:call)
95
72
 
96
- should "raise an exception on failure if raise_error is true" do
97
- VirtualBox::Command.stubs(:vboxmanage).raises(VirtualBox::Exceptions::CommandFailedException)
98
- assert_raises(VirtualBox::Exceptions::CommandFailedException) {
99
- @vm.export("foo", {}, true)
100
- }
101
- end
102
- end
73
+ value = @klass.import(@path) do |proc|
74
+ proc.call
75
+ end
103
76
 
104
- context "controlling a VM (start, stop, pause, etc.)" do
105
- setup do
106
- @vm = create_vm
77
+ assert_equal result, value
78
+ end
107
79
  end
108
80
 
109
- context "control method" do
110
- should "run the given command when 'control' is called" do
111
- VirtualBox::Command.expects(:vboxmanage).with("controlvm", @name, :foo)
112
- assert @vm.control(:foo)
113
- end
81
+ context "populating relationship" do
82
+ setup do
83
+ @instance = mock("instance")
114
84
 
115
- should "return false if the command failed" do
116
- VirtualBox::Command.stubs(:vboxmanage).raises(VirtualBox::Exceptions::CommandFailedException)
117
- assert !@vm.control(:foo)
85
+ @klass.stubs(:new).returns(@instance)
118
86
  end
119
87
 
120
- should "raise an exception if flag is set" do
121
- VirtualBox::Command.stubs(:vboxmanage).raises(VirtualBox::Exceptions::CommandFailedException)
122
- assert_raises(VirtualBox::Exceptions::CommandFailedException) {
123
- @vm.control(:foo, true)
124
- }
88
+ should "return a proxied collection" do
89
+ result = @klass.populate_relationship(nil, [])
90
+ assert result.is_a?(VirtualBox::Proxies::Collection)
125
91
  end
126
- end
127
-
128
- should "start a VM with the given type" do
129
- VirtualBox::Command.expects(:vboxmanage).with("startvm", @name, "--type", :FOO)
130
- assert @vm.start(:FOO)
131
- end
132
-
133
- should "return false if start failed" do
134
- VirtualBox::Command.stubs(:vboxmanage).raises(VirtualBox::Exceptions::CommandFailedException)
135
- assert !@vm.start
136
- end
137
92
 
138
- should "raise an exception if start fails and flag is set" do
139
- VirtualBox::Command.stubs(:vboxmanage).raises(VirtualBox::Exceptions::CommandFailedException)
140
- assert_raises(VirtualBox::Exceptions::CommandFailedException) {
141
- @vm.start(:foo, true)
142
- }
143
- end
93
+ should "call new for every machine" do
94
+ machines = []
95
+ 5.times { |i| machines << mock("m#{i}") }
144
96
 
145
- should "stop a VM with a 'acpipowerbutton'" do
146
- @vm.expects(:control).with(:acpipowerbutton, false).returns(true)
147
- assert @vm.shutdown
148
- end
97
+ expected_result = []
98
+ new_seq = sequence("new_seq")
99
+ machines.each do |machine|
100
+ expected_value = "instance-#{machine.inspect}"
101
+ @klass.expects(:new).with(machine).in_sequence(new_seq).returns(expected_value)
102
+ expected_result << expected_value
103
+ end
149
104
 
150
- should "stop a VM with a 'poweroff'" do
151
- @vm.expects(:control).with(:poweroff, false).returns(true)
152
- assert @vm.stop
105
+ assert_equal expected_result, @klass.populate_relationship(nil, machines)
106
+ end
153
107
  end
108
+ end
154
109
 
155
- should "pause a VM" do
156
- @vm.expects(:control).with(:pause, false).returns(true)
157
- assert @vm.pause
110
+ context "initializing" do
111
+ should "load attributes from the machine" do
112
+ @klass.any_instance.expects(:initialize_attributes).with(@interface).once
113
+ @klass.new(@interface)
158
114
  end
115
+ end
159
116
 
160
- should "resume a VM" do
161
- @vm.expects(:control).with(:resume, false).returns(true)
162
- assert @vm.resume
117
+ context "initializing attributes" do
118
+ setup do
119
+ @klass.any_instance.stubs(:load_interface_attributes)
120
+ @klass.any_instance.stubs(:populate_relationships)
163
121
  end
164
122
 
165
- should "save the state of a VM" do
166
- @vm.expects(:control).with(:savestate, false).returns(true)
167
- assert @vm.save_state
123
+ should "load interface attribtues" do
124
+ @klass.any_instance.expects(:load_interface_attributes).with(@interface).once
125
+ @klass.new(@interface)
168
126
  end
169
127
 
170
- should "discard a saved state of a VM" do
171
- VirtualBox::Command.expects(:vboxmanage).with("discardstate", @name)
172
- assert @vm.discard_state
128
+ should "populate relationships" do
129
+ @klass.any_instance.expects(:populate_relationships).with(@interface).once
130
+ @klass.new(@interface)
173
131
  end
174
132
 
175
- should "return false if discarding state failed" do
176
- VirtualBox::Command.stubs(:vboxmanage).raises(VirtualBox::Exceptions::CommandFailedException)
177
- assert !@vm.discard_state
133
+ should "not be dirty" do
134
+ @instance = @klass.new(@interface)
135
+ assert !@instance.changed?
178
136
  end
179
137
 
180
- should "raise an exception if discarding state fails and flag is set" do
181
- VirtualBox::Command.stubs(:vboxmanage).raises(VirtualBox::Exceptions::CommandFailedException)
182
- assert_raises(VirtualBox::Exceptions::CommandFailedException) {
183
- @vm.discard_state(true)
184
- }
138
+ should "be existing record" do
139
+ @instance = @klass.new(@interface)
140
+ assert !@instance.new_record?
185
141
  end
186
142
  end
187
143
 
188
- context "destroying" do
144
+ context "instance methods" do
189
145
  setup do
190
- @vm = create_vm
146
+ @klass.any_instance.stubs(:initialize_attributes)
147
+ @instance = @klass.new(@interface)
191
148
  end
192
149
 
193
- should "destroy all storage controllers before destroying VM" do
194
- destroy_seq = sequence("destroy_seq")
195
- VirtualBox::StorageController.expects(:destroy_relationship).in_sequence(destroy_seq)
196
- VirtualBox::Command.expects(:vboxmanage).with("unregistervm", @name, "--delete").in_sequence(destroy_seq)
197
- @vm.destroy
198
- end
150
+ def setup_session_mocks
151
+ @parent = mock("parent")
152
+ @session = mock("session")
153
+ @lib = mock("lib")
154
+ @progress = mock("progress")
199
155
 
200
- should "mark global for reloading" do
201
- VirtualBox::Global.expects(:reload!)
202
- @vm.destroy
156
+ @session.stubs(:close)
157
+ @progress.stubs(:wait_for_completion)
158
+ @lib.stubs(:session).returns(@session)
159
+ @uuid = :foo
160
+
161
+ VirtualBox::Lib.stubs(:lib).returns(@lib)
162
+ @interface.stubs(:parent).returns(@parent)
163
+ @instance.stubs(:imachine).returns(@interface)
164
+ @instance.stubs(:uuid).returns(@uuid)
165
+ @instance.stubs(:running).returns(false)
203
166
  end
204
- end
205
167
 
206
- context "finding all VMs" do
207
- setup do
208
- VirtualBox::VM.reloaded!
168
+ context "destroying" do
169
+ setup do
170
+ @instance.stubs(:uuid).returns(:foo)
209
171
 
210
- @global = mock("global")
211
- @global.stubs(:vms)
212
- end
172
+ @interface_parent = mock("interface_parent")
173
+ @interface.stubs(:parent).returns(@interface_parent)
174
+ end
213
175
 
214
- should "list VMs then parse them" do
215
- VirtualBox::Global.expects(:global).with(false).returns(@global)
216
- VirtualBox::VM.all
217
- end
176
+ should "destroy relationships first, then the machine" do
177
+ destroy_seq = sequence("destroy_seq")
178
+ VirtualBox::StorageController.expects(:destroy_relationship).in_sequence(destroy_seq)
179
+ @interface_parent.expects(:unregister_machine).with(@instance.uuid).in_sequence(destroy_seq)
180
+ @interface.expects(:delete_settings).once.in_sequence(destroy_seq)
218
181
 
219
- should "reload the VMs list if given the reload argument" do
220
- VirtualBox::Global.expects(:global).with(true).returns(@global)
221
- VirtualBox::VM.all(true)
182
+ @instance.destroy
183
+ end
222
184
  end
223
185
 
224
- context "parser" do
186
+ context "state" do
225
187
  setup do
226
- @raw = <<-raw
227
- "foo" {abcdefg}
228
- "bar" {zefaldf}
229
- raw
188
+ @state = mock("state")
189
+ @instance.stubs(:read_attribute).with(:state).returns(@state)
230
190
  end
231
191
 
232
- should "ignore non-matching lines" do
233
- assert VirtualBox::VM.parse_vm_list("HEY YOU").empty?
192
+ should "just return the state" do
193
+ assert_equal @state, @instance.state
234
194
  end
235
195
 
236
- should "return VM objects for valid lines" do
237
- vm_foo = mock("vm_foo")
238
- vm_bar = mock("vm_bar")
239
- parse_seq = sequence("parse")
240
- VirtualBox::VM.expects(:find).with("foo").returns(vm_foo).in_sequence(parse_seq)
241
- VirtualBox::VM.expects(:find).with("bar").returns(vm_bar).in_sequence(parse_seq)
242
-
243
- result = VirtualBox::VM.parse_vm_list(@raw)
244
- assert !result.empty?
245
- assert_equal 2, result.length
246
- assert_equal vm_foo, result[0]
247
- assert_equal vm_bar, result[1]
196
+ should "reload the state if reload is set" do
197
+ @instance.expects(:load_interface_attribute).with(:state).once
198
+ assert_equal @state, @instance.state(true)
248
199
  end
249
200
  end
250
- end
251
201
 
252
- context "importing a VM" do
253
- setup do
254
- @raw = <<-raw
255
- 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
256
- Interpreting /Users/mitchellh/base.ovf...
257
- OK.
258
- Disks: vmdisk1 21474836480 -1 http://www.vmware.com/specifications/vmdk.html#sparse HoboBase.vmdk 379268096 -1 <NULL>
259
- Virtual system 0:
260
- 0: Suggested OS type: "Ubuntu"
261
- (change with "--vsys 0 --ostype <type>"; use "list ostypes" to list all possible values)
262
- 1: Suggested VM name "Base_1"
263
- (change with "--vsys 0 --vmname <name>")
264
- 2: Number of CPUs: 1
265
- raw
266
- end
202
+ context "starting" do
203
+ setup do
204
+ setup_session_mocks
205
+ end
267
206
 
268
- should "attempt to find the imported VM" do
269
- VirtualBox::Command.expects(:vboxmanage).with("import", "whatever").returns(@raw)
270
- VirtualBox::VM.expects(:find).with("Base_1").once
271
- VirtualBox::VM.import("whatever")
272
- end
207
+ should "open remote session using the given mode, wait for completion, then close" do
208
+ start_seq = sequence('start_seq')
209
+ mode = "foo"
210
+ @parent.expects(:open_remote_session).with(@session, @uuid, mode, "").once.returns(@progress).in_sequence(start_seq)
211
+ @progress.expects(:wait_for_completion).with(-1).in_sequence(start_seq)
212
+ @session.expects(:close).in_sequence(start_seq)
213
+ assert @instance.start(mode)
214
+ end
273
215
 
274
- should "parse the VM name from the raw string" do
275
- assert_equal "Base_1", VirtualBox::VM.parse_vm_name(@raw)
216
+ should "return false if state is running" do
217
+ @instance.expects(:running?).returns(true)
218
+ assert !@instance.start(nil)
219
+ end
276
220
  end
277
221
 
278
- should "return nil on parsing the VM name if its invalid" do
279
- assert_nil VirtualBox::VM.parse_vm_name("Name foo")
280
- end
281
- end
222
+ context "controlling" do
223
+ setup do
224
+ setup_session_mocks
282
225
 
283
- context "saving a changed VM" do
284
- setup do
285
- @vm = create_vm
286
- VirtualBox::AttachedDevice.any_instance.stubs(:save)
287
- end
226
+ @parent.stubs(:open_existing_session)
288
227
 
289
- teardown do
290
- VirtualBox::Global.reloaded!
291
- end
228
+ @console = mock("console")
229
+ @console.stubs(:send)
230
+ @session.stubs(:console).returns(@console)
292
231
 
293
- should "force a reload on the global class" do
294
- VirtualBox::Global.expects(:reload!).once
295
- assert @vm.save
296
- end
232
+ @method = :foo
233
+ end
297
234
 
298
- should "return false if saving fails" do
299
- VirtualBox::Command.stubs(:vboxmanage).raises(VirtualBox::Exceptions::CommandFailedException)
235
+ should "get an existing, session, send the command, and close" do
236
+ method = :foo
237
+ control_seq = sequence("control_seq")
238
+ @parent.expects(:open_existing_session).with(@session, @uuid).once.in_sequence(control_seq)
239
+ @console.expects(:send).with(@method).once.in_sequence(control_seq)
240
+ @session.expects(:close).in_sequence(control_seq)
300
241
 
301
- @vm.ostype = "Zubuntu"
302
- assert !@vm.save
303
- end
242
+ @instance.control(@method)
243
+ end
304
244
 
305
- should "raise an error if saving fails and flag to true" do
306
- VirtualBox::Command.stubs(:vboxmanage).raises(VirtualBox::Exceptions::CommandFailedException)
245
+ should "wait for completion if an IProgress is returned" do
246
+ progress = mock("IProgress")
247
+ progress.stubs(:is_a?).with(VirtualBox::COM::Interface::Progress).returns(true)
248
+ progress.expects(:wait_for_completion).with(-1).once
249
+ @console.expects(:send).with(@method).returns(progress)
250
+ @instance.control(@method)
251
+ end
307
252
 
308
- @vm.ostype = "Zubuntu"
309
- assert_raises(VirtualBox::Exceptions::CommandFailedException) {
310
- @vm.save(true)
311
- }
253
+ should "forward other args" do
254
+ @console.expects(:send).with(@method, 1, 2, 3).once
255
+ @instance.control(@method, 1, 2, 3)
256
+ end
312
257
  end
313
258
 
314
- should "save only the attributes which saved" do
315
- VirtualBox::Command.expects(:vboxmanage).with("modifyvm", @name, "--ostype", "Zubuntu")
259
+ context "control helpers" do
260
+ should "call the proper control method" do
261
+ methods = {
262
+ :shutdown => :power_button,
263
+ :stop => :power_down,
264
+ :pause => :pause,
265
+ :resume => :resume,
266
+ :save_state => :save_state,
267
+ :discard_state => [:forget_saved_state, true]
268
+ }
316
269
 
317
- @vm.ostype = "Zubuntu"
318
- assert @vm.save
270
+ methods.each do |method, control|
271
+ control = [control] unless control.is_a?(Array)
272
+ @instance.expects(:control).with(*control).once
273
+ @instance.send(method)
274
+ end
275
+ end
319
276
  end
320
277
 
321
- should "do nothing if no attributes changed" do
322
- VirtualBox::Command.expects(:vboxmanage).never
323
- assert !@vm.changed?
324
- assert @vm.save
325
- end
278
+ context "saving" do
279
+ setup do
280
+ @session = mock("session")
281
+ @session.stubs(:machine).returns(@parent)
326
282
 
327
- should "save name first if changed, then following values should modify new VM" do
328
- new_name = "foo2"
329
- VirtualBox::Command.expects(:vboxmanage).with("modifyvm", @name, "--ostype", "Zubuntu", "--name", new_name)
283
+ @locked_interface = mock("locked_interface")
284
+ end
285
+
286
+ should "open the session, save, and close" do
287
+ save_seq = sequence("save_seq")
288
+ @instance.expects(:with_open_session).once.yields(@session).in_sequence(save_seq)
289
+ @session.expects(:machine).returns(@locked_interface).in_sequence(save_seq)
290
+ @instance.expects(:save_changed_interface_attributes).with(@locked_interface).in_sequence(save_seq)
291
+ @instance.expects(:save_relationships).in_sequence(save_seq)
330
292
 
331
- @vm.name = new_name
332
- @vm.ostype = "Zubuntu"
333
- assert @vm.save
293
+ @instance.save
294
+ end
334
295
  end
335
296
 
336
- should "save the new name as the original name after saving" do
337
- new_name = "foo2"
338
- assert_equal @name, @vm.instance_variable_get(:@original_name)
297
+ context "opening a session [direct]" do
298
+ setup do
299
+ setup_session_mocks
339
300
 
340
- @vm.name = new_name
341
- assert @vm.save
342
- assert_equal new_name, @vm.instance_variable_get(:@original_name)
343
- end
301
+ @locked_interface = mock("locked_interface")
302
+ @session.stubs(:machine).returns(@locked_interface)
303
+ @session.stubs(:state).returns(:closed)
304
+ end
344
305
 
345
- should "save the relationships as well" do
346
- VirtualBox::Nic.expects(:save_relationship).once
347
- VirtualBox::StorageController.expects(:save_relationship).once
348
- VirtualBox::SharedFolder.expects(:save_relationship).once
349
- VirtualBox::ExtraData.expects(:save_relationship).once
350
- VirtualBox::ForwardedPort.expects(:save_relationship).once
351
- assert @vm.save
352
- end
353
- end
306
+ should "open the session, save, and close" do
307
+ save_seq = sequence("save_seq")
308
+ @proc = Proc.new {}
354
309
 
355
- context "loading a VM from XML" do
356
- should "parse the XML then initializing the class" do
357
- VirtualBox::Command.expects(:parse_xml).with("foo").returns(@raw_xml_doc)
358
- VirtualBox::VM.expects(:new).with(@raw_xml_doc).once
359
- VirtualBox::VM.load_from_xml("foo")
360
- end
310
+ @parent.expects(:open_session).with(@session, @uuid).in_sequence(save_seq)
311
+ @proc.expects(:call).with(@session).once.in_sequence(save_seq)
312
+ @locked_interface.expects(:save_settings).once.in_sequence(save_seq)
313
+ @session.expects(:close).in_sequence(save_seq)
361
314
 
362
- should "initialize the attributes when called with an XML document" do
363
- VirtualBox::VM.any_instance.expects(:initialize_attributes).once.with(@raw_xml_doc)
364
- VirtualBox::VM.new(@raw_xml_doc)
365
- end
366
- end
315
+ @instance.with_open_session do |session|
316
+ @proc.call(session)
317
+ end
318
+ end
367
319
 
368
- context "initializing attributes" do
369
- # TODO: This needs to be tested
370
- end
320
+ should "only open the session and close once" do
321
+ open_seq = sequence("open_seq")
371
322
 
372
- context "finding a VM by name" do
373
- setup do
374
- @expected = {
375
- :name => "foo",
376
- :ostype => "Ubuntu",
377
- :uuid => "8710d3db-d96a-46ed-9004-59fa891fda90"
378
- }
379
- end
323
+ @parent.expects(:open_session).with(@session, @uuid).in_sequence(open_seq)
324
+ @locked_interface.expects(:save_settings).once.in_sequence(open_seq)
325
+ @session.expects(:close).once.in_sequence(open_seq)
380
326
 
381
- should "use the global 'all' array to find the VM" do
382
- VirtualBox::VM.expects(:all).with(true).returns([create_vm])
383
- vm = VirtualBox::VM.find(@name)
384
- assert vm
327
+ @instance.with_open_session do |session|
328
+ session.stubs(:state).returns(:open)
385
329
 
386
- @expected.each do |k,v|
387
- assert_equal v, vm.read_attribute(k)
330
+ @instance.with_open_session do |subsession|
331
+ assert_equal session, subsession
332
+ end
333
+ end
388
334
  end
389
335
  end
390
336
 
391
- should "return nil if the VM doesn't exist" do
392
- VirtualBox::VM.expects(:all).returns([])
393
- assert_nil VirtualBox::VM.find("dont exist")
394
- end
395
- end
337
+ context "state methods" do
338
+ should "check the proper results" do
339
+ methods = {
340
+ :running? => :running,
341
+ :powered_off? => :powered_off,
342
+ :paused? => :paused,
343
+ :saved? => :saved,
344
+ :aborted? => :aborted
345
+ }
396
346
 
397
- context "parsing the showvminfo output" do
398
- should "lowercase and symbolize the keys" do
399
- result = VirtualBox::VM.parse_vm_info("ZING=Zam")
400
- assert_equal 1, result.length
401
- assert_equal "Zam", result[:zing]
402
- end
347
+ methods.each do |method, value|
348
+ @instance.stubs(:state).returns(value)
349
+ assert @instance.send(method)
403
350
 
404
- should "ignore quotes for multi-word keys or values" do
405
- result = VirtualBox::VM.parse_vm_info('"foo bar"="baz"')
406
- assert_equal 1, result.length
407
- assert_equal "baz", result[:"foo bar"]
351
+ @instance.stubs(:state).returns(:nope)
352
+ assert !@instance.send(method)
353
+ end
354
+ end
408
355
  end
409
356
 
410
- should "ignore the lines which aren't the proper format" do
411
- result = VirtualBox::VM.parse_vm_info(<<-block)
412
- This should not be parsed
413
- Neither should this
357
+ context "exporting" do
358
+ setup do
359
+ @path = "foo.rb"
360
+ @appliance = mock("appliance")
361
+ @appliance.stubs(:path=)
362
+ @appliance.stubs(:add_machine)
363
+
364
+ VirtualBox::Appliance.stubs(:new).returns(@appliance)
365
+ end
414
366
 
415
- foo=bar
416
- block
367
+ should "create a new appliance with path and export" do
368
+ result = mock("result")
369
+ VirtualBox::Appliance.expects(:new).returns(@appliance)
370
+ @appliance.expects(:path=).with(@path)
371
+ @appliance.expects(:add_machine).with(@instance)
372
+ @appliance.expects(:export)
417
373
 
418
- assert_equal 1, result.length
419
- assert_equal "bar", result[:foo]
374
+ @instance.export(@path)
375
+ end
376
+
377
+ should "forward any block to the appliance export method" do
378
+ proc = mock("proc")
379
+ @appliance.expects(:export).yields(proc)
380
+ proc.expects(:call)
381
+
382
+ @instance.export(@path) do |yielded_proc|
383
+ yielded_proc.call
384
+ end
385
+ end
420
386
  end
421
387
  end
422
388
  end