vagrant-libvirt 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +170 -17
  3. data/lib/vagrant-libvirt/action/create_domain.rb +30 -9
  4. data/lib/vagrant-libvirt/action/forward_ports.rb +1 -1
  5. data/lib/vagrant-libvirt/action/package_domain.rb +2 -1
  6. data/lib/vagrant-libvirt/action/start_domain.rb +86 -29
  7. data/lib/vagrant-libvirt/action/wait_till_up.rb +7 -27
  8. data/lib/vagrant-libvirt/config.rb +202 -41
  9. data/lib/vagrant-libvirt/driver.rb +46 -31
  10. data/lib/vagrant-libvirt/provider.rb +2 -9
  11. data/lib/vagrant-libvirt/templates/domain.xml.erb +29 -5
  12. data/lib/vagrant-libvirt/version +1 -1
  13. data/lib/vagrant-libvirt/version.rb +57 -9
  14. data/spec/spec_helper.rb +28 -2
  15. data/spec/support/libvirt_context.rb +2 -0
  16. data/spec/support/sharedcontext.rb +4 -0
  17. data/spec/unit/action/create_domain_spec.rb +110 -35
  18. data/spec/unit/action/create_domain_spec/{default_storage_pool.xml → default_system_storage_pool.xml} +0 -0
  19. data/spec/unit/action/create_domain_spec/default_user_storage_pool.xml +17 -0
  20. data/spec/unit/action/start_domain_spec.rb +183 -1
  21. data/spec/unit/action/start_domain_spec/clock_timer_rtc.xml +50 -0
  22. data/spec/unit/action/start_domain_spec/default.xml +2 -2
  23. data/spec/unit/action/start_domain_spec/default_added_tpm_path.xml +48 -0
  24. data/spec/unit/action/start_domain_spec/default_added_tpm_version.xml +48 -0
  25. data/spec/unit/action/wait_till_up_spec.rb +14 -9
  26. data/spec/unit/config_spec.rb +392 -127
  27. data/spec/unit/provider_spec.rb +11 -0
  28. data/spec/unit/templates/domain_all_settings.xml +6 -3
  29. data/spec/unit/templates/domain_custom_cpu_model.xml +2 -1
  30. data/spec/unit/templates/domain_defaults.xml +2 -1
  31. data/spec/unit/templates/domain_spec.rb +80 -2
  32. data/spec/unit/templates/tpm/version_1.2.xml +54 -0
  33. data/spec/unit/templates/tpm/version_2.0.xml +53 -0
  34. metadata +74 -17
@@ -1,3 +1,5 @@
1
+ require 'contextual_proc'
2
+
1
3
  require 'spec_helper'
2
4
  require 'support/sharedcontext'
3
5
 
@@ -8,6 +10,50 @@ describe VagrantPlugins::ProviderLibvirt::Config do
8
10
 
9
11
  let(:fake_env) { Hash.new }
10
12
 
13
+ describe '#clock_timer' do
14
+ it 'should handle all options' do
15
+ expect(
16
+ subject.clock_timer(
17
+ :name => 'rtc',
18
+ :track => 'wall',
19
+ :tickpolicy => 'delay',
20
+ :present => 'yes',
21
+ ).length
22
+ ).to be(1)
23
+ expect(
24
+ subject.clock_timer(
25
+ :name => 'tsc',
26
+ :tickpolicy => 'delay',
27
+ :frequency => '100',
28
+ :mode => 'auto',
29
+ :present => 'yes',
30
+ ).length
31
+ ).to be(2)
32
+ end
33
+
34
+ it 'should correctly save the options' do
35
+ opts = {:name => 'rtc', :track => 'wall'}
36
+ expect(subject.clock_timer(opts).length).to be(1)
37
+
38
+ expect(subject.clock_timers[0]).to eq(opts)
39
+
40
+ opts[:name] = 'tsc'
41
+ expect(subject.clock_timers[0]).to_not eq(opts)
42
+ end
43
+
44
+ it 'should error name option is missing' do
45
+ expect{ subject.clock_timer(:track => "wall") }.to raise_error("Clock timer name must be specified")
46
+ end
47
+
48
+ it 'should error if nil value for option supplied' do
49
+ expect{ subject.clock_timer(:name => "rtc", :track => nil) }.to raise_error("Value of timer option track is nil")
50
+ end
51
+
52
+ it 'should error if unrecognized option specified' do
53
+ expect{ subject.clock_timer(:name => "tsc", :badopt => "value") }.to raise_error("Unknown clock timer option: badopt")
54
+ end
55
+ end
56
+
11
57
  describe '#finalize!' do
