require 'spec_helper' require 'support/sharedcontext' require 'vagrant-libvirt/config' describe VagrantPlugins::ProviderLibvirt::Config do include_context 'unit' let(:fake_env) { Hash.new } describe '#finalize!' do it 'is valid with defaults' do subject.finalize! end context '@uri' do before(:example) do stub_const("ENV", fake_env) end context 'when LIBVIRT_DEFAULT_URI is defined' do it 'should always use this value' do fake_env['LIBVIRT_DEFAULT_URI'] = "custom:///custom_path" subject.finalize! expect(subject.uri).to eq("custom:///custom_path") expect(subject.qemu_use_session).to eq(false) end context 'when LIBVIRT_DEFAULT_URI contains "qemu"' do [ [ 'set qemu_use_session if "session" present', 'qemu:///session', true, ], [ 'handle different protocol additions', 'qemu+ssh:///session', true, ], [ 'handle options before and after path', 'qemu://remote/session?keyfile=my_id_rsa', true, ], [ 'identify when session not set', 'qemu://remote/system', false, ], [ 'handle session appearing elsewhere', 'qemu://remote/system?keyfile=my_session_id', false, ], ].each do |title, uri, session| it "should #{title}" do fake_env['LIBVIRT_DEFAULT_URI'] = uri subject.finalize! expect(subject.uri).to eq(uri) expect(subject.qemu_use_session).to eq(session) end end end end context 'when @driver is defined' do defaults = {'id_ssh_key_file' => nil} [ [ {'driver' => 'kvm'}, 'qemu:///system?no_verify=1', false, ], [ {'driver' => 'qemu'}, 'qemu:///system?no_verify=1', false, ], [ {'driver' => 'qemu', 'qemu_use_session' => true}, 'qemu:///session?no_verify=1', true, ], [ {'driver' => 'openvz'}, 'openvz:///system?no_verify=1', false, ], [ {'driver' => 'vbox'}, 'vbox:///session?no_verify=1', false, ], ].each do |inputs, output_uri, output_session| it "should detect #{inputs}" do inputs.merge(defaults).each do |k, v| subject.instance_variable_set("@#{k}", v) end subject.finalize! expect(subject.uri).to eq(output_uri) expect(subject.qemu_use_session).to eq(output_session) end end it "should raise exception for unrecognized" do subject.driver = "bad-driver" expect { subject.finalize! }.to raise_error("Require specify driver bad-driver") end end context 'when @connect_via_ssh defined' do defaults = {'driver' => 'qemu', 'id_ssh_key_file' => nil} [ [ {'connect_via_ssh' => true}, 'qemu+ssh://localhost/system?no_verify=1', ], [ {'connect_via_ssh' => true, 'username' => 'my_user'}, 'qemu+ssh://my_user@localhost/system?no_verify=1', ], [ {'connect_via_ssh' => true, 'host' => 'remote_server'}, 'qemu+ssh://remote_server/system?no_verify=1', ], ].each do |inputs, output_uri| it "should detect #{inputs}" do inputs.merge(defaults).each do |k, v| subject.instance_variable_set("@#{k}", v) end subject.finalize! expect(subject.uri).to eq(output_uri) end end end context 'when @id_ssh_key_file defined' do defaults = {'driver' => 'qemu'} [ [ {}, 'qemu:///system?no_verify=1&keyfile=/home/user/.ssh/id_rsa', ], [ {'id_ssh_key_file' => '/path/to/keyfile'}, 'qemu:///system?no_verify=1&keyfile=/path/to/keyfile', ], ].each do |inputs, output_uri| it "should detect #{inputs}" do inputs.merge(defaults).each do |k, v| subject.instance_variable_set("@#{k}", v) end fake_env['HOME'] = '/home/user' subject.finalize! expect(subject.uri).to eq(output_uri) end end end context 'when @socket defined' do it "should detect @socket set" do subject.socket = '/var/run/libvirt/libvirt-sock' subject.id_ssh_key_file = false subject.finalize! expect(subject.uri).to eq('qemu:///system?no_verify=1&socket=/var/run/libvirt/libvirt-sock') end end end end def assert_invalid subject.finalize! errors = subject.validate(machine) raise "No errors: #{errors.inspect}" if errors.values.all?(&:empty?) end def assert_valid subject.finalize! errors = subject.validate(machine) raise "Errors: #{errors.inspect}" unless errors.values.all?(&:empty?) end describe '#validate' do it 'is valid with defaults' do assert_valid end context 'with disks defined' do before { expect(machine).to receive(:provider_config).and_return(subject).at_least(:once) } it 'is valid if relative path used for disk' do subject.storage :file, path: '../path/to/file.qcow2' assert_valid end it 'should be invalid if absolute path used for disk' do subject.storage :file, path: '/absolute/path/to/file.qcow2' assert_invalid end end context 'with mac defined' do let (:vm) { double('vm') } before { expect(machine.config).to receive(:vm).and_return(vm) } it 'is valid with valid mac' do expect(vm).to receive(:networks).and_return([[:public, { mac: 'aa:bb:cc:dd:ee:ff' }]]) assert_valid end it 'is valid with MAC containing no delimiters' do network = [:public, { mac: 'aabbccddeeff' }] expect(vm).to receive(:networks).and_return([network]) assert_valid expect(network[1][:mac]).to eql('aa:bb:cc:dd:ee:ff') end it 'should be invalid if MAC not formatted correctly' do expect(vm).to receive(:networks).and_return([[:public, { mac: 'aa/bb/cc/dd/ee/ff' }]]) assert_invalid end end end describe '#merge' do let(:one) { described_class.new } let(:two) { described_class.new } subject { one.merge(two) } context 'storage' do context 'with disks' do context 'assigned specific devices' do it 'should merge disks with specific devices' do one.storage(:file, device: 'vdb') two.storage(:file, device: 'vdc') subject.finalize! expect(subject.disks).to include(include(device: 'vdb'), include(device: 'vdc')) end end context 'without devices given' do it 'should merge disks with different devices assigned automatically' do one.storage(:file) two.storage(:file) subject.finalize! expect(subject.disks).to include(include(device: 'vdb'), include(device: 'vdc')) end end end context 'with cdroms only' do context 'assigned specific devs' do it 'should merge disks with specific devices' do one.storage(:file, device: :cdrom, dev: 'hda') two.storage(:file, device: :cdrom, dev: 'hdb') subject.finalize! expect(subject.cdroms).to include(include(dev: 'hda'), include(dev: 'hdb')) end end context 'without devs given' do it 'should merge cdroms with different devs assigned automatically' do one.storage(:file, device: :cdrom) two.storage(:file, device: :cdrom) subject.finalize! expect(subject.cdroms).to include(include(dev: 'hda'), include(dev: 'hdb')) end end end end end end