virtualbox 0.7.2 → 0.7.3
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/Gemfile +16 -3
- data/Rakefile +4 -48
- data/Readme.md +2 -3
- data/VERSION +1 -1
- data/features/README.md +33 -0
- data/features/global.feature +19 -0
- data/features/global_extra_data.feature +27 -0
- data/features/step_definitions/abstract_model_steps.rb +35 -0
- data/features/step_definitions/extra_data_steps.rb +36 -0
- data/features/step_definitions/global_steps.rb +29 -0
- data/features/step_definitions/network_adapter_steps.rb +38 -0
- data/features/step_definitions/shared_folder_steps.rb +57 -0
- data/features/step_definitions/storage_controller_steps.rb +16 -0
- data/features/step_definitions/virtualbox_steps.rb +17 -0
- data/features/step_definitions/vm_steps.rb +50 -0
- data/features/support/env.rb +56 -0
- data/features/support/helpers.rb +23 -0
- data/features/support/hooks.rb +30 -0
- data/features/support/vboxmanage.rb +110 -0
- data/features/version.feature +16 -0
- data/features/vm.feature +13 -0
- data/features/vm_bios.feature +29 -0
- data/features/vm_cpu.feature +29 -0
- data/features/vm_extra_data.feature +35 -0
- data/features/vm_hw_virt.feature +29 -0
- data/features/vm_network_adapters.feature +27 -0
- data/features/vm_shared_folders.feature +29 -0
- data/features/vm_storage_controllers.feature +11 -0
- data/lib/virtualbox/abstract_model/version_matcher.rb +2 -0
- data/lib/virtualbox/version.rb +1 -1
- data/lib/virtualbox/vm.rb +0 -2
- data/tasks/cucumber.task +13 -0
- data/tasks/jeweler.task +21 -0
- data/tasks/rcov.task +15 -0
- data/tasks/test.task +10 -0
- data/tasks/yard.task +9 -0
- data/test/virtualbox/abstract_model/version_matcher_test.rb +4 -0
- data/test/virtualbox/version_test.rb +2 -3
- data/virtualbox.gemspec +31 -2
- metadata +32 -3
data/Gemfile
CHANGED
@@ -3,10 +3,23 @@ source :gemcutter
|
|
3
3
|
# External Dependencies
|
4
4
|
gem "ffi"
|
5
5
|
|
6
|
-
# Gems required for
|
7
|
-
group :
|
6
|
+
# Gems required for development only.
|
7
|
+
group :development do
|
8
|
+
# Gem and docs
|
9
|
+
gem "jeweler"
|
10
|
+
gem "yard"
|
11
|
+
|
12
|
+
# Unit tests
|
8
13
|
gem "contest", ">= 0.1.2"
|
9
14
|
gem "mocha"
|
15
|
+
gem "rcov"
|
16
|
+
|
17
|
+
# Integration tests
|
18
|
+
gem "cucumber", "~> 0.8.0"
|
19
|
+
gem "aruba", "~> 0.1.9"
|
20
|
+
gem "rspec"
|
21
|
+
|
22
|
+
# Generally good to have
|
10
23
|
gem "ruby-debug", ">= 0.10.3" if RUBY_VERSION < '1.9'
|
11
24
|
gem "ruby-debug19", ">= 0.11.6" if RUBY_VERSION >= '1.9'
|
12
|
-
end
|
25
|
+
end
|
data/Rakefile
CHANGED
@@ -1,49 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
gemspec.summary = "Create and modify virtual machines in VirtualBox using pure ruby."
|
6
|
-
gemspec.description = "Create and modify virtual machines in VirtualBox using pure ruby."
|
7
|
-
gemspec.email = "mitchell.hashimoto@gmail.com"
|
8
|
-
gemspec.homepage = "http://github.com/mitchellh/virtualbox"
|
9
|
-
gemspec.authors = ["Mitchell Hashimoto"]
|
10
|
-
gemspec.executables = []
|
11
|
-
|
12
|
-
gemspec.add_dependency('ffi', '>= 0.6.3')
|
13
|
-
end
|
14
|
-
Jeweler::GemcutterTasks.new
|
15
|
-
rescue LoadError
|
16
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
1
|
+
# Tests are placed into *.task files in the tasks/ directory since
|
2
|
+
# the Rakefile was getting quite large and intimidating to approach.
|
3
|
+
Dir[File.join(File.dirname(__FILE__), "tasks", "**", "*.task")].each do |f|
|
4
|
+
load f
|
17
5
|
end
|
18
|
-
|
19
|
-
require 'rake/testtask'
|
20
|
-
|
21
|
-
task :default => :test
|
22
|
-
|
23
|
-
Rake::TestTask.new do |t|
|
24
|
-
t.libs << "test"
|
25
|
-
t.pattern = 'test/**/*_test.rb'
|
26
|
-
end
|
27
|
-
|
28
|
-
begin
|
29
|
-
require 'yard'
|
30
|
-
YARD::Rake::YardocTask.new do |t|
|
31
|
-
t.options = ['--main', 'Readme.md', '--markup', 'markdown']
|
32
|
-
t.options += ['--title', 'VirtualBox Ruby Library Documentation']
|
33
|
-
end
|
34
|
-
rescue LoadError
|
35
|
-
puts "Yard not available. Install it with: gem install yard bluecloth"
|
36
|
-
end
|
37
|
-
|
38
|
-
begin
|
39
|
-
require 'rcov/rcovtask'
|
40
|
-
Rcov::RcovTask.new do |t|
|
41
|
-
t.libs << "test"
|
42
|
-
t.test_files = FileList["test/**/*_test.rb"]
|
43
|
-
t.output_dir = "test/coverage"
|
44
|
-
t.verbose = true
|
45
|
-
end
|
46
|
-
rescue LoadError
|
47
|
-
puts "Rcov not available. Coverage data tasks not available."
|
48
|
-
puts "Install it with: gem install rcov"
|
49
|
-
end
|
data/Readme.md
CHANGED
@@ -56,8 +56,7 @@ If you'd like to contribute to VirtualBox, the first step to developing is to
|
|
56
56
|
clone this repo, get [bundler](http://github.com/carlhuda/bundler) if you
|
57
57
|
don't have it already, and do the following:
|
58
58
|
|
59
|
-
bundle install
|
60
|
-
bundle lock
|
59
|
+
bundle install --relock
|
61
60
|
rake
|
62
61
|
|
63
62
|
This will run the test suite, which should come back all green! Then you're good to go!
|
@@ -68,4 +67,4 @@ These folks went above and beyond with contributions to the virtualbox gem, and
|
|
68
67
|
for that, I have to say "thanks!"
|
69
68
|
|
70
69
|
* [Kieran Pilkington](http://github.com/KieranP)
|
71
|
-
* [Aleksey Palazhchenko](http://github.com/AlekSi)
|
70
|
+
* [Aleksey Palazhchenko](http://github.com/AlekSi)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.3
|
data/features/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# VirtualBox Gem Feature Tests
|
2
|
+
|
3
|
+
**Warning: These tests actually hit the real VirtualBox software!**
|
4
|
+
|
5
|
+
The tests in this directory are _not_ meant as a replacement
|
6
|
+
for the unit tests in the `test/` directory. Instead, these
|
7
|
+
features are meant to test the actual integration of the
|
8
|
+
virtualbox gem with an actual VirtualBox installation.
|
9
|
+
|
10
|
+
Whereas the unit tests try to test every branch of the code in a
|
11
|
+
very prescribed, isolated environment, the feature tests do not
|
12
|
+
test specific branches of code, but test behavior of the gem.
|
13
|
+
The reasoning for both tests is that the unit tests test proper
|
14
|
+
behavior _within the library itself_ whereas these feature tests
|
15
|
+
test proper behavior _with the outside world_.
|
16
|
+
|
17
|
+
## Running Feature Tests
|
18
|
+
|
19
|
+
The easiest way to run these feature tests is via `rake` or the
|
20
|
+
`cucumber` binary. `rake` shown below:
|
21
|
+
|
22
|
+
rake test:integration
|
23
|
+
|
24
|
+
## Feature Coverage
|
25
|
+
|
26
|
+
The test coverage of the features are purposefully not trying to
|
27
|
+
reach 100% branch coverage. They test the basic functionality (and
|
28
|
+
as much as the functionality as possible) to verify the library is
|
29
|
+
functional. If a bug is found, then a feature should be added to
|
30
|
+
reproduce and verify the bug no longer exists, but I'm not concerned
|
31
|
+
with getting 100% branch coverage right away.
|
32
|
+
|
33
|
+
For 100% branch coverage, see the unit tests, which do this.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Feature: Global Data
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to access information about the global state of VirtualBox
|
4
|
+
In order to get information about my environment
|
5
|
+
|
6
|
+
Scenario: Reading the VMs
|
7
|
+
Given the global object
|
8
|
+
When I read the "vms"
|
9
|
+
Then I should get a matching length for "vms"
|
10
|
+
|
11
|
+
Scenario: Reading the hard drives
|
12
|
+
Given the global object
|
13
|
+
When I read the media "hard drives"
|
14
|
+
Then I should get a matching length of media items
|
15
|
+
|
16
|
+
Scenario: Reading the dvds
|
17
|
+
Given the global object
|
18
|
+
When I read the media "dvds"
|
19
|
+
Then I should get a matching length of media items
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Feature: Global Extra Data
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to access and update global extra data
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given the global object
|
7
|
+
And I delete the "global" extra data "VirtualBoxGemTest/Key"
|
8
|
+
And the "extra_data" relationship
|
9
|
+
|
10
|
+
Scenario: Reading extra data
|
11
|
+
When I get the extra data of "global"
|
12
|
+
Then all the extra data should match
|
13
|
+
|
14
|
+
@unsafe
|
15
|
+
Scenario: Writing extra data
|
16
|
+
When I set the extra data "VirtualBoxGemTest/Key" to "Value"
|
17
|
+
And I save the relationship
|
18
|
+
And I get the extra data of "global"
|
19
|
+
Then the extra data should include "VirtualBoxGemTest/Key" as "Value"
|
20
|
+
|
21
|
+
@unsafe
|
22
|
+
Scenario: Deleting extra data
|
23
|
+
When I set the extra data "VirtualBoxGemTest/Key" to "Value"
|
24
|
+
And I save the relationship
|
25
|
+
And I delete the extra data "VirtualBoxGemTest/Key"
|
26
|
+
And I get the extra data of "global"
|
27
|
+
Then the extra data should not include "VirtualBoxGemTest/Key"
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Given /the "(.+?)" relationship/ do |relationship|
|
2
|
+
@relationship = @model.send(relationship)
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /I reload the model/ do
|
6
|
+
@model.reload
|
7
|
+
end
|
8
|
+
|
9
|
+
When /I read the "(.+?)"/ do |property|
|
10
|
+
@value = @model.send(property)
|
11
|
+
end
|
12
|
+
|
13
|
+
When /I set the property "(.+?)" to "(.+?)"/ do |key, value|
|
14
|
+
value = value == "true" if %W[true false].include?(value)
|
15
|
+
@model.send("#{key}=", value)
|
16
|
+
end
|
17
|
+
|
18
|
+
When /I set the relationship property "(.+?)" to "(.+?)"/ do |key, value|
|
19
|
+
old = @model
|
20
|
+
@model = @relationship
|
21
|
+
When %Q[I set the property "#{key}" to "#{value}"]
|
22
|
+
@model = old
|
23
|
+
end
|
24
|
+
|
25
|
+
When /I add the new record to the relationship/ do
|
26
|
+
@relationship << @new_record
|
27
|
+
end
|
28
|
+
|
29
|
+
When /I save the relationship/ do
|
30
|
+
@relationship.save
|
31
|
+
end
|
32
|
+
|
33
|
+
When /I save the model/ do
|
34
|
+
@model.save
|
35
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Given /I set the "(.+?)" extra data "(.+?)" to "(.*?)"/ do |name, key, value|
|
2
|
+
name = @name if name == "VM"
|
3
|
+
VBoxManage.execute("setextradata", name, key, value)
|
4
|
+
end
|
5
|
+
|
6
|
+
Given /I delete the "(.+?)" extra data "(.+?)"/ do |name, key|
|
7
|
+
# Same as setting to empty
|
8
|
+
Given %Q[I set the "#{name}" extra data "#{key}" to ""]
|
9
|
+
end
|
10
|
+
|
11
|
+
When /I get the extra data of "(.+?)"/ do |name|
|
12
|
+
@extra_data = VBoxManage.extra_data(name)
|
13
|
+
end
|
14
|
+
|
15
|
+
When /I set the extra data "(.+?)" to "(.+?)"/ do |key, value|
|
16
|
+
@relationship[key] = value
|
17
|
+
end
|
18
|
+
|
19
|
+
When /I delete the extra data "(.+?)"/ do |key|
|
20
|
+
@relationship.delete(key)
|
21
|
+
end
|
22
|
+
|
23
|
+
Then /all the extra data should match/ do
|
24
|
+
@relationship.length.should == @extra_data.length
|
25
|
+
@extra_data.each do |k,v|
|
26
|
+
@relationship[k].should == v
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Then /the extra data should include "(.+?)" as "(.+?)"/ do |key, value|
|
31
|
+
@extra_data[key].should == value
|
32
|
+
end
|
33
|
+
|
34
|
+
Then /the extra data should not include "(.+?)"/ do |key|
|
35
|
+
@extra_data.should_not have_key(key)
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Given /the global object/ do
|
2
|
+
@model = VirtualBox::Global.global(true)
|
3
|
+
end
|
4
|
+
|
5
|
+
When /I read the media "(.+?)"/ do |property|
|
6
|
+
@media = property.gsub(" ", "_").to_sym
|
7
|
+
@value = @model.media.send(@media)
|
8
|
+
end
|
9
|
+
|
10
|
+
Then /I should get a matching length for "vms"/ do
|
11
|
+
output = VBoxManage.execute("list", "vms")
|
12
|
+
@value.length.should == output.split("\n").length
|
13
|
+
end
|
14
|
+
|
15
|
+
Then /I should get a matching length of media items/ do
|
16
|
+
mapping = {
|
17
|
+
:hard_drives => "hdds",
|
18
|
+
:dvds => "dvds",
|
19
|
+
:floppies => "floppies"
|
20
|
+
}
|
21
|
+
|
22
|
+
output = VBoxManage.execute("list", mapping[@media])
|
23
|
+
count = output.split("\n").inject(0) do |acc, line|
|
24
|
+
acc += 1 if line =~ /^UUID:/
|
25
|
+
acc
|
26
|
+
end
|
27
|
+
|
28
|
+
@value.length.should == count
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Given /the adapters are reset/ do
|
2
|
+
VBoxManage.network_adapters(@output).each_with_index do |obj, i|
|
3
|
+
VBoxManage.execute("modifyvm", @name, "--nic#{i+1}", "none")
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
Given /the adapter in slot "(.+?)" is type "(.+?)"/ do |slot, type|
|
8
|
+
VBoxManage.execute("modifyvm", @name, "--nic#{slot}", type)
|
9
|
+
end
|
10
|
+
|
11
|
+
Given /the following adapters are set:/ do |table|
|
12
|
+
table.hashes.each do |hash|
|
13
|
+
Given %Q[the adapter in slot "#{hash["slot"]}" is type "#{hash["type"]}"]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
When /I update the adapter in slot "(.+?)"/ do |slot|
|
18
|
+
adapter = @relationship.find { |na| na.slot == (slot.to_i - 1) }
|
19
|
+
adapter.should_not be_nil
|
20
|
+
|
21
|
+
@model = adapter
|
22
|
+
end
|
23
|
+
|
24
|
+
Then /the network adapter properties should match/ do
|
25
|
+
adapters = VBoxManage.network_adapters(@output)
|
26
|
+
@relationship.length.should == adapters.length
|
27
|
+
|
28
|
+
@relationship.each do |na|
|
29
|
+
adapter = adapters[na.slot + 1]
|
30
|
+
adapter.should_not be_nil
|
31
|
+
|
32
|
+
if na.enabled?
|
33
|
+
test_mappings(NETWORK_ADAPTER_MAPPINGS, na, adapter)
|
34
|
+
else
|
35
|
+
adapter[:type].should == "none"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
Given /I add a shared folder "(.+?)" with path "(.+?)" via VBoxManage/ do |name,hostpath|
|
2
|
+
VBoxManage.execute("sharedfolder", "add", @name,
|
3
|
+
"--name", name,
|
4
|
+
"--hostpath", hostpath)
|
5
|
+
end
|
6
|
+
|
7
|
+
Given /I delete the shared folder "(.+?)" via VBoxManage/ do |name|
|
8
|
+
VBoxManage.execute("sharedfolder", "remove", @name,
|
9
|
+
"--name", name)
|
10
|
+
end
|
11
|
+
|
12
|
+
Given /a shared folder "(.+?)" exists/ do |name|
|
13
|
+
folders = VBoxManage.shared_folders(@output)
|
14
|
+
|
15
|
+
if !folders.keys.include?(name)
|
16
|
+
Given %Q[I add a shared folder "#{name}" with path "/#{name}" via VBoxManage]
|
17
|
+
Given %Q[I reload the VM]
|
18
|
+
Given %Q[the "shared_folders" relationship]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Given /no shared folder "(.+?)" exists/ do |name|
|
23
|
+
folders = VBoxManage.shared_folders(@output)
|
24
|
+
|
25
|
+
if folders.keys.include?(name)
|
26
|
+
Given %Q[I delete the shared folder "#{name}" via VBoxManage]
|
27
|
+
Given %Q[I reload the VM]
|
28
|
+
Given %Q[the "shared_folders" relationship]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
When /I create a new shared folder "(.+?)" with path "(.+?)"/ do |name,hostpath|
|
33
|
+
@new_record = VirtualBox::SharedFolder.new
|
34
|
+
@new_record.name = name
|
35
|
+
@new_record.host_path = hostpath
|
36
|
+
end
|
37
|
+
|
38
|
+
When /I delete the shared folder "(.+?)"$/ do |name|
|
39
|
+
@relationship.each do |sf|
|
40
|
+
sf.destroy if sf.name == name
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Then /the shared folder "(.+?)" should not exist/ do |name|
|
45
|
+
VBoxManage.shared_folders(@output).keys.should_not include(name)
|
46
|
+
end
|
47
|
+
|
48
|
+
Then /the shared folder properties should match/ do
|
49
|
+
folders = VBoxManage.shared_folders(@output)
|
50
|
+
|
51
|
+
@relationship.length.should == folders.length
|
52
|
+
|
53
|
+
@relationship.each do |sf|
|
54
|
+
folder = folders[sf.name]
|
55
|
+
test_mappings(SHARED_FOLDER_MAPPINGS, sf, folder)
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Then /the number of storage controllers should match/ do
|
2
|
+
@relationship.length.should == VBoxManage.storage_controllers(@output).length
|
3
|
+
end
|
4
|
+
|
5
|
+
Then /the storage controller properties should match/ do
|
6
|
+
controllers = VBoxManage.storage_controllers(@output)
|
7
|
+
|
8
|
+
@relationship.each do |sc|
|
9
|
+
controller = controllers[sc.name]
|
10
|
+
controller.should_not be_nil
|
11
|
+
|
12
|
+
test_mappings(STORAGE_MAPPINGS, sc, controller) do |value, output|
|
13
|
+
[value.to_s.downcase.gsub("_",""), output.downcase]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Testing VBoxManage -v output
|
2
|
+
When /I try to read the virtualbox "(.+?)"/ do |item|
|
3
|
+
@key = item.to_sym
|
4
|
+
@result = VirtualBox.send(item)
|
5
|
+
end
|
6
|
+
|
7
|
+
Then /the result should match version output/ do
|
8
|
+
data = VBoxManage.execute("-v").split("r")
|
9
|
+
results = {
|
10
|
+
:version => data[0],
|
11
|
+
:revision => data[1],
|
12
|
+
:supported? => !!data
|
13
|
+
}
|
14
|
+
|
15
|
+
@result.should == results[@key]
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
Given /I set the VM "(.+?)" to "(.+?)"/ do |key, value|
|
2
|
+
VBoxManage.execute("modifyvm", @name, "--#{key}", value)
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /I set the VM properties:/ do |properties|
|
6
|
+
properties.hashes.each do |hash|
|
7
|
+
Given %Q[I set the VM "#{hash["name"]}" to "#{hash["value"]}"]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Given /I reload the VM$/ do
|
12
|
+
Given %Q[I find a VM identified by "#{@name}"]
|
13
|
+
end
|
14
|
+
|
15
|
+
When /I find a VM identified by "(.+?)"/ do |name|
|
16
|
+
@name = name
|
17
|
+
@output = VBoxManage.vm_info(name)
|
18
|
+
@vm = VirtualBox::VM.find(name)
|
19
|
+
@model = @vm
|
20
|
+
end
|
21
|
+
|
22
|
+
When /I reload the VM info$/ do
|
23
|
+
@output = VBoxManage.vm_info(@name)
|
24
|
+
end
|
25
|
+
|
26
|
+
When /I save the VM/ do
|
27
|
+
@vm.save
|
28
|
+
end
|
29
|
+
|
30
|
+
Then /the VM should not exist/ do
|
31
|
+
@output.should be_empty
|
32
|
+
@vm.should be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
Then /the VM should exist/ do
|
36
|
+
@output.should have_key("UUID")
|
37
|
+
@vm.should_not be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
Then /the "(.+?)" properties should match/ do |type|
|
41
|
+
map = {
|
42
|
+
"BIOS" => BIOS_MAPPINGS,
|
43
|
+
"CPU" => CPU_MAPPINGS,
|
44
|
+
"HW virt" => HWVIRT_MAPPINGS,
|
45
|
+
"VM" => VM_MAPPINGS
|
46
|
+
}
|
47
|
+
|
48
|
+
object = type == "VM" ? @vm : @relationship
|
49
|
+
test_mappings(map[type], object, @output)
|
50
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Before everything, load virtualbox, of course
|
2
|
+
require 'spec'
|
3
|
+
require 'aruba'
|
4
|
+
require File.join(File.dirname(__FILE__), %W[.. .. lib virtualbox])
|
5
|
+
|
6
|
+
# Configuration settings/info
|
7
|
+
IntegrationInfo = {
|
8
|
+
:test_unsafe => !!ENV["TEST_UNSAFE"],
|
9
|
+
:vm_name => "test_vm"
|
10
|
+
}
|
11
|
+
|
12
|
+
# Mapping of VirtualBox::VM property keys to attributes in the
|
13
|
+
# `showvminfo` output.
|
14
|
+
VM_MAPPINGS = {
|
15
|
+
:uuid => "UUID",
|
16
|
+
:name => "name",
|
17
|
+
:os_type_id => "ostype",
|
18
|
+
:memory_size => "memory",
|
19
|
+
:vram_size => "vram",
|
20
|
+
:cpu_count => "cpus",
|
21
|
+
:accelerate_3d_enabled => "accelerate3d",
|
22
|
+
:accelerate_2d_video_enabled => "accelerate2dvideo",
|
23
|
+
:clipboard_mode => "clipboard",
|
24
|
+
:monitor_count => "monitorcount"
|
25
|
+
}
|
26
|
+
|
27
|
+
BIOS_MAPPINGS = {
|
28
|
+
:acpi_enabled => "acpi",
|
29
|
+
:io_apic_enabled => "ioapic"
|
30
|
+
}
|
31
|
+
|
32
|
+
HWVIRT_MAPPINGS = {
|
33
|
+
:enabled => "hwvirtex",
|
34
|
+
:exclusive => "hwvirtexexcl",
|
35
|
+
:nested_paging => "nestedpaging",
|
36
|
+
:vpid => "vtxvpid"
|
37
|
+
}
|
38
|
+
|
39
|
+
CPU_MAPPINGS = {
|
40
|
+
:pae => "pae",
|
41
|
+
:synthetic => "synthcpu"
|
42
|
+
}
|
43
|
+
|
44
|
+
STORAGE_MAPPINGS = {
|
45
|
+
:port_count => "portcount",
|
46
|
+
:controller_type => "type"
|
47
|
+
}
|
48
|
+
|
49
|
+
SHARED_FOLDER_MAPPINGS = {
|
50
|
+
:host_path => "path"
|
51
|
+
}
|
52
|
+
|
53
|
+
NETWORK_ADAPTER_MAPPINGS = {
|
54
|
+
:mac_address => "macaddress",
|
55
|
+
:cable_connected => "cableconnected"
|
56
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module VirtualBox
|
2
|
+
module IntegrationHelpers
|
3
|
+
# Tests that given a mappings hash (see `VM_MAPPINGS` in env.rb),
|
4
|
+
# a model, and an output hash (string to string), that all the
|
5
|
+
# mappings from model match output.
|
6
|
+
def test_mappings(mappings, model, output, match=true)
|
7
|
+
mappings.each do |model_key, output_key|
|
8
|
+
value = model.send(model_key)
|
9
|
+
|
10
|
+
if [TrueClass, FalseClass].include?(value.class)
|
11
|
+
# Convert true/false to VirtualBox-style string boolean values
|
12
|
+
value = value ? "on" : "off"
|
13
|
+
end
|
14
|
+
|
15
|
+
output_value = output[output_key.to_sym] || output[output_key]
|
16
|
+
value, output_value = yield value, output_value if block_given?
|
17
|
+
value.to_s.should == output_value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
World(VirtualBox::IntegrationHelpers)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#------------------------------------------------------------
|
2
|
+
# Hooks
|
3
|
+
#------------------------------------------------------------
|
4
|
+
# Unsafe tags specify that a test modifies (writes or deletes)
|
5
|
+
# actual data in VirtualBox.
|
6
|
+
Around('@unsafe') do |scenario, block|
|
7
|
+
block.call if IntegrationInfo[:test_unsafe]
|
8
|
+
end
|
9
|
+
|
10
|
+
Around('@pending') do |scenario, block|
|
11
|
+
# Don't run the block
|
12
|
+
end
|
13
|
+
|
14
|
+
#------------------------------------------------------------
|
15
|
+
# Warning/Info messages about settings.
|
16
|
+
#------------------------------------------------------------
|
17
|
+
if !IntegrationInfo[:test_unsafe]
|
18
|
+
puts <<-MSG
|
19
|
+
========================================================================
|
20
|
+
|
21
|
+
For your own safety, unsafe tests (tests which modify actual VirtualBox
|
22
|
+
data), are disabled unless the environmental variable TEST_UNSAFE is
|
23
|
+
set. To enable unsafe tests, the easiest way is to do the following:
|
24
|
+
|
25
|
+
TEST_UNSAFE=yes rake test:integration
|
26
|
+
|
27
|
+
========================================================================
|
28
|
+
MSG
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,110 @@
|
|
1
|
+
class VBoxManage
|
2
|
+
class << self
|
3
|
+
def command(*args)
|
4
|
+
args = args.dup.flatten
|
5
|
+
args.unshift("-q")
|
6
|
+
"VBoxManage #{args.join(" ")}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute(*args)
|
10
|
+
cmd = command(*args)
|
11
|
+
result = `#{cmd}`.chomp
|
12
|
+
raise Exception.new("Failed command: #{cmd}") if $?.exitstatus != 0
|
13
|
+
result
|
14
|
+
end
|
15
|
+
|
16
|
+
# Gets the extra data for a VM of the given ID and returns it in
|
17
|
+
# hash format.
|
18
|
+
def extra_data(name)
|
19
|
+
output = execute("getextradata", name, "enumerate")
|
20
|
+
|
21
|
+
output.split("\n").inject({}) do |acc, line|
|
22
|
+
acc[$1.to_s] = $2.to_s if line =~ /^Key: (.+?), Value: (.+?)$/
|
23
|
+
acc
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Gets the info for a VM and returns it in hash format.
|
28
|
+
def vm_info(name)
|
29
|
+
output = begin
|
30
|
+
execute("showvminfo", name, "--machinereadable")
|
31
|
+
rescue Exception
|
32
|
+
""
|
33
|
+
end
|
34
|
+
|
35
|
+
output.split("\n").inject({}) do |acc, line|
|
36
|
+
if line =~ /^"?(.+?)"?=(.+?)$/
|
37
|
+
key = $1.to_s
|
38
|
+
value = $2.to_s
|
39
|
+
value = $1.to_s if value =~ /^"(.*?)"$/
|
40
|
+
acc[key] = value
|
41
|
+
end
|
42
|
+
|
43
|
+
acc
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Parses the storage controllers out of VM info output and returns
|
48
|
+
# it in a programmer-friendly hash.
|
49
|
+
def storage_controllers(info)
|
50
|
+
raw = info.inject({}) do |acc, data|
|
51
|
+
k,v = data
|
52
|
+
|
53
|
+
if k =~ /^storagecontroller(.+?)(\d+)$/
|
54
|
+
subkey = $2.to_s
|
55
|
+
acc[subkey] ||= {}
|
56
|
+
acc[subkey][$1.to_s.to_sym] = v
|
57
|
+
end
|
58
|
+
|
59
|
+
acc
|
60
|
+
end
|
61
|
+
|
62
|
+
raw.inject({}) do |acc, data|
|
63
|
+
k,v = data
|
64
|
+
acc[v.delete(:name)] = v
|
65
|
+
acc
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Parses the shared folders out of the VM info output and returns
|
70
|
+
# it in a programmer-friendly hash.
|
71
|
+
def shared_folders(info)
|
72
|
+
raw = info.inject({}) do |acc, data|
|
73
|
+
k,v = data
|
74
|
+
|
75
|
+
if k =~ /^SharedFolder(.+?)MachineMapping(\d+)$/
|
76
|
+
subkey = $2.to_s
|
77
|
+
acc[subkey] ||= {}
|
78
|
+
acc[subkey][$1.to_s.downcase.to_sym] = v
|
79
|
+
end
|
80
|
+
|
81
|
+
acc
|
82
|
+
end
|
83
|
+
|
84
|
+
raw.inject({}) do |acc, data|
|
85
|
+
k,v = data
|
86
|
+
acc[v.delete(:name)] = v
|
87
|
+
acc
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Parses the network adapters out of the VM info output and
|
92
|
+
# returns it in a hash.
|
93
|
+
def network_adapters(info)
|
94
|
+
valid_keys = %W[natnet macaddress cableconnected hostonlyadapter]
|
95
|
+
|
96
|
+
info.inject({}) do |acc, data|
|
97
|
+
k,v = data
|
98
|
+
if k =~ /^nic(\d+)$/
|
99
|
+
acc[$1.to_i] ||= {}
|
100
|
+
acc[$1.to_i][:type] = v
|
101
|
+
elsif k=~ /^(.+?)(\d+)$/ && valid_keys.include?($1.to_s)
|
102
|
+
acc[$2.to_i] ||= {}
|
103
|
+
acc[$2.to_i][$1.to_s.to_sym] = v
|
104
|
+
end
|
105
|
+
|
106
|
+
acc
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: VirtualBox version information
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to access information about the installed version
|
4
|
+
In order to determine if I support this version of VirtualBox
|
5
|
+
|
6
|
+
Scenario: Reading the version
|
7
|
+
When I try to read the virtualbox "version"
|
8
|
+
Then the result should match version output
|
9
|
+
|
10
|
+
Scenario: Reading the revision
|
11
|
+
When I try to read the virtualbox "revision"
|
12
|
+
Then the result should match version output
|
13
|
+
|
14
|
+
Scenario: Checking if VirtualBox supported
|
15
|
+
When I try to read the virtualbox "supported?"
|
16
|
+
Then the result should match version output
|
data/features/vm.feature
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Virtual Machine
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to access information about specific virtual machines
|
4
|
+
In order to get information about VMs in VirtualBox
|
5
|
+
|
6
|
+
Scenario: Finding a non-existent VM
|
7
|
+
When I find a VM identified by "this_should_never_exist1234"
|
8
|
+
Then the VM should not exist
|
9
|
+
|
10
|
+
Scenario: Finding a VM
|
11
|
+
When I find a VM identified by "test_vm_A"
|
12
|
+
Then the VM should exist
|
13
|
+
And the "VM" properties should match
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Virtual Machine BIOS Settings
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to read and update VM BIOS
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I find a VM identified by "test_vm_A"
|
7
|
+
And I set the VM properties:
|
8
|
+
| name | value |
|
9
|
+
| acpi | off |
|
10
|
+
| ioapic | off |
|
11
|
+
And I reload the VM
|
12
|
+
And the "bios" relationship
|
13
|
+
|
14
|
+
Scenario: Reading BIOS
|
15
|
+
Then the "BIOS" properties should match
|
16
|
+
|
17
|
+
@unsafe
|
18
|
+
Scenario: Updating the BIOS
|
19
|
+
When I set the relationship property "acpi_enabled" to "true"
|
20
|
+
And I save the relationship
|
21
|
+
And I reload the VM info
|
22
|
+
Then the "BIOS" properties should match
|
23
|
+
|
24
|
+
@unsafe
|
25
|
+
Scenario: Updating the BIOS via the VM
|
26
|
+
When I set the relationship property "io_apic_enabled" to "true"
|
27
|
+
And I save the model
|
28
|
+
And I reload the VM info
|
29
|
+
Then the "BIOS" properties should match
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Virtual Machine CPU Settings
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to read and update VM CPU settings
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I find a VM identified by "test_vm_A"
|
7
|
+
And I set the VM properties:
|
8
|
+
| name | value |
|
9
|
+
| pae | off |
|
10
|
+
| synthcpu | off |
|
11
|
+
And I reload the VM
|
12
|
+
And the "cpu" relationship
|
13
|
+
|
14
|
+
Scenario: Reading CPU settings
|
15
|
+
Then the "CPU" properties should match
|
16
|
+
|
17
|
+
@unsafe
|
18
|
+
Scenario: Updating the CPU settings
|
19
|
+
When I set the relationship property "pae" to "true"
|
20
|
+
And I save the relationship
|
21
|
+
And I reload the VM info
|
22
|
+
Then the "CPU" properties should match
|
23
|
+
|
24
|
+
@unsafe
|
25
|
+
Scenario: Updating the CPU settings via the VM
|
26
|
+
When I set the relationship property "synthetic" to "true"
|
27
|
+
And I save the model
|
28
|
+
And I reload the VM info
|
29
|
+
Then the "CPU" properties should match
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Feature: VM Extra Data
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to access and update VM extra data
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I find a VM identified by "test_vm_A"
|
7
|
+
And I delete the "VM" extra data "VirtualBoxGemTest/Key"
|
8
|
+
And I reload the VM
|
9
|
+
And the "extra_data" relationship
|
10
|
+
|
11
|
+
Scenario: Reading extra data
|
12
|
+
When I get the extra data of "test_vm_A"
|
13
|
+
Then all the extra data should match
|
14
|
+
|
15
|
+
@unsafe
|
16
|
+
Scenario: Writing extra data
|
17
|
+
When I set the extra data "VirtualBoxGemTest/Key" to "Value"
|
18
|
+
And I save the relationship
|
19
|
+
And I get the extra data of "test_vm_A"
|
20
|
+
Then the extra data should include "VirtualBoxGemTest/Key" as "Value"
|
21
|
+
|
22
|
+
@unsafe
|
23
|
+
Scenario: Deleting extra data
|
24
|
+
When I set the extra data "VirtualBoxGemTest/Key" to "Value"
|
25
|
+
And I save the relationship
|
26
|
+
And I delete the extra data "VirtualBoxGemTest/Key"
|
27
|
+
And I get the extra data of "test_vm_A"
|
28
|
+
Then the extra data should not include "VirtualBoxGemTest/Key"
|
29
|
+
|
30
|
+
@unsafe
|
31
|
+
Scenario: Writing extra data and saving VM
|
32
|
+
When I set the extra data "VirtualBoxGemTest/Key" to "Value"
|
33
|
+
And I save the model
|
34
|
+
And I get the extra data of "test_vm_A"
|
35
|
+
Then the extra data should include "VirtualBoxGemTest/Key" as "Value"
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Virtual Machine HW Virtualization
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to read and update HW Virtualization settings
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I find a VM identified by "test_vm_A"
|
7
|
+
And I set the VM properties:
|
8
|
+
| name | value |
|
9
|
+
| hwvirtex | on |
|
10
|
+
| nestedpaging | on |
|
11
|
+
And I reload the VM
|
12
|
+
And the "hw_virt" relationship
|
13
|
+
|
14
|
+
Scenario: Reading
|
15
|
+
Then the "HW virt" properties should match
|
16
|
+
|
17
|
+
@unsafe
|
18
|
+
Scenario: Updating
|
19
|
+
When I set the relationship property "enabled" to "false"
|
20
|
+
And I save the relationship
|
21
|
+
And I reload the VM info
|
22
|
+
Then the "HW virt" properties should match
|
23
|
+
|
24
|
+
@unsafe
|
25
|
+
Scenario: Updating and saving via VM
|
26
|
+
When I set the relationship property "nested_paging" to "false"
|
27
|
+
And I save the model
|
28
|
+
And I reload the VM info
|
29
|
+
Then the "HW virt" properties should match
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Feature: Virtual Machine Network Adapters
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to read and update network adapters
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I find a VM identified by "test_vm_A"
|
7
|
+
And the "network_adapters" relationship
|
8
|
+
|
9
|
+
@unsafe
|
10
|
+
Scenario: Reading adapters
|
11
|
+
Given the adapters are reset
|
12
|
+
And the following adapters are set:
|
13
|
+
| slot | type |
|
14
|
+
| 1 | nat |
|
15
|
+
Then the network adapter properties should match
|
16
|
+
|
17
|
+
@unsafe
|
18
|
+
Scenario: Updating adapters
|
19
|
+
Given the adapters are reset
|
20
|
+
And the following adapters are set:
|
21
|
+
| slot | type |
|
22
|
+
| 1 | nat |
|
23
|
+
When I update the adapter in slot "1"
|
24
|
+
And I set the property "cable_connected" to "false"
|
25
|
+
And I save the VM
|
26
|
+
And I reload the VM info
|
27
|
+
Then the network adapter properties should match
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Virtual Machine Shared Folders
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to read and update shared folders
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I find a VM identified by "test_vm_A"
|
7
|
+
And the "shared_folders" relationship
|
8
|
+
|
9
|
+
@unsafe
|
10
|
+
Scenario: Reading Shared Folders
|
11
|
+
Given a shared folder "foo" exists
|
12
|
+
Then the shared folder properties should match
|
13
|
+
|
14
|
+
@unsafe
|
15
|
+
Scenario: Creating Shared Folders
|
16
|
+
Given no shared folder "bar" exists
|
17
|
+
When I create a new shared folder "bar" with path "/baz"
|
18
|
+
And I add the new record to the relationship
|
19
|
+
And I save the model
|
20
|
+
And I reload the VM info
|
21
|
+
Then the shared folder properties should match
|
22
|
+
|
23
|
+
@unsafe
|
24
|
+
Scenario: Deleting Shared Folders
|
25
|
+
Given a shared folder "foo" exists
|
26
|
+
When I delete the shared folder "foo"
|
27
|
+
And I reload the VM info
|
28
|
+
Then the shared folder "foo" should not exist
|
29
|
+
Then the shared folder properties should match
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: Virtual Machine Storage Controllers
|
2
|
+
As a virtualbox library user
|
3
|
+
I want to read and update storage controllers on a VM
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I find a VM identified by "test_vm_A"
|
7
|
+
And the "storage_controllers" relationship
|
8
|
+
|
9
|
+
Scenario: Reading Storage Controllers
|
10
|
+
Then the number of storage controllers should match
|
11
|
+
And the storage controller properties should match
|
data/lib/virtualbox/version.rb
CHANGED
data/lib/virtualbox/vm.rb
CHANGED
@@ -295,8 +295,6 @@ module VirtualBox
|
|
295
295
|
validates_numericality_of :memory_balloon_size, :monitor_count
|
296
296
|
validates_inclusion_of :accelerate_3d_enabled, :accelerate_2d_video_enabled, :teleporter_enabled, :in => [true, false]
|
297
297
|
|
298
|
-
validates_format_of :name, :with => /^[\w\d\s-]+$/, :message => 'must only contain letters, numbers, spaces, underscores, and dashes.'
|
299
|
-
|
300
298
|
if !errors_on(:name)
|
301
299
|
# Only validate the name if the name has no errors already
|
302
300
|
vms_of_same_name = self.class.find(name)
|
data/tasks/cucumber.task
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
begin
|
2
|
+
require 'cucumber'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
|
5
|
+
namespace :test do
|
6
|
+
Cucumber::Rake::Task.new(:integration) do |t|
|
7
|
+
t.cucumber_opts = "features --format pretty"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
rescue LoadError
|
11
|
+
puts "Cucumber not available. Feature testing not available."
|
12
|
+
puts "Install it with: gem install cucumber"
|
13
|
+
end
|
data/tasks/jeweler.task
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
|
4
|
+
namespace :gem do
|
5
|
+
Jeweler::Tasks.new do |gemspec|
|
6
|
+
gemspec.name = "virtualbox"
|
7
|
+
gemspec.summary = "Create and modify virtual machines in VirtualBox using pure ruby."
|
8
|
+
gemspec.description = "Create and modify virtual machines in VirtualBox using pure ruby."
|
9
|
+
gemspec.email = "mitchell.hashimoto@gmail.com"
|
10
|
+
gemspec.homepage = "http://github.com/mitchellh/virtualbox"
|
11
|
+
gemspec.authors = ["Mitchell Hashimoto"]
|
12
|
+
gemspec.executables = []
|
13
|
+
|
14
|
+
gemspec.add_dependency('ffi', '>= 0.6.3')
|
15
|
+
end
|
16
|
+
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
end
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
+
end
|
data/tasks/rcov.task
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
begin
|
2
|
+
require 'rcov/rcovtask'
|
3
|
+
|
4
|
+
namespace :test do
|
5
|
+
Rcov::RcovTask.new do |t|
|
6
|
+
t.libs << "test"
|
7
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
8
|
+
t.output_dir = "test/coverage"
|
9
|
+
t.verbose = true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
rescue LoadError
|
13
|
+
puts "Rcov not available. Coverage data tasks not available."
|
14
|
+
puts "Install it with: gem install rcov"
|
15
|
+
end
|
data/tasks/test.task
ADDED
data/tasks/yard.task
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
begin
|
2
|
+
require 'yard'
|
3
|
+
YARD::Rake::YardocTask.new do |t|
|
4
|
+
t.options = ['--main', 'Readme.md', '--markup', 'markdown']
|
5
|
+
t.options += ['--title', 'VirtualBox Ruby Library Documentation']
|
6
|
+
end
|
7
|
+
rescue LoadError
|
8
|
+
puts "Yard not available. Install it with: gem install yard bluecloth"
|
9
|
+
end
|
@@ -33,5 +33,9 @@ class VersionMatcherTest < Test::Unit::TestCase
|
|
33
33
|
assert_equal %W[3 2], @klass.split_version("3.2.0")
|
34
34
|
assert_equal %W[3 1], @klass.split_version("3.1.1.1.1")
|
35
35
|
end
|
36
|
+
|
37
|
+
should "return an empty array if it can't split" do
|
38
|
+
assert_equal [], @klass.split_version(nil)
|
39
|
+
end
|
36
40
|
end
|
37
41
|
end
|
@@ -39,8 +39,7 @@ class VersionTest < Test::Unit::TestCase
|
|
39
39
|
end
|
40
40
|
|
41
41
|
should "return the revision" do
|
42
|
-
|
43
|
-
@
|
44
|
-
assert_equal revision, @module.revision
|
42
|
+
@vbox.expects(:revision).returns(7)
|
43
|
+
assert_equal "7", @module.revision
|
45
44
|
end
|
46
45
|
end
|
data/virtualbox.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{virtualbox}
|
8
|
-
s.version = "0.7.
|
8
|
+
s.version = "0.7.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Mitchell Hashimoto"]
|
12
|
-
s.date = %q{2010-06-
|
12
|
+
s.date = %q{2010-06-28}
|
13
13
|
s.description = %q{Create and modify virtual machines in VirtualBox using pure ruby.}
|
14
14
|
s.email = %q{mitchell.hashimoto@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,6 +25,30 @@ Gem::Specification.new do |s|
|
|
25
25
|
"VERSION",
|
26
26
|
"docs/GettingStarted.md",
|
27
27
|
"docs/WhatsNew.md",
|
28
|
+
"features/README.md",
|
29
|
+
"features/global.feature",
|
30
|
+
"features/global_extra_data.feature",
|
31
|
+
"features/step_definitions/abstract_model_steps.rb",
|
32
|
+
"features/step_definitions/extra_data_steps.rb",
|
33
|
+
"features/step_definitions/global_steps.rb",
|
34
|
+
"features/step_definitions/network_adapter_steps.rb",
|
35
|
+
"features/step_definitions/shared_folder_steps.rb",
|
36
|
+
"features/step_definitions/storage_controller_steps.rb",
|
37
|
+
"features/step_definitions/virtualbox_steps.rb",
|
38
|
+
"features/step_definitions/vm_steps.rb",
|
39
|
+
"features/support/env.rb",
|
40
|
+
"features/support/helpers.rb",
|
41
|
+
"features/support/hooks.rb",
|
42
|
+
"features/support/vboxmanage.rb",
|
43
|
+
"features/version.feature",
|
44
|
+
"features/vm.feature",
|
45
|
+
"features/vm_bios.feature",
|
46
|
+
"features/vm_cpu.feature",
|
47
|
+
"features/vm_extra_data.feature",
|
48
|
+
"features/vm_hw_virt.feature",
|
49
|
+
"features/vm_network_adapters.feature",
|
50
|
+
"features/vm_shared_folders.feature",
|
51
|
+
"features/vm_storage_controllers.feature",
|
28
52
|
"lib/virtualbox.rb",
|
29
53
|
"lib/virtualbox/abstract_model.rb",
|
30
54
|
"lib/virtualbox/abstract_model/attributable.rb",
|
@@ -211,6 +235,11 @@ Gem::Specification.new do |s|
|
|
211
235
|
"lib/virtualbox/virtual_system_description.rb",
|
212
236
|
"lib/virtualbox/vm.rb",
|
213
237
|
"lib/virtualbox/vrdp_server.rb",
|
238
|
+
"tasks/cucumber.task",
|
239
|
+
"tasks/jeweler.task",
|
240
|
+
"tasks/rcov.task",
|
241
|
+
"tasks/test.task",
|
242
|
+
"tasks/yard.task",
|
214
243
|
"test/test_helper.rb",
|
215
244
|
"test/virtualbox/abstract_model/attributable_test.rb",
|
216
245
|
"test/virtualbox/abstract_model/dirty_test.rb",
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 7
|
8
|
-
-
|
9
|
-
version: 0.7.
|
8
|
+
- 3
|
9
|
+
version: 0.7.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Mitchell Hashimoto
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-06-
|
17
|
+
date: 2010-06-28 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -49,6 +49,30 @@ files:
|
|
49
49
|
- VERSION
|
50
50
|
- docs/GettingStarted.md
|
51
51
|
- docs/WhatsNew.md
|
52
|
+
- features/README.md
|
53
|
+
- features/global.feature
|
54
|
+
- features/global_extra_data.feature
|
55
|
+
- features/step_definitions/abstract_model_steps.rb
|
56
|
+
- features/step_definitions/extra_data_steps.rb
|
57
|
+
- features/step_definitions/global_steps.rb
|
58
|
+
- features/step_definitions/network_adapter_steps.rb
|
59
|
+
- features/step_definitions/shared_folder_steps.rb
|
60
|
+
- features/step_definitions/storage_controller_steps.rb
|
61
|
+
- features/step_definitions/virtualbox_steps.rb
|
62
|
+
- features/step_definitions/vm_steps.rb
|
63
|
+
- features/support/env.rb
|
64
|
+
- features/support/helpers.rb
|
65
|
+
- features/support/hooks.rb
|
66
|
+
- features/support/vboxmanage.rb
|
67
|
+
- features/version.feature
|
68
|
+
- features/vm.feature
|
69
|
+
- features/vm_bios.feature
|
70
|
+
- features/vm_cpu.feature
|
71
|
+
- features/vm_extra_data.feature
|
72
|
+
- features/vm_hw_virt.feature
|
73
|
+
- features/vm_network_adapters.feature
|
74
|
+
- features/vm_shared_folders.feature
|
75
|
+
- features/vm_storage_controllers.feature
|
52
76
|
- lib/virtualbox.rb
|
53
77
|
- lib/virtualbox/abstract_model.rb
|
54
78
|
- lib/virtualbox/abstract_model/attributable.rb
|
@@ -235,6 +259,11 @@ files:
|
|
235
259
|
- lib/virtualbox/virtual_system_description.rb
|
236
260
|
- lib/virtualbox/vm.rb
|
237
261
|
- lib/virtualbox/vrdp_server.rb
|
262
|
+
- tasks/cucumber.task
|
263
|
+
- tasks/jeweler.task
|
264
|
+
- tasks/rcov.task
|
265
|
+
- tasks/test.task
|
266
|
+
- tasks/yard.task
|
238
267
|
- test/test_helper.rb
|
239
268
|
- test/virtualbox/abstract_model/attributable_test.rb
|
240
269
|
- test/virtualbox/abstract_model/dirty_test.rb
|