beaker-vagrant 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.
@@ -0,0 +1,11 @@
1
+ require 'beaker/hypervisor/vagrant'
2
+
3
+ class Beaker::VagrantCustom < Beaker::Vagrant
4
+ def provision(provider = nil)
5
+ super
6
+ end
7
+
8
+ def make_vfile hosts, options = {}
9
+ FileUtils.cp(@options[:vagrantfile_path], @vagrant_file)
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ require 'beaker/hypervisor/vagrant'
2
+
3
+ class Beaker::VagrantFusion < Beaker::Vagrant
4
+ def provision(provider = 'vmware_fusion')
5
+ # By default vmware_fusion creates a .vagrant directory relative to the
6
+ # Vagrantfile path. That means beaker tries to scp the VM to itself unless
7
+ # we move the VM files elsewhere.
8
+ ENV['VAGRANT_VMWARE_CLONE_DIRECTORY'] = '~/.vagrant/vmware_fusion'
9
+ super
10
+ end
11
+
12
+ def self.provider_vfile_section(host, options)
13
+ " v.vm.provider :vmware_fusion do |v|\n" +
14
+ " v.vmx['memsize'] = '#{memsize(host, options)}'\n" +
15
+ " end\n"
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ require 'beaker/hypervisor/vagrant'
2
+
3
+ class Beaker::VagrantLibvirt < Beaker::Vagrant
4
+ @memory = nil
5
+ @cpu = nil
6
+
7
+ class << self
8
+ attr_reader :memory
9
+ end
10
+
11
+ # Return a random mac address with colons
12
+ #
13
+ # @return [String] a random mac address
14
+ def randmac
15
+ "08:00:27:" + (1..3).map{"%0.2X"%rand(256)}.join(':')
16
+ end
17
+
18
+ def provision(provider = 'libvirt')
19
+ super
20
+ end
21
+
22
+ def self.provider_vfile_section(host, options)
23
+ " v.vm.provider :libvirt do |node|\n" +
24
+ " node.cpus = #{cpus(host, options)}\n" +
25
+ " node.memory = #{memsize(host, options)}\n" +
26
+ build_options_str(options) +
27
+ " end\n"
28
+ end
29
+
30
+ def self.build_options_str(options)
31
+ other_options_str = ''
32
+ if options['libvirt']
33
+ other_options = []
34
+ options['libvirt'].each do |k, v|
35
+ other_options << " node.#{k} = '#{v}'"
36
+ end
37
+ other_options_str = other_options.join("\n")
38
+ end
39
+ "#{other_options_str}\n"
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ require 'beaker/hypervisor/vagrant'
2
+
3
+ class Beaker::VagrantParallels < Beaker::Vagrant
4
+ def provision(provider = 'parallels')
5
+ super
6
+ end
7
+
8
+ def self.provider_vfile_section(host, options)
9
+ provider_section = ""
10
+ provider_section << " v.vm.provider :parallels do |prl|\n"
11
+ provider_section << " prl.optimize_power_consumption = false\n"
12
+ provider_section << " prl.memory = '#{memsize(host,options)}'\n"
13
+ provider_section << " prl.update_guest_tools = false\n" if options[:prl_update_guest_tools] == 'disable'
14
+ provider_section << " end\n"
15
+
16
+ provider_section
17
+ end
18
+ end
@@ -0,0 +1,76 @@
1
+ require 'beaker/hypervisor/vagrant'
2
+
3
+ class Beaker::VagrantVirtualbox < Beaker::Vagrant
4
+ def provision(provider = 'virtualbox')
5
+ super
6
+ end
7
+
8
+ # Generate a VM customization string
9
+ def self.vb_customize(command, args)
10
+ " vb.customize ['#{command}', #{args.map{|a| "'#{a.to_s}'"}.join(", ")}]\n"
11
+ end
12
+
13
+ # Generate a VM customization string for the current VM
14
+ def self.vb_customize_vm(command, args)
15
+ " vb.customize ['#{command}', :id, #{args.map{|a| "'#{a.to_s}'"}.join(", ")}]\n"
16
+ end
17
+
18
+ def self.provider_vfile_section(host, options)
19
+ # Allow memory and CPUs to be set at a per node level or overall, and take the most specific setting
20
+ provider_section = ""
21
+ provider_section << " v.vm.provider :virtualbox do |vb|\n"
22
+ provider_section << " vb.customize ['modifyvm', :id, '--memory', '#{memsize(host,options)}', '--cpus', '#{cpus(host,options)}']\n"
23
+ provider_section << " vb.vbguest.auto_update = false" if options[:vbguest_plugin] == 'disable'
24
+
25
+ # Guest volume support
26
+ # - Creates a new AHCI controller with the requisite number of ports,
27
+ # the default controller is limited in its number of supported ports (2).
28
+ # The AHCI emulation is generic enough for acceptance testing, and
29
+ # presents the devices as SCSI devices in /sys/class/scsi_disk.
30
+ # - Creates the defined volumes in beaker's temporary folder and attaches
31
+ # them to the controller in order starting at port 0. This presents disks
32
+ # as 2:0:0:0, 3:0:0:0 ... much like you'd see on commercial storage boxes
33
+ if host['volumes']
34
+ provider_section << self.vb_customize_vm('storagectl', [
35
+ '--name', 'SATA Controller',
36
+ '--add', 'sata',
37
+ '--controller', 'IntelAHCI',
38
+ '--portcount', host['volumes'].length
39
+ ])
40
+ host['volumes'].keys.each_with_index do |volume, index|
41
+ volume_path = "#{host.name}-#{volume}.vdi"
42
+ provider_section << self.vb_customize('createhd', [
43
+ '--filename', volume_path,
44
+ '--size', host['volumes'][volume]['size'],
45
+ ])
46
+ provider_section << self.vb_customize_vm('storageattach', [
47
+ '--storagectl', 'SATA Controller',
48
+ '--port', index,
49
+ '--device', 0,
50
+ '--type', 'hdd',
51
+ '--medium', volume_path,
52
+ ])
53
+ end
54
+ end
55
+
56
+ provider_section << " vb.customize [\"modifyvm\", :id, \"--natdnshostresolver1\", \"#{host['natdns']}\"]\n" unless host['natdns'].nil?
57
+
58
+ provider_section << " vb.customize [\"modifyvm\", :id, \"--natdnsproxy1\", \"#{host['natdns']}\"]\n" unless host['natdns'].nil?
59
+
60
+ provider_section << " vb.gui = true\n" unless host['vb_gui'].nil?
61
+
62
+ provider_section << " [\"modifyvm\", :id, \"--cpuidset\", \"1\",\"000206a7\",\"02100800\",\"1fbae3bf\",\"bfebfbff\"\]" if /osx/i.match(host['platform'])
63
+
64
+ if host['disk_path']
65
+ unless File.exist?(host['disk_path'])
66
+ host['disk_path'] = File.join(host['disk_path'], "#{host.name}.vmdk")
67
+ provider_section << " vb.customize ['createhd', '--filename', '#{host['disk_path']}', '--size', #{host['disk_size'] ||= 5 * 1024}, '--format', 'vmdk']\n"
68
+ end
69
+ provider_section << " vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium','#{host['disk_path']}']\n"
70
+ end
71
+
72
+ provider_section << " end\n"
73
+
74
+ provider_section
75
+ end
76
+ end
@@ -0,0 +1,13 @@
1
+ require 'beaker/hypervisor/vagrant'
2
+
3
+ class Beaker::VagrantWorkstation < Beaker::Vagrant
4
+ def provision(provider = 'vmware_workstation')
5
+ super
6
+ end
7
+
8
+ def self.provider_vfile_section(host, options)
9
+ " v.vm.provider :vmware_workstation do |v|\n" +
10
+ " v.vmx['memsize'] = '#{memsize(host,options)}'\n" +
11
+ " end\n"
12
+ end
13
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Beaker::VagrantCustom do
4
+ let( :options ) { make_opts.merge({ :hosts_file => 'sample.cfg', 'logger' => double().as_null_object }) }
5
+ let( :vagrant ) { Beaker::VagrantCustom.new( @hosts, options ) }
6
+
7
+ let(:test_dir) { 'tmp/tests' }
8
+ let(:custom_vagrant_file_path) { File.expand_path(test_dir + '/CustomVagrantfile') }
9
+
10
+ before :each do
11
+ @hosts = make_hosts()
12
+ end
13
+
14
+ it "uses the vagrant_custom provider for provisioning" do
15
+ @hosts.each do |host|
16
+ host_prev_name = host['user']
17
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, 'vagrant' ).once
18
+ expect( vagrant ).to receive( :copy_ssh_to_root ).with( host, options ).once
19
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, host_prev_name ).once
20
+ end
21
+ expect( vagrant ).to receive( :hack_etc_hosts ).with( @hosts, options ).once
22
+ FakeFS.activate!
23
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "up" ).once
24
+ vagrant.provision
25
+ end
26
+
27
+ context 'takes vagrant configuration from existing file' do
28
+ it 'writes the vagrant file to the correct location' do
29
+ options.merge!({ :vagrantfile_path => custom_vagrant_file_path })
30
+
31
+ create_files([custom_vagrant_file_path])
32
+
33
+ vagrant_file_contents = <<-EOF
34
+ FOO
35
+ EOF
36
+ File.open(custom_vagrant_file_path, 'w') { |file| file.write(vagrant_file_contents) }
37
+
38
+ vagrant_copy_location = "#{test_dir}/NewVagrantLocation"
39
+ vagrant.instance_variable_set(:@vagrant_file, vagrant_copy_location)
40
+ vagrant.make_vfile(@hosts, options)
41
+ vagrant_copy_file = File.open(vagrant_copy_location, 'r')
42
+ expect(vagrant_copy_file.read).to be === vagrant_file_contents
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Beaker::VagrantFusion do
4
+ let( :options ) { make_opts.merge({ :hosts_file => 'sample.cfg', 'logger' => double().as_null_object }) }
5
+ let( :vagrant ) { Beaker::VagrantFusion.new( @hosts, options ) }
6
+
7
+ before :each do
8
+ @hosts = make_hosts()
9
+ end
10
+
11
+ it "uses the vmware_fusion provider for provisioning" do
12
+ @hosts.each do |host|
13
+ host_prev_name = host['user']
14
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, 'vagrant' ).once
15
+ expect( vagrant ).to receive( :copy_ssh_to_root ).with( host, options ).once
16
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, host_prev_name ).once
17
+ end
18
+ expect( vagrant ).to receive( :hack_etc_hosts ).with( @hosts, options ).once
19
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "up --provider vmware_fusion" ).once
20
+ vagrant.provision
21
+ end
22
+
23
+ it "can make a Vagranfile for a set of hosts" do
24
+ path = vagrant.instance_variable_get( :@vagrant_path )
25
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
26
+
27
+ vagrant.make_vfile( @hosts )
28
+
29
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
30
+ expect( vagrantfile ).to include( %Q{ v.vm.provider :vmware_fusion do |v|\n v.vmx['memsize'] = '1024'\n end})
31
+ end
32
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe Beaker::VagrantLibvirt do
4
+ let( :options ) { make_opts.merge({ :hosts_file => 'sample.cfg',
5
+ 'logger' => double().as_null_object,
6
+ 'libvirt' => { 'uri' => 'qemu+ssh://root@host/system'},
7
+ 'vagrant_cpus' => 2,
8
+ }) }
9
+ let( :vagrant ) { Beaker::VagrantLibvirt.new( @hosts, options ) }
10
+
11
+ before :each do
12
+ @hosts = make_hosts()
13
+ end
14
+
15
+ it "uses the vagrant_libvirt provider for provisioning" do
16
+ @hosts.each do |host|
17
+ host_prev_name = host['user']
18
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, 'vagrant' ).once
19
+ expect( vagrant ).to receive( :copy_ssh_to_root ).with( host, options ).once
20
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, host_prev_name ).once
21
+ end
22
+ expect( vagrant ).to receive( :hack_etc_hosts ).with( @hosts, options ).once
23
+ FakeFS.activate!
24
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "up --provider libvirt" ).once
25
+ vagrant.provision
26
+ end
27
+
28
+ context 'Correct vagrant configuration' do
29
+ before(:each) do
30
+ FakeFS.activate!
31
+ path = vagrant.instance_variable_get( :@vagrant_path )
32
+
33
+ vagrant.make_vfile( @hosts, options )
34
+ @vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
35
+ end
36
+
37
+ it "can make a Vagranfile for a set of hosts" do
38
+ expect( @vagrantfile ).to include( %Q{ v.vm.provider :libvirt do |node|})
39
+ end
40
+
41
+ it "can specify the memory as an integer" do
42
+ expect( @vagrantfile.split("\n").map(&:strip) )
43
+ .to include('node.memory = 1024')
44
+ end
45
+
46
+ it "can specify the number of cpus" do
47
+ expect( @vagrantfile.split("\n").map(&:strip) )
48
+ .to include("node.cpus = 2")
49
+ end
50
+
51
+ it "can specify any libvirt option" do
52
+ expect( @vagrantfile.split("\n").map(&:strip) )
53
+ .to include("node.uri = 'qemu+ssh://root@host/system'")
54
+ end
55
+
56
+ it "has a mac address in the proper format" do
57
+ expect( @vagrantfile.split("\n").map(&:strip) )
58
+ .to include(/:mac => "08:00:27:\h{2}:\h{2}:\h{2}"/)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe Beaker::VagrantParallels do
4
+ let( :options ) { make_opts.merge({ :hosts_file => 'sample.cfg', 'logger' => double().as_null_object }) }
5
+ let( :vagrant ) { Beaker::VagrantParallels.new( @hosts, options ) }
6
+
7
+ before :each do
8
+ @hosts = make_hosts()
9
+ end
10
+
11
+ it "uses the parallels provider for provisioning" do
12
+ @hosts.each do |host|
13
+ host_prev_name = host['user']
14
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, 'vagrant' ).once
15
+ expect( vagrant ).to receive( :copy_ssh_to_root ).with( host, options ).once
16
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, host_prev_name ).once
17
+ end
18
+ expect( vagrant ).to receive( :hack_etc_hosts ).with( @hosts, options ).once
19
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "up --provider parallels" ).once
20
+ vagrant.provision
21
+ end
22
+
23
+ it "can make a Vagranfile for a set of hosts" do
24
+ path = vagrant.instance_variable_get( :@vagrant_path )
25
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
26
+
27
+ vagrant.make_vfile( @hosts )
28
+
29
+ vagrantfile = File.read( File.expand_path( File.join( path, 'Vagrantfile' )))
30
+ expect( vagrantfile ).to include( %Q{ v.vm.provider :parallels do |prl|\n prl.optimize_power_consumption = false\n prl.memory = '1024'\n end})
31
+ end
32
+
33
+ it "can disable the auto-update functionality of the Parallels Guest Tools" do
34
+ options.merge!({ :prl_update_guest_tools => 'disable' })
35
+
36
+ vfile_section = vagrant.class.provider_vfile_section( @hosts.first, options )
37
+
38
+ match = vfile_section.match(/prl.update_guest_tools = false/)
39
+
40
+ expect( match ).to_not be nil
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,479 @@
1
+ require 'spec_helper'
2
+
3
+ module Beaker
4
+ describe Vagrant do
5
+
6
+ let( :options ) {
7
+ make_opts.merge({
8
+ 'logger' => double().as_null_object,
9
+ :hosts_file => 'sample.cfg',
10
+ :forward_ssh_agent => true,
11
+ })
12
+ }
13
+
14
+ let( :vagrant ) { Beaker::Vagrant.new( @hosts, options ) }
15
+
16
+ before :each do
17
+ @hosts = make_hosts({
18
+ :mount_folders => {
19
+ :test_temp => {:from => './', :to => '/temp'},
20
+ :test_tmp => {:from => '../', :to => '/tmp'}
21
+ },
22
+ :forwarded_ports => {
23
+ :http => {:from => 10080, :to => 80},
24
+ :ssl => {:from => 4443, :to => 443},
25
+ :tomcat => {:from => 8080, :to => 8080}
26
+ }
27
+ })
28
+ end
29
+
30
+ it "stores the vagrant file in $WORKINGDIR/.vagrant/beaker_vagrant_files/sample.cfg" do
31
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
32
+ path = vagrant.instance_variable_get( :@vagrant_path )
33
+
34
+ expect( path ).to be === File.join(Dir.pwd, '.vagrant', 'beaker_vagrant_files', 'sample.cfg')
35
+
36
+ end
37
+
38
+ it "can make a Vagrantfile for a set of hosts" do
39
+ path = vagrant.instance_variable_get( :@vagrant_path )
40
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
41
+
42
+ vagrant.make_vfile( @hosts )
43
+
44
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
45
+ puts "file is #{path}\n"
46
+ expect( vagrantfile ).to be === <<-EOF
47
+ Vagrant.configure("2") do |c|
48
+ c.ssh.insert_key = false
49
+ c.vm.define 'vm1' do |v|
50
+ v.vm.hostname = 'vm1'
51
+ v.vm.box = 'vm2vm1_of_my_box'
52
+ v.vm.box_url = 'http://address.for.my.box.vm1'
53
+ v.vm.box_check_update = 'true'
54
+ v.vm.network :private_network, ip: "ip.address.for.vm1", :netmask => "255.255.0.0", :mac => "0123456789"
55
+ v.vm.synced_folder './', '/temp', create: true
56
+ v.vm.synced_folder '../', '/tmp', create: true
57
+ v.vm.network :forwarded_port, guest: 80, host: 10080
58
+ v.vm.network :forwarded_port, guest: 443, host: 4443
59
+ v.vm.network :forwarded_port, guest: 8080, host: 8080
60
+ v.vm.provider :virtualbox do |vb|
61
+ vb.customize ['modifyvm', :id, '--memory', '1024', '--cpus', '1']
62
+ end
63
+ end
64
+ c.vm.define 'vm2' do |v|
65
+ v.vm.hostname = 'vm2'
66
+ v.vm.box = 'vm2vm2_of_my_box'
67
+ v.vm.box_url = 'http://address.for.my.box.vm2'
68
+ v.vm.box_check_update = 'true'
69
+ v.vm.network :private_network, ip: "ip.address.for.vm2", :netmask => "255.255.0.0", :mac => "0123456789"
70
+ v.vm.synced_folder './', '/temp', create: true
71
+ v.vm.synced_folder '../', '/tmp', create: true
72
+ v.vm.network :forwarded_port, guest: 80, host: 10080
73
+ v.vm.network :forwarded_port, guest: 443, host: 4443
74
+ v.vm.network :forwarded_port, guest: 8080, host: 8080
75
+ v.vm.provider :virtualbox do |vb|
76
+ vb.customize ['modifyvm', :id, '--memory', '1024', '--cpus', '1']
77
+ end
78
+ end
79
+ c.vm.define 'vm3' do |v|
80
+ v.vm.hostname = 'vm3'
81
+ v.vm.box = 'vm2vm3_of_my_box'
82
+ v.vm.box_url = 'http://address.for.my.box.vm3'
83
+ v.vm.box_check_update = 'true'
84
+ v.vm.network :private_network, ip: "ip.address.for.vm3", :netmask => "255.255.0.0", :mac => "0123456789"
85
+ v.vm.synced_folder './', '/temp', create: true
86
+ v.vm.synced_folder '../', '/tmp', create: true
87
+ v.vm.network :forwarded_port, guest: 80, host: 10080
88
+ v.vm.network :forwarded_port, guest: 443, host: 4443
89
+ v.vm.network :forwarded_port, guest: 8080, host: 8080
90
+ v.vm.provider :virtualbox do |vb|
91
+ vb.customize ['modifyvm', :id, '--memory', '1024', '--cpus', '1']
92
+ end
93
+ end
94
+ end
95
+ EOF
96
+ end
97
+
98
+ it "can make a Vagrantfile with ssh agent forwarding enabled" do
99
+ path = vagrant.instance_variable_get( :@vagrant_path )
100
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
101
+
102
+ hosts = make_hosts({},1)
103
+ vagrant.make_vfile( hosts, options )
104
+
105
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
106
+ expect( vagrantfile ).to match(/(ssh.forward_agent = true)/)
107
+ end
108
+
109
+ it "can make a Vagrantfile with synced_folder disabled" do
110
+ path = vagrant.instance_variable_get( :@vagrant_path )
111
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
112
+
113
+ hosts = make_hosts({:synced_folder => 'disabled'},1)
114
+ vagrant.make_vfile( hosts, options )
115
+
116
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
117
+ expect( vagrantfile ).to match(/v.vm.synced_folder .* disabled: true/)
118
+ end
119
+
120
+ it "can make a Vagrantfile with network mac autogenerated" do
121
+ path = vagrant.instance_variable_get( :@vagrant_path )
122
+
123
+ hosts = make_hosts({},1)
124
+ vagrant.make_vfile( hosts, options )
125
+
126
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
127
+ expect( vagrantfile ).to match(/v.vm.network :private_network, ip: "ip.address.for.vm1", :netmask => "255.255.0.0", :mac => ".+/)
128
+ end
129
+
130
+ it "can make a Vagrantfile with network mac specified" do
131
+ path = vagrant.instance_variable_get( :@vagrant_path )
132
+
133
+ hosts = make_hosts({:network_mac => 'b6:33:ae:19:48:f9'},1)
134
+ vagrant.make_vfile( hosts, options )
135
+
136
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
137
+ expect( vagrantfile ).to match(/v.vm.network :private_network, ip: "ip.address.for.vm1", :netmask => "255.255.0.0", :mac => "b6:33:ae:19:48:f9/)
138
+ end
139
+
140
+ it "can make a Vagrantfile with network mac disabled" do
141
+ path = vagrant.instance_variable_get( :@vagrant_path )
142
+
143
+ hosts = make_hosts({:network_mac => 'false'},1)
144
+ vagrant.make_vfile( hosts, options )
145
+
146
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
147
+ expect( vagrantfile ).to match(/v.vm.network :private_network, ip: "ip.address.for.vm1", :netmask => "255.255.0.0"/)
148
+ end
149
+
150
+ context "when generating a windows config" do
151
+ before do
152
+ path = vagrant.instance_variable_get( :@vagrant_path )
153
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
154
+ @hosts[0][:platform] = 'windows'
155
+
156
+ vagrant.make_vfile( @hosts )
157
+
158
+ @generated_file = File.read( File.expand_path( File.join( path, "Vagrantfile") ) )
159
+ end
160
+
161
+ it 'has the proper port forwarding for RDP' do
162
+ expect( @generated_file ).to match /v.vm.network :forwarded_port, guest: 3389, host: 3389, id: 'rdp', auto_correct: true/
163
+ end
164
+
165
+ it 'has the proper port forwarding for WinRM' do
166
+ expect( @generated_file ).to match /v.vm.network :forwarded_port, guest: 5985, host: 5985, id: 'winrm', auto_correct: true/
167
+ end
168
+
169
+ it 'configures the guest type to windows' do
170
+ expect( @generated_file ).to match /v.vm.guest = :windows/
171
+ end
172
+
173
+ it 'sets a non-default memsize' do
174
+ expect( @generated_file ).to match /'--memory', '2048',/
175
+ end
176
+ end
177
+
178
+ it "uses the memsize defined per vagrant host" do
179
+ path = vagrant.instance_variable_get( :@vagrant_path )
180
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
181
+
182
+ vagrant.make_vfile( @hosts, {'vagrant_memsize' => 'hello!'} )
183
+
184
+ generated_file = File.read( File.expand_path( File.join( path, "Vagrantfile") ) )
185
+
186
+ match = generated_file.match(/vb.customize \['modifyvm', :id, '--memory', 'hello!', '--cpus', '1'\]/)
187
+
188
+ expect( match ).to_not be nil
189
+
190
+ end
191
+
192
+ it "uses the cpus defined per vagrant host" do
193
+ path = vagrant.instance_variable_get( :@vagrant_path )
194
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
195
+
196
+ vagrant.make_vfile( @hosts, {'vagrant_cpus' => 'goodbye!'} )
197
+
198
+ generated_file = File.read( File.expand_path( File.join( path, "Vagrantfile") ) )
199
+
200
+ match = generated_file.match(/vb.customize \['modifyvm', :id, '--memory', '1024', '--cpus', 'goodbye!'\]/)
201
+
202
+ expect( match ).to_not be nil
203
+
204
+ end
205
+
206
+ context "port forwarding rules" do
207
+ it "supports all Vagrant parameters" do
208
+ path = vagrant.instance_variable_get( :@vagrant_path )
209
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
210
+
211
+ hosts = make_hosts(
212
+ {
213
+ :forwarded_ports => {
214
+ :http => {
215
+ :from => 10080,
216
+ :from_ip => '127.0.0.1',
217
+ :to => 80,
218
+ :to_ip => '0.0.0.0',
219
+ :protocol => 'udp'
220
+ }
221
+ }
222
+ },1)
223
+ vagrant.make_vfile( hosts, options )
224
+
225
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
226
+ expect( vagrantfile ).to match(/v.vm.network :forwarded_port, protocol: 'udp', guest_ip: '0.0.0.0', guest: 80, host_ip: '127.0.0.1', host: 10080/)
227
+ end
228
+
229
+ it "supports supports from_ip" do
230
+ path = vagrant.instance_variable_get( :@vagrant_path )
231
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
232
+
233
+ hosts = make_hosts(
234
+ {
235
+ :forwarded_ports => {
236
+ :http => {
237
+ :from => 10080,
238
+ :from_ip => '127.0.0.1',
239
+ :to => 80,
240
+ }
241
+ }
242
+ },1)
243
+ vagrant.make_vfile( hosts, options )
244
+
245
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
246
+ expect( vagrantfile ).to match(/v.vm.network :forwarded_port, guest: 80, host_ip: '127.0.0.1', host: 10080/)
247
+ end
248
+
249
+ it "supports all to_ip" do
250
+ path = vagrant.instance_variable_get( :@vagrant_path )
251
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
252
+
253
+ hosts = make_hosts(
254
+ {
255
+ :forwarded_ports => {
256
+ :http => {
257
+ :from => 10080,
258
+ :to => 80,
259
+ :to_ip => '0.0.0.0',
260
+ }
261
+ }
262
+ },1)
263
+ vagrant.make_vfile( hosts, options )
264
+
265
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
266
+ expect( vagrantfile ).to match(/v.vm.network :forwarded_port, guest_ip: '0.0.0.0', guest: 80, host: 10080/)
267
+ end
268
+
269
+ it "supports all protocol" do
270
+ path = vagrant.instance_variable_get( :@vagrant_path )
271
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
272
+
273
+ hosts = make_hosts(
274
+ {
275
+ :forwarded_ports => {
276
+ :http => {
277
+ :from => 10080,
278
+ :to => 80,
279
+ :protocol => 'udp'
280
+ }
281
+ }
282
+ },1)
283
+ vagrant.make_vfile( hosts, options )
284
+
285
+ vagrantfile = File.read( File.expand_path( File.join( path, "Vagrantfile")))
286
+ expect( vagrantfile ).to match(/v.vm.network :forwarded_port, protocol: 'udp', guest: 80, host: 10080/)
287
+
288
+ end
289
+ end
290
+
291
+ it "can generate a new /etc/hosts file referencing each host" do
292
+
293
+ @hosts.each do |host|
294
+ expect( vagrant ).to receive( :get_domain_name ).with( host ).and_return( 'labs.lan' )
295
+ expect( vagrant ).to receive( :set_etc_hosts ).with( host, "127.0.0.1\tlocalhost localhost.localdomain\nip.address.for.vm1\tvm1.labs.lan vm1\nip.address.for.vm2\tvm2.labs.lan vm2\nip.address.for.vm3\tvm3.labs.lan vm3\n" ).once
296
+ end
297
+
298
+ vagrant.hack_etc_hosts( @hosts, options )
299
+
300
+ end
301
+
302
+ context "can copy vagrant's key to root .ssh on each host" do
303
+
304
+ it "can copy to root on unix" do
305
+ host = @hosts[0]
306
+ host[:platform] = 'unix'
307
+
308
+ expect( Command ).to receive( :new ).with("sudo su -c \"cp -r .ssh /root/.\"").once
309
+ expect( Command ).to receive( :new ).with("sudo fixfiles restore /root").once
310
+ expect( Command ).to receive( :new ).with("sudo selinuxenabled").once
311
+
312
+ vagrant.copy_ssh_to_root( host, options )
313
+
314
+ end
315
+
316
+ it "can copy to Administrator on windows" do
317
+ host = @hosts[0]
318
+ host[:platform] = 'windows'
319
+ expect( host ).to receive( :is_cygwin? ).and_return(true)
320
+
321
+ expect( Command ).to_not receive( :new ).with("sudo fixfiles restore /root")
322
+ expect( Command ).to receive( :new ).with("cp -r .ssh /cygdrive/c/Users/Administrator/.").once
323
+ expect( Command ).to receive( :new ).with("chown -R Administrator /cygdrive/c/Users/Administrator/.ssh").once
324
+
325
+ # This is checked on all platforms since Linux isn't called out specifically in the code
326
+ # If this fails, nothing further is activated
327
+ result = Beaker::Result.new(host, '')
328
+ result.exit_code = 1
329
+ expect( Command ).to receive( :new ).with("sudo selinuxenabled")
330
+ allow( host ).to receive(:exec).and_return(result)
331
+
332
+ vagrant.copy_ssh_to_root( host, options )
333
+
334
+ end
335
+ end
336
+
337
+ it "can generate a ssh-config file" do
338
+ host = @hosts[0]
339
+ name = host.name
340
+ allow( Dir ).to receive( :chdir ).and_yield()
341
+ out = double( 'stdout' )
342
+ allow( out ).to receive( :read ).and_return("Host #{name}
343
+ HostName 127.0.0.1
344
+ User vagrant
345
+ Port 2222
346
+ UserKnownHostsFile /dev/null
347
+ StrictHostKeyChecking no
348
+ PasswordAuthentication no
349
+ IdentityFile /home/root/.vagrant.d/insecure_private_key
350
+ IdentitiesOnly yes")
351
+
352
+ wait_thr = OpenStruct.new
353
+ state = double( 'state' )
354
+ allow( state ).to receive( :success? ).and_return( true )
355
+ wait_thr.value = state
356
+
357
+ allow( Open3 ).to receive( :popen3 ).with( {"RUBYLIB"=>""}, 'vagrant', 'ssh-config', name ).and_return( [ "", out, "", wait_thr ])
358
+
359
+ file = double( 'file' )
360
+ allow( file ).to receive( :path ).and_return( '/path/sshconfig' )
361
+ allow( file ).to receive( :rewind ).and_return( true )
362
+
363
+ expect( Tempfile ).to receive( :new ).with( "#{host.name}").and_return( file )
364
+ expect( file ).to receive( :write ).with("Host ip.address.for.#{name}\n HostName 127.0.0.1\n User root\n Port 2222\n UserKnownHostsFile /dev/null\n StrictHostKeyChecking no\n PasswordAuthentication no\n IdentityFile /home/root/.vagrant.d/insecure_private_key\n IdentitiesOnly yes")
365
+
366
+ vagrant.set_ssh_config( host, 'root' )
367
+ expect( host['ssh'] ).to be === { :config => file.path }
368
+ expect( host['user']).to be === 'root'
369
+
370
+ end
371
+
372
+ describe "get_ip_from_vagrant_file" do
373
+ before :each do
374
+ allow( vagrant ).to receive( :randmac ).and_return( "0123456789" )
375
+ vagrant.make_vfile( @hosts )
376
+ end
377
+
378
+ it "can find the correct ip for the provided hostname" do
379
+ @hosts.each do |host|
380
+ expect( vagrant.get_ip_from_vagrant_file(host.name) ).to be === host[:ip]
381
+ end
382
+
383
+ end
384
+
385
+ it "returns nil if it is unable to find an ip" do
386
+ expect( vagrant.get_ip_from_vagrant_file("unknown") ).to be_nil
387
+ end
388
+
389
+ it "raises an error if no Vagrantfile is present" do
390
+ File.delete( vagrant.instance_variable_get( :@vagrant_file ) )
391
+ @hosts.each do |host|
392
+ expect{ vagrant.get_ip_from_vagrant_file(host.name) }.to raise_error RuntimeError, /No vagrant file found/
393
+ end
394
+ end
395
+ end
396
+
397
+ describe "provisioning and cleanup" do
398
+
399
+ before :each do
400
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "up" ).once
401
+ @hosts.each do |host|
402
+ host_prev_name = host['user']
403
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, 'vagrant' ).once
404
+ expect( vagrant ).to receive( :copy_ssh_to_root ).with( host, options ).once
405
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, host_prev_name ).once
406
+ end
407
+ expect( vagrant ).to receive( :hack_etc_hosts ).with( @hosts, options ).once
408
+ end
409
+
410
+ it "can provision a set of hosts" do
411
+ options = vagrant.instance_variable_get( :@options )
412
+ expect( vagrant ).to receive( :make_vfile ).with( @hosts, options ).once
413
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "destroy --force" ).never
414
+ vagrant.provision
415
+ end
416
+
417
+ it "destroys an existing set of hosts before provisioning" do
418
+ vagrant.make_vfile( @hosts )
419
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "destroy --force" ).once
420
+ vagrant.provision
421
+ end
422
+
423
+ it "notifies user of failed provision" do
424
+ vagrant.provision
425
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "destroy --force" ).and_raise( RuntimeError )
426
+ expect( options['logger'] ).to receive( :debug ).with( /Vagrantfile/ )
427
+ expect{ vagrant.provision }.to raise_error( RuntimeError )
428
+ end
429
+
430
+ it "can cleanup" do
431
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "destroy --force" ).once
432
+ expect( FileUtils ).to receive( :rm_rf ).once
433
+
434
+ vagrant.provision
435
+ vagrant.cleanup
436
+
437
+ end
438
+
439
+ end
440
+
441
+ describe "provisioning and cleanup on windows" do
442
+ before :each do
443
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "up" ).once
444
+ @hosts.each do |host|
445
+ host_prev_name = host['user']
446
+ expect( vagrant ).to receive( :set_ssh_config ).with( host, 'vagrant' ).once
447
+ expect( vagrant ).not_to receive( :copy_ssh_to_root ).with( host, options ).once
448
+ expect( vagrant ).not_to receive( :set_ssh_config ).with( host, host_prev_name ).once
449
+ end
450
+ expect( vagrant ).to receive( :hack_etc_hosts ).with( @hosts, options ).once
451
+ end
452
+
453
+ it "can provision a set of hosts" do
454
+ options = vagrant.instance_variable_get( :@options )
455
+ expect( vagrant ).to receive( :make_vfile ).with( @hosts, options ).once
456
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "destroy --force" ).never
457
+ vagrant.provision
458
+ end
459
+
460
+ it "destroys an existing set of hosts before provisioning" do
461
+ vagrant.make_vfile( @hosts )
462
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "destroy --force" ).once
463
+ vagrant.provision
464
+ end
465
+
466
+ it "can cleanup" do
467
+ expect( vagrant ).to receive( :vagrant_cmd ).with( "destroy --force" ).once
468
+ expect( FileUtils ).to receive( :rm_rf ).once
469
+
470
+ vagrant.provision
471
+ vagrant.cleanup
472
+
473
+ end
474
+
475
+ end
476
+
477
+ end
478
+
479
+ end