virtualbox 0.7.1 → 0.7.2
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.
- data/VERSION +1 -1
- data/lib/virtualbox/abstract_model.rb +10 -1
- data/lib/virtualbox/abstract_model/attributable.rb +21 -2
- data/lib/virtualbox/abstract_model/interface_attributes.rb +3 -1
- data/lib/virtualbox/abstract_model/relatable.rb +11 -1
- data/lib/virtualbox/abstract_model/version_matcher.rb +33 -0
- data/lib/virtualbox/com/ffi/interfaces.rb +9 -1
- data/lib/virtualbox/exceptions.rb +2 -1
- data/lib/virtualbox/forwarded_port.rb +1 -1
- data/lib/virtualbox/nat_engine.rb +71 -0
- data/lib/virtualbox/nat_forwarded_port.rb +171 -0
- data/lib/virtualbox/network_adapter.rb +10 -1
- data/lib/virtualbox/shared_folder.rb +1 -1
- data/lib/virtualbox/vm.rb +7 -2
- data/test/test_helper.rb +1 -1
- data/test/virtualbox/abstract_model/attributable_test.rb +24 -3
- data/test/virtualbox/abstract_model/interface_attributes_test.rb +26 -1
- data/test/virtualbox/abstract_model/relatable_test.rb +64 -5
- data/test/virtualbox/abstract_model/version_matcher_test.rb +37 -0
- data/test/virtualbox/abstract_model_test.rb +29 -11
- data/test/virtualbox/forwarded_port_test.rb +20 -3
- data/test/virtualbox/nat_engine_test.rb +106 -0
- data/test/virtualbox/nat_forwarded_port_test.rb +216 -0
- data/test/virtualbox/network_adapter_test.rb +2 -0
- data/test/virtualbox/shared_folder_test.rb +1 -0
- data/test/virtualbox/vm_test.rb +16 -2
- data/virtualbox.gemspec +12 -3
- metadata +12 -3
@@ -44,6 +44,7 @@ module VirtualBox
|
|
44
44
|
attribute :internal_network
|
45
45
|
attribute :host_interface
|
46
46
|
attribute :interface, :readonly => true, :property => false
|
47
|
+
relationship :nat_driver, :NATEngine, :version => "3.2", :lazy => true
|
47
48
|
|
48
49
|
class << self
|
49
50
|
# Populates the nic relationship for anything which is related to it.
|
@@ -98,6 +99,13 @@ module VirtualBox
|
|
98
99
|
existing_record!
|
99
100
|
end
|
100
101
|
|
102
|
+
def load_relationship(name)
|
103
|
+
# Lazy load the NAT driver. This is only supported by VirtualBox
|
104
|
+
# 3.2 and higher. This restriction is checked when the
|
105
|
+
# relationship attribute is accessed.
|
106
|
+
populate_relationship(:nat_driver, interface.nat_driver)
|
107
|
+
end
|
108
|
+
|
101
109
|
# Gets the host interface object associated with the class if it
|
102
110
|
# exists.
|
103
111
|
def host_interface_object
|
@@ -111,6 +119,7 @@ module VirtualBox
|
|
111
119
|
modify_adapter do |adapter|
|
112
120
|
save_attachment_type(adapter)
|
113
121
|
save_changed_interface_attributes(adapter)
|
122
|
+
save_relationships
|
114
123
|
end
|
115
124
|
end
|
116
125
|
|
@@ -133,7 +142,7 @@ module VirtualBox
|
|
133
142
|
# Opens a session, yields the adapter and then saves the machine at
|
134
143
|
# the end
|
135
144
|
def modify_adapter
|
136
|
-
|
145
|
+
parent_machine.with_open_session do |session|
|
137
146
|
machine = session.machine
|
138
147
|
yield machine.get_network_adapter(slot)
|
139
148
|
end
|
@@ -179,7 +179,7 @@ module VirtualBox
|
|
179
179
|
def create
|
180
180
|
return unless new_record?
|
181
181
|
|
182
|
-
|
182
|
+
parent_machine.with_open_session do |session|
|
183
183
|
machine = session.machine
|
184
184
|
machine.create_shared_folder(name, host_path, writable)
|
185
185
|
end
|
data/lib/virtualbox/vm.rb
CHANGED
@@ -174,7 +174,7 @@ module VirtualBox
|
|
174
174
|
relationship :medium_attachments, :MediumAttachment
|
175
175
|
relationship :shared_folders, :SharedFolder
|
176
176
|
relationship :extra_data, :ExtraData
|
177
|
-
relationship :forwarded_ports, :ForwardedPort
|
177
|
+
relationship :forwarded_ports, :ForwardedPort, :version => "3.1"
|
178
178
|
relationship :network_adapters, :NetworkAdapter
|
179
179
|
relationship :usb_controller, :USBController
|
180
180
|
relationship :current_snapshot, :Snapshot
|
@@ -529,7 +529,12 @@ module VirtualBox
|
|
529
529
|
#
|
530
530
|
# @return [Boolean] True if command was successful, false otherwise.
|
531
531
|
def discard_state
|
532
|
-
|
532
|
+
# Since the VM should be saved as it is, we don't open an
|
533
|
+
# existing session like the other control methods. We open a new
|
534
|
+
# session.
|
535
|
+
with_open_session do |session|
|
536
|
+
session.console.forget_saved_state(true)
|
537
|
+
end
|
533
538
|
end
|
534
539
|
|
535
540
|
# Controls the virtual machine. This method is used by {#stop},
|
data/test/test_helper.rb
CHANGED
@@ -24,4 +24,4 @@ end
|
|
24
24
|
# FFI is initialized (on non-windows machines). Since the tests test
|
25
25
|
# the FFI classes, we force initialize a specific version here. It
|
26
26
|
# doesn't matter what version, since no actual FFI calls are made.
|
27
|
-
VirtualBox::COM::FFI.setup("3.
|
27
|
+
VirtualBox::COM::FFI.setup("3.2.x") unless defined?(VirtualBox::COM::FFI::Version_3_2_X)
|
@@ -195,11 +195,16 @@ class AttributableTest < Test::Unit::TestCase
|
|
195
195
|
end
|
196
196
|
|
197
197
|
context "reading and writing attributes" do
|
198
|
+
class VersionedAttributeModel < AttributeModel
|
199
|
+
attribute :ver, :version => "3.1"
|
200
|
+
end
|
201
|
+
|
198
202
|
setup do
|
199
|
-
@model =
|
203
|
+
@model = VersionedAttributeModel.new
|
200
204
|
@model.populate_attributes({
|
201
205
|
:foo => "foo",
|
202
|
-
:bar => false
|
206
|
+
:bar => false,
|
207
|
+
:ver => "ver"
|
203
208
|
})
|
204
209
|
|
205
210
|
@checkstring = "HEY"
|
@@ -231,6 +236,22 @@ class AttributableTest < Test::Unit::TestCase
|
|
231
236
|
}
|
232
237
|
end
|
233
238
|
|
239
|
+
should "raise an exception if version not supported" do
|
240
|
+
VirtualBox.stubs(:version).returns("3.0.14")
|
241
|
+
|
242
|
+
assert_raises(VirtualBox::Exceptions::UnsupportedVersionException) {
|
243
|
+
@model.ver
|
244
|
+
}
|
245
|
+
end
|
246
|
+
|
247
|
+
should "read value if version supported" do
|
248
|
+
VirtualBox.stubs(:version).returns("3.1.8")
|
249
|
+
|
250
|
+
assert_nothing_raised {
|
251
|
+
assert_equal "ver", @model.ver
|
252
|
+
}
|
253
|
+
end
|
254
|
+
|
234
255
|
should "understand false values" do
|
235
256
|
assert_nothing_raised {
|
236
257
|
assert_equal false, @model.bar
|
@@ -245,4 +266,4 @@ class AttributableTest < Test::Unit::TestCase
|
|
245
266
|
assert_raises(NoMethodError) { @model.baz }
|
246
267
|
end
|
247
268
|
end
|
248
|
-
end
|
269
|
+
end
|
@@ -12,6 +12,7 @@ class InterfaceAttributesTest < Test::Unit::TestCase
|
|
12
12
|
attribute :foo3, :property => :grab_foo3, :readonly => true
|
13
13
|
attribute :foo4, :property => :put_foo4
|
14
14
|
attribute :bar, :property => false
|
15
|
+
attribute :ver, :version => "3.1.3"
|
15
16
|
end
|
16
17
|
|
17
18
|
context "converting spec to a proc" do
|
@@ -64,6 +65,18 @@ class InterfaceAttributesTest < Test::Unit::TestCase
|
|
64
65
|
@instance.load_interface_attribute(:bar, @interface)
|
65
66
|
end
|
66
67
|
|
68
|
+
should "return immediately if version mismatch" do
|
69
|
+
VirtualBox.stubs(:version).returns("3.2.4")
|
70
|
+
@interface.expects(:ver).never
|
71
|
+
@instance.load_interface_attribute(:ver, @interface)
|
72
|
+
end
|
73
|
+
|
74
|
+
should "load the attribute if version matches" do
|
75
|
+
VirtualBox.stubs(:version).returns("3.1.3")
|
76
|
+
@interface.expects(:ver).returns("foo")
|
77
|
+
@instance.load_interface_attribute(:ver, @interface)
|
78
|
+
end
|
79
|
+
|
67
80
|
should "use the getter specified if exists" do
|
68
81
|
key = :foo2
|
69
82
|
@interface.expects(:get_foo).returns(:bar)
|
@@ -111,6 +124,18 @@ class InterfaceAttributesTest < Test::Unit::TestCase
|
|
111
124
|
@instance.save_interface_attribute(:bar, @interface)
|
112
125
|
end
|
113
126
|
|
127
|
+
should "return immediately if version mismatch" do
|
128
|
+
VirtualBox.stubs(:version).returns("3.2.4")
|
129
|
+
@interface.expects(:ver).never
|
130
|
+
@instance.save_interface_attribute(:ver, @interface)
|
131
|
+
end
|
132
|
+
|
133
|
+
should "load the attribute if version matches" do
|
134
|
+
VirtualBox.stubs(:version).returns("3.1.3")
|
135
|
+
@interface.expects(:ver=)
|
136
|
+
@instance.save_interface_attribute(:ver, @interface)
|
137
|
+
end
|
138
|
+
|
114
139
|
should "save the attribute with the value of the proc" do
|
115
140
|
key = :foo
|
116
141
|
@interface.expects(:foo=).with(@value).once
|
@@ -166,4 +191,4 @@ class InterfaceAttributesTest < Test::Unit::TestCase
|
|
166
191
|
@instance.save_interface_attributes(@interface)
|
167
192
|
end
|
168
193
|
end
|
169
|
-
end
|
194
|
+
end
|
@@ -194,16 +194,45 @@ class RelatableTest < Test::Unit::TestCase
|
|
194
194
|
end
|
195
195
|
|
196
196
|
context "saving relationships" do
|
197
|
+
class RelatableWithLazyModel < RelatableModel
|
198
|
+
relationship :bazs, RelatableTest::Relatee, :lazy => true
|
199
|
+
relationship :vers, RelatableTest::Relatee, :version => "3.1"
|
200
|
+
|
201
|
+
def load_relationship(name)
|
202
|
+
populate_relationship(:bazs, "foo")
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
197
206
|
setup do
|
198
|
-
@model =
|
207
|
+
@model = RelatableWithLazyModel.new
|
208
|
+
VirtualBox.stubs(:version).returns("3.1.3")
|
199
209
|
end
|
200
210
|
|
201
211
|
should "call save_relationship for all relationships" do
|
202
212
|
@model.expects(:save_relationship).with(:foos)
|
203
213
|
@model.expects(:save_relationship).with(:bars)
|
214
|
+
@model.expects(:save_relationship).with(:bazs)
|
215
|
+
@model.expects(:save_relationship).with(:vers)
|
204
216
|
@model.save_relationships
|
205
217
|
end
|
206
218
|
|
219
|
+
should "not call save_relationship on non-loaded relations" do
|
220
|
+
Relatee.expects(:save_relationship).never
|
221
|
+
@model.save_relationship(:bazs)
|
222
|
+
end
|
223
|
+
|
224
|
+
should "not call save_relationship on relationships with mismatched versions" do
|
225
|
+
VirtualBox.stubs(:version).returns("3.2.4")
|
226
|
+
Relatee.expects(:save_relationship).never
|
227
|
+
@model.save_relationship(:vers)
|
228
|
+
end
|
229
|
+
|
230
|
+
should "call save_relationship on loaded lazy relationships" do
|
231
|
+
@model.load_relationship(:bazs)
|
232
|
+
Relatee.expects(:save_relationship).once
|
233
|
+
@model.save_relationship(:bazs)
|
234
|
+
end
|
235
|
+
|
207
236
|
should "call save_relationship on the related class" do
|
208
237
|
Relatee.expects(:save_relationship).with(@model, @model.foos).once
|
209
238
|
@model.save_relationship(:foos)
|
@@ -216,13 +245,31 @@ class RelatableTest < Test::Unit::TestCase
|
|
216
245
|
end
|
217
246
|
|
218
247
|
context "reading relationships" do
|
248
|
+
class VersionedRelatableModel < RelatableModel
|
249
|
+
relationship :ver, :Ver, :version => "3.1"
|
250
|
+
end
|
251
|
+
|
219
252
|
setup do
|
220
|
-
@model =
|
253
|
+
@model = VersionedRelatableModel.new
|
221
254
|
end
|
222
255
|
|
223
256
|
should "provide a read method for relationships" do
|
224
257
|
assert_nothing_raised { @model.foos }
|
225
258
|
end
|
259
|
+
|
260
|
+
should "raise an exception if invalid version for versioned relationships" do
|
261
|
+
VirtualBox.stubs(:version).returns("3.0.14")
|
262
|
+
assert_raises(VirtualBox::Exceptions::UnsupportedVersionException) {
|
263
|
+
@model.ver
|
264
|
+
}
|
265
|
+
end
|
266
|
+
|
267
|
+
should "not raise an exception if valid version for versioned relationship" do
|
268
|
+
VirtualBox.stubs(:version).returns("3.1.8")
|
269
|
+
assert_nothing_raised {
|
270
|
+
@model.ver
|
271
|
+
}
|
272
|
+
end
|
226
273
|
end
|
227
274
|
|
228
275
|
context "checking for relationships" do
|
@@ -264,8 +311,13 @@ class RelatableTest < Test::Unit::TestCase
|
|
264
311
|
end
|
265
312
|
|
266
313
|
context "populating relationships" do
|
314
|
+
class PopulatingRelatableModel < RelatableModel
|
315
|
+
relationship :bazs, RelatableTest::Relatee, :version => "3.1"
|
316
|
+
end
|
317
|
+
|
267
318
|
setup do
|
268
|
-
@model =
|
319
|
+
@model = PopulatingRelatableModel.new
|
320
|
+
VirtualBox.stubs(:version).returns("3.1.4")
|
269
321
|
end
|
270
322
|
|
271
323
|
should "be able to populate a single relationship" do
|
@@ -273,17 +325,24 @@ class RelatableTest < Test::Unit::TestCase
|
|
273
325
|
@model.populate_relationship(:foos, @data)
|
274
326
|
end
|
275
327
|
|
328
|
+
should "not populate versioned relationships if version mismatch" do
|
329
|
+
VirtualBox.stubs(:version).returns("3.0.4")
|
330
|
+
Relatee.expects(:populate_relationship).never
|
331
|
+
@model.populate_relationship(:bazs, @data)
|
332
|
+
end
|
333
|
+
|
276
334
|
should "call populate_relationship on the related class" do
|
277
335
|
populate_seq = sequence("populate_seq")
|
278
336
|
@model.expects(:populate_relationship).with(:foos, @data).once.in_sequence(populate_seq)
|
279
337
|
@model.expects(:populate_relationship).with(:bars, @data).once.in_sequence(populate_seq)
|
338
|
+
@model.expects(:populate_relationship).with(:bazs, @data).once.in_sequence(populate_seq)
|
280
339
|
@model.populate_relationships(@data)
|
281
340
|
end
|
282
341
|
|
283
342
|
should "properly save returned value as the value for the relationship" do
|
284
|
-
Relatee.expects(:populate_relationship).
|
343
|
+
Relatee.expects(:populate_relationship).twice.returns("HEY")
|
285
344
|
@model.populate_relationships(@data)
|
286
345
|
assert_equal "HEY", @model.foos
|
287
346
|
end
|
288
347
|
end
|
289
|
-
end
|
348
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
2
|
+
|
3
|
+
class VersionMatcherTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
@module = VirtualBox::AbstractModel::VersionMatcher
|
6
|
+
@klass = Class.new
|
7
|
+
@klass.send(:extend, @module)
|
8
|
+
end
|
9
|
+
|
10
|
+
context "asserting version matches" do
|
11
|
+
should "raise an exception if versions do not match" do
|
12
|
+
assert_raises(VirtualBox::Exceptions::UnsupportedVersionException) {
|
13
|
+
@klass.assert_version_match("3.1", "3.2.4")
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
should "not raise an exception if versions do match" do
|
18
|
+
assert_nothing_raised {
|
19
|
+
@klass.assert_version_match("3.0", "3.0.14")
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "version matching" do
|
25
|
+
should "return true if versions match" do
|
26
|
+
assert @klass.version_match?("3.2", "3.2.4")
|
27
|
+
assert !@klass.version_match?("3.1", "3.2.4")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "splitting version" do
|
32
|
+
should "split into a max of two parts by period" do
|
33
|
+
assert_equal %W[3 2], @klass.split_version("3.2.0")
|
34
|
+
assert_equal %W[3 1], @klass.split_version("3.1.1.1.1")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -84,16 +84,6 @@ class AbstractModelTest < Test::Unit::TestCase
|
|
84
84
|
assert !@model.lazy_attribute?(:foo)
|
85
85
|
assert !@model.lazy_relationship?(:foos)
|
86
86
|
end
|
87
|
-
|
88
|
-
should "only save loaded relationships" do
|
89
|
-
@model.existing_record!
|
90
|
-
assert @model.lazy_relationship?(:foos)
|
91
|
-
assert @model.lazy_relationship?(:bars)
|
92
|
-
@model.stubs(:loaded_relationship?).with(:foos).returns(false)
|
93
|
-
@model.stubs(:loaded_relationship?).with(:bars).returns(true)
|
94
|
-
@model.expects(:save_relationship).with(:bars).once
|
95
|
-
@model.save
|
96
|
-
end
|
97
87
|
end
|
98
88
|
|
99
89
|
context "inspecting" do
|
@@ -112,7 +102,7 @@ class AbstractModelTest < Test::Unit::TestCase
|
|
112
102
|
|
113
103
|
should "turn attributes which are AbstractInterfaces into classes" do
|
114
104
|
@model.foo = VirtualBox::COM::Util.versioned_interface(:VirtualBox).new(VirtualBox::COM::Implementer::Nil, nil)
|
115
|
-
assert_equal "#<AbstractModelTest::FakeModel :bar=nil, :bars=..., :foo=#<VirtualBox::COM::Interface::
|
105
|
+
assert_equal "#<AbstractModelTest::FakeModel :bar=nil, :bars=..., :foo=#<VirtualBox::COM::Interface::Version_3_2_X::VirtualBox>, :foos=...>", @model.inspect
|
116
106
|
end
|
117
107
|
end
|
118
108
|
|
@@ -197,6 +187,34 @@ class AbstractModelTest < Test::Unit::TestCase
|
|
197
187
|
end
|
198
188
|
end
|
199
189
|
|
190
|
+
context "parent machine" do
|
191
|
+
setup do
|
192
|
+
# Create a subclass of VM and no-op the initialize so it doesn't
|
193
|
+
# try to populate VM attributes or relationships
|
194
|
+
@root = Class.new(VirtualBox::VM)
|
195
|
+
@root.class_eval("def initialize; end")
|
196
|
+
@root = @root.new
|
197
|
+
|
198
|
+
@leaf = @root
|
199
|
+
3.times do |i|
|
200
|
+
child = Class.new(VirtualBox::AbstractModel)
|
201
|
+
child.attribute(:parent, :readonly => true, :property => false)
|
202
|
+
child = child.new
|
203
|
+
child.write_attribute(:parent, @leaf)
|
204
|
+
@leaf = child
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
should "get the parent" do
|
209
|
+
# Sanity test
|
210
|
+
assert_equal @root, @leaf.parent.parent.parent
|
211
|
+
assert @root.is_a?(VirtualBox::VM)
|
212
|
+
|
213
|
+
# Actual test
|
214
|
+
assert_equal @root, @leaf.parent_machine
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
200
218
|
context "subclasses" do
|
201
219
|
class FakeTwoModel < FakeModel
|
202
220
|
attribute :baz
|
@@ -2,6 +2,8 @@ require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
|
2
2
|
|
3
3
|
class ForwardedPortTest < Test::Unit::TestCase
|
4
4
|
setup do
|
5
|
+
@klass = VirtualBox::ForwardedPort
|
6
|
+
|
5
7
|
@nic = mock("nic")
|
6
8
|
@nic.stubs(:adapter_type).returns(:foo)
|
7
9
|
@nics = [@nic]
|
@@ -16,7 +18,7 @@ class ForwardedPortTest < Test::Unit::TestCase
|
|
16
18
|
setup do
|
17
19
|
@collection = VirtualBox::Proxies::Collection.new(@caller)
|
18
20
|
|
19
|
-
@port =
|
21
|
+
@port = @klass.new
|
20
22
|
@port.name = "foo"
|
21
23
|
@port.guestport = "22"
|
22
24
|
@port.hostport = "2222"
|
@@ -50,7 +52,7 @@ class ForwardedPortTest < Test::Unit::TestCase
|
|
50
52
|
|
51
53
|
context "with an instance" do
|
52
54
|
setup do
|
53
|
-
@port =
|
55
|
+
@port = @klass.new({
|
54
56
|
:name => "foo",
|
55
57
|
:guestport => "22",
|
56
58
|
:hostport => "2222"
|
@@ -68,6 +70,20 @@ class ForwardedPortTest < Test::Unit::TestCase
|
|
68
70
|
@caller.stubs(:extra_data).returns(@ed)
|
69
71
|
end
|
70
72
|
|
73
|
+
context "initializing a new record" do
|
74
|
+
setup do
|
75
|
+
@port = @klass.new
|
76
|
+
end
|
77
|
+
|
78
|
+
should "be a new record" do
|
79
|
+
assert @port.new_record?
|
80
|
+
end
|
81
|
+
|
82
|
+
should "not be dirty" do
|
83
|
+
assert !@port.changed?
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
71
87
|
context "device" do
|
72
88
|
setup do
|
73
89
|
@port.new_record!
|
@@ -149,7 +165,8 @@ class ForwardedPortTest < Test::Unit::TestCase
|
|
149
165
|
context "a new record" do
|
150
166
|
setup do
|
151
167
|
@port.stubs(:valid?).returns(true)
|
152
|
-
|
168
|
+
@port.new_record!
|
169
|
+
assert @port.new_record?
|
153
170
|
end
|
154
171
|
|
155
172
|
should "no longer be a new record after saving" do
|