virtualbox 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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