12
58
  it 'is valid with defaults' do
13
59
  subject.finalize!
@@ -16,96 +62,264 @@ describe VagrantPlugins::ProviderLibvirt::Config do
16
62
  context '@uri' do
17
63
  before(:example) do
18
64
  stub_const("ENV", fake_env)
65
+ fake_env['HOME'] = "/home/tests"
19
66
  end
20
67
 
21
- context 'when LIBVIRT_DEFAULT_URI is defined' do
22
- it 'should always use this value' do
23
- fake_env['LIBVIRT_DEFAULT_URI'] = "custom:///custom_path"
68
+ # table describing expected behaviour of inputs that affect the resulting uri as
69
+ # well as any subsequent settings that might be inferred if the uri was
70
+ # explicitly set.
71
+ [
72
+ # settings
73
+ [ # all default
74
+ {},
75
+ {:uri => "qemu:///system"},
76
+ ],
77
+
78
+ # explicit uri settings
79
+ [ # transport and hostname
80
+ {:uri => "qemu+ssh://localhost/system"},
81
+ {:uri => "qemu+ssh://localhost/system", :connect_via_ssh => true, :host => "localhost", :username => nil},
82
+ ],
83
+ [ # tcp transport with port
84
+ {:uri => "qemu+tcp://localhost:5000/system"},
85
+ {:uri => "qemu+tcp://localhost:5000/system", :connect_via_ssh => false, :host => "localhost", :username => nil},
86
+ ],
87
+ [ # connect explicit to unix socket
88
+ {:uri => "qemu+unix:///system"},
89
+ {:uri => "qemu+unix:///system", :connect_via_ssh => false, :host => nil, :username => nil},
90
+ ],
91
+ [ # via libssh2 should enable ssh as well
92
+ {:uri => "qemu+libssh2://user@remote/system?known_hosts=/home/user/.ssh/known_hosts"},
93
+ {
94
+ :uri => "qemu+libssh2://user@remote/system?known_hosts=/home/user/.ssh/known_hosts",
95
+ :connect_via_ssh => true, :host => "remote", :username => "user",
96
+ },
97
+ ],
98
+ [ # xen
99
+ {:uri => "xen://remote/system?no_verify=1"},
100
+ {
101
+ :uri => "xen://remote/system?no_verify=1",
102
+ :connect_via_ssh => false, :host => "remote", :username => nil,
103
+ :id_ssh_key_file => nil,
104
+ },
105
+ {
106
+ :setup => ContextualProc.new {
107
+ expect(File).to_not receive(:file?)
108
+ }
109
+ }
110
+ ],
111
+ [ # xen
112
+ {:uri => "xen+ssh://remote/system?no_verify=1"},
113
+ {
114
+ :uri => "xen+ssh://remote/system?no_verify=1",
115
+ :connect_via_ssh => true, :host => "remote", :username => nil,
116
+ :id_ssh_key_file => "/home/tests/.ssh/id_rsa",
117
+ },
118
+ {
119
+ :setup => ContextualProc.new {
120
+ expect(File).to receive(:file?).with("/home/tests/.ssh/id_rsa").and_return(true)
121
+ }
122
+ }
123
+ ],
124
+
125
+ # with LIBVIRT_DEFAULT_URI
126
+ [ # all other set to default
127
+ {},
128
+ {:uri => "custom:///custom_path", :qemu_use_session => false},
129
+ {
130
+ :env => {'LIBVIRT_DEFAULT_URI' => "custom:///custom_path"},
131
+ }
132
+ ],
133
+ [ # with session
134
+ {},
135
+ {:uri => "qemu:///session", :qemu_use_session => true},
136
+ {
137
+ :env => {'LIBVIRT_DEFAULT_URI' => "qemu:///session"},
138
+ }
139
+ ],
140
+ [ # with session and using ssh infer connect by ssh and ignore host as not provided
141
+ {},
142
+ {:uri => "qemu+ssh:///session", :qemu_use_session => true, :connect_via_ssh => true, :host => nil},
143
+ {
144
+ :env => {'LIBVIRT_DEFAULT_URI' => "qemu+ssh:///session"},
145
+ }
146
+ ],
147
+ [ # with session and using ssh to specific host with additional query options provided, infer host and ssh
148
+ {},
149
+ {:uri => "qemu+ssh://remote/session?keyfile=my_id_rsa", :qemu_use_session => true, :connect_via_ssh => true, :host => 'remote'},
150
+ {
151
+ :env => {'LIBVIRT_DEFAULT_URI' => "qemu+ssh://remote/session?keyfile=my_id_rsa"},
152
+ }
153
+ ],
154
+ [ # when session not set
155
+ {},
156
+ {:uri => "qemu:///system", :qemu_use_session => false},
157
+ {
158
+ :env => {'LIBVIRT_DEFAULT_URI' => "qemu:///system"},
159
+ }
160
+ ],
161
+ [ # when session appearing elsewhere
162
+ {},
163
+ {:uri => "qemu://remote/system?keyfile=my_session_id", :qemu_use_session => false},
164
+ {
165
+ :env => {'LIBVIRT_DEFAULT_URI' => "qemu://remote/system?keyfile=my_session_id"},
166
+ }
167
+ ],
168
+
169
+ # ignore LIBVIRT_DEFAULT_URI due to explicit settings
170
+ [ # when uri explicitly set
171
+ {:uri => 'qemu:///system'},
172
+ {:uri => 'qemu:///system'},
173
+ {
174
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
175
+ }
176
+ ],
177
+ [ # when host explicitly set
178
+ {:host => 'remote'},
179
+ {:uri => 'qemu://remote/system'},
180
+ {
181
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
182
+ }
183
+ ],
184
+ [ # when connect_via_ssh explicitly set
185
+ {:connect_via_ssh => true},
186
+ {:uri => 'qemu+ssh://localhost/system?no_verify=1'},
187
+ {
188
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
189
+ }
190
+ ],
191
+ [ # when username explicitly set without ssh
192
+ {:username => 'my_user' },
193
+ {:uri => 'qemu:///system'},
194
+ {
195
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
196
+ }
197
+ ],
198
+ [ # when username explicitly set with host but without ssh
199
+ {:username => 'my_user', :host => 'remote'},
200
+ {:uri => 'qemu://remote/system'},
201
+ {
202
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
203
+ }
204
+ ],
205
+ [ # when password explicitly set
206
+ {:password => 'some_password'},
207
+ {:uri => 'qemu:///system', :password => 'some_password'},
208
+ {
209
+ :env => {'LIBVIRT_DEFAULT_URI' => 'qemu://session'},
210
+ }
211
+ ],
212
+
213
+ # driver settings
214
+ [ # set to kvm only
215
+ {:driver => 'kvm'},
216
+ {:uri => "qemu:///system"},
217
+ ],
218
+ [ # set to qemu only
219
+ {:driver => 'qemu'},
220
+ {:uri => "qemu:///system"},
221
+ ],
222
+ [ # set to qemu with session enabled
223
+ {:driver => 'qemu', :qemu_use_session => true},
224
+ {:uri => "qemu:///session"},
225
+ ],
226
+ [ # set to openvz only
227
+ {:driver => 'openvz'},
228
+ {:uri => "openvz:///system"},
229
+ ],
230
+ [ # set to esx
231
+ {:driver => 'esx'},
232
+ {:uri => "esx:///"},
233
+ ],
234
+ [ # set to vbox only
235
+ {:driver => 'vbox'},
236
+ {:uri => "vbox:///session"},
237
+ ],
238
+
239
+ # connect_via_ssh settings
240
+ [ # enabled
241
+ {:connect_via_ssh => true},
242
+ {:uri => "qemu+ssh://localhost/system?no_verify=1"},
243
+ ],
244
+ [ # enabled with user
245
+ {:connect_via_ssh => true, :username => 'my_user'},
246
+ {:uri => "qemu+ssh://my_user@localhost/system?no_verify=1"},
247
+ ],
248
+ [ # enabled with host
249
+ {:connect_via_ssh => true, :host => 'remote_server'},
250
+ {:uri => "qemu+ssh://remote_server/system?no_verify=1"},
251
+ ],
252
+
253
+ # id_ssh_key_file behaviour
254
+ [ # set should take given value
255
+ {:connect_via_ssh => true, :id_ssh_key_file => '/path/to/keyfile'},
256
+ {:uri => 'qemu+ssh://localhost/system?no_verify=1&keyfile=/path/to/keyfile', :connect_via_ssh => true},
257
+ ],
258
+ [ # set should infer use of ssh
259
+ {:id_ssh_key_file => '/path/to/keyfile'},
260
+ {:uri => 'qemu+ssh://localhost/system?no_verify=1&keyfile=/path/to/keyfile', :connect_via_ssh => true},
261
+ ],
262
+ [ # connect_via_ssh should enable default but ignore due to not existing
263
+ {:connect_via_ssh => true},
264
+ {:uri => 'qemu+ssh://localhost/system?no_verify=1', :id_ssh_key_file => nil},
265
+ {
266
+ :setup => ContextualProc.new {
267
+ expect(File).to receive(:file?).with("/home/tests/.ssh/id_rsa").and_return(false)
268
+ }
269
+ }
270
+ ],
271
+ [ # connect_via_ssh should enable default and include due to existing
272
+ {:connect_via_ssh => true},
273
+ {:uri => 'qemu+ssh://localhost/system?no_verify=1&keyfile=/home/tests/.ssh/id_rsa', :id_ssh_key_file => '/home/tests/.ssh/id_rsa'},
274
+ {
275
+ :setup => ContextualProc.new {
276
+ expect(File).to receive(:file?).with("/home/tests/.ssh/id_rsa").and_return(true)
277
+ }
278
+ }
279
+ ],
280
+
281
+ # socket behaviour
282
+ [ # set
283
+ {:socket => '/var/run/libvirt/libvirt-sock'},
284
+ {:uri => "qemu:///system?socket=/var/run/libvirt/libvirt-sock"},
285
+ ],
286
+ ].each do |inputs, outputs, options|
287
+ opts = {}
288
+ opts.merge!(options) if options
289
+
290
+ it "should handle inputs #{inputs} with env (#{opts[:env]})" do
291
+ # allow some of these to fail for now if marked as such
292
+ if !opts[:allow_failure].nil?
293
+ pending(opts[:allow_failure])
294
+ end
24
295
 
