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.
- data/.gitignore +4 -0
- data/Gemfile +11 -0
- data/Rakefile +32 -0
- data/Readme.md +75 -0
- data/TODO +13 -0
- data/VERSION +1 -0
- data/lib/virtualbox.rb +11 -0
- data/lib/virtualbox/abstract_model.rb +95 -0
- data/lib/virtualbox/abstract_model/attributable.rb +193 -0
- data/lib/virtualbox/abstract_model/dirty.rb +164 -0
- data/lib/virtualbox/abstract_model/relatable.rb +163 -0
- data/lib/virtualbox/attached_device.rb +104 -0
- data/lib/virtualbox/command.rb +54 -0
- data/lib/virtualbox/dvd.rb +31 -0
- data/lib/virtualbox/errors.rb +7 -0
- data/lib/virtualbox/ext/subclass_listing.rb +24 -0
- data/lib/virtualbox/hard_drive.rb +169 -0
- data/lib/virtualbox/image.rb +94 -0
- data/lib/virtualbox/nic.rb +150 -0
- data/lib/virtualbox/storage_controller.rb +122 -0
- data/lib/virtualbox/vm.rb +287 -0
- data/test/test_helper.rb +25 -0
- data/test/virtualbox/abstract_model/attributable_test.rb +150 -0
- data/test/virtualbox/abstract_model/dirty_test.rb +66 -0
- data/test/virtualbox/abstract_model/relatable_test.rb +141 -0
- data/test/virtualbox/abstract_model_test.rb +146 -0
- data/test/virtualbox/attached_device_test.rb +92 -0
- data/test/virtualbox/command_test.rb +30 -0
- data/test/virtualbox/dvd_test.rb +58 -0
- data/test/virtualbox/ext/subclass_listing_test.rb +25 -0
- data/test/virtualbox/hard_drive_test.rb +161 -0
- data/test/virtualbox/image_test.rb +113 -0
- data/test/virtualbox/nic_test.rb +119 -0
- data/test/virtualbox/storage_controller_test.rb +79 -0
- data/test/virtualbox/vm_test.rb +313 -0
- metadata +103 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
2
|
+
|
3
|
+
class DirtyTest < Test::Unit::TestCase
|
4
|
+
class DirtyModel
|
5
|
+
include VirtualBox::AbstractModel::Dirty
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@foo = "foo"
|
9
|
+
@bar = "bar"
|
10
|
+
end
|
11
|
+
|
12
|
+
def foo=(value)
|
13
|
+
set_dirty!(:foo, @foo, value)
|
14
|
+
@foo = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def bar=(value)
|
18
|
+
set_dirty!(:bar, @bar, value)
|
19
|
+
@bar = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "dirty attributes" do
|
24
|
+
setup do
|
25
|
+
@model = DirtyModel.new
|
26
|
+
end
|
27
|
+
|
28
|
+
should "not be dirty initially" do
|
29
|
+
assert !@model.changed?
|
30
|
+
end
|
31
|
+
|
32
|
+
should "be dirty after changing an attribute" do
|
33
|
+
assert !@model.changed? # sanity
|
34
|
+
@model.foo = "my value"
|
35
|
+
assert @model.changed?
|
36
|
+
end
|
37
|
+
|
38
|
+
should "be able to clear dirty state" do
|
39
|
+
assert !@model.changed?
|
40
|
+
@model.foo = "my value"
|
41
|
+
assert @model.changed?
|
42
|
+
@model.clear_dirty!(:foo)
|
43
|
+
assert !@model.changed?
|
44
|
+
end
|
45
|
+
|
46
|
+
should "show changes on specific field" do
|
47
|
+
assert !@model.changed?
|
48
|
+
@model.foo = "my value"
|
49
|
+
assert @model.foo_changed?
|
50
|
+
assert_equal ["foo", "my value"], @model.foo_change
|
51
|
+
assert_equal "foo", @model.foo_was
|
52
|
+
end
|
53
|
+
|
54
|
+
should "show changes for the whole model" do
|
55
|
+
assert !@model.changed?
|
56
|
+
@model.foo = "foo2"
|
57
|
+
@model.bar = "bar2"
|
58
|
+
|
59
|
+
assert @model.changed?
|
60
|
+
changes = @model.changes
|
61
|
+
assert_equal 2, changes.length
|
62
|
+
assert_equal ["foo", "foo2"], changes[:foo]
|
63
|
+
assert_equal ["bar", "bar2"], changes[:bar]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
2
|
+
|
3
|
+
class RelatableTest < Test::Unit::TestCase
|
4
|
+
class Relatee
|
5
|
+
def self.populate_relationship(caller, data)
|
6
|
+
"FOO"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
class BarRelatee; end
|
10
|
+
|
11
|
+
class RelatableModel
|
12
|
+
include VirtualBox::AbstractModel::Relatable
|
13
|
+
|
14
|
+
relationship :foos, Relatee
|
15
|
+
relationship :bars, BarRelatee
|
16
|
+
end
|
17
|
+
|
18
|
+
setup do
|
19
|
+
@data = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
context "subclasses" do
|
23
|
+
class SubRelatableModel < RelatableModel
|
24
|
+
relationship :bars, Relatee
|
25
|
+
end
|
26
|
+
|
27
|
+
setup do
|
28
|
+
@relationships = SubRelatableModel.relationships
|
29
|
+
end
|
30
|
+
|
31
|
+
should "inherit relationships of parent" do
|
32
|
+
assert @relationships.has_key?(:foos)
|
33
|
+
assert @relationships.has_key?(:bars)
|
34
|
+
end
|
35
|
+
|
36
|
+
should "inherit options of relationships" do
|
37
|
+
assert_equal Relatee, @relationships[:foos][:klass]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "default callbacks" do
|
42
|
+
setup do
|
43
|
+
@model = RelatableModel.new
|
44
|
+
end
|
45
|
+
|
46
|
+
should "not raise an error if populate_relationship doesn't exist" do
|
47
|
+
assert !BarRelatee.respond_to?(:populate_relationship)
|
48
|
+
assert_nothing_raised { @model.populate_relationships(nil) }
|
49
|
+
end
|
50
|
+
|
51
|
+
should "not raise an error when saving relationships if the callback doesn't exist" do
|
52
|
+
assert !Relatee.respond_to?(:save_relationship)
|
53
|
+
assert_nothing_raised { @model.save_relationships }
|
54
|
+
end
|
55
|
+
|
56
|
+
should "not raise an error in destroying relationships if the callback doesn't exist" do
|
57
|
+
assert !Relatee.respond_to?(:destroy_relationship)
|
58
|
+
assert_nothing_raised { @model.destroy_relationships }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "destroying" do
|
63
|
+
setup do
|
64
|
+
@model = RelatableModel.new
|
65
|
+
@model.populate_relationships({})
|
66
|
+
end
|
67
|
+
|
68
|
+
context "a single relationship" do
|
69
|
+
should "call destroy_relationship only for the given relationship" do
|
70
|
+
Relatee.expects(:destroy_relationship).once
|
71
|
+
BarRelatee.expects(:destroy_relationship).never
|
72
|
+
@model.destroy_relationship(:foos)
|
73
|
+
end
|
74
|
+
|
75
|
+
should "forward any args passed into destroy_relationship" do
|
76
|
+
Relatee.expects(:destroy_relationship).with(@model, anything, "HELLO").once
|
77
|
+
@model.destroy_relationship(:foos, "HELLO")
|
78
|
+
end
|
79
|
+
|
80
|
+
should "pass the data into destroy_relationship" do
|
81
|
+
Relatee.expects(:destroy_relationship).with(@model, "FOO").once
|
82
|
+
@model.destroy_relationship(:foos)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "all relationships" do
|
87
|
+
should "call destroy_relationship on the related class" do
|
88
|
+
Relatee.expects(:destroy_relationship).with(@model, anything).once
|
89
|
+
@model.destroy_relationships
|
90
|
+
end
|
91
|
+
|
92
|
+
should "forward any args passed into destroy relationships" do
|
93
|
+
Relatee.expects(:destroy_relationship).with(@model, anything, "HELLO").once
|
94
|
+
@model.destroy_relationships("HELLO")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "saving relationships" do
|
100
|
+
setup do
|
101
|
+
@model = RelatableModel.new
|
102
|
+
end
|
103
|
+
|
104
|
+
should "call save_relationship on the related class" do
|
105
|
+
Relatee.expects(:save_relationship).with(@model, @model.foos).once
|
106
|
+
@model.save_relationships
|
107
|
+
end
|
108
|
+
|
109
|
+
should "forward parameters through" do
|
110
|
+
Relatee.expects(:save_relationship).with(@model, @model.foos, "YES").once
|
111
|
+
@model.save_relationships("YES")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "reading relationships" do
|
116
|
+
setup do
|
117
|
+
@model = RelatableModel.new
|
118
|
+
end
|
119
|
+
|
120
|
+
should "provide a read method for relationships" do
|
121
|
+
assert_nothing_raised { @model.foos }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "populating relationships" do
|
126
|
+
setup do
|
127
|
+
@model = RelatableModel.new
|
128
|
+
end
|
129
|
+
|
130
|
+
should "call populate_relationship on the related class" do
|
131
|
+
Relatee.expects(:populate_relationship).with(@model, @data).once
|
132
|
+
@model.populate_relationships(@data)
|
133
|
+
end
|
134
|
+
|
135
|
+
should "properly save returned value as the value for the relationship" do
|
136
|
+
Relatee.expects(:populate_relationship).once.returns("HEY")
|
137
|
+
@model.populate_relationships(@data)
|
138
|
+
assert_equal "HEY", @model.foos
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
2
|
+
|
3
|
+
class AbstractModelTest < Test::Unit::TestCase
|
4
|
+
class Foo; end
|
5
|
+
class Bar; end
|
6
|
+
|
7
|
+
class FakeModel < VirtualBox::AbstractModel
|
8
|
+
attribute :foo
|
9
|
+
attribute :bar
|
10
|
+
relationship :foos, Foo
|
11
|
+
relationship :bars, Bar, :dependent => :destroy
|
12
|
+
end
|
13
|
+
|
14
|
+
context "new/existing records" do
|
15
|
+
setup do
|
16
|
+
@model = FakeModel.new
|
17
|
+
end
|
18
|
+
|
19
|
+
should "be a new record by default" do
|
20
|
+
assert @model.new_record?
|
21
|
+
end
|
22
|
+
|
23
|
+
should "not be a new record if populate_attributes is called" do
|
24
|
+
@model.populate_attributes({})
|
25
|
+
assert !@model.new_record?
|
26
|
+
end
|
27
|
+
|
28
|
+
should "not be a new record after saving" do
|
29
|
+
assert @model.new_record?
|
30
|
+
@model.save
|
31
|
+
assert !@model.new_record?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "subclasses" do
|
36
|
+
class FakeTwoModel < FakeModel
|
37
|
+
attribute :baz
|
38
|
+
end
|
39
|
+
|
40
|
+
setup do
|
41
|
+
@model = FakeTwoModel.new
|
42
|
+
@model.populate_attributes({
|
43
|
+
:foo => "foo",
|
44
|
+
:bar => "bar",
|
45
|
+
:baz => "baz"
|
46
|
+
})
|
47
|
+
end
|
48
|
+
|
49
|
+
should "have access to parents attributes" do
|
50
|
+
assert_nothing_raised do
|
51
|
+
assert_equal "foo", @model.foo
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "destroying" do
|
57
|
+
setup do
|
58
|
+
@model = FakeModel.new
|
59
|
+
end
|
60
|
+
|
61
|
+
should "call destroy_relationship only for dependent relationships" do
|
62
|
+
Foo.expects(:destroy_relationship).never
|
63
|
+
Bar.expects(:destroy_relationship).once
|
64
|
+
|
65
|
+
@model.destroy
|
66
|
+
end
|
67
|
+
|
68
|
+
should "forward any arguments to the destroy method" do
|
69
|
+
Bar.expects(:destroy_relationship).with(@model, anything, "HELLO").once
|
70
|
+
@model.destroy("HELLO")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "saving" do
|
75
|
+
setup do
|
76
|
+
@model = FakeModel.new
|
77
|
+
@model.populate_attributes({
|
78
|
+
:foo => "foo",
|
79
|
+
:bar => "bar"
|
80
|
+
})
|
81
|
+
end
|
82
|
+
|
83
|
+
should "call save_attribute for only attributes which have changed" do
|
84
|
+
@model.foo = "foo2"
|
85
|
+
assert @model.foo_changed?
|
86
|
+
assert !@model.bar_changed?
|
87
|
+
@model.expects(:save_attribute).with(:foo, "foo2").once
|
88
|
+
@model.save
|
89
|
+
end
|
90
|
+
|
91
|
+
should "call save_relationships" do
|
92
|
+
@model.expects(:save_relationships).once
|
93
|
+
@model.save
|
94
|
+
end
|
95
|
+
|
96
|
+
should "clear dirty state once saved" do
|
97
|
+
@model.foo = "foo2"
|
98
|
+
assert @model.foo_changed?
|
99
|
+
@model.save
|
100
|
+
assert !@model.foo_changed?
|
101
|
+
end
|
102
|
+
|
103
|
+
should "forward parameters through" do
|
104
|
+
@model.expects(:save_attribute).with(:foo, "foo2", "YES").once
|
105
|
+
Foo.expects(:save_relationship).with(@model, anything, "YES").once
|
106
|
+
|
107
|
+
@model.foo = "foo2"
|
108
|
+
@model.save("YES")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "populating relationships and attributes" do
|
113
|
+
setup do
|
114
|
+
@model = FakeModel.new
|
115
|
+
end
|
116
|
+
|
117
|
+
should "populate relationships at the same time as attributes" do
|
118
|
+
Foo.expects(:populate_relationship).once
|
119
|
+
@model.populate_attributes({})
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "integrating attributable and dirty" do
|
124
|
+
setup do
|
125
|
+
@model = FakeModel.new
|
126
|
+
end
|
127
|
+
|
128
|
+
should "not affect dirtiness with populate_attributes" do
|
129
|
+
assert !@model.changed?
|
130
|
+
@model.populate_attributes({
|
131
|
+
:foo => "foo2"
|
132
|
+
})
|
133
|
+
|
134
|
+
assert !@model.changed?
|
135
|
+
assert_equal "foo2", @model.foo
|
136
|
+
end
|
137
|
+
|
138
|
+
should "mark dirtiness on write_attribute" do
|
139
|
+
assert !@model.changed?
|
140
|
+
@model.write_attribute(:foo, "foo2")
|
141
|
+
assert @model.changed?
|
142
|
+
assert @model.foo_changed?
|
143
|
+
assert_equal "foo2", @model.foo
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'test_helper')
|
2
|
+
|
3
|
+
class AttachedDeviceTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
@data = {
|
6
|
+
:"foo controller-0-0" => "foomedium",
|
7
|
+
:"foo controller-imageuuid-0-0" => "322f79fd-7da6-416f-a16f-e70066ccf165",
|
8
|
+
:"foo controller-1-0" => "barmedium"
|
9
|
+
}
|
10
|
+
|
11
|
+
@vm = mock("vm")
|
12
|
+
@vm.stubs(:name).returns("foo")
|
13
|
+
|
14
|
+
@caller = mock("caller")
|
15
|
+
@caller.stubs(:parent).returns(@vm)
|
16
|
+
@caller.stubs(:name).returns("Foo Controller")
|
17
|
+
|
18
|
+
# Stub execute to make sure nothing actually happens
|
19
|
+
VirtualBox::Command.stubs(:execute).returns('')
|
20
|
+
end
|
21
|
+
|
22
|
+
context "destroying" do
|
23
|
+
setup do
|
24
|
+
@value = VirtualBox::AttachedDevice.populate_relationship(@caller, @data)
|
25
|
+
@value = @value[0]
|
26
|
+
|
27
|
+
@image = mock("image")
|
28
|
+
@value.stubs(:image).returns(@image)
|
29
|
+
|
30
|
+
VirtualBox::Command.stubs(:execute)
|
31
|
+
end
|
32
|
+
|
33
|
+
should "simply call destroy on each object when destroying the relationship" do
|
34
|
+
obj_one = mock("one")
|
35
|
+
obj_two = mock("two")
|
36
|
+
|
37
|
+
obj_one.expects(:destroy).with("HELLO").once
|
38
|
+
obj_two.expects(:destroy).with("HELLO").once
|
39
|
+
|
40
|
+
VirtualBox::AttachedDevice.destroy_relationship(self, [obj_one, obj_two], "HELLO")
|
41
|
+
end
|
42
|
+
|
43
|
+
should "shell escape VM name and storage controller name" do
|
44
|
+
shell_seq = sequence("shell_seq")
|
45
|
+
VirtualBox::Command.expects(:shell_escape).with(@vm.name).in_sequence(shell_seq)
|
46
|
+
VirtualBox::Command.expects(:shell_escape).with(@caller.name).in_sequence(shell_seq)
|
47
|
+
VirtualBox::Command.expects(:vboxmanage).in_sequence(shell_seq)
|
48
|
+
@value.destroy
|
49
|
+
end
|
50
|
+
|
51
|
+
should "not destroy image by default" do
|
52
|
+
@image.expects(:destroy).never
|
53
|
+
@value.destroy
|
54
|
+
end
|
55
|
+
|
56
|
+
should "destroy image if flag is set" do
|
57
|
+
@image.expects(:destroy).once
|
58
|
+
@value.destroy({
|
59
|
+
:destroy_image => true
|
60
|
+
})
|
61
|
+
end
|
62
|
+
|
63
|
+
should "ignore destroy image flag if image is nil" do
|
64
|
+
@value.expects(:image).once.returns(nil)
|
65
|
+
@value.destroy({
|
66
|
+
:destroy_image => true
|
67
|
+
})
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "populating relationships" do
|
72
|
+
setup do
|
73
|
+
@value = VirtualBox::AttachedDevice.populate_relationship(@caller, @data)
|
74
|
+
end
|
75
|
+
|
76
|
+
should "create the correct amount of objects" do
|
77
|
+
assert_equal 2, @value.length
|
78
|
+
end
|
79
|
+
|
80
|
+
should "create objects with proper values" do
|
81
|
+
obj = @value[0]
|
82
|
+
assert_equal "foomedium", obj.medium
|
83
|
+
assert_equal "322f79fd-7da6-416f-a16f-e70066ccf165", obj.uuid
|
84
|
+
assert_equal 0, obj.port
|
85
|
+
|
86
|
+
obj = @value[1]
|
87
|
+
assert_equal "barmedium", obj.medium
|
88
|
+
assert_nil obj.uuid
|
89
|
+
assert_equal 1, obj.port
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|