# frozen_string_literal: true require 'beaker/hypervisor/gke' describe Beaker::Gke do let(:hosts) { make_hosts } let(:options) { { logger: logger } } let(:logger) do logger = instance_double('logger') allow(logger).to receive(:debug) allow(logger).to receive(:info) allow(logger).to receive(:warn) allow(logger).to receive(:error) allow(logger).to receive(:notify) logger end let(:config) { instance_double('config') } let(:context) do instance_double('context', api_endpoint: 'v1', ssl_options: { verify_ssl: 1, cert_store: true }, auth_options: { bearer_token: 'TOKEN_STRING' }) end let(:gke) { ::Beaker::Gke.new(hosts, options) } def pass_through_initialization allow(ENV).to receive(:fetch).with('KUBECONFIG').and_return('default_value') allow(ENV).to receive(:fetch).with('GOOGLE_APPLICATION_CREDENTIALS').and_return('default_value') allow(config).to receive(:context).and_return(context) allow(Kubeclient::Config).to receive(:read).with(ENV['KUBECONFIG']).and_return(config) end before do FakeFS.deactivate! end describe ' #initialize' do let(:env_error_message) { 'OS environment variable KUBECONFIG and GOOGLE_APPLICATION_CREDENTIALS must be set' } it 'raises error when KUBECONFIG and GOOGLE_APPLICATION_CREDENTIALS ENV variables are not set' do expect { gke }.to raise_error(ArgumentError, env_error_message) end it 'raises error when only GOOGLE_APPLICATION_CREDENTIALS ENV variable is set' do with_modified_env GOOGLE_APPLICATION_CREDENTIALS: 'default_value' do expect { gke }.to raise_error(ArgumentError, env_error_message) end end it 'raises error when only KUBECONFIG ENV variable is set' do with_modified_env KUBECONFIG: 'default_value' do expect { gke }.to raise_error(ArgumentError, env_error_message) end end context 'when both KUBECONFIG and GOOGLE_APPLICATION_CREDENTIALS ENV are set' do before do pass_through_initialization end it 'sets the hosts data member accordingly' do expect(gke.instance_variable_get(:@hosts)).to equal(hosts) end it 'sets the options data member accordingly' do expect(gke.instance_variable_get(:@options)).to equal(options) end it 'sets the logger data member accordingly' do expect(gke.instance_variable_get(:@logger)).to equal(logger) end it 'succeeds and does not raise any errors' do expect { gke }.not_to raise_error end end end describe ' #provision' do let(:pod) { instance_double('pod') } let(:status) { instance_double('status', podIP: '10.236.246.250') } let(:empty_ip_status) { instance_double('status', podIP: nil) } def pass_through_pod_and_service_creation allow(gke).to receive(:create_pod).and_return(nil) allow(gke).to receive(:read_file).with('pod.yaml').and_return('pod.yaml content') allow(gke).to receive(:create_srv).and_return(nil) allow(gke).to receive(:read_file).with('service.yaml').and_return('service.yaml content') end before do pass_through_initialization pass_through_pod_and_service_creation allow(gke).to receive(:sleep).and_return(true) end context 'when no hosts given' do let(:no_hosts_gke) { ::Beaker::Gke.new([], options) } it 'returns nil' do expect(no_hosts_gke.provision).to eq(nil) end it 'logs no info' do no_hosts_gke.provision expect(logger).not_to have_received(:info) end it 'does not raise any error' do expect { no_hosts_gke.provision }.not_to raise_error end end it 'raises StandardError and logs podIP retrieval attempts' do # rubocop:disable RSpec/MultipleExpectations allow(gke).to receive(:get_pod).and_return(pod) allow(pod).to receive(:status).and_return(empty_ip_status) expect { gke.provision }.to raise_error(StandardError) expect(logger).to have_received(:info).with(/Retrying, could not get podIP for/).at_least(:once) end it 'succeeds' do allow(gke).to receive(:get_pod).and_return(pod) allow(pod).to receive(:status).and_return(status) expect(gke.provision).to eq(nil) end end describe ' #cleanup' do before do pass_through_initialization end context 'when no hosts given' do let(:no_hosts_gke) { ::Beaker::Gke.new([], options) } it 'does not raise any error' do expect { no_hosts_gke.cleanup }.not_to raise_error end it 'logs no info' do no_hosts_gke.cleanup expect(logger).not_to have_received(:info) end end context 'when succeeds' do before do allow(gke).to receive(:delete_pod).and_return(nil) allow(gke).to receive(:delete_service).and_return(nil) end it 'does not raise any error' do expect { gke.cleanup }.not_to raise_error end it 'logs deleted pods' do gke.cleanup expect(logger).to have_received(:info).with(/Deleting POD with ID:/).exactly(hosts.size).times end end end end