libvirt 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. data/.gitignore +10 -0
  2. data/.yardopts +3 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +12 -0
  5. data/Gemfile.lock +36 -0
  6. data/README.md +83 -0
  7. data/Rakefile +20 -0
  8. data/docs/user_guide.md +259 -0
  9. data/examples/README.md +10 -0
  10. data/examples/create_domain.rb +46 -0
  11. data/examples/print_domain_info.rb +46 -0
  12. data/examples/print_hypervisor_info.rb +40 -0
  13. data/lib/ffi/libvirt/domain_info.rb +12 -0
  14. data/lib/ffi/libvirt/error.rb +25 -0
  15. data/lib/ffi/libvirt/error_functions.rb +21 -0
  16. data/lib/ffi/libvirt/error_types.rb +125 -0
  17. data/lib/ffi/libvirt/functions.rb +363 -0
  18. data/lib/ffi/libvirt/node_info.rb +27 -0
  19. data/lib/ffi/libvirt/storage_pool_info.rb +11 -0
  20. data/lib/ffi/libvirt/storage_volume_info.rb +14 -0
  21. data/lib/ffi/libvirt/types.rb +61 -0
  22. data/lib/ffi/libvirt/util.rb +19 -0
  23. data/lib/ffi/libvirt/version.rb +46 -0
  24. data/lib/ffi/libvirt.rb +29 -0
  25. data/lib/libvirt/collection/abstract_collection.rb +49 -0
  26. data/lib/libvirt/collection/domain_collection.rb +98 -0
  27. data/lib/libvirt/collection/interface_collection.rb +16 -0
  28. data/lib/libvirt/collection/network_collection.rb +58 -0
  29. data/lib/libvirt/collection/node_device_collection.rb +29 -0
  30. data/lib/libvirt/collection/nwfilter_collection.rb +15 -0
  31. data/lib/libvirt/collection/storage_pool_collection.rb +58 -0
  32. data/lib/libvirt/collection/storage_volume_collection.rb +57 -0
  33. data/lib/libvirt/collection.rb +12 -0
  34. data/lib/libvirt/connection.rb +225 -0
  35. data/lib/libvirt/domain.rb +241 -0
  36. data/lib/libvirt/error.rb +91 -0
  37. data/lib/libvirt/exception.rb +19 -0
  38. data/lib/libvirt/network.rb +118 -0
  39. data/lib/libvirt/node.rb +118 -0
  40. data/lib/libvirt/node_device.rb +75 -0
  41. data/lib/libvirt/spec/device/disk.rb +58 -0
  42. data/lib/libvirt/spec/device/emulator.rb +23 -0
  43. data/lib/libvirt/spec/device.rb +8 -0
  44. data/lib/libvirt/spec/domain/os_booting.rb +69 -0
  45. data/lib/libvirt/spec/domain.rb +71 -0
  46. data/lib/libvirt/spec.rb +12 -0
  47. data/lib/libvirt/storage_pool.rb +164 -0
  48. data/lib/libvirt/storage_volume.rb +109 -0
  49. data/lib/libvirt/version.rb +3 -0
  50. data/lib/libvirt.rb +53 -0
  51. data/libvirt.gemspec +27 -0
  52. data/test/libvirt/collection/abstract_collection_test.rb +14 -0
  53. data/test/libvirt/collection/domain_collection_test.rb +122 -0
  54. data/test/libvirt/collection/interface_collection_test.rb +9 -0
  55. data/test/libvirt/collection/network_collection_test.rb +41 -0
  56. data/test/libvirt/collection/node_device_collection_test.rb +24 -0
  57. data/test/libvirt/collection/nwfilter_collection_test.rb +7 -0
  58. data/test/libvirt/collection/storage_pool_collection_test.rb +41 -0
  59. data/test/libvirt/collection/storage_volume_collection_test.rb +86 -0
  60. data/test/libvirt/connection_test.rb +133 -0
  61. data/test/libvirt/domain_test.rb +221 -0
  62. data/test/libvirt/error_test.rb +93 -0
  63. data/test/libvirt/libvirt_test.rb +16 -0
  64. data/test/libvirt/network_test.rb +76 -0
  65. data/test/libvirt/node_device_test.rb +16 -0
  66. data/test/libvirt/node_test.rb +24 -0
  67. data/test/libvirt/spec/devices/disk_test.rb +107 -0
  68. data/test/libvirt/spec/devices/emulator_test.rb +20 -0
  69. data/test/libvirt/spec/domain_test.rb +17 -0
  70. data/test/libvirt/storage_pool_test.rb +133 -0
  71. data/test/libvirt/storage_volume_test.rb +63 -0
  72. data/test/support/xml_assertions.rb +29 -0
  73. data/test/test_helper.rb +23 -0
  74. metadata +219 -0