25
- subject.finalize!
26
- expect(subject.uri).to eq("custom:///custom_path")
27
- expect(subject.qemu_use_session).to eq(false)
28
- end
296
+ if !opts[:setup].nil?
297
+ opts[:setup].apply(binding)
298
+ end
29
299
 
30
- context 'when LIBVIRT_DEFAULT_URI contains "qemu"' do
31
- [
32
- [
33
- 'set qemu_use_session if "session" present',
34
- 'qemu:///session',
35
- true,
36
- ],
37
- [
38
- 'handle different protocol additions',
39
- 'qemu+ssh:///session',
40
- true,
41
- ],
42
- [
43
- 'handle options before and after path',
44
- 'qemu://remote/session?keyfile=my_id_rsa',
45
- true,
46
- ],
47
- [
48
- 'identify when session not set',
49
- 'qemu://remote/system',
50
- false,
51
- ],
52
- [
53
- 'handle session appearing elsewhere',
54
- 'qemu://remote/system?keyfile=my_session_id',
55
- false,
56
- ],
57
- ].each do |title, uri, session|
58
- it "should #{title}" do
59
- fake_env['LIBVIRT_DEFAULT_URI'] = uri
60
-
61
- subject.finalize!
62
- expect(subject.uri).to eq(uri)
63
- expect(subject.qemu_use_session).to eq(session)
64
- end
300
+ inputs.each do |k, v|
301
+ subject.instance_variable_set("@#{k}", v)
65
302
  end
