virtualbox 0.1.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 (36) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +11 -0
  3. data/Rakefile +32 -0
  4. data/Readme.md +75 -0
  5. data/TODO +13 -0
  6. data/VERSION +1 -0
  7. data/lib/virtualbox.rb +11 -0
  8. data/lib/virtualbox/abstract_model.rb +95 -0
  9. data/lib/virtualbox/abstract_model/attributable.rb +193 -0
  10. data/lib/virtualbox/abstract_model/dirty.rb +164 -0
  11. data/lib/virtualbox/abstract_model/relatable.rb +163 -0
  12. data/lib/virtualbox/attached_device.rb +104 -0
  13. data/lib/virtualbox/command.rb +54 -0
  14. data/lib/virtualbox/dvd.rb +31 -0
  15. data/lib/virtualbox/errors.rb +7 -0
  16. data/lib/virtualbox/ext/subclass_listing.rb +24 -0
  17. data/lib/virtualbox/hard_drive.rb +169 -0
  18. data/lib/virtualbox/image.rb +94 -0
  19. data/lib/virtualbox/nic.rb +150 -0
  20. data/lib/virtualbox/storage_controller.rb +122 -0
  21. data/lib/virtualbox/vm.rb +287 -0
  22. data/test/test_helper.rb +25 -0
  23. data/test/virtualbox/abstract_model/attributable_test.rb +150 -0
  24. data/test/virtualbox/abstract_model/dirty_test.rb +66 -0
  25. data/test/virtualbox/abstract_model/relatable_test.rb +141 -0
  26. data/test/virtualbox/abstract_model_test.rb +146 -0
  27. data/test/virtualbox/attached_device_test.rb +92 -0
  28. data/test/virtualbox/command_test.rb +30 -0
  29. data/test/virtualbox/dvd_test.rb +58 -0
  30. data/test/virtualbox/ext/subclass_listing_test.rb +25 -0
  31. data/test/virtualbox/hard_drive_test.rb +161 -0
  32. data/test/virtualbox/image_test.rb +113 -0
  33. data/test/virtualbox/nic_test.rb +119 -0
  34. data/test/virtualbox/storage_controller_test.rb +79 -0
  35. data/test/virtualbox/vm_test.rb +313 -0
  36. metadata +103 -0