@@ -0,0 +1,122 @@
1
+ require "test_helper"
2
+
3
+ Protest.describe("domain collection") do
4
+ setup do
5
+ @klass = Libvirt::Collection::DomainCollection
6
+ @instance = @klass.new(Libvirt::Connection.new("test:///default"))
7
+ end
8
+
9
+ should "provide a list of active domains" do
10
+ active = @instance.active
11
+ assert active.is_a?(Array)
12
+ assert_equal 1, active.length
13
+ assert active.all? { |a| a.is_a?(Libvirt::Domain) }
14
+ end
15
+
16
+ should "provide a list of inactive domains" do
17
+ inactive = @instance.inactive
18
+ assert inactive.is_a?(Array)
19
+ # TODO: Define inactive domains and test they're here?
20
+ end
21
+
22
+ should "provide a list of all domains" do
23
+ assert_equal (@instance.active + @instance.inactive), @instance.all
24
+ end
25
+
26
+ should "provide a length method" do
27
+ assert_equal @instance.all.length, @instance.length
28
+ end
29
+
30
+ should "provide a first method" do
31
+ assert_equal @instance.all.first, @instance.first
32
+ end
33
+
34
+ should "provide an each method" do
35
+ assert @instance.respond_to?(:each)
36
+ end
37
+
38
+ context "finding" do
39
+ should "find by name and UUID for `find`" do
40
+ assert @instance.find("test")
41
+ assert @instance.find(1)
42
+ assert @instance.find(@instance.first.uuid)
43
+
44
+ result = @instance.find("lksadjfkj") rescue nil
45
+ assert !result
46
+ end
47
+
48
+ should "find by name" do
49
+ result = @instance.find_by_name("test")
50
+ assert result
51
+
52
+ result = @instance.find_by_name("bar") rescue nil
53
+ assert !result
54
+ end
55
+
56
+ should "find by id" do
57
+ assert @instance.find_by_id(1)
58
+ assert_raises(Libvirt::Exception::LibvirtError) { @instance.find_by_id(42) }
59
+ end
60
+
61
+ should "find by UUID" do
62
+ result = @instance.find_by_uuid(@instance.first.uuid)
63
+ assert result
64
+
65
+ result = @instance.find_by_uuid("dklf") rescue nil
66
+ assert !result
67
+ end
68
+ end
69
+
70
+ context "a new domain" do
71
+ setup do
72
+ @spec = Libvirt::Spec::Domain.new
73
+ @spec.hypervisor = :test
74
+ @spec.name = "My Test VM"
75
+ @spec.os.type = :hvm
76
+ @spec.memory = 123456 # KB
77
+ end
78
+
79
+ context "defining a new domain" do
80
+ should "define the new domain when the specification is valid" do
81
+ result = nil
82
+ assert_nothing_raised { result = @instance.define(@spec) }
83
+ assert result.is_a?(Libvirt::Domain)
84
+ assert !result.active?
85
+ assert_equal @spec.name, result.name
86
+ end
87
+
88
+ should "define the new domain when the specification is a string" do
89
+ result = nil
90
+ assert_nothing_raised { result = @instance.define(@spec.to_xml) }
91
+ assert result.is_a?(Libvirt::Domain)
92
+ assert !result.active?
93
+ assert_equal @spec.name, result.name
94
+ end
95
+
96
+ should "raise an error when the specification is not valid" do
97
+ @spec.hypervisor = nil
98
+ assert_raise(Libvirt::Exception::LibvirtError) {
99
+ @instance.define(@spec)
100
+ }
101
+ end
102
+ end
103
+
104
+ context "creating a new domain" do
105
+ should "create the new domain with the specification" do
106
+ result = nil
107
+ assert_nothing_raised { result = @instance.create(@spec) }
108
+ assert result.is_a?(Libvirt::Domain)
109
+ assert result.active?
110
+ assert_equal @spec.name, result.name
111
+ end
112
+
113
+ should "create a new domain with a string specification" do
114
+ result = nil
115
+ assert_nothing_raised { result = @instance.create(@spec.to_xml) }
116
+ assert result.is_a?(Libvirt::Domain)
117
+ assert result.active?
118
+ assert_equal @spec.name, result.name
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,9 @@
1
+ require "test_helper"
2
+
3
+ Protest.describe("interface collection") do
4
+ setup do
5
+ @klass = Libvirt::Collection::InterfaceCollection
6
+ end
7
+
8
+ # TODO
9
+ end
@@ -0,0 +1,41 @@
1
+ require "test_helper"
2
+
3
+ Protest.describe("network collection") do
4
+ setup do
5
+ @klass = Libvirt::Collection::NetworkCollection
6
+ @instance = @klass.new(Libvirt.connect("test:///default"))
7
+ end
8
+
9
+ context "finding" do
10
+ should "be able to find by name or UUID" do
11
+ assert @instance.find("default")
12
+ assert !@instance.find("foo")
13
+ end
14
+
15
+ should "be able to find by name" do
16
+ assert @instance.find_by_name("default")
17
+ assert_raises(Libvirt::Exception::LibvirtError) { @instance.find_by_name("foo") }
18
+ end
19
+
20
+ should "be able to find by UUID" do
21
+ assert_raises(Libvirt::Exception::LibvirtError) { @instance.find_by_uuid("bad") }
22
+ # TODO: Test successful case
23
+ end
24
+ end
25
+
26
+ should "provide a list of active networks" do
27
+ active = @instance.active
28
+ assert active.is_a?(Array)
29
+ assert active.all? { |a| a.is_a?(Libvirt::Network) }
30
+ end
31
+
32
+ should "provide a list of inactive networks" do
33
+ inactive = @instance.inactive
34
+ assert inactive.is_a?(Array)
35
+ # TODO: Create inactive networks to test result
36
+ end
37
+
38
+ should "provide a list of all networks" do
39
+ assert_equal (@instance.active + @instance.inactive), @instance.all
40
+ end
41
+ end
@@ -0,0 +1,24 @@
1
+ require "test_helper"
2
+
3
+ Protest.describe("node device collection") do
4
+ setup do
5
+ @klass = Libvirt::Collection::NodeDeviceCollection
6
+ @instance = Libvirt.connect("test:///default").node.devices
7
+ end
8
+
9
+ should "provide access to all nodes" do
10
+ result = nil
11
+ assert_nothing_raised { result = @instance.all }
12
+ assert result
13
+ end
14
+
15
+ should "be able to create a node device" do
16
+ assert_raises(Libvirt::Exception::LibvirtError) {
17
+ @instance.create(<<-XML)
18
+ <device>
19
+ <name>computer2</name>
20
+ </device>
21
+ XML
22
+ }
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ require "test_helper"
2
+
3
+ Protest.describe("nwfilter collection") do
4
+ setup do
5
+ @klass = Libvirt::Collection::NWFilterCollection
6
+ end
7
+ end
@@ -0,0 +1,41 @@
1
+ require "test_helper"
2
+
3
+ Protest.describe("storage pool collection") do
4
+ setup do
5
+ @klass = Libvirt::Collection::StoragePoolCollection
6
+ @instance = @klass.new(Libvirt.connect("test:///default"))
7
+ end
8
+
9
+ context "finding" do
10
+ should "be able to generally find" do
11
+ assert @instance.find("default-pool")
12
+ assert !@instance.find("foo")
13
+ end
14
+
15
+ should "be able to find by name" do
16
+ assert @instance.find_by_name("default-pool")
17
+ assert_raises(Libvirt::Exception::LibvirtError) { @instance.find_by_name("foo") }
18
+ end
19
+
20
+ should "be able to find by UUID" do
21
+ # TODO: Test happy-path
22
+ assert_raises(Libvirt::Exception::LibvirtError) { @instance.find_by_uuid("foo") }
23
+ end
24
+ end
25
+
26
+ should "provide a list of active storage pools" do
27
+ active = @instance.active
28
+ assert active.is_a?(Array)
29
+ # assert active.all? { |a| a.is_a?(Libvirt::StoragePool) }
30
+ end
31
+
32
+ should "provide a list of inactive storage pools" do
33
+ inactive = @instance.inactive
34
+ assert inactive.is_a?(Array)
35
+ # TODO: Create inactive storage pools to test result
36
+ end
37
+
38
+ should "provide a list of all storage pools" do
39
+ assert_equal (@instance.active + @instance.inactive), @instance.all
40
+ end
41
+ end
@@ -0,0 +1,86 @@
1
+ require "test_helper"
2
+
3
+ Protest.describe("storage volume collection") do
4
+ setup do
5
+ @klass = Libvirt::Collection::StorageVolumeCollection
6
+ @instance = @klass.new(Libvirt.connect("test:///default").storage_pools.first)
7
+
8
+ @single = @instance.create(<<-XML)
9
+ <volume>
10
+ <name>test</name>
11
+ <key>g9eba311-ea76-4e4a-ad7b-401fa81e38c8</key>
12
+ <source>
13
+ </source>
14
+ <capacity>8589934592</capacity>
15
+ <allocation>33280</allocation>
16
+ <target>
17
+ <format type='raw'/>
18
+ <permissions>
19
+ <mode>00</mode>
20
+ <owner>0</owner>
21
+ <group>0</group>
22
+ </permissions>
23
+ </target>
24
+ </volume>
25
+ XML
26
+ end
27
+
28
+ context "finding" do
29
+ should "find by any string" do
30
+ assert @instance.find("test")
31
+ assert @instance.find(@single.key)
32
+ assert @instance.find(@single.path)
33
+ assert !@instance.find("foo")
34
+ end
35
+
36
+ should "find by name" do
37
+ assert @instance.find_by_name("test")
38
+ assert_raises(Libvirt::Exception::LibvirtError) {
39
+ @instance.find_by_name("slkjfdlksa")
40
+ }
41
+ end
42
+
43
+ should "find by key" do
44
+ assert @instance.find_by_key(@single.key)
45
+ assert_raises(Libvirt::Exception::LibvirtError) {
46
+ @instance.find_by_key("foo")
47
+ }
48
+ end
49
+
50
+ should "find_by_path" do
51
+ assert @instance.find_by_path(@single.path)
52
+ assert_raises(Libvirt::Exception::LibvirtError) {
53
+ @instance.find_by_path("foo")
54
+ }
55
+ end
56
+ end
57
+
58
+ should "be able to create a new volume" do
59
+ result = @instance.create(<<-XML)
60
+ <volume>
61
+ <name>test_vm_A.vdi</name>
62
+ <key>f9eba311-ea76-4e4a-ad7b-401fa81e38c8</key>
63
+ <source>
64
+ </source>
65
+ <capacity>8589934592</capacity>
66
+ <allocation>33280</allocation>
67
+ <target>
68
+ <format type='raw'/>
69
+ <permissions>
70
+ <mode>00</mode>
71
+ <owner>0</owner>
72
+ <group>0</group>
73
+ </permissions>
74
+ </target>
75
+ </volume>
76
+ XML
77
+
78
+ assert result
79
+ assert @instance.all.include?(result)
80
+ end
81
+
82
+ should "provide a list of all volumes" do
83
+ all = @instance.all
84
+ assert all.is_a?(Array)
85
+ end
86
+ end
@@ -0,0 +1,133 @@
1
+ require "test_helper"
2
+
3
+ Protest.describe("connection") do
4
+ setup do
5
+ @klass = Libvirt::Connection
6
+ end
7
+
8
+ context "connecting" do
9
+ should "connect given a pointer to a connection" do
10
+ pointer = FFI::Libvirt.virConnectOpen("test:///default")
11
+ result = @klass.new(pointer)
12
+ assert_equal pointer, result.to_ptr
13
+ end
14
+
15
+ should "connect and return a connection" do
16
+ result = nil
17
+ assert_nothing_raised { result = @klass.new("test:///default") }
18
+ assert result.is_a?(@klass)
19
+ end
20
+
21
+ should "connect to a readonly connection" do
22
+ result = nil
23
+ assert_nothing_raised { result = @klass.new("test:///default", :readonly => true) }
24
+ assert result.is_a?(@klass)
25
+
26
+ # Test readonly-ness
27
+ end
28
+
29
+ should "raise an exception if the connection fails" do
30
+ assert_raise(Libvirt::Exception::LibvirtError) {
31
+ @klass.new("thisshouldneverpass:)")
32
+ }
33
+ end
34
+ end
35
+
36
+ context "with a valid connection" do
37
+ setup do
38
+ @cxn = @klass.new("test:///default")
39
+ end
40
+
41
+ should "provide the library version" do
42
+ # We rely on virsh to get the version of libvirt
43
+ version = @cxn.lib_version
44
+ actual = `virsh --version`.chomp.split(".").map { |s| s.to_i }
45
+ assert_equal actual, version
46
+ end
47
+
48
+ should "provide the node" do
49
+ result = @cxn.node
50
+ assert result
51
+ assert result.is_a?(Libvirt::Node)
52
+ assert result.connection.eql?(@cxn)
53
+ end
54
+
55
+ should "provide the capabilities of the connection" do
56
+ assert_nothing_raised { @cxn.capabilities }
57
+ end
58
+
59
+ should "provide the hostname of the connection" do
60
+ assert_nothing_raised { @cxn.hostname }
61
+ end
62
+
63
+ should "provide the uri of the connection" do
64
+ result = nil
65
+ assert_nothing_raised { result = @cxn.uri }
66
+ assert_equal "test:///default", result
67
+ end
68
+
69
+ should "provide the type of the connection" do
70
+ result = nil
71
+ assert_nothing_raised { result = @cxn.type }
72
+ assert_equal "Test", result
73
+ end
74
+
75
+ should "provide the max virtual CPUs" do
76
+ assert_equal 32, @cxn.max_virtual_cpus("test")
77
+ end
78
+
79
+ should "provide the hypervisor version of the connection" do
80
+ result = nil
81
+ assert_nothing_raised { result = @cxn.hypervisor_version }
82
+ assert_equal [0,0,2], result
83
+ end
84
+
85
+ should "provide a list of domains" do
86
+ result = nil
87
+ assert_nothing_raised { result = @cxn.domains }
88
+ assert result.is_a?(Libvirt::Collection::DomainCollection)
89
+ assert @cxn.equal?(result.interface)
90
+ end
91
+
92
+ should "provide a list of interfaces" do
93
+ result = nil
94
+ assert_nothing_raised { result = @cxn.interfaces }
95
+ assert result.is_a?(Libvirt::Collection::InterfaceCollection)
96
+ assert @cxn.equal?(result.interface)
97
+ end
98
+
99
+ should "providea list of networks" do
100
+ result = nil
101
+ assert_nothing_raised { result = @cxn.networks }
102
+ assert result.is_a?(Libvirt::Collection::NetworkCollection)
103
+ assert @cxn.equal?(result.interface)
104
+ end
105
+
106
+ should "provide a list of NW filters" do
107
+ result = nil
108
+ assert_nothing_raised { result = @cxn.nwfilters }
109
+ assert result.is_a?(Libvirt::Collection::NWFilterCollection)
110
+ assert @cxn.equal?(result.interface)
111
+ end
112
+
113
+ should "provide a list of storage pools" do
114
+ result = nil
115
+ assert_nothing_raised { result = @cxn.storage_pools }
116
+ assert result.is_a?(Libvirt::Collection::StoragePoolCollection)
117
+ assert @cxn.equal?(result.interface)
118
+ end
119
+
120
+ should "check if encrypted" do
121
+ assert !@cxn.encrypted?
122
+ end
123
+
124
+ should "check if secure" do
125
+ assert @cxn.secure?
126
+ end
127
+
128
+ should "garbage collect the connection" do
129
+ # TODO: Memprof this thing to figure out what is holding
130
+ # references to a connection so the GC actually works.
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,221 @@
1
+ require "test_helper"
2
+
3
+ Protest.describe("domain") do
4
+ setup do
5
+ @klass = Libvirt::Domain
6
+
7
+ @spec = Libvirt::Spec::Domain.new
8
+ @spec.hypervisor = :test
9
+ @spec.name = "libvirt-rb-test"
10
+ @spec.os.type = :hvm
11
+ @spec.memory = 123456 # KB
12
+
13
+ @conn = Libvirt.connect("test:///default")
14
+ @instance = @conn.domains.define(@spec)
15
+ end
16
+
17
+ should "provide the name of the domain" do
18
+ assert_equal "libvirt-rb-test", @instance.name
19
+ end
20
+
21
+ should "provide the UUID of the domain" do
22
+ result = nil
23
+ assert_nothing_raised { result = @instance.uuid }
24
+ assert_equal 36, result.length
25
+ end
26
+
27
+ should "provide the ID of the domain" do
28
+ assert_equal 4294967295, @instance.id
29
+ end
30
+
31
+ should "provide the OS type of the domain" do
32
+ assert_equal "linux", @instance.os_type
33
+ end
34
+
35
+ should "provide the state of the domain" do
36
+ assert_equal :shutoff, @instance.state
37
+ end
38
+
39
+ context "maximum memory" do
40
+ should "be retrievable" do
41
+ assert_equal 123456, @instance.max_memory
42
+ end
43
+
44
+ should "be settable" do
45
+ @instance.max_memory = 234567
46
+ assert_equal 234567, @instance.max_memory
47
+ end
48
+ end
49
+
50
+ context "memory" do
51
+ should "be retrievable" do
52
+ assert_equal 123456, @instance.memory
53
+ end
54
+
55
+ should "be settable" do
56
+ @instance.memory = 7000
57
+ assert_equal 7000, @instance.memory
58
+ end
59
+ end
60
+
61
+ context "virtual CPUs" do
62
+ should "be retrievable" do
63
+ assert_equal 1, @instance.virtual_cpus
64
+ end
65
+
66
+ should "be able to retrieve maximum" do
67
+ @instance.start
68
+ assert_equal 1, @instance.max_virtual_cpus
69
+ end
70
+
71
+ should "be settable" do
72
+ @instance.start
73
+ @instance.virtual_cpus = 1
74
+ assert_equal 1, @instance.virtual_cpus
75
+ end
76
+ end
77
+
78
+ should "provide the CPU time used in nanoseconds" do
79
+ # This result is constantly changing so all we can really test is that
80
+ # its properly returned
81
+ result = nil
82
+ assert_nothing_raised { result = @instance.cpu_time_used }
83
+ assert result.is_a?(Integer)
84
+ end
85
+
86
+ should "provide an XML dump of the description of the domain" do
87
+ result = nil
88
+ assert_nothing_raised { result = @instance.xml }
89
+ assert result.is_a?(String)
90
+ assert !result.empty?
91
+ end
92
+
93
+ should "return result of active status" do
94
+ @instance.start
95
+ assert @instance.active?
96
+ @instance.destroy
97
+ assert !@instance.active?
98
+ end
99
+
100
+ should "return result of persistent status" do
101
+ # Instance domain is defined so should be persistent:
102
+ assert @instance.persistent?
103
+
104
+ # Create a new domain, shouldn't be persistent
105
+ @spec.name = "another"
106
+ other = @conn.domains.create(@spec)
107
+ assert !other.persistent?
108
+ end
109
+
110
+ context "autostart" do
111
+ should "check status" do
112
+ assert !@instance.autostart?
113
+ end
114
+
115
+ should "set status" do
116
+ @instance.autostart = true
117
+ assert @instance.autostart?
118
+ end
119
+ end
120
+
121
+ context "when creating" do
122
+ should "return true if succeeds" do
123
+ @instance.destroy
124
+ assert !@instance.active?
125
+ assert @instance.create
126
+ assert @instance.active?
127
+ end
128
+
129
+ should "not raise an error if the domain is already running" do
130
+ @instance.start
131
+ assert @instance.active? # pre-requisite
132
+ assert_nothing_raised { @instance.create }
133
+ end
134
+
135
+ should "also respond to `start`" do
136
+ assert !@instance.active?
137
+ assert @instance.start
138
+ assert @instance.active?
139
+ end
140
+ end
141
+
142
+ context "when destroying" do
143
+ should "return true if succeeds" do
144
+ assert @instance.destroy
145
+ assert !@instance.active?
146
+ end
147
+
148
+ should "not raise an error if the domain is already stopped" do
149
+ @instance.destroy
150
+ assert_nothing_raised { @instance.destroy }
151
+ end
152
+
153
+ should "also respond to `stop`" do
154
+ assert @instance.stop
155
+ assert !@instance.active?
156
+ end
157
+ end
158
+
159
+ context "when suspending" do
160
+ setup do
161
+ @instance.create
162
+ end
163
+
164
+ should "return true if succeeds" do
165
+ assert @instance.suspend
166
+ end
167
+
168
+ should "raise an error if the domain is already suspended" do
169
+ @instance.suspend
170
+ assert_raise(Libvirt::Exception::LibvirtError) {
171
+ @instance.suspend
172
+ }
173
+ end
174
+
175
+ should "raise an error if the domain is destroyed" do
176
+ @instance.destroy
177
+ assert_raise(Libvirt::Exception::LibvirtError) {
178
+ @instance.suspend
179
+ }
180
+ end
181
+ end
182
+
183
+ context "when resuming" do
184
+ setup do
185
+ @instance.create
186
+ end
187
+
188
+ should "return true if succeeds" do
189
+ assert @instance.suspend
190
+ assert @instance.resume
191
+ end
192
+
193
+ should "not raise an error if the domain is running" do
194
+ assert @instance.active?
195
+ assert @instance.resume
196
+ end
197
+
198
+ should "raise an error if the domain is destroyed" do
199
+ @instance.destroy
200
+ assert_raise(Libvirt::Exception::LibvirtError) {
201
+ @instance.resume
202
+ }
203
+ end
204
+ end
205
+
206
+ should "be able to reboot" do
207
+ assert_nothing_raised { @instance.reboot }
208
+ end
209
+
210
+ should "be able to shutdown" do
211
+ @instance.start
212
+ assert_nothing_raised { @instance.shutdown }
213
+ end
214
+
215
+ should "be able to undefine a domain" do
216
+ @instance.destroy
217
+ assert @conn.domains.include?(@instance)
218
+ @instance.undefine
219
+ assert !@conn.domains.include?(@instance)
220
+ end
221
+ end