66
- end
67
- end
68
303
 
69
- context 'when @driver is defined' do
70
- defaults = {'id_ssh_key_file' => nil}
71
- [
72
- [
73
- {'driver' => 'kvm'},
74
- 'qemu:///system?no_verify=1',
75
- false,
76
- ],
77
- [
78
- {'driver' => 'qemu'},
79
- 'qemu:///system?no_verify=1',
80
- false,
81
- ],
82
- [
83
- {'driver' => 'qemu', 'qemu_use_session' => true},
84
- 'qemu:///session?no_verify=1',
85
- true,
86
- ],
87
- [
88
- {'driver' => 'openvz'},
89
- 'openvz:///system?no_verify=1',
90
- false,
91
- ],
92
- [
93
- {'driver' => 'vbox'},
94
- 'vbox:///session?no_verify=1',
95
- false,
96
- ],
97
- ].each do |inputs, output_uri, output_session|
98
- it "should detect #{inputs}" do
99
- inputs.merge(defaults).each do |k, v|
100
- subject.instance_variable_set("@#{k}", v)
304
+ if !opts[:env].nil?
305
+ opts[:env].each do |k, v|
306
+ fake_env[k] = v
101
307
  end
308
+ end
102
309
 
103
- subject.finalize!
104
- expect(subject.uri).to eq(output_uri)
105
- expect(subject.qemu_use_session).to eq(output_session)
310
+ subject.finalize!
311
+
312
+ # ensure failed output indicates which settings are incorrect in the failed test
313
+ got = subject.instance_variables.each_with_object({}) do |name, hash|
314
+ if outputs.key?(name.to_s[1..-1].to_sym)
315
+ hash["#{name.to_s[1..-1]}".to_sym] =subject.instance_variable_get(name)
316
+ end
106
317
  end
