kitchen-vagrant 0.15.0 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,6 +21,6 @@ module Kitchen
21
21
  module Driver
22
22
 
23
23
  # Version string for Vagrant Kitchen driver
24
- VAGRANT_VERSION = "0.15.0"
24
+ VAGRANT_VERSION = "0.16.0"
25
25
  end
26
26
  end
@@ -0,0 +1,1165 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
4
+ #
5
+ # Copyright (C) 2015, Fletcher Nichol
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+ require_relative "../../spec_helper"
20
+
21
+ require "logger"
22
+ require "stringio"
23
+
24
+ require "kitchen/driver/vagrant"
25
+ require "kitchen/provisioner/dummy"
26
+
27
+ describe Kitchen::Driver::Vagrant do
28
+
29
+ let(:logged_output) { StringIO.new }
30
+ let(:logger) { Logger.new(logged_output) }
31
+ let(:config) { { :kitchen_root => "/kroot" } }
32
+ let(:platform) { Kitchen::Platform.new(:name => "fooos-99") }
33
+ let(:suite) { Kitchen::Suite.new(:name => "suitey") }
34
+ let(:busser) { double("busser") }
35
+ let(:provisioner) { Kitchen::Provisioner::Dummy.new }
36
+ let(:state_file) { double("state_file") }
37
+ let(:state) { Hash.new }
38
+ let(:env) { Hash.new }
39
+
40
+ let(:driver_object) { Kitchen::Driver::Vagrant.new(config) }
41
+
42
+ let(:driver) do
43
+ d = driver_object
44
+ instance
45
+ d
46
+ end
47
+
48
+ let(:instance) do
49
+ Kitchen::Instance.new(
50
+ :busser => busser,
51
+ :driver => driver_object,
52
+ :logger => logger,
53
+ :suite => suite,
54
+ :platform => platform,
55
+ :provisioner => provisioner,
56
+ :state_file => state_file
57
+ )
58
+ end
59
+
60
+ before { stub_const("ENV", env) }
61
+
62
+ describe "configuration" do
63
+
64
+ context "for known bento platform names" do
65
+
66
+ before { allow(platform).to receive(:name) { "ubuntu-14.04" } }
67
+
68
+ it "sets :box based on the platform name by default" do
69
+ expect(driver[:box]).to eq("opscode-ubuntu-14.04")
70
+ end
71
+
72
+ it "sets :box to a custom value" do
73
+ config[:box] = "booya"
74
+
75
+ expect(driver[:box]).to eq("booya")
76
+ end
77
+
78
+ it "sets :box_url to a bento box URL for a virtualbox provider" do
79
+ config[:provider] = "virtualbox"
80
+
81
+ expect(driver[:box_url]).to eq(
82
+ "https://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/" \
83
+ "opscode_ubuntu-14.04_chef-provisionerless.box"
84
+ )
85
+ end
86
+
87
+ it "sets :box_url to a bento box URL for a vmware-based provider" do
88
+ config[:provider] = "vmware_awesometown"
89
+
90
+ expect(driver[:box_url]).to eq(
91
+ "https://opscode-vm-bento.s3.amazonaws.com/vagrant/vmware/" \
92
+ "opscode_ubuntu-14.04_chef-provisionerless.box"
93
+ )
94
+ end
95
+
96
+ it "sets :box_url to nil for any other provider" do
97
+ config[:provider] = "the-next-coolness"
98
+
99
+ expect(driver[:box_url]).to eq(nil)
100
+ end
101
+ end
102
+
103
+ context "for unknown bento platform names" do
104
+
105
+ before { allow(platform).to receive(:name) { "slackware-14.1" } }
106
+
107
+ it "sets :box based on the platform name by default" do
108
+ expect(driver[:box]).to eq("slackware-14.1")
109
+ end
110
+
111
+ it "sets :box to a custom value" do
112
+ config[:box] = "booya"
113
+
114
+ expect(driver[:box]).to eq("booya")
115
+ end
116
+
117
+ it "sets :box_url to nil" do
118
+ expect(driver[:box_url]).to eq(nil)
119
+ end
120
+ end
121
+
122
+ it "sets :box_check_update to nil by default" do
123
+ expect(driver[:box_check_update]).to eq(nil)
124
+ end
125
+
126
+ it "sets :box_check_update to a custom value" do
127
+ config[:box_check_update] = true
128
+
129
+ expect(driver[:box_check_update]).to eq(true)
130
+ end
131
+
132
+ it "sets :box_version to nil by default" do
133
+ expect(driver[:box_version]).to eq(nil)
134
+ end
135
+
136
+ it "sets :box_version to a custom value" do
137
+ config[:box_version] = "1.2.3"
138
+
139
+ expect(driver[:box_version]).to eq("1.2.3")
140
+ end
141
+
142
+ it "sets :customize to an empty hash by default" do
143
+ expect(driver[:customize]).to eq({})
144
+ end
145
+
146
+ it "sets :customize to a custom value" do
147
+ config[:customize] = { :a => "b", :c => { :d => "e" } }
148
+
149
+ expect(driver[:customize]).to eq(:a => "b", :c => { :d => "e" })
150
+ end
151
+
152
+ it "sets :gui to nil by default" do
153
+ expect(driver[:gui]).to eq(nil)
154
+ end
155
+
156
+ it "sets :network to an empty array by default" do
157
+ expect(driver[:network]).to eq([])
158
+ end
159
+
160
+ it "sets :network to a custom value" do
161
+ config[:network] = [
162
+ ["forwarded_port", :guest => 80, :host => 8080]
163
+ ]
164
+
165
+ expect(driver[:network]).to eq([
166
+ ["forwarded_port", :guest => 80, :host => 8080]
167
+ ])
168
+ end
169
+
170
+ it "sets :pre_create_command to nil by default" do
171
+ expect(driver[:pre_create_command]).to eq(nil)
172
+ end
173
+
174
+ it "sets :pre_create_command to a custom value" do
175
+ config[:pre_create_command] = "execute yo"
176
+
177
+ expect(driver[:pre_create_command]).to eq("execute yo")
178
+ end
179
+
180
+ it "replaces {{vagrant_root}} in :pre_create_command" do
181
+ config[:pre_create_command] = "{{vagrant_root}}/candy"
182
+
183
+ expect(driver[:pre_create_command]).to eq(
184
+ "/kroot/.kitchen/kitchen-vagrant/kitchen-kroot-suitey-fooos-99/candy"
185
+ )
186
+ end
187
+
188
+ it "sets :provision to false by default" do
189
+ expect(driver[:provision]).to eq(false)
190
+ end
191
+
192
+ it "sets :provision to a custom value" do
193
+ config[:provision] = true
194
+
195
+ expect(driver[:provision]).to eq(true)
196
+ end
197
+
198
+ it "sets :provider to virtualbox by default" do
199
+ expect(driver[:provider]).to eq("virtualbox")
200
+ end
201
+
202
+ it "sets :provider to the value of VAGRANT_DEFAULT_PROVIDER from ENV" do
203
+ env["VAGRANT_DEFAULT_PROVIDER"] = "vcool"
204
+
205
+ expect(driver[:provider]).to eq("vcool")
206
+ end
207
+
208
+ it "sets :provider to a custom value" do
209
+ config[:provider] = "mything"
210
+
211
+ expect(driver[:provider]).to eq("mything")
212
+ end
213
+
214
+ it "sets :ssh to an empty hash by default" do
215
+ expect(driver[:ssh]).to eq({})
216
+ end
217
+
218
+ it "sets :ssh to a custom value" do
219
+ config[:ssh] = { :a => "b", :c => { :d => "e" } }
220
+
221
+ expect(driver[:ssh]).to eq(:a => "b", :c => { :d => "e" })
222
+ end
223
+
224
+ it "sets :synced_folders to an empty array by default" do
225
+ expect(driver[:synced_folders]).to eq([])
226
+ end
227
+
228
+ it "sets :synced_folders to a custom value" do
229
+ config[:synced_folders] = [
230
+ ["/host_path", "/vm_path", "create: true, type: :nfs"]
231
+ ]
232
+
233
+ expect(driver[:synced_folders]).to eq([
234
+ ["/host_path", "/vm_path", "create: true, type: :nfs"]
235
+ ])
236
+ end
237
+
238
+ it "replaces %{instance_name} with instance name in :synced_folders" do
239
+ config[:synced_folders] = [
240
+ ["/root/%{instance_name}", "/vm_path", "stuff"]
241
+ ]
242
+
243
+ expect(driver[:synced_folders]).to eq([
244
+ ["/root/suitey-fooos-99", "/vm_path", "stuff"]
245
+ ])
246
+ end
247
+
248
+ it "expands source paths relative to :kitchen_root in :synced_folders" do
249
+ config[:synced_folders] = [
250
+ ["./a", "/vm_path", "stuff"]
251
+ ]
252
+
253
+ expect(driver[:synced_folders]).to eq([
254
+ ["/kroot/a", "/vm_path", "stuff"]
255
+ ])
256
+ end
257
+
258
+ it "sets options to 'nil' if not set in :synced_folders entry" do
259
+ config[:synced_folders] = [
260
+ ["/host_path", "/vm_path", nil]
261
+ ]
262
+
263
+ expect(driver[:synced_folders]).to eq([
264
+ ["/host_path", "/vm_path", "nil"]
265
+ ])
266
+ end
267
+
268
+ it "sets :vagrantfile_erb to a default" do
269
+ expect(driver[:vagrantfile_erb]).to match(
270
+ %r{/kitchen-vagrant/templates/Vagrantfile\.erb$}
271
+ )
272
+ end
273
+
274
+ it "sets :vagrantfile_erb to a default value" do
275
+ config[:vagrantfile_erb] = "/a/Vagrantfile.erb"
276
+
277
+ expect(driver[:vagrantfile_erb]).to eq("/a/Vagrantfile.erb")
278
+ end
279
+
280
+ it "expands path for :vagrantfile_erb" do
281
+ config[:vagrantfile_erb] = "Yep.erb"
282
+
283
+ expect(driver[:vagrantfile_erb]).to eq("/kroot/Yep.erb")
284
+ end
285
+
286
+ it "sets :vagrantfiles to an empty array by default" do
287
+ expect(driver[:vagrantfiles]).to eq([])
288
+ end
289
+
290
+ it "sets and expands paths in :vagrantfiles" do
291
+ config[:vagrantfiles] = %W[one two three]
292
+
293
+ expect(driver[:vagrantfiles]).to eq(
294
+ %W[/kroot/one /kroot/two /kroot/three]
295
+ )
296
+ end
297
+
298
+ it "sets :vm_hostname to the instance name by default" do
299
+ expect(driver[:vm_hostname]).to eq("suitey-fooos-99")
300
+ end
301
+
302
+ it "sets :vm_hostname to a custom value" do
303
+ config[:vm_hostname] = "okay"
304
+
305
+ expect(driver[:vm_hostname]).to eq("okay")
306
+ end
307
+ end
308
+
309
+ describe "#verify_dependencies" do
310
+
311
+ it "passes for supported versions of Vagrant" do
312
+ with_modern_vagrant
313
+
314
+ driver.verify_dependencies
315
+ end
316
+
317
+ it "raises a UserError for unsupported versions of Vagrant" do
318
+ with_unsupported_vagrant
319
+
320
+ expect { driver.verify_dependencies }.to raise_error(
321
+ Kitchen::UserError, /Please upgrade to version 1.1.0 or higher/
322
+ )
323
+ end
324
+
325
+ it "raises a UserError for a missing Vagrant command" do
326
+ allow(driver).to receive(:run_command).
327
+ with("vagrant --version", any_args).and_raise(Errno::ENOENT)
328
+
329
+ expect { driver.verify_dependencies }.to raise_error(
330
+ Kitchen::UserError, /Vagrant 1.1.0 or higher is not installed/
331
+ )
332
+ end
333
+ end
334
+
335
+ describe "#create" do
336
+
337
+ let(:cmd) { driver.create(state) }
338
+
339
+ let(:vagrant_root) do
340
+ File.join(%W[
341
+ #{@dir} .kitchen kitchen-vagrant
342
+ kitchen-#{File.basename(@dir)}-suitey-fooos-99
343
+ ])
344
+ end
345
+
346
+ before do
347
+ @dir = Dir.mktmpdir("kitchen_root")
348
+ config[:kitchen_root] = @dir
349
+
350
+ allow(driver).to receive(:run_command).and_return("")
351
+ with_modern_vagrant
352
+ end
353
+
354
+ after do
355
+ FileUtils.remove_entry_secure(@dir)
356
+ end
357
+
358
+ it "logs a message on debug level for creating the Vagrantfile" do
359
+ cmd
360
+
361
+ expect(logged_output.string).to match(
362
+ /^D, .+ DEBUG -- : Creating Vagrantfile for \<suitey-fooos-99\> /
363
+ )
364
+ end
365
+
366
+ it "creates a Vagrantfile in the vagrant root directory" do
367
+ cmd
368
+
369
+ expect(File.exist?(File.join(vagrant_root, "Vagrantfile"))).to eq(true)
370
+ end
371
+
372
+ it "logs the Vagrantfile contents on debug level" do
373
+ cmd
374
+
375
+ expect(debug_lines).to match(Regexp.new(<<-REGEXP.gsub(/^ {8}/, "")))
376
+ ------------
377
+ Vagrant.configure\("2"\) do \|c\|
378
+ .*
379
+ end
380
+ ------------
381
+ REGEXP
382
+ end
383
+
384
+ it "raises ActionFailed if a custom Vagrantfile template was not found" do
385
+ config[:vagrantfile_erb] = "/a/bunch/of/nope"
386
+
387
+ expect { cmd }.to raise_error(
388
+ Kitchen::ActionFailed, /^Could not find Vagrantfile template/
389
+ )
390
+ end
391
+
392
+ it "runs the pre create command, if set" do
393
+ config[:pre_create_command] = "echo heya"
394
+ expect(driver).to receive(:run_command).with("echo heya", any_args)
395
+
396
+ cmd
397
+ end
398
+
399
+ it "runs vagrant up with --no-provision if :provision is falsey" do
400
+ config[:provision] = false
401
+ expect(driver).to receive(:run_command).
402
+ with("vagrant up --no-provision --provider virtualbox", any_args)
403
+
404
+ cmd
405
+ end
406
+
407
+ it "runs vagrant up without --no-provision if :provision is truthy" do
408
+ config[:provision] = true
409
+ expect(driver).to receive(:run_command).
410
+ with("vagrant up --provider virtualbox", any_args)
411
+
412
+ cmd
413
+ end
414
+
415
+ it "runs vagrant up with a custom provider if :provider is set" do
416
+ config[:provider] = "bananas"
417
+ expect(driver).to receive(:run_command).
418
+ with("vagrant up --no-provision --provider bananas", any_args)
419
+
420
+ cmd
421
+ end
422
+
423
+ describe "for state" do
424
+
425
+ let(:output) do
426
+ <<-OUTPUT.gsub(/^ {10}/, "")
427
+ Host hehe
428
+ HostName 192.168.32.64
429
+ User vagrant
430
+ Port 2022
431
+ UserKnownHostsFile /dev/null
432
+ StrictHostKeyChecking no
433
+ PasswordAuthentication no
434
+ IdentityFile /path/to/private_key
435
+ IdentitiesOnly yes
436
+ LogLevel FATAL
437
+ OUTPUT
438
+ end
439
+
440
+ before do
441
+ allow(driver).to receive(:run_command).
442
+ with("vagrant ssh-config", any_args).and_return(output)
443
+ end
444
+
445
+ it "sets :hostname from ssh-config" do
446
+ cmd
447
+
448
+ expect(state).to include(:hostname => "192.168.32.64")
449
+ end
450
+
451
+ it "sets :username from ssh-config" do
452
+ cmd
453
+
454
+ expect(state).to include(:username => "vagrant")
455
+ end
456
+
457
+ it "sets :ssh_key from ssh-config" do
458
+ cmd
459
+
460
+ expect(state).to include(:ssh_key => "/path/to/private_key")
461
+ end
462
+
463
+ it "sets :port from ssh-config" do
464
+ cmd
465
+
466
+ expect(state).to include(:port => "2022")
467
+ end
468
+
469
+ it "does not set :proxy_command by default" do
470
+ cmd
471
+
472
+ expect(state.keys).to_not include(:proxy_command)
473
+ end
474
+
475
+ it "sets :proxy_command if ProxyCommand is in ssh-config" do
476
+ output.concat(" ProxyCommand echo proxy\n")
477
+ cmd
478
+
479
+ expect(state).to include(:proxy_command => "echo proxy")
480
+ end
481
+ end
482
+
483
+ it "logs a message on info level" do
484
+ cmd
485
+
486
+ expect(logged_output.string).to match(
487
+ /I, .+ INFO -- : Vagrant instance \<suitey-fooos-99\> created\.$/
488
+ )
489
+ end
490
+ end
491
+
492
+ describe "#destroy" do
493
+
494
+ let(:cmd) { driver.destroy(state) }
495
+
496
+ let(:vagrant_root) do
497
+ File.join(%W[
498
+ #{@dir} .kitchen kitchen-vagrant
499
+ kitchen-#{File.basename(@dir)}-suitey-fooos-99
500
+ ])
501
+ end
502
+
503
+ before do
504
+ @dir = Dir.mktmpdir("kitchen_root")
505
+ config[:kitchen_root] = @dir
506
+
507
+ allow(driver).to receive(:run_command).and_return("")
508
+ with_modern_vagrant
509
+
510
+ FileUtils.mkdir_p(vagrant_root)
511
+ state[:hostname] = "hosta"
512
+ end
513
+
514
+ after do
515
+ FileUtils.remove_entry_secure(@dir)
516
+ end
517
+
518
+ it "logs a message on debug level for creating the Vagrantfile" do
519
+ cmd
520
+
521
+ expect(logged_output.string).to match(
522
+ /^D, .+ DEBUG -- : Creating Vagrantfile for \<suitey-fooos-99\> /
523
+ )
524
+ end
525
+
526
+ it "logs the Vagrantfile contents on debug level" do
527
+ cmd
528
+
529
+ expect(debug_lines).to match(Regexp.new(<<-REGEXP.gsub(/^ {8}/, "")))
530
+ ------------
531
+ Vagrant.configure\("2"\) do \|c\|
532
+ .*
533
+ end
534
+ ------------
535
+ REGEXP
536
+ end
537
+
538
+ it "does not run vagrant destroy if :hostname is not present in state" do
539
+ state.delete(:hostname)
540
+ expect(driver).to_not receive(:run_command).
541
+ with("vagrant destroy -f", any_args)
542
+
543
+ cmd
544
+ end
545
+
546
+ it "runs vagrant destroy" do
547
+ expect(driver).to receive(:run_command).
548
+ with("vagrant destroy -f", any_args)
549
+
550
+ cmd
551
+ end
552
+
553
+ it "deletes the vagrant root directory" do
554
+ expect(File.directory?(vagrant_root)).to eq(true)
555
+ cmd
556
+ expect(File.directory?(vagrant_root)).to eq(false)
557
+ end
558
+
559
+ it "logs a message on info level" do
560
+ cmd
561
+
562
+ expect(logged_output.string).to match(
563
+ /I, .+ INFO -- : Vagrant instance \<suitey-fooos-99\> destroyed\.$/
564
+ )
565
+ end
566
+
567
+ it "deletes :hostname from state" do
568
+ cmd
569
+
570
+ expect(state.keys).to_not include(:hostname)
571
+ end
572
+ end
573
+
574
+ describe "Vagrantfile" do
575
+
576
+ let(:cmd) { driver.create(state) }
577
+
578
+ let(:vagrant_root) do
579
+ File.join(%W[
580
+ #{@dir} .kitchen kitchen-vagrant
581
+ kitchen-#{File.basename(@dir)}-suitey-fooos-99
582
+ ])
583
+ end
584
+
585
+ before do
586
+ @dir = Dir.mktmpdir("kitchen_root")
587
+ config[:kitchen_root] = @dir
588
+
589
+ allow(driver).to receive(:run_command).and_return("")
590
+ with_modern_vagrant
591
+ end
592
+
593
+ after do
594
+ FileUtils.remove_entry_secure(@dir)
595
+ end
596
+
597
+ it "disables the vagrant-berkshelf plugin is present" do
598
+ cmd
599
+
600
+ expect(vagrantfile).to match(regexify(
601
+ "c.berkshelf.enabled = false " \
602
+ "if Vagrant.has_plugin?(\"vagrant-berkshelf\")"
603
+ ))
604
+ end
605
+
606
+ it "sets the vm.box" do
607
+ cmd
608
+
609
+ expect(vagrantfile).to match(regexify(%{c.vm.box = "fooos-99"}))
610
+ end
611
+
612
+ it "sets the vm.hostname" do
613
+ config[:vm_hostname] = "charlie"
614
+ cmd
615
+
616
+ expect(vagrantfile).to match(regexify(%{c.vm.hostname = "charlie"}))
617
+ end
618
+
619
+ it "disables the /vagrant synced folder by default" do
620
+ cmd
621
+
622
+ expect(vagrantfile).to match(regexify(
623
+ %{c.vm.synced_folder ".", "/vagrant", disabled: true}
624
+ ))
625
+ end
626
+
627
+ it "creates an empty provider block by default" do
628
+ config[:provider] = "wowza"
629
+ cmd
630
+
631
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {6}/, "").chomp))
632
+ c.vm.provider :wowza do |p|
633
+ end
634
+ RUBY
635
+ end
636
+
637
+ it "requires no Vagrantfiles by default" do
638
+ cmd
639
+
640
+ expect(vagrantfile).to_not match(regexify("require"))
641
+ end
642
+
643
+ it "requires each entry in :vagranfiles" do
644
+ config[:vagrantfiles] = %W[/a /b /c]
645
+ cmd
646
+
647
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
648
+ require "/a"
649
+ require "/b"
650
+ require "/c"
651
+ RUBY
652
+ end
653
+
654
+ it "sets no vm.box_url if missing" do
655
+ config[:box_url] = nil
656
+ cmd
657
+
658
+ expect(vagrantfile).to_not match(regexify(%{c.vm.box_url}, :partial))
659
+ end
660
+
661
+ it "sets vm.box_url if :box_url is set" do
662
+ config[:box_url] = "dat.url"
663
+ cmd
664
+
665
+ expect(vagrantfile).to match(regexify(%{c.vm.box_url = "dat.url"}))
666
+ end
667
+
668
+ it "sets no vm.box_version if missing" do
669
+ config[:box_version] = nil
670
+ cmd
671
+
672
+ expect(vagrantfile).to_not match(regexify(%{c.vm.box_version}, :partial))
673
+ end
674
+
675
+ it "sets vm.box_version if :box_version is set" do
676
+ config[:box_version] = "a.b.c"
677
+ cmd
678
+
679
+ expect(vagrantfile).to match(regexify(%{c.vm.box_version = "a.b.c"}))
680
+ end
681
+
682
+ it "sets no vm.box_check_update if missing" do
683
+ config[:box_check_update] = nil
684
+ cmd
685
+
686
+ expect(vagrantfile).to_not match(
687
+ regexify(%{c.vm.box_check_update}, :partial)
688
+ )
689
+ end
690
+
691
+ it "sets vm.box_check_update if :box_check_update is set" do
692
+ config[:box_check_update] = "um"
693
+ cmd
694
+
695
+ expect(vagrantfile).to match(regexify(%{c.vm.box_check_update = "um"}))
696
+ end
697
+
698
+ it "sets no vm.communicator if missing" do
699
+ config[:communicator] = nil
700
+ cmd
701
+
702
+ expect(vagrantfile).to_not match(regexify(%{c.vm.communicator}, :partial))
703
+ end
704
+
705
+ it "sets vm.communicator if :communicator is set" do
706
+ config[:communicator] = "wat"
707
+ cmd
708
+
709
+ expect(vagrantfile).to match(regexify(%{c.vm.communicator = "wat"}))
710
+ end
711
+
712
+ it "sets no vm.guest if missing" do
713
+ config[:guest] = nil
714
+ cmd
715
+
716
+ expect(vagrantfile).to_not match(regexify(%{c.vm.guest}, :partial))
717
+ end
718
+
719
+ it "sets vm.guest if :guest is set" do
720
+ config[:guest] = "mac"
721
+ cmd
722
+
723
+ expect(vagrantfile).to match(regexify(%{c.vm.guest = "mac"}))
724
+ end
725
+
726
+ it "sets no ssh.username if missing" do
727
+ config[:username] = nil
728
+ cmd
729
+
730
+ expect(vagrantfile).to_not match(regexify(%{c.ssh.username}, :partial))
731
+ end
732
+
733
+ it "sets ssh.username if :username is set" do
734
+ config[:username] = "jdoe"
735
+ cmd
736
+
737
+ expect(vagrantfile).to match(regexify(%{c.ssh.username = "jdoe"}))
738
+ end
739
+
740
+ it "sets no ssh.password if missing" do
741
+ config[:password] = nil
742
+ cmd
743
+
744
+ expect(vagrantfile).to_not match(regexify(%{c.ssh.password}, :partial))
745
+ end
746
+
747
+ it "sets ssh.password if :password is set" do
748
+ config[:password] = "okay"
749
+ cmd
750
+
751
+ expect(vagrantfile).to match(regexify(%{c.ssh.password = "okay"}))
752
+ end
753
+
754
+ it "sets no ssh.private_key_path if missing" do
755
+ config[:ssh_key] = nil
756
+ cmd
757
+
758
+ expect(vagrantfile).to_not match(
759
+ regexify(%{c.ssh.private_key_path}, :partial)
760
+ )
761
+ end
762
+
763
+ it "sets ssh.private_key_path if :ssh_key is set" do
764
+ config[:ssh_key] = "okay"
765
+ cmd
766
+
767
+ expect(vagrantfile).to match(regexify(%{c.ssh.private_key_path = "okay"}))
768
+ end
769
+
770
+ it "adds a vm.ssh line for each key/value pair in :ssh" do
771
+ config[:ssh] = {
772
+ :username => %{"jdoe"},
773
+ :password => %{"secret"},
774
+ :private_key_path => %{"/key"}
775
+ }
776
+ cmd
777
+
778
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {6}/, "").chomp))
779
+ c.ssh.username = "jdoe"
780
+ c.ssh.password = "secret"
781
+ c.ssh.private_key_path = "/key"
782
+ RUBY
783
+ end
784
+
785
+ it "adds a vm.network line for each element in :network" do
786
+ config[:network] = [
787
+ ["forwarded_port", { :guest => 80, :host => 8080 }],
788
+ ["private_network", { :ip => "192.168.33.33" }]
789
+ ]
790
+ cmd
791
+
792
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {6}/, "").chomp))
793
+ c.vm.network(:forwarded_port, {:guest=>80, :host=>8080})
794
+ c.vm.network(:private_network, {:ip=>"192.168.33.33"})
795
+ RUBY
796
+ end
797
+
798
+ it "adds a vm.synced_folder line for each element in :synced_folders" do
799
+ config[:synced_folders] = [
800
+ ["/a/b", "/opt/instance_data", "nil"],
801
+ ["/host_path", "/vm_path", "create: true, type: :nfs"]
802
+ ]
803
+ cmd
804
+
805
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {6}/, "").chomp))
806
+ c.vm.synced_folder "/a/b", "/opt/instance_data", nil
807
+ c.vm.synced_folder "/host_path", "/vm_path", create: true, type: :nfs
808
+ RUBY
809
+ end
810
+
811
+ context "for virtualbox provider" do
812
+
813
+ before { config[:provider] = "virtualbox" }
814
+
815
+ it "adds a line for each element in :customize" do
816
+ config[:customize] = {
817
+ :a_key => "some value",
818
+ :something => "else"
819
+ }
820
+ cmd
821
+
822
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
823
+ c.vm.provider :virtualbox do |p|
824
+ p.customize ["modifyvm", :id, "--a_key", "some value"]
825
+ p.customize ["modifyvm", :id, "--something", "else"]
826
+ end
827
+ RUBY
828
+ end
829
+
830
+ it "does not set :gui to nil" do
831
+ config[:gui] = nil
832
+ cmd
833
+
834
+ expect(vagrantfile).to_not match(regexify(%{p.gui = }, :partial))
835
+ end
836
+
837
+ it "sets :gui to false if set" do
838
+ config[:gui] = false
839
+ cmd
840
+
841
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
842
+ c.vm.provider :virtualbox do |p|
843
+ p.gui = false
844
+ end
845
+ RUBY
846
+ end
847
+
848
+ it "sets :gui to true if set" do
849
+ config[:gui] = true
850
+ cmd
851
+
852
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
853
+ c.vm.provider :virtualbox do |p|
854
+ p.gui = true
855
+ end
856
+ RUBY
857
+ end
858
+ end
859
+
860
+ context "for parallels provider" do
861
+
862
+ before { config[:provider] = "parallels" }
863
+
864
+ it "adds a line for each element in :customize" do
865
+ config[:customize] = {
866
+ :a_key => "some value",
867
+ :something => "else"
868
+ }
869
+ cmd
870
+
871
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
872
+ c.vm.provider :parallels do |p|
873
+ p.customize ["set", :id, "--a-key", "some value"]
874
+ p.customize ["set", :id, "--something", "else"]
875
+ end
876
+ RUBY
877
+ end
878
+ end
879
+
880
+ context "for rackspace provider" do
881
+
882
+ before { config[:provider] = "rackspace" }
883
+
884
+ it "adds a line for each element in :customize" do
885
+ config[:customize] = {
886
+ :a_key => "some value",
887
+ :something => "else"
888
+ }
889
+ cmd
890
+
891
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
892
+ c.vm.provider :rackspace do |p|
893
+ p.a_key = "some value"
894
+ p.something = "else"
895
+ end
896
+ RUBY
897
+ end
898
+ end
899
+
900
+ context "for softlayer provider" do
901
+
902
+ before { config[:provider] = "softlayer" }
903
+
904
+ it "adds a line for disk_capacity" do
905
+ config[:customize] = {
906
+ :disk_capacity => {
907
+ :"0" => 25,
908
+ :"2" => 100
909
+ }
910
+ }
911
+ cmd
912
+
913
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
914
+ c.vm.provider :softlayer do |p|
915
+ p.disk_capacity = {:"0"=>25, :"2"=>100}
916
+ end
917
+ RUBY
918
+ end
919
+
920
+ it "adds a line for each element in :customize" do
921
+ config[:customize] = {
922
+ :a_key => "some value",
923
+ :something => "else"
924
+ }
925
+ cmd
926
+
927
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
928
+ c.vm.provider :softlayer do |p|
929
+ p.a_key = "some value"
930
+ p.something = "else"
931
+ end
932
+ RUBY
933
+ end
934
+ end
935
+
936
+ context "for libvirt provider" do
937
+
938
+ before { config[:provider] = "libvirt" }
939
+
940
+ it "adds a line for each element in :customize" do
941
+ config[:customize] = {
942
+ :a_key => "some value",
943
+ :something => "else"
944
+ }
945
+ cmd
946
+
947
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
948
+ c.vm.provider :libvirt do |p|
949
+ p.a_key = some value
950
+ p.something = else
951
+ end
952
+ RUBY
953
+ end
954
+ end
955
+
956
+ context "for lxc provider" do
957
+
958
+ before { config[:provider] = "lxc" }
959
+
960
+ it "sets container_name to :machine if set" do
961
+ config[:customize] = {
962
+ :container_name => ":machine"
963
+ }
964
+ cmd
965
+
966
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
967
+ c.vm.provider :lxc do |p|
968
+ p.container_name = :machine
969
+ end
970
+ RUBY
971
+ end
972
+
973
+ it "sets container_name to another value in quotes if set" do
974
+ config[:customize] = {
975
+ :container_name => "beans"
976
+ }
977
+ cmd
978
+
979
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
980
+ c.vm.provider :lxc do |p|
981
+ p.container_name = "beans"
982
+ end
983
+ RUBY
984
+ end
985
+
986
+ it "sets backingstore if set" do
987
+ config[:customize] = {
988
+ :backingstore => "lvm"
989
+ }
990
+ cmd
991
+
992
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
993
+ c.vm.provider :lxc do |p|
994
+ p.backingstore = "lvm"
995
+ end
996
+ RUBY
997
+ end
998
+
999
+ it "sets backingstore_option line for each backingstore_options" do
1000
+ config[:customize] = {
1001
+ :backingstore_options => {
1002
+ :vgname => "schroots",
1003
+ :fstype => "xfs"
1004
+ }
1005
+ }
1006
+ cmd
1007
+
1008
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
1009
+ c.vm.provider :lxc do |p|
1010
+ p.backingstore_option "--vgname", "schroots"
1011
+ p.backingstore_option "--fstype", "xfs"
1012
+ end
1013
+ RUBY
1014
+ end
1015
+
1016
+ it "sets all other options to customize lines" do
1017
+ config[:customize] = {
1018
+ :cookies => "cream",
1019
+ :salt => "vinegar"
1020
+ }
1021
+ cmd
1022
+
1023
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
1024
+ c.vm.provider :lxc do |p|
1025
+ p.customize "cookies", "cream"
1026
+ p.customize "salt", "vinegar"
1027
+ end
1028
+ RUBY
1029
+ end
1030
+ end
1031
+
1032
+ context "for vmware_* providers" do
1033
+
1034
+ before { config[:provider] = "vmware_desktop" }
1035
+
1036
+ it "does not set :gui to nil" do
1037
+ config[:gui] = nil
1038
+ cmd
1039
+
1040
+ expect(vagrantfile).to_not match(regexify(%{p.gui = }, :partial))
1041
+ end
1042
+
1043
+ it "sets :gui to false if set" do
1044
+ config[:gui] = false
1045
+ cmd
1046
+
1047
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
1048
+ c.vm.provider :vmware_desktop do |p|
1049
+ p.gui = false
1050
+ end
1051
+ RUBY
1052
+ end
1053
+
1054
+ it "sets :gui to true if set" do
1055
+ config[:gui] = true
1056
+ cmd
1057
+
1058
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
1059
+ c.vm.provider :vmware_desktop do |p|
1060
+ p.gui = true
1061
+ end
1062
+ RUBY
1063
+ end
1064
+
1065
+ it "adds a line for each element in :customize" do
1066
+ config[:customize] = {
1067
+ :a_key => "some value",
1068
+ :something => "else"
1069
+ }
1070
+ cmd
1071
+
1072
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
1073
+ c.vm.provider :vmware_desktop do |p|
1074
+ p.vmx["a_key"] = "some value"
1075
+ p.vmx["something"] = "else"
1076
+ end
1077
+ RUBY
1078
+ end
1079
+
1080
+ it "converts :memory into :memsize" do
1081
+ config[:customize] = {
1082
+ :memory => "222"
1083
+ }
1084
+ cmd
1085
+
1086
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
1087
+ c.vm.provider :vmware_desktop do |p|
1088
+ p.vmx["memsize"] = "222"
1089
+ end
1090
+ RUBY
1091
+ end
1092
+
1093
+ it "skips :memory if key :memsize exists" do
1094
+ config[:customize] = {
1095
+ :memory => "222",
1096
+ :memsize => "444"
1097
+ }
1098
+ cmd
1099
+
1100
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
1101
+ c.vm.provider :vmware_desktop do |p|
1102
+ p.vmx["memsize"] = "444"
1103
+ end
1104
+ RUBY
1105
+ end
1106
+ end
1107
+
1108
+ context "for managed provider" do
1109
+
1110
+ before { config[:provider] = "managed" }
1111
+
1112
+ it "adds a line a server" do
1113
+ config[:customize] = {
1114
+ :server => "my_server"
1115
+ }
1116
+ cmd
1117
+
1118
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
1119
+ c.vm.provider :managed do |p|
1120
+ p.server = "my_server"
1121
+ end
1122
+ RUBY
1123
+ end
1124
+
1125
+ it "ignores all other key types than server" do
1126
+ config[:customize] = {
1127
+ :other => "stuff",
1128
+ :is => "ignored"
1129
+ }
1130
+ cmd
1131
+
1132
+ expect(vagrantfile).to match(regexify(<<-RUBY.gsub(/^ {8}/, "").chomp))
1133
+ c.vm.provider :managed do |p|
1134
+ end
1135
+ RUBY
1136
+ end
1137
+ end
1138
+ end
1139
+
1140
+ def debug_lines
1141
+ regex = %r{^D, .* : }
1142
+ logged_output.string.lines.
1143
+ select { |l| l =~ regex }.map { |l| l.sub(regex, "") }.join
1144
+ end
1145
+
1146
+ def with_modern_vagrant
1147
+ allow(driver).to receive(:run_command).
1148
+ with("vagrant --version", any_args).and_return("Vagrant 1.7.2")
1149
+ end
1150
+
1151
+ def with_unsupported_vagrant
1152
+ allow(driver).to receive(:run_command).
1153
+ with("vagrant --version", any_args).and_return("Vagrant 1.0.5")
1154
+ end
1155
+
1156
+ def regexify(str, line = :whole_line)
1157
+ r = Regexp.escape(str)
1158
+ r = "^\s*#{r}$" if line == :whole_line
1159
+ Regexp.new(r)
1160
+ end
1161
+
1162
+ def vagrantfile
1163
+ IO.read(File.join(vagrant_root, "Vagrantfile"))
1164
+ end
1165
+ end