# frozen_string_literal: true require 'spec_helper' require 'support/sharedcontext' require 'support/libvirt_context' require 'fog/libvirt/models/compute/volume' require 'vagrant-libvirt/errors' require 'vagrant-libvirt/util/byte_number' require 'vagrant-libvirt/action/create_domain' describe VagrantPlugins::ProviderLibvirt::Action::CreateDomain do subject { described_class.new(app, env) } include_context 'unit' include_context 'libvirt' let(:servers) { double('servers') } let(:volumes) { double('volumes') } let(:domain_volume) { instance_double(::Fog::Libvirt::Compute::Volume) } let(:domain_xml) { File.read(File.join(File.dirname(__FILE__), File.basename(__FILE__, '.rb'), domain_xml_file)) } describe '#call' do before do allow(connection).to receive(:servers).and_return(servers) allow(connection).to receive(:volumes).and_return(volumes) allow(volumes).to receive(:all).and_return([domain_volume]) allow(domain_volume).to receive(:pool_name).and_return('default') allow(domain_volume).to receive(:path).and_return('/var/lib/libvirt/images/vagrant-test_default.img') allow(machine).to receive_message_chain("box.name") { 'vagrant-libvirt/test' } allow(logger).to receive(:info) allow(logger).to receive(:debug) allow(ui).to receive(:info) env[:domain_name] = "vagrant-test_default" env[:domain_volumes] = [] env[:domain_volumes].push({ :device=>'vda', :bus=>'virtio', :cache=>'default', :absolute_path=>'/var/lib/libvirt/images/vagrant-test_default.img', :path=>"/test/box.img", :name=>'test_vagrant_box_image_1.1.1_0.img', :virtual_size=> ByteNumber.new(5), :pool=>'default', }) end context 'connection => qemu:///system' do let(:domain_xml_file) { 'default_domain.xml' } before do allow(machine.provider_config).to receive(:qemu_use_session).and_return(false) end it 'should execute correctly' do expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine) expect(volumes).to_not receive(:create) # additional disks only expect(subject.call(env)).to be_nil end context 'additional disks' do let(:disks) do [ :device => 'vdb', :cache => 'default', :bus => 'virtio', :type => 'qcow2', :absolute_path => '/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2', :virtual_size => ByteNumber.new(20*1024*1024*1024), :pool => 'default', ] end before do env[:disks] = disks end context 'volume create failed' do it 'should raise an exception' do expect(volumes).to receive(:create).and_raise(Libvirt::Error) expect{ subject.call(env) }.to raise_error(VagrantPlugins::ProviderLibvirt::Errors::FogCreateDomainVolumeError) end end context 'volume create succeeded' do let(:domain_xml_file) { 'additional_disks_domain.xml' } it 'should complete' do expect(volumes).to receive(:create).with( hash_including( :path => "/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2", :owner => 0, :group => 0, :pool_name => "default", ) ) expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine) expect(subject.call(env)).to be_nil end end end context 'with custom disk device setting' do let(:domain_xml_file) { 'custom_disk_settings.xml' } before do env[:domain_volumes][0][:device] = 'sda' end it 'should set the domain device' do expect(ui).to receive(:info).with(/ -- Image\(sda\):.*/) expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine) expect(subject.call(env)).to be_nil end end context 'with two domain disks' do let(:domain_xml_file) { 'two_disk_settings.xml' } let(:domain_volume_2) { double('domain_volume 2') } before do expect(volumes).to receive(:all).with(name: 'vagrant-test_default.img').and_return([domain_volume]) expect(volumes).to receive(:all).with(name: 'vagrant-test_default_1.img').and_return([domain_volume_2]) expect(domain_volume_2).to receive(:pool_name).and_return('default') env[:domain_volumes].push({ :device=>'vdb', :bus=>'virtio', :cache=>'default', :absolute_path=>'/var/lib/libvirt/images/vagrant-test_default_1.img', :path=>"/test/box_1.img", :name=>"test_vagrant_box_image_1.1.1_1.img", :virtual_size=> ByteNumber.new(5), :pool=>'default', }) end it 'should list multiple device entries' do expect(ui).to receive(:info).with(/ -- Image\(vda\):.*/) expect(ui).to receive(:info).with(/ -- Image\(vdb\):.*/) expect(servers).to receive(:create).with(xml: domain_xml).and_return(machine) expect(subject.call(env)).to be_nil end end end context 'connection => qemu:///session' do before do allow(machine.provider_config).to receive(:qemu_use_session).and_return(true) end it 'should execute correctly' do expect(servers).to receive(:create).and_return(machine) expect(subject.call(env)).to be_nil end context 'additional disks' do let(:vagrantfile_providerconfig) do <<-EOF libvirt.qemu_use_session = true EOF end let(:disks) do [ :device => 'vdb', :cache => 'default', :bus => 'virtio', :type => 'qcow2', :absolute_path => '/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2', :virtual_size => ByteNumber.new(20*1024*1024*1024), :pool => 'default', ] end before do expect(Process).to receive(:uid).and_return(9999).at_least(:once) expect(Process).to receive(:gid).and_return(9999).at_least(:once) env[:disks] = disks end context 'volume create succeeded' do it 'should complete' do expect(volumes).to receive(:create).with( hash_including( :path => "/var/lib/libvirt/images/vagrant-test_default-vdb.qcow2", :owner => 9999, :group => 9999, :pool_name => "default", ) ) expect(servers).to receive(:create).and_return(machine) expect(subject.call(env)).to be_nil end end end end end end