318
+ expect(got).to eq(outputs)
107
319
  end
320
+ end
108
321
 
322
+ context 'when invalid @driver is defined' do
109
323
  it "should raise exception for unrecognized" do
110
324
  subject.driver = "bad-driver"
111
325
 
@@ -113,65 +327,106 @@ describe VagrantPlugins::ProviderLibvirt::Config do
113
327
  end
114
328
  end
115
329
 
116
- context 'when @connect_via_ssh defined' do
117
- defaults = {'driver' => 'qemu', 'id_ssh_key_file' => nil}
118
- [
119
- [
120
- {'connect_via_ssh' => true},
121
- 'qemu+ssh://localhost/system?no_verify=1',
122
- ],
123
- [
124
- {'connect_via_ssh' => true, 'username' => 'my_user'},
125
- 'qemu+ssh://my_user@localhost/system?no_verify=1',
126
- ],
127
- [
128
- {'connect_via_ssh' => true, 'host' => 'remote_server'},
129
- 'qemu+ssh://remote_server/system?no_verify=1',
130
- ],
131
- ].each do |inputs, output_uri|
132
- it "should detect #{inputs}" do
133
- inputs.merge(defaults).each do |k, v|
134
- subject.instance_variable_set("@#{k}", v)
135
- end
330
+ context 'when invalid @uri is defined' do
331
+ it "should raise exception for unrecognized" do
332
+ subject.uri = "://bad-uri"
136
333
 
137
- subject.finalize!
138
- expect(subject.uri).to eq(output_uri)
139
- end
334
+ expect { subject.finalize! }.to raise_error("@uri set to invalid uri '://bad-uri'")
140
335
  end
141
336
  end
337
+ end
338
+
339
+ context '@proxy_command' do
340
+ before(:example) do
341
+ stub_const("ENV", fake_env)
342
+ fake_env['HOME'] = "/home/tests"
343
+ end
142
344
 
