require 'spec_helper' module Beaker describe Vmpooler do before :each do vms = make_hosts() MockVsphereHelper.set_config( fog_file_contents ) MockVsphereHelper.set_vms( vms ) stub_const( "VsphereHelper", MockVsphereHelper ) stub_const( "Net", MockNet ) allow( JSON ).to receive( :parse ) do |arg| arg end allow( Socket ).to receive( :getaddrinfo ).and_return( true ) allow_any_instance_of( Beaker::Vmpooler ).to \ receive(:load_credentials).and_return(fog_file_contents) end describe '#get_template_url' do it 'works returns the valid url when passed valid pooling_api and template name' do vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) uri = vmpooler.get_template_url("http://pooling.com", "template") expect( uri ).to be === "http://pooling.com/vm/template" end it 'adds a missing scheme to a given URL' do vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) uri = vmpooler.get_template_url("pooling.com", "template") expect( URI.parse(uri).scheme ).to_not be === nil end it 'raises an error on an invalid pooling api url' do vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) expect{ vmpooler.get_template_url("pooling### ", "template")}.to raise_error ArgumentError end it 'raises an error on an invalide template name' do vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) expect{ vmpooler.get_template_url("pooling.com", "t!e&m*p(l\\a/t e")}.to raise_error ArgumentError end end describe '#add_tags' do let(:vmpooler) { Beaker::Vmpooler.new(make_hosts({:host_tags => {'test_tag' => 'test_value'}}), make_opts) } it 'merges tags correctly' do vmpooler.instance_eval { @options = @options.merge({:project => 'vmpooler-spec'}) } host = vmpooler.instance_variable_get(:@hosts)[0] merged_tags = vmpooler.add_tags(host) expected_hash = { test_tag: 'test_value', beaker_version: Beaker::Version::STRING, project: 'vmpooler-spec' } expect(merged_tags).to include(expected_hash) end end describe "#provision" do it 'provisions hosts from the pool' do vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) allow( vmpooler ).to receive( :require ).and_return( true ) allow( vmpooler ).to receive( :sleep ).and_return( true ) vmpooler.provision hosts = vmpooler.instance_variable_get( :@hosts ) hosts.each do | host | expect( host['vmhostname'] ).to be === 'pool' end end it 'raises an error when a host template is not found in returned json' do vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) allow( vmpooler ).to receive( :require ).and_return( true ) allow( vmpooler ).to receive( :sleep ).and_return( true ) allow( vmpooler ).to receive( :get_host_info ).and_return( nil ) expect { vmpooler.provision }.to raise_error( RuntimeError, /Vmpooler\.provision - requested VM templates \[.*\,.*\,.*\] not available/ ) end it 'repeats asking only for failed hosts' do vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) allow( vmpooler ).to receive( :require ).and_return( true ) allow( vmpooler ).to receive( :sleep ).and_return( true ) allow( vmpooler ).to receive( :get_host_info ).with( anything, "vm1_has_a_template" ).and_return( nil ) allow( vmpooler ).to receive( :get_host_info ).with( anything, "vm2_has_a_template" ).and_return( 'y' ) allow( vmpooler ).to receive( :get_host_info ).with( anything, "vm3_has_a_template" ).and_return( 'y' ) expect { vmpooler.provision }.to raise_error( RuntimeError, /Vmpooler\.provision - requested VM templates \[[^\,]*\] not available/ ) # should be only one item in the list, no commas end end describe "#cleanup" do it "cleans up hosts in the pool" do MockVsphereHelper.powerOn vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) allow( vmpooler ).to receive( :require ).and_return( true ) allow( vmpooler ).to receive( :sleep ).and_return( true ) vmpooler.provision vmpooler.cleanup hosts = vmpooler.instance_variable_get( :@hosts ) hosts.each do | host | name = host.name vm = MockVsphereHelper.find_vm( name ) expect( vm.runtime.powerState ).to be === "poweredOn" #handed back to the pool, stays on end end end end describe Vmpooler do before :each do vms = make_hosts() MockVsphereHelper.set_config( fog_file_contents ) MockVsphereHelper.set_vms( vms ) stub_const( "VsphereHelper", MockVsphereHelper ) stub_const( "Net", MockNet ) allow( JSON ).to receive( :parse ) do |arg| arg end allow( Socket ).to receive( :getaddrinfo ).and_return( true ) end describe "#load_credentials" do it 'continues without credentials when fog file is missing' do allow_any_instance_of( Beaker::Vmpooler ).to \ receive(:read_fog_file).and_raise(Errno::ENOENT.new) vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) expect( vmpooler.credentials ).to be == {} end it 'continues without credentials when fog file is empty' do allow_any_instance_of( Beaker::Vmpooler ).to \ receive(:read_fog_file).and_return(false) vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) expect( vmpooler.credentials ).to be == {} end it 'continues without credentials when fog file contains no :default section' do data = { :some => { :other => :data } } allow_any_instance_of( Beaker::Vmpooler ).to \ receive(:read_fog_file).and_return(data) vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) expect( vmpooler.credentials ).to be == { } end it 'continues without credentials when fog file :default section has no :vmpooler_token' do data = { :default => { :something_else => "TOKEN" } } allow_any_instance_of( Beaker::Vmpooler ).to \ receive(:read_fog_file).and_return(data) vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) expect( vmpooler.credentials ).to be == { } end it 'stores vmpooler token when found in fog file' do data = { :default => { :vmpooler_token => "TOKEN" } } allow_any_instance_of( Beaker::Vmpooler ).to \ receive(:read_fog_file).and_return(data) vmpooler = Beaker::Vmpooler.new( make_hosts, make_opts ) expect( vmpooler.credentials ).to be == { :vmpooler_token => "TOKEN" } end end end end