@@ -0,0 +1,30 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class CommandTest < Test::Unit::TestCase
4
+ context "shell escaping" do
5
+ should "convert value to string" do
6
+ assert_nothing_raised do
7
+ assert_equal "400", VirtualBox::Command.shell_escape(400)
8
+ end
9
+ end
10
+ end
11
+
12
+ context "testing command results" do
13
+ setup do
14
+ @command = "foo"
15
+ VirtualBox::Command.stubs(:execute)
16
+ end
17
+
18
+ should "return true if the exit code is 0" do
19
+ system("echo 'hello' 1>/dev/null")
20
+ assert_equal 0, $?.to_i
21
+ assert VirtualBox::Command.test(@command)
22
+ end
23
+
24
+ should "return false if the exit code is 1" do
25
+ system("there_is_no_way_this_can_exist_1234567890")
26
+ assert_not_equal 0, $?.to_i
27
+ assert !VirtualBox::Command.test(@command)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class DVDTest < Test::Unit::TestCase
4
+ context "retrieving all dvds" do
5
+ setup do
6
+ @expectations = {
7
+ "d3252617-8176-4f8c-9d73-1c9c82b23960" => {
8
+ :location => "/Users/mitchellh/Downloads/jeos-8.04.3-jeos-i386.iso",
9
+ :accessible => "yes"
10
+ },
11
+
12
+ "4a08f52c-bca3-4908-8da4-4f48aaa4ebba" => {
13
+ :location => "/Applications/VirtualBox.app/Contents/MacOS/VBoxGuestAdditions.iso",
14
+ :accessible => "yes"
15
+ }
16
+ }
17
+
18
+ @valid = <<-valid
19
+ VirtualBox Command Line Management Interface Version 3.1.2
20
+ (C) 2005-2009 Sun Microsystems, Inc.
21
+ All rights reserved.
22
+
23
+ UUID: d3252617-8176-4f8c-9d73-1c9c82b23960
24
+ Path: /Users/mitchellh/Downloads/jeos-8.04.3-jeos-i386.iso
25
+ Accessible: yes
26
+
27
+ UUID: 4a08f52c-bca3-4908-8da4-4f48aaa4ebba
28
+ Path: /Applications/VirtualBox.app/Contents/MacOS/VBoxGuestAdditions.iso
29
+ Accessible: yes
30
+ Usage: TestJeOS (UUID: 3d0f87b4-50f7-4fc5-ad89-93375b1b32a3)
31
+ valid
32
+
33
+ VirtualBox::Command.expects(:vboxmanage).with("list dvds").returns(@valid)
34
+ end
35
+
36
+ should "return an array of DVD objects" do
37
+ result = VirtualBox::DVD.all
38
+ assert result.is_a?(Array)
39
+
40
+ result.each { |v| assert v.is_a?(VirtualBox::DVD) }
41
+ end
42
+
43
+ should "return the proper results" do
44
+ result = VirtualBox::DVD.all
45
+ assert result.is_a?(Array)
46
+ assert_equal @expectations.length, result.length
47
+
48
+ result.each do |image|
49
+ expected_image = @expectations[image.uuid]
50
+ assert expected_image
51
+
52
+ expected_image.each do |k,v|
53
+ assert_equal v, image.read_attribute(k)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,25 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+ require 'virtualbox/ext/subclass_listing'
3
+
4
+ class SubclassListingTest < Test::Unit::TestCase
5
+ class A
6
+ include VirtualBox::SubclassListing
7
+ end
8
+ class B < A; end
9
+ class C < B; end
10
+ class D < A; end
11
+ class E
12
+ include VirtualBox::SubclassListing
13
+ end
14
+ class F < E; end
15
+
16
+ should "list subclasses, including sub-subclasses, etc" do
17
+ assert_equal [F], E.subclasses
18
+ assert_equal [C], B.subclasses
19
+ assert_equal [B, C, D], A.subclasses.sort_by { |c| c.name }
20
+ end
21
+
22
+ should "list direct subclasses if flag is set" do
23
+ assert_equal [B, D], A.subclasses(true).sort_by { |c| c.name }
24
+ end
25
+ end
@@ -0,0 +1,161 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class HardDriveTest < Test::Unit::TestCase
4
+ setup do
5
+ VirtualBox::Command.stubs(:execute)
6
+
7
+ @find_raw = <<-raw
8
+ VirtualBox Command Line Management Interface Version 3.1.2
9
+ (C) 2005-2009 Sun Microsystems, Inc.
10
+ All rights reserved.
11
+
12
+ UUID: 11dedd14-57a1-4bdb-adeb-dd1d67f066e1
13
+ Accessible: yes
14
+ Description:
15
+ Logical size: 20480 MBytes
16
+ Current size on disk: 1218 MBytes
17
+ Type: normal (base)
18
+ Storage format: VDI
19
+ In use by VMs: FooVM (UUID: 696249ad-00b6-4087-b47f-9b82629efc31)
20
+ Location: /Users/mitchellh/Library/VirtualBox/HardDisks/foo.vdi
21
+ raw
22
+ @name = "foo"
23
+ VirtualBox::Command.stubs(:vboxmanage).with("showhdinfo #{@name}").returns(@find_raw)
24
+ end
25
+
26
+ context "cloning a hard drive" do
27
+ setup do
28
+ @hd = VirtualBox::HardDrive.find(@name)
29
+ VirtualBox::Command.expects(:vboxmanage).with("clonehd #{@hd.uuid} bar --format VDI --remember").returns(@find_raw)
30
+ end
31
+
32
+ should "call vboxmanage with the clone command" do
33
+ VirtualBox::HardDrive.expects(:find).returns(nil)
34
+ @hd.clone("bar")
35
+ end
36
+
37
+ should "return the newly cloned hard drive" do
38
+ @new_hd = mock("hd")
39
+ VirtualBox::HardDrive.expects(:find).returns(@new_hd)
40
+ assert_equal @new_hd, @hd.clone("bar")
41
+ end
42
+ end
43
+
44
+ context "creating a hard drive" do
45
+ setup do
46
+ @location = "foo.foo"
47
+ @size = "758"
48
+ @format = "VDI"
49
+
50
+ @hd = VirtualBox::HardDrive.new
51
+ @hd.location = @location
52
+ @hd.size = @size
53
+
54
+ @fake_hd = mock("hd")
55
+ @fake_hd.stubs(:attributes).returns({
56
+ :uuid => "foo"
57
+ })
58
+
59
+ VirtualBox::HardDrive.stubs(:find).returns(@fake_hd)
60
+ VirtualBox::Command.stubs(:vboxmanage).returns("UUID: FOO")
61
+ end
62
+
63
+ should "call create on save" do
64
+ @hd.expects(:create).once
65
+
66
+ assert @hd.new_record?
67
+ @hd.save
68
+ end
69
+
70
+ should "call not call create on existing records" do
71
+ @hd.save
72
+ assert !@hd.new_record?
73
+
74
+ @hd.expects(:create).never
75
+ @hd.save
76
+ end
77
+
78
+ should "call createhd" do
79
+ VirtualBox::Command.expects(:vboxmanage).with("createhd --filename #{@location} --size #{@size} --format #{@format} --remember")
80
+ @hd.save
81
+ end
82
+
83
+ should "replace attributes with those of the newly created hard drive" do
84
+ @hd.save
85
+
86
+ assert_equal "foo", @hd.uuid
87
+ end
88
+ end
89
+
90
+ context "finding a single hard drive" do
91
+ should "parse proper fields" do
92
+ VirtualBox::Command.expects(:vboxmanage).with("showhdinfo #{@name}").returns(@find_raw)
93
+
94
+ @expected = {
95
+ :uuid => "11dedd14-57a1-4bdb-adeb-dd1d67f066e1",
96
+ :accessible => "yes",
97
+ :size => "20480",
98
+ :location => "/Users/mitchellh/Library/VirtualBox/HardDisks/foo.vdi"
99
+ }
100
+
101
+ hd = VirtualBox::HardDrive.find(@name)
102
+ assert hd.is_a?(VirtualBox::HardDrive)
103
+
104
+ @expected.each do |k,v|
105
+ assert_equal v, hd.send(k)
106
+ end
107
+ end
108
+
109
+ should "return nil if finding a non-existent hard drive" do
110
+ VirtualBox::Command.expects(:vboxmanage).with("showhdinfo 12").returns("UH OH (VERR_FILE_NOT_FOUND)")
111
+
112
+ assert_nothing_raised do
113
+ assert_nil VirtualBox::HardDrive.find(12)
114
+ end
115
+ end
116
+ end
117
+
118
+ context "retrieving all hard drives" do
119
+ setup do
120
+ @valid = <<-valid
121
+ VirtualBox Command Line Management Interface Version 3.1.2
122
+ (C) 2005-2009 Sun Microsystems, Inc.
123
+ All rights reserved.
124
+
125
+ UUID: 9d2e4353-d1e9-466c-ac58-f2249264147b
126
+ Format: VDI
127
+ Location: /Users/mitchellh/Library/VirtualBox/HardDisks/foo.vdi
128
+ Accessible: yes
129
+ Type: normal
130
+ Usage: TestJeOS (UUID: 3d0f87b4-50f7-4fc5-ad89-93375b1b32a3)
131
+
132
+ UUID: 11dedd14-57a1-4bdb-adeb-dd1d67f066e1
133
+ Format: VDI
134
+ Location: /Users/mitchellh/Library/VirtualBox/HardDisks/bar.vdi
135
+ Accessible: yes
136
+ Type: normal
137
+ Usage: HoboBase (UUID: 696249ad-00b6-4087-b47f-9b82629efc31)
138
+
139
+ UUID: 5e090af6-7d71-4f40-8b03-33aa665f9ecf
140
+ Format: VMDK
141
+ Location: /Users/mitchellh/Library/VirtualBox/HardDisks/baz.vmdk
142
+ Accessible: yes
143
+ Type: normal
144
+ Usage: foo (UUID: 8710d3db-d96a-46ed-9004-59fa891fda90)
145
+ valid
146
+
147
+ VirtualBox::Command.expects(:vboxmanage).with("list hdds").returns(@valid)
148
+
149
+ @hd = mock("hd")
150
+ @hd.stubs(:is_a?).with(VirtualBox::HardDrive).returns(true)
151
+ VirtualBox::HardDrive.expects(:find).at_least(0).returns(@hd)
152
+ end
153
+
154
+ should "return an array of HardDrive objects" do
155
+ result = VirtualBox::HardDrive.all
156
+ assert result.is_a?(Array)
157
+
158
+ result.each { |v| assert v.is_a?(VirtualBox::HardDrive) }
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,113 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class ImageTest < Test::Unit::TestCase
4
+ context "recording subclasses" do
5
+ should "list all subclasses" do
6
+ assert_nothing_raised { VirtualBox::Image.subclasses }
7
+ end
8
+ end
9
+
10
+ context "parsing raw" do
11
+ setup do
12
+ @raw = <<-raw
13
+ VirtualBox Command Line Management Interface Version 3.1.2
14
+ (C) 2005-2009 Sun Microsystems, Inc.
15
+ All rights reserved.
16
+
17
+ UUID: 9d2e4353-d1e9-466c-ac58-f2249264147b
18
+ Format: VDI
19
+ Location: /Users/mitchellh/Library/VirtualBox/HardDisks/TestJeOS.vdi
20
+ Accessible: yes
21
+ Type: normal
22
+ Usage: TestJeOS (UUID: 3d0f87b4-50f7-4fc5-ad89-93375b1b32a3)
23
+
24
+ UUID: 11dedd14-57a1-4bdb-adeb-dd1d67f066e1
25
+ Format: VDI
26
+ Location: /Users/mitchellh/Library/VirtualBox/HardDisks/HoboBase.vdi
27
+ Accessible: yes
28
+ Type: normal
29
+ Usage: HoboBase (UUID: 696249ad-00b6-4087-b47f-9b82629efc31)
30
+
31
+ UUID: 322f79fd-7da6-416f-a16f-e70066ccf165
32
+ Format: VMDK
33
+ Location: /Users/mitchellh/Library/VirtualBox/HardDisks/HoboBase.vmdk
34
+ Accessible: yes
35
+ Type: normal
36
+ Usage: HoboBase_2 (UUID: 3cc36c5d-562a-4030-8acf-f061f44170c4)
37
+ raw
38
+ end
39
+
40
+ should "call parse block the correct number of times" do
41
+ VirtualBox::Image.expects(:parse_block).times(4).returns({})
42
+ VirtualBox::Image.parse_raw(@raw)
43
+ end
44
+
45
+ should "remove nil (invalid) blocks from result" do
46
+ result = VirtualBox::Image.parse_raw(@raw)
47
+ assert_equal 3, result.length
48
+ end
49
+ end
50
+
51
+ context "parsing multiple blocks" do
52
+ setup do
53
+ @raw = <<-raw
54
+ one
55
+
56
+ two
57
+
58
+ three
59
+ raw
60
+ end
61
+
62
+ should "call parse block for each multiline" do
63
+ parse_seq = sequence("parse")
64
+ VirtualBox::Image.expects(:parse_block).with("one").in_sequence(parse_seq)
65
+ VirtualBox::Image.expects(:parse_block).with("two").in_sequence(parse_seq)
66
+ VirtualBox::Image.expects(:parse_block).with("three").in_sequence(parse_seq)
67
+ VirtualBox::Image.parse_blocks(@raw)
68
+ end
69
+
70
+ should "return an array of the parses with nil ignored" do
71
+ parse_seq = sequence("parse")
72
+ VirtualBox::Image.expects(:parse_block).with("one").returns({}).in_sequence(parse_seq)
73
+ VirtualBox::Image.expects(:parse_block).with("two").returns(nil).in_sequence(parse_seq)
74
+ VirtualBox::Image.expects(:parse_block).with("three").returns({}).in_sequence(parse_seq)
75
+ result = VirtualBox::Image.parse_blocks(@raw)
76
+
77
+ assert result.is_a?(Array)
78
+ assert_equal 2, result.length
79
+ end
80
+ end
81
+
82
+ context "parsing a single block" do
83
+ setup do
84
+ @expected = {
85
+ :uuid => "1234567890",
86
+ :path => "foo",
87
+ :accessible => "yes"
88
+ }
89
+
90
+ @block = ""
91
+ @expected.each { |k,v| @block += "#{k}: #{v}\n" }
92
+ end
93
+
94
+ should "return nil for an invalid block" do
95
+ assert VirtualBox::Image.parse_block("HI").nil?
96
+ end
97
+
98
+ should "mirror location to path" do
99
+ result = VirtualBox::Image.parse_block(@block)
100
+ assert_equal "foo", result[:location]
101
+ end
102
+
103
+ should "properly parse if all properties are available" do
104
+ result = VirtualBox::Image.parse_block(@block)
105
+ assert !result.nil?
106
+
107
+ @expected.each do |k,v|
108
+ k = :location if k == :path
109
+ assert_equal v, result[k]
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,119 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class NicTest < Test::Unit::TestCase
4
+ setup do
5
+ @data = {
6
+ :nic1 => "bridged",
7
+ :nic2 => "foo",
8
+ :nic3 => "bar"
9
+ }
10
+
11
+ @caller = mock("caller")
12
+ @caller.stubs(:name).returns("foo")
13
+
14
+ VirtualBox::VM.stubs(:human_info).returns(<<-raw)
15
+ NIC 1: MAC: 08002745B49F, Attachment: Bridged Interface 'en0: Ethernet', Cable connected: on, Trace: off (file: none), Type: Am79C973, Reported speed: 0 Mbps
16
+ NIC 2: MAC: 08002745B49F, Attachment: Bridged Interface 'en0: Ethernet', Cable connected: on, Trace: off (file: none), Type: Am79C973, Reported speed: 0 Mbps
17
+ NIC 3: MAC: 08002745B49F, Attachment: Bridged Interface 'en0: Ethernet', Cable connected: on, Trace: off (file: none), Type: Am79C973, Reported speed: 0 Mbps
18
+ raw
19
+ end
20
+
21
+ context "saving" do
22
+ setup do
23
+ @nic = VirtualBox::Nic.populate_relationship(@caller, @data)
24
+ @vmname = "myvm"
25
+ end
26
+
27
+ should "use the vmname strung through the save" do
28
+ VirtualBox::Command.expects(:vboxmanage).with("modifyvm #{@vmname} --nic1 foo")
29
+
30
+ nic = @nic[0]
31
+ nic.nic = "foo"
32
+ nic.save(@vmname)
33
+ end
34
+
35
+ should "use the proper index" do
36
+ VirtualBox::Command.expects(:vboxmanage).with("modifyvm #{@vmname} --nic2 far")
37
+
38
+ nic = @nic[1]
39
+ nic.nic = "far"
40
+ nic.save(@vmname)
41
+ end
42
+
43
+ should "save the nictype" do
44
+ VirtualBox::Command.expects(:vboxmanage).with("modifyvm #{@vmname} --nictype1 ZOO")
45
+
46
+ nic = @nic[0]
47
+ nic.nictype = "ZOO"
48
+ assert nic.nictype_changed?
49
+ nic.save(@vmname)
50
+ end
51
+ end
52
+
53
+ context "populating relationships" do
54
+ setup do
55
+ @value = VirtualBox::Nic.populate_relationship(@caller, @data)
56
+ end
57
+
58
+ should "create the correct amount of objects" do
59
+ assert_equal 3, @value.length
60
+ end
61
+
62
+ should "parse the type" do
63
+ assert_equal "Am79C973", @value[0].nictype
64
+ end
65
+ end
66
+
67
+ context "parsing nic data from human readable output" do
68
+ setup do
69
+ @raw = "NIC 1: MAC: 08002745B49F, Attachment: Bridged Interface 'en0: Ethernet', Cable connected: on, Trace: off (file: none), Type: Am79C973, Reported speed: 0 Mbps"
70
+
71
+ @multiline_raw = <<-raw
72
+ Storage Controller Port Count (0): 2
73
+ Storage Controller Name (1): Floppy Controller
74
+ Storage Controller Type (1): I82078
75
+ Storage Controller Instance Number (1): 0
76
+ Storage Controller Max Port Count (1): 1
77
+ Storage Controller Port Count (1): 1
78
+ IDE Controller (0, 0): /Users/mitchellh/Library/VirtualBox/HardDisks/HoboBase.vmdk (UUID: fb0256a9-5685-4bc2-98ff-5b7503586bf3)
79
+ IDE Controller (1, 0): Empty
80
+ Floppy Controller (0, 0): Empty
81
+ NIC 1: MAC: 08002745B49F, Attachment: Bridged Interface 'en0: Ethernet', Cable connected: on, Trace: off (file: none), Type: Am79C973, Reported speed: 0 Mbps
82
+ NIC 2: disabled
83
+ raw
84
+ end
85
+
86
+ should "only return valid objects in hash" do
87
+ VirtualBox::VM.expects(:human_info).returns(@multiline_raw)
88
+ result = VirtualBox::Nic.nic_data("foo")
89
+ assert result.is_a?(Hash)
90
+ assert_equal 1, result.length
91
+ end
92
+
93
+ should "return nil if its an invalid string" do
94
+ assert_nil VirtualBox::Nic.parse_nic("FOO")
95
+ end
96
+
97
+ should "return proper data for valid string" do
98
+ @name = :nic1
99
+ @expected = {
100
+ :mac => "08002745B49F",
101
+ :attachment => "Bridged Interface 'en0: Ethernet'",
102
+ :trace => "off (file: none)",
103
+ :type => "Am79C973"
104
+ }
105
+
106
+ name, result = VirtualBox::Nic.parse_nic(@raw)
107
+ assert_equal @name, name
108
+ assert result.is_a?(Hash)
109
+
110
+ @expected.each do |k,v|
111
+ assert_equal v, result[k]
112
+ end
113
+ end
114
+
115
+ should "ignore nics that are disabled" do
116
+ assert_nil VirtualBox::Nic.parse_nic("NIC 1: disabled")
117
+ end
118
+ end
119
+ end