143
- context 'when @id_ssh_key_file defined' do
144
- defaults = {'driver' => 'qemu'}
345
+ [
346
+ # no connect_via_ssh
145
347
  [
146
- [
147
- {},
148
- 'qemu:///system?no_verify=1&keyfile=/home/user/.ssh/id_rsa',
149
- ],
150
- [
151
- {'id_ssh_key_file' => '/path/to/keyfile'},
152
- 'qemu:///system?no_verify=1&keyfile=/path/to/keyfile',
153
- ],
154
- ].each do |inputs, output_uri|
155
- it "should detect #{inputs}" do
156
- inputs.merge(defaults).each do |k, v|
157
- subject.instance_variable_set("@#{k}", v)
158
- end
348
+ {:host => "remote"},
349
+ nil,
350
+ ],
351
+
352
+ # connect_via_ssh
353
+ [ # host
354
+ {:connect_via_ssh => true, :host => 'remote'},
355
+ "ssh 'remote' -W %h:%p",
356
+ ],
357
+ [ # include user
358
+ {:connect_via_ssh => true, :host => 'remote', :username => 'myuser'},
359
+ "ssh 'remote' -l 'myuser' -W %h:%p",
360
+ ],
361
+ [ # include user and default ssh key exists
362
+ {:connect_via_ssh => true, :host => 'remote', :username => 'myuser'},
363
+ "ssh 'remote' -l 'myuser' -i '/home/tests/.ssh/id_rsa' -W %h:%p",
364
+ {
365
+ :setup => ContextualProc.new {
366
+ expect(File).to receive(:file?).with("/home/tests/.ssh/id_rsa").and_return(true)
367
+ }
368
+ }
369
+ ],
370
+
371
+ # disable id_ssh_key_file
372
+ [
373
+ {:connect_via_ssh => true, :host => 'remote', :id_ssh_key_file => nil},
374
+ "ssh 'remote' -W %h:%p",
375
+ ],
376
+ [ # include user
377
+ {:connect_via_ssh => true, :host => 'remote', :id_ssh_key_file => nil},
378
+ "ssh 'remote' -W %h:%p",
379
+ ],
380
+
381
+ # use @uri
382
+ [
383
+ {:uri => 'qemu+ssh://remote/system'},
384
+ "ssh 'remote' -W %h:%p",
385
+ ],
386
+ [
387
+ {:uri => 'qemu+ssh://myuser@remote/system'},
388
+ "ssh 'remote' -l 'myuser' -W %h:%p",
389
+ ],
390
+ [
391
+ {:uri => 'qemu+ssh://remote/system?keyfile=/some/path/to/keyfile'},
392
+ "ssh 'remote' -i '/some/path/to/keyfile' -W %h:%p",
393
+ {:allow_failure => "keyfile not yet inferred from uri"},
394
+ ],
159
395
 
160
- fake_env['HOME'] = '/home/user'
396
+ # provide custom template
397
+ [
398
+ {:connect_via_ssh => true, :host => 'remote', :proxy_command => "ssh {host} nc %h %p" },
399
+ "ssh remote nc %h %p",
400
+ ],
401
+ [
402
+ {:connect_via_ssh => true, :host => 'remote', :username => 'myuser', :proxy_command => "ssh {host} nc %h %p" },
403
+ "ssh remote nc %h %p",
404
+ ],
405
+ [
406
+ {:connect_via_ssh => true, :host => 'remote', :username => 'myuser', :proxy_command => "ssh {host} -l {username} nc %h %p" },
407
+ "ssh remote -l myuser nc %h %p",
408
+ ],
409
+ ].each do |inputs, proxy_command, options|
410
+ opts = {}
411
+ opts.merge!(options) if options
412
+
413
+ it "should handle inputs #{inputs}" do
414
+ # allow some of these to fail for now if marked as such
415
+ if !opts[:allow_failure].nil?
416
+ pending(opts[:allow_failure])
417
+ end
161
418
 
162
- subject.finalize!
163
- expect(subject.uri).to eq(output_uri)
419
+ if !opts[:setup].nil?
420
+ opts[:setup].apply(binding)
164
421
  end
165
- end
166
- end
167
422
 
168
- context 'when @socket defined' do
169
- it "should detect @socket set" do
170
- subject.socket = '/var/run/libvirt/libvirt-sock'
171
- subject.id_ssh_key_file = false
423
+ inputs.each do |k, v|
424
+ subject.instance_variable_set("@#{k}", v)
425
+ end
172
426
 
173
427
  subject.finalize!
174
- expect(subject.uri).to eq('qemu:///system?no_verify=1&socket=/var/run/libvirt/libvirt-sock')
428
+
429
+ expect(subject.proxy_command).to eq(proxy_command)
175
430
  end
176
431
  end
177
432
  end
@@ -282,5 +537,15 @@ describe VagrantPlugins::ProviderLibvirt::Config do
282
537
  end
283
538
  end
284
539
  end
540
+
541
+ context 'clock_timers' do
542
+ it 'should merge clock_timers' do
543
+ one.clock_timer(:name => 'rtc', :tickpolicy => 'catchup')
544
+ two.clock_timer(:name => 'hpet', :present => 'no')
545
+
546
+ expect(subject.clock_timers).to include(include(name: 'rtc'),
547
+ include(name: 'hpet'))
548
+ end
549
+ end
285
550
  end
286
551
  end