From 2b96d7e476d7a4e5ad10e5d400b4a2410c1ba30c Mon Sep 17 00:00:00 2001 From: "kirby@puppetlabs.com" Date: Thu, 30 Apr 2020 12:22:31 -0700 Subject: [PATCH] Fix tests for changes --- lib/vmpooler/api/v1.rb | 21 +++- lib/vmpooler/pool_manager.rb | 9 +- spec/helpers.rb | 23 ++-- spec/integration/api/v1/status_spec.rb | 14 +-- spec/integration/api/v1/vm_hostname_spec.rb | 80 ++++++------ spec/integration/api/v1/vm_spec.rb | 76 ++++++------ spec/integration/api/v1/vm_template_spec.rb | 62 +++++----- spec/integration/dashboard_spec.rb | 40 +++--- spec/unit/pool_manager_spec.rb | 129 +++++++++++++------- spec/unit/providers/vsphere_spec.rb | 3 + 10 files changed, 268 insertions(+), 189 deletions(-) diff --git a/lib/vmpooler/api/v1.rb b/lib/vmpooler/api/v1.rb index 5a21ee2..c8654a1 100644 --- a/lib/vmpooler/api/v1.rb +++ b/lib/vmpooler/api/v1.rb @@ -103,13 +103,26 @@ module Vmpooler count_selection(selection) end - def fetch_single_vm(template) template_backends = [template] - aliases = get_template_aliases(template) + aliases = Vmpooler::API.settings.config[:alias] if aliases - template_backends += aliases - weighted_pools = get_pool_weights(template_backends) + template_backends += aliases[template] if aliases[template].is_a?(Array) + template_backends << aliases[template] if aliases[template].is_a?(String) + pool_index = pool_index(pools) + weighted_pools = {} + template_backends.each do |t| + next unless pool_index.key? t + + index = pool_index[t] + clone_target = pools[index]['clone_target'] || config['clone_target'] + next unless config.key?('backend_weight') + + weight = config['backend_weight'][clone_target] + if weight + weighted_pools[t] = weight + end + end if weighted_pools.count == template_backends.count pickup = Pickup.new(weighted_pools) diff --git a/lib/vmpooler/pool_manager.rb b/lib/vmpooler/pool_manager.rb index 7ea69c8..a3a7b7b 100644 --- a/lib/vmpooler/pool_manager.rb +++ b/lib/vmpooler/pool_manager.rb @@ -2,7 +2,6 @@ require 'vmpooler/providers' require 'spicy-proton' -require 'redis' module Vmpooler class PoolManager @@ -453,10 +452,11 @@ module Vmpooler redis.multi redis.hget("vmpooler__vm__#{vm}", 'checkout') redis.hget("vmpooler__vm__#{vm}", 'tag:jenkins_build_url') - redis.hget("vmpooler__vm__#{vm}", 'token:user') || 'unauthenticated' + redis.hget("vmpooler__vm__#{vm}", 'token:user') redis.hget("vmpooler__vm__#{vm}", 'template') checkout, jenkins_build_url, user, poolname = redis.exec return if checkout.nil? + user ||= 'unauthenticated' unless jenkins_build_url user = user.gsub('.', '_') @@ -491,7 +491,8 @@ module Vmpooler $metrics.increment(metric_parts.join('.')) rescue StandardError => e - logger.log('d', "[!] [#{poolname}] failed while evaluating usage labels on '#{vm}' with an error: #{e}") + $logger.log('d', "[!] [#{poolname}] failed while evaluating usage labels on '#{vm}' with an error: #{e}") + raise end def component_to_test(match, labels_string) @@ -1040,7 +1041,7 @@ module Vmpooler redis.scard("vmpooler__ready__#{pool['name']}") redis.scard("vmpooler__pending__#{pool['name']}") ready, pending = redis.exec - total = pending.to_i + total.to_i + total = pending.to_i + ready.to_i return if total.nil? return if total == 0 diff --git a/spec/helpers.rb b/spec/helpers.rb index 19bec9e..917ccc0 100644 --- a/spec/helpers.rb +++ b/spec/helpers.rb @@ -1,5 +1,12 @@ require 'mock_redis' +def redis + unless @redis + @redis = MockRedis.new + end + @redis +end + # Mock an object which represents a Logger. This stops the proliferation # of allow(logger).to .... expectations in tests. class MockLogger @@ -87,38 +94,38 @@ def fetch_vm(vm) redis.hgetall("vmpooler__vm__#{vm}") end -def set_vm_data(vm, key, value) +def set_vm_data(vm, key, value, redis) redis.hset("vmpooler__vm__#{vm}", key, value) end -def snapshot_revert_vm(vm, snapshot = '12345678901234567890123456789012') +def snapshot_revert_vm(vm, snapshot = '12345678901234567890123456789012', redis) redis.sadd('vmpooler__tasks__snapshot-revert', "#{vm}:#{snapshot}") redis.hset("vmpooler__vm__#{vm}", "snapshot:#{snapshot}", "1") end -def snapshot_vm(vm, snapshot = '12345678901234567890123456789012') +def snapshot_vm(vm, snapshot = '12345678901234567890123456789012', redis) redis.sadd('vmpooler__tasks__snapshot', "#{vm}:#{snapshot}") redis.hset("vmpooler__vm__#{vm}", "snapshot:#{snapshot}", "1") end -def disk_task_vm(vm, disk_size = '10') +def disk_task_vm(vm, disk_size = '10', redis) redis.sadd('vmpooler__tasks__disk', "#{vm}:#{disk_size}") end -def has_vm_snapshot?(vm) +def has_vm_snapshot?(vm, redis) redis.smembers('vmpooler__tasks__snapshot').any? do |snapshot| - instance, sha = snapshot.split(':') + instance, _sha = snapshot.split(':') vm == instance end end -def vm_reverted_to_snapshot?(vm, snapshot = nil) +def vm_reverted_to_snapshot?(vm, redis, snapshot = nil) redis.smembers('vmpooler__tasks__snapshot-revert').any? do |action| instance, sha = action.split(':') instance == vm and (snapshot ? (sha == snapshot) : true) end end -def pool_has_ready_vm?(pool, vm) +def pool_has_ready_vm?(pool, vm, redis) !!redis.sismember('vmpooler__ready__' + pool, vm) end diff --git a/spec/integration/api/v1/status_spec.rb b/spec/integration/api/v1/status_spec.rb index ffd69aa..10f127f 100644 --- a/spec/integration/api/v1/status_spec.rb +++ b/spec/integration/api/v1/status_spec.rb @@ -50,7 +50,7 @@ describe Vmpooler::API::V1 do end it 'returns the number of ready vms for each pool' do - 3.times {|i| create_ready_vm("pool1", "vm-#{i}") } + 3.times {|i| create_ready_vm("pool1", "vm-#{i}", redis) } get "#{prefix}/status/" # of course /status doesn't conform to the weird standard everything else uses... @@ -61,8 +61,8 @@ describe Vmpooler::API::V1 do end it 'returns the number of running vms for each pool' do - 3.times {|i| create_running_vm("pool1", "vm-#{i}") } - 4.times {|i| create_running_vm("pool2", "vm-#{i}") } + 3.times {|i| create_running_vm("pool1", "vm-#{i}", redis) } + 4.times {|i| create_running_vm("pool2", "vm-#{i}", redis) } get "#{prefix}/status/" @@ -74,8 +74,8 @@ describe Vmpooler::API::V1 do end it 'returns the number of pending vms for each pool' do - 3.times {|i| create_pending_vm("pool1", "vm-#{i}") } - 4.times {|i| create_pending_vm("pool2", "vm-#{i}") } + 3.times {|i| create_pending_vm("pool1", "vm-#{i}", redis) } + 4.times {|i| create_pending_vm("pool2", "vm-#{i}", redis) } get "#{prefix}/status/" @@ -230,8 +230,8 @@ describe Vmpooler::API::V1 do it 'returns the number of running VMs' do get "#{prefix}/totalrunning" expect(last_response.header['Content-Type']).to eq('application/json') - 5.times {|i| create_running_vm("pool1", "vm-#{i}") } - 5.times {|i| create_running_vm("pool3", "vm-#{i}") } + 5.times {|i| create_running_vm("pool1", "vm-#{i}", redis, redis) } + 5.times {|i| create_running_vm("pool3", "vm-#{i}", redis, redis) } result = JSON.parse(last_response.body) expect(result["running"] == 10) end diff --git a/spec/integration/api/v1/vm_hostname_spec.rb b/spec/integration/api/v1/vm_hostname_spec.rb index 973163e..20546d6 100644 --- a/spec/integration/api/v1/vm_hostname_spec.rb +++ b/spec/integration/api/v1/vm_hostname_spec.rb @@ -41,7 +41,7 @@ describe Vmpooler::API::V1 do describe 'PUT /vm/:hostname' do it 'allows tags to be set' do - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"tags":{"tested_by":"rspec"}}' expect_json(ok = true, http = 200) @@ -49,7 +49,7 @@ describe Vmpooler::API::V1 do end it 'skips empty tags' do - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"tags":{"tested_by":""}}' expect_json(ok = true, http = 200) @@ -57,7 +57,7 @@ describe Vmpooler::API::V1 do end it 'does not set tags if request body format is invalid' do - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"tags":{"tested"}}' expect_json(ok = false, http = 400) @@ -69,7 +69,7 @@ describe Vmpooler::API::V1 do app.settings.set :config, { :config => { 'allowed_tags' => ['created_by', 'project', 'url'] } } - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"tags":{"created_by":"rspec","tested_by":"rspec"}}' expect_json(ok = false, http = 400) @@ -84,7 +84,7 @@ describe Vmpooler::API::V1 do } } it 'correctly filters tags' do - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"tags":{"url":"foo.com/something.html"}}' expect_json(ok = true, http = 200) @@ -93,7 +93,7 @@ describe Vmpooler::API::V1 do end it "doesn't eat tags not matching filter" do - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"tags":{"url":"foo.com"}}' expect_json(ok = true, http = 200) @@ -105,7 +105,7 @@ describe Vmpooler::API::V1 do let(:config) { { auth: false } } it 'allows VM lifetime to be modified without a token' do - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"lifetime":"1"}' expect_json(ok = true, http = 200) @@ -115,7 +115,7 @@ describe Vmpooler::API::V1 do end it 'does not allow a lifetime to be 0' do - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"lifetime":"0"}' expect_json(ok = false, http = 400) @@ -125,7 +125,7 @@ describe Vmpooler::API::V1 do end it 'does not enforce a lifetime' do - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"lifetime":"20000"}' expect_json(ok = true, http = 200) @@ -137,7 +137,7 @@ describe Vmpooler::API::V1 do it 'does not allow a lifetime to be initially past config max_lifetime_upper_limit' do app.settings.set :config, { :config => { 'max_lifetime_upper_limit' => 168 } } - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"lifetime":"200"}' expect_json(ok = false, http = 400) @@ -146,6 +146,18 @@ describe Vmpooler::API::V1 do expect(vm['lifetime']).to be_nil end + it 'does not allow a lifetime to be extended past config 168' do + app.settings.set :config, + { :config => { 'max_lifetime_upper_limit' => 168 } } + create_vm('testhost', redis) + + set_vm_data('testhost', "checkout", (Time.now - (69*60*60)), redis) + put "#{prefix}/vm/testhost", '{"lifetime":"100"}' + expect_json(ok = false, http = 400) + + vm = fetch_vm('testhost') + expect(vm['lifetime']).to be_nil + end end context '(auth configured)' do @@ -154,7 +166,7 @@ describe Vmpooler::API::V1 do end it 'allows VM lifetime to be modified with a token' do - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"lifetime":"1"}', { 'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345' @@ -166,7 +178,7 @@ describe Vmpooler::API::V1 do end it 'does not allows VM lifetime to be modified without a token' do - create_vm('testhost') + create_vm('testhost', redis) put "#{prefix}/vm/testhost", '{"lifetime":"1"}' expect_json(ok = false, http = 401) @@ -182,7 +194,7 @@ describe Vmpooler::API::V1 do end it 'deletes an existing VM' do - create_running_vm('pool1', 'testhost') + create_running_vm('pool1', 'testhost', redis) expect fetch_vm('testhost') delete "#{prefix}/vm/testhost" @@ -198,7 +210,7 @@ describe Vmpooler::API::V1 do context '(checked-out without token)' do it 'deletes a VM without supplying a token' do - create_running_vm('pool1', 'testhost') + create_running_vm('pool1', 'testhost', redis) expect fetch_vm('testhost') delete "#{prefix}/vm/testhost" @@ -209,7 +221,7 @@ describe Vmpooler::API::V1 do context '(checked-out with token)' do it 'fails to delete a VM without supplying a token' do - create_running_vm('pool1', 'testhost', 'abcdefghijklmnopqrstuvwxyz012345') + create_running_vm('pool1', 'testhost', redis, 'abcdefghijklmnopqrstuvwxyz012345') expect fetch_vm('testhost') delete "#{prefix}/vm/testhost" @@ -218,7 +230,7 @@ describe Vmpooler::API::V1 do end it 'deletes a VM when token is supplied' do - create_running_vm('pool1', 'testhost', 'abcdefghijklmnopqrstuvwxyz012345') + create_running_vm('pool1', 'testhost', redis, 'abcdefghijklmnopqrstuvwxyz012345') expect fetch_vm('testhost') delete "#{prefix}/vm/testhost", "", { @@ -235,7 +247,7 @@ describe Vmpooler::API::V1 do describe 'POST /vm/:hostname/snapshot' do context '(auth not configured)' do it 'creates a snapshot' do - create_vm('testhost') + create_vm('testhost', redis) post "#{prefix}/vm/testhost/snapshot" expect_json(ok = true, http = 202) expect(JSON.parse(last_response.body)['testhost']['snapshot'].length).to be(32) @@ -250,19 +262,19 @@ describe Vmpooler::API::V1 do it 'returns a 401 if not authed' do post "#{prefix}/vm/testhost/snapshot" expect_json(ok = false, http = 401) - expect !has_vm_snapshot?('testhost') + expect !has_vm_snapshot?('testhost', redis) end it 'creates a snapshot if authed' do - create_vm('testhost') - snapshot_vm('testhost', 'testsnapshot') + create_vm('testhost', redis) + snapshot_vm('testhost', 'testsnapshot', redis) post "#{prefix}/vm/testhost/snapshot", "", { 'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345' } expect_json(ok = true, http = 202) expect(JSON.parse(last_response.body)['testhost']['snapshot'].length).to be(32) - expect has_vm_snapshot?('testhost') + expect has_vm_snapshot?('testhost', redis) end end end @@ -270,22 +282,22 @@ describe Vmpooler::API::V1 do describe 'POST /vm/:hostname/snapshot/:snapshot' do context '(auth not configured)' do it 'reverts to a snapshot' do - create_vm('testhost') - snapshot_vm('testhost', 'testsnapshot') + create_vm('testhost', redis) + snapshot_vm('testhost', 'testsnapshot', redis) post "#{prefix}/vm/testhost/snapshot/testsnapshot" expect_json(ok = true, http = 202) - expect vm_reverted_to_snapshot?('testhost', 'testsnapshot') + expect vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot') end it 'fails if the specified snapshot does not exist' do - create_vm('testhost') + create_vm('testhost', redis) post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", { 'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345' } expect_json(ok = false, http = 404) - expect !vm_reverted_to_snapshot?('testhost', 'testsnapshot') + expect !vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot') end end @@ -295,33 +307,33 @@ describe Vmpooler::API::V1 do end it 'returns a 401 if not authed' do - create_vm('testhost') - snapshot_vm('testhost', 'testsnapshot') + create_vm('testhost', redis) + snapshot_vm('testhost', 'testsnapshot', redis) post "#{prefix}/vm/testhost/snapshot/testsnapshot" expect_json(ok = false, http = 401) - expect !vm_reverted_to_snapshot?('testhost', 'testsnapshot') + expect !vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot') end it 'fails if authed and the specified snapshot does not exist' do - create_vm('testhost') + create_vm('testhost', redis) post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", { 'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345' } expect_json(ok = false, http = 404) - expect !vm_reverted_to_snapshot?('testhost', 'testsnapshot') + expect !vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot') end it 'reverts to a snapshot if authed' do - create_vm('testhost') - snapshot_vm('testhost', 'testsnapshot') + create_vm('testhost', redis) + snapshot_vm('testhost', 'testsnapshot', redis) post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", { 'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345' } expect_json(ok = true, http = 202) - expect vm_reverted_to_snapshot?('testhost', 'testsnapshot') + expect vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot') end end end diff --git a/spec/integration/api/v1/vm_spec.rb b/spec/integration/api/v1/vm_spec.rb index 78be432..54af246 100644 --- a/spec/integration/api/v1/vm_spec.rb +++ b/spec/integration/api/v1/vm_spec.rb @@ -42,7 +42,7 @@ describe Vmpooler::API::V1 do describe 'GET /vm/:hostname' do it 'returns correct information on a running vm' do - create_running_vm 'pool1', vmname + create_running_vm 'pool1', vmname, redis get "#{prefix}/vm/#{vmname}" expect_json(ok = true, http = 200) response_body = (JSON.parse(last_response.body)[vmname]) @@ -63,7 +63,7 @@ describe Vmpooler::API::V1 do let(:socket) { double('socket') } it 'returns a single VM' do - create_ready_vm 'pool1', vmname + create_ready_vm 'pool1', vmname, redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) post "#{prefix}/vm", '{"pool1":"1"}' @@ -80,7 +80,7 @@ describe Vmpooler::API::V1 do end it 'returns a single VM for an alias' do - create_ready_vm 'pool1', vmname + create_ready_vm 'pool1', vmname, redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -106,7 +106,7 @@ describe Vmpooler::API::V1 do Vmpooler::API.settings.config.delete(:alias) Vmpooler::API.settings.config[:pool_names] = ['pool1', 'pool2'] - create_ready_vm 'pool1', vmname + create_ready_vm 'pool1', vmname, redis post "#{prefix}/vm/pool1" post "#{prefix}/vm/pool1" @@ -117,7 +117,7 @@ describe Vmpooler::API::V1 do end it 'returns 503 for empty pool referenced by alias' do - create_ready_vm 'pool1', vmname + create_ready_vm 'pool1', vmname, redis post "#{prefix}/vm/poolone" post "#{prefix}/vm/poolone" @@ -128,8 +128,8 @@ describe Vmpooler::API::V1 do end it 'returns multiple VMs' do - create_ready_vm 'pool1', vmname - create_ready_vm 'pool2', 'qrstuvwxyz012345' + create_ready_vm 'pool1', vmname, redis + create_ready_vm 'pool2', 'qrstuvwxyz012345', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -150,9 +150,9 @@ describe Vmpooler::API::V1 do end it 'returns multiple VMs even when multiple instances from the same pool are requested' do - create_ready_vm 'pool1', '1abcdefghijklmnop' - create_ready_vm 'pool1', '2abcdefghijklmnop' - create_ready_vm 'pool2', 'qrstuvwxyz012345' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis + create_ready_vm 'pool1', '2abcdefghijklmnop', redis + create_ready_vm 'pool2', 'qrstuvwxyz012345', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -177,11 +177,11 @@ describe Vmpooler::API::V1 do end it 'returns multiple VMs even when multiple instances from multiple pools are requested' do - create_ready_vm 'pool1', '1abcdefghijklmnop' - create_ready_vm 'pool1', '2abcdefghijklmnop' - create_ready_vm 'pool2', '1qrstuvwxyz012345' - create_ready_vm 'pool2', '2qrstuvwxyz012345' - create_ready_vm 'pool2', '3qrstuvwxyz012345' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis + create_ready_vm 'pool1', '2abcdefghijklmnop', redis + create_ready_vm 'pool2', '1qrstuvwxyz012345', redis + create_ready_vm 'pool2', '2qrstuvwxyz012345', redis + create_ready_vm 'pool2', '3qrstuvwxyz012345', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -208,9 +208,9 @@ describe Vmpooler::API::V1 do it 'returns VMs from multiple backend pools requested by an alias' do Vmpooler::API.settings.config[:alias]['genericpool'] = ['pool1', 'pool2', 'pool3'] - create_ready_vm 'pool1', '1abcdefghijklmnop' - create_ready_vm 'pool2', '2abcdefghijklmnop' - create_ready_vm 'pool3', '1qrstuvwxyz012345' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis + create_ready_vm 'pool2', '2abcdefghijklmnop', redis + create_ready_vm 'pool3', '1qrstuvwxyz012345', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -231,9 +231,9 @@ describe Vmpooler::API::V1 do end it 'returns the first VM that was moved to the ready state when checking out a VM' do - create_ready_vm 'pool1', '1abcdefghijklmnop' - create_ready_vm 'pool1', '2abcdefghijklmnop' - create_ready_vm 'pool1', '3abcdefghijklmnop' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis + create_ready_vm 'pool1', '2abcdefghijklmnop', redis + create_ready_vm 'pool1', '3abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -251,7 +251,7 @@ describe Vmpooler::API::V1 do end it 'fails when not all requested vms can be allocated' do - create_ready_vm 'pool1', '1abcdefghijklmnop' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis post "#{prefix}/vm", '{"pool1":"1","pool2":"1"}' @@ -262,7 +262,7 @@ describe Vmpooler::API::V1 do end it 'returns any checked out vms to their pools when not all requested vms can be allocated' do - create_ready_vm 'pool1', '1abcdefghijklmnop' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -273,11 +273,11 @@ describe Vmpooler::API::V1 do expect(last_response.body).to eq(JSON.pretty_generate(expected)) expect_json(ok = false, http = 503) - expect(pool_has_ready_vm?('pool1', '1abcdefghijklmnop')).to eq(true) + expect(pool_has_ready_vm?('pool1', '1abcdefghijklmnop', redis)).to eq(true) end it 'fails when not all requested vms can be allocated, when requesting multiple instances from a pool' do - create_ready_vm 'pool1', '1abcdefghijklmnop' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis post "#{prefix}/vm", '{"pool1":"2","pool2":"1"}' @@ -288,7 +288,7 @@ describe Vmpooler::API::V1 do end it 'returns any checked out vms to their pools when not all requested vms can be allocated, when requesting multiple instances from a pool' do - create_ready_vm 'pool1', '1abcdefghijklmnop' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -299,11 +299,11 @@ describe Vmpooler::API::V1 do expect(last_response.body).to eq(JSON.pretty_generate(expected)) expect_json(ok = false, http = 503) - expect(pool_has_ready_vm?('pool1', '1abcdefghijklmnop')).to eq(true) + expect(pool_has_ready_vm?('pool1', '1abcdefghijklmnop', redis)).to eq(true) end it 'fails when not all requested vms can be allocated, when requesting multiple instances from multiple pools' do - create_ready_vm 'pool1', '1abcdefghijklmnop' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis post "#{prefix}/vm", '{"pool1":"2","pool2":"3"}' @@ -314,8 +314,8 @@ describe Vmpooler::API::V1 do end it 'returns any checked out vms to their pools when not all requested vms can be allocated, when requesting multiple instances from multiple pools' do - create_ready_vm 'pool1', '1abcdefghijklmnop' - create_ready_vm 'pool1', '2abcdefghijklmnop' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis + create_ready_vm 'pool1', '2abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -326,13 +326,13 @@ describe Vmpooler::API::V1 do expect(last_response.body).to eq(JSON.pretty_generate(expected)) expect_json(ok = false, http = 503) - expect(pool_has_ready_vm?('pool1', '1abcdefghijklmnop')).to eq(true) - expect(pool_has_ready_vm?('pool1', '2abcdefghijklmnop')).to eq(true) + expect(pool_has_ready_vm?('pool1', '1abcdefghijklmnop', redis)).to eq(true) + expect(pool_has_ready_vm?('pool1', '2abcdefghijklmnop', redis)).to eq(true) end it 'returns the second VM when the first fails to respond' do - create_ready_vm 'pool1', vmname - create_ready_vm 'pool1', "2#{vmname}" + create_ready_vm 'pool1', vmname, redis + create_ready_vm 'pool1', "2#{vmname}", redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).with(vmname, nil).and_raise('mockerror') allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).with("2#{vmname}", nil).and_return(socket) @@ -349,14 +349,14 @@ describe Vmpooler::API::V1 do expect(last_response.body).to eq(JSON.pretty_generate(expected)) - expect(pool_has_ready_vm?('pool1', vmname)).to be false + expect(pool_has_ready_vm?('pool1', vmname, redis)).to be false end context '(auth not configured)' do it 'does not extend VM lifetime if auth token is provided' do app.settings.set :config, auth: false - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -382,7 +382,7 @@ describe Vmpooler::API::V1 do it 'extends VM lifetime if auth token is provided' do app.settings.set :config, auth: true - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -405,7 +405,7 @@ describe Vmpooler::API::V1 do it 'does not extend VM lifetime if auth token is not provided' do app.settings.set :config, auth: true - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) diff --git a/spec/integration/api/v1/vm_template_spec.rb b/spec/integration/api/v1/vm_template_spec.rb index 9620f1f..043c8e5 100644 --- a/spec/integration/api/v1/vm_template_spec.rb +++ b/spec/integration/api/v1/vm_template_spec.rb @@ -19,7 +19,8 @@ describe Vmpooler::API::V1 do }, pools: [ {'name' => 'pool1', 'size' => 5}, - {'name' => 'pool2', 'size' => 10} + {'name' => 'pool2', 'size' => 10}, + {'name' => 'poolone', 'size' => 0} ], statsd: { 'prefix' => 'stats_prefix'}, alias: { 'poolone' => 'pool1' }, @@ -42,7 +43,7 @@ describe Vmpooler::API::V1 do describe 'POST /vm/:template' do it 'returns a single VM' do - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -60,7 +61,7 @@ describe Vmpooler::API::V1 do end it 'returns a single VM for an alias' do - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -86,7 +87,7 @@ describe Vmpooler::API::V1 do Vmpooler::API.settings.config.delete(:alias) Vmpooler::API.settings.config[:pool_names] = ['pool1', 'pool2'] - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis post "#{prefix}/vm/pool1" post "#{prefix}/vm/pool1" @@ -97,8 +98,7 @@ describe Vmpooler::API::V1 do end it 'returns 503 for empty pool referenced by alias' do - create_ready_vm 'pool1', 'abcdefghijklmnop' - post "#{prefix}/vm/poolone" + create_ready_vm 'pool1', 'abcdefghijklmnop', redis post "#{prefix}/vm/poolone" expected = { ok: false } @@ -108,8 +108,8 @@ describe Vmpooler::API::V1 do end it 'returns multiple VMs' do - create_ready_vm 'pool1', 'abcdefghijklmnop' - create_ready_vm 'pool2', 'qrstuvwxyz012345' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis + create_ready_vm 'pool2', 'qrstuvwxyz012345', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -130,12 +130,12 @@ describe Vmpooler::API::V1 do end it 'returns multiple VMs even when multiple instances from multiple pools are requested' do - create_ready_vm 'pool1', '1abcdefghijklmnop' - create_ready_vm 'pool1', '2abcdefghijklmnop' + create_ready_vm 'pool1', '1abcdefghijklmnop', redis + create_ready_vm 'pool1', '2abcdefghijklmnop', redis - create_ready_vm 'pool2', '1qrstuvwxyz012345' - create_ready_vm 'pool2', '2qrstuvwxyz012345' - create_ready_vm 'pool2', '3qrstuvwxyz012345' + create_ready_vm 'pool2', '1qrstuvwxyz012345', redis + create_ready_vm 'pool2', '2qrstuvwxyz012345', redis + create_ready_vm 'pool2', '3qrstuvwxyz012345', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -159,7 +159,7 @@ describe Vmpooler::API::V1 do end it 'fails when not all requested vms can be allocated' do - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis post "#{prefix}/vm/pool1+pool2", '' @@ -170,7 +170,7 @@ describe Vmpooler::API::V1 do end it 'returns any checked out vms to their pools when not all requested vms can be allocated' do - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -181,12 +181,12 @@ describe Vmpooler::API::V1 do expect(last_response.body).to eq(JSON.pretty_generate(expected)) expect_json(ok = false, http = 503) - expect(pool_has_ready_vm?('pool1', 'abcdefghijklmnop')).to eq(true) + expect(pool_has_ready_vm?('pool1', 'abcdefghijklmnop', redis)).to eq(true) end it 'fails when not all requested vms can be allocated, when requesting multiple instances from a pool' do - create_ready_vm 'pool1', 'abcdefghijklmnop' - create_ready_vm 'pool1', '0123456789012345' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis + create_ready_vm 'pool1', '0123456789012345', redis post "#{prefix}/vm/pool1+pool1+pool2", '' @@ -197,8 +197,8 @@ describe Vmpooler::API::V1 do end it 'returns any checked out vms to their pools when not all requested vms can be allocated, when requesting multiple instances from a pool' do - create_ready_vm 'pool1', 'abcdefghijklmnop' - create_ready_vm 'pool1', '0123456789012345' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis + create_ready_vm 'pool1', '0123456789012345', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -209,13 +209,13 @@ describe Vmpooler::API::V1 do expect(last_response.body).to eq(JSON.pretty_generate(expected)) expect_json(ok = false, http = 503) - expect(pool_has_ready_vm?('pool1', 'abcdefghijklmnop')).to eq(true) - expect(pool_has_ready_vm?('pool1', '0123456789012345')).to eq(true) + expect(pool_has_ready_vm?('pool1', 'abcdefghijklmnop', redis)).to eq(true) + expect(pool_has_ready_vm?('pool1', '0123456789012345', redis)).to eq(true) end it 'fails when not all requested vms can be allocated, when requesting multiple instances from multiple pools' do - create_ready_vm 'pool1', 'abcdefghijklmnop' - create_ready_vm 'pool2', '0123456789012345' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis + create_ready_vm 'pool2', '0123456789012345', redis post "#{prefix}/vm/pool1+pool1+pool2+pool2+pool2", '' @@ -226,8 +226,8 @@ describe Vmpooler::API::V1 do end it 'returns any checked out vms to their pools when not all requested vms can be allocated, when requesting multiple instances from multiple pools' do - create_ready_vm 'pool1', 'abcdefghijklmnop' - create_ready_vm 'pool2', '0123456789012345' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis + create_ready_vm 'pool2', '0123456789012345', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -238,15 +238,15 @@ describe Vmpooler::API::V1 do expect(last_response.body).to eq(JSON.pretty_generate(expected)) expect_json(ok = false, http = 503) - expect(pool_has_ready_vm?('pool1', 'abcdefghijklmnop')).to eq(true) - expect(pool_has_ready_vm?('pool2', '0123456789012345')).to eq(true) + expect(pool_has_ready_vm?('pool1', 'abcdefghijklmnop', redis)).to eq(true) + expect(pool_has_ready_vm?('pool2', '0123456789012345', redis)).to eq(true) end context '(auth not configured)' do it 'does not extend VM lifetime if auth token is provided' do app.settings.set :config, auth: false - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -272,7 +272,7 @@ describe Vmpooler::API::V1 do it 'extends VM lifetime if auth token is provided' do app.settings.set :config, auth: true - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) @@ -295,7 +295,7 @@ describe Vmpooler::API::V1 do it 'does not extend VM lifetime if auth token is not provided' do app.settings.set :config, auth: true - create_ready_vm 'pool1', 'abcdefghijklmnop' + create_ready_vm 'pool1', 'abcdefghijklmnop', redis allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) diff --git a/spec/integration/dashboard_spec.rb b/spec/integration/dashboard_spec.rb index 5bb9ac2..9d5a64a 100644 --- a/spec/integration/dashboard_spec.rb +++ b/spec/integration/dashboard_spec.rb @@ -56,11 +56,11 @@ describe Vmpooler::API do context 'without history param' do it 'returns basic JSON' do - create_ready_vm('pool1', 'vm1') - create_ready_vm('pool1', 'vm2') - create_ready_vm('pool1', 'vm3') - create_ready_vm('pool2', 'vm4') - create_ready_vm('pool2', 'vm5') + create_ready_vm('pool1', 'vm1', redis) + create_ready_vm('pool1', 'vm2', redis) + create_ready_vm('pool1', 'vm3', redis) + create_ready_vm('pool2', 'vm4', redis) + create_ready_vm('pool2', 'vm5', redis) get '/dashboard/stats/vmpooler/pool' @@ -90,11 +90,11 @@ describe Vmpooler::API do end it 'returns JSON with history when redis has values' do - create_ready_vm('pool1', 'vm1') - create_ready_vm('pool1', 'vm2') - create_ready_vm('pool1', 'vm3') - create_ready_vm('pool2', 'vm4') - create_ready_vm('pool2', 'vm5') + create_ready_vm('pool1', 'vm1', redis) + create_ready_vm('pool1', 'vm2', redis) + create_ready_vm('pool1', 'vm3', redis) + create_ready_vm('pool2', 'vm4', redis) + create_ready_vm('pool2', 'vm5', redis) get '/dashboard/stats/vmpooler/pool', :history => true @@ -140,18 +140,18 @@ describe Vmpooler::API do end it 'adds major correctly' do - create_running_vm('pool-1', 'vm1') - create_running_vm('pool-1', 'vm2') - create_running_vm('pool-1', 'vm3') + create_running_vm('pool-1', 'vm1', redis) + create_running_vm('pool-1', 'vm2', redis) + create_running_vm('pool-1', 'vm3', redis) - create_running_vm('pool-2', 'vm4') - create_running_vm('pool-2', 'vm5') - create_running_vm('pool-2', 'vm6') - create_running_vm('pool-2', 'vm7') - create_running_vm('pool-2', 'vm8') + create_running_vm('pool-2', 'vm4', redis) + create_running_vm('pool-2', 'vm5', redis) + create_running_vm('pool-2', 'vm6', redis) + create_running_vm('pool-2', 'vm7', redis) + create_running_vm('pool-2', 'vm8', redis) - create_running_vm('diffpool-1', 'vm9') - create_running_vm('diffpool-1', 'vm10') + create_running_vm('diffpool-1', 'vm9', redis) + create_running_vm('diffpool-1', 'vm10', redis) get '/dashboard/stats/vmpooler/running' diff --git a/spec/unit/pool_manager_spec.rb b/spec/unit/pool_manager_spec.rb index 1a1b324..055544d 100644 --- a/spec/unit/pool_manager_spec.rb +++ b/spec/unit/pool_manager_spec.rb @@ -8,7 +8,6 @@ require 'mock_redis' RSpec::Matchers.define :a_pool_with_name_of do |value| match { |actual| actual['name'] == value } end - describe 'Pool Manager' do let(:logger) { MockLogger.new } let(:metrics) { Vmpooler::DummyStatsd.new } @@ -276,7 +275,7 @@ EOT redis_connection_pool.with do |redis| expect(redis.hget('vmpooler__boot__' + Date.today.to_s, pool + ':' + vm)).to be_nil subject.move_pending_vm_to_ready(vm, pool, redis) - expect(redis.hget('vmpooler__boot__' + Date.today.to_s, pool + ':' + vm)).to eq("") # Possible implementation bug here. Should still be nil here + expect(redis.hget('vmpooler__boot__' + Date.today.to_s, pool + ':' + vm)).to match(/\d\.\d{2}/) end end @@ -661,7 +660,7 @@ EOT end it 'calls _clone_vm' do - expect(subject).to receive(:_clone_vm).with(pool_object,provider) + expect(subject).to receive(:_clone_vm).with(pool_object,provider,nil,nil) subject.clone_vm(pool_object,provider) end @@ -669,7 +668,7 @@ EOT it 'logs a message if an error is raised' do allow(logger).to receive(:log) expect(logger).to receive(:log).with('s',"[!] [#{pool}] failed while cloning VM with an error: MockError") - expect(subject).to receive(:_clone_vm).with(pool,provider).and_raise('MockError') + expect(subject).to receive(:_clone_vm).with(pool,provider,nil,nil).and_raise('MockError') expect{subject.clone_vm(pool,provider)}.to raise_error(/MockError/) end @@ -696,10 +695,13 @@ EOT context 'with no errors during cloning' do before(:each) do + allow(metrics).to receive(:timing) expect(metrics).to receive(:timing).with(/clone\./,/0/) expect(provider).to receive(:create_vm).with(pool, String) allow(logger).to receive(:log) - expect(subject).to receive(:find_unique_hostname).with(pool).and_return(vm) + redis_connection_pool.with do |redis| + expect(subject).to receive(:find_unique_hostname).with(pool, redis).and_return(vm) + end end it 'should create a cloning VM' do @@ -745,7 +747,9 @@ EOT before(:each) do expect(provider).to receive(:create_vm).with(pool, String).and_raise('MockError') allow(logger).to receive(:log) - expect(subject).to receive(:find_unique_hostname).with(pool).and_return(vm) + redis_connection_pool.with do |redis| + expect(subject).to receive(:find_unique_hostname).with(pool, redis).and_return(vm) + end end it 'should not create a cloning VM' do @@ -865,13 +869,16 @@ EOT it 'should emit a timing metric' do allow(subject).to receive(:get_vm_usage_labels) + allow(metrics).to receive(:timing) expect(metrics).to receive(:timing).with("destroy.#{pool}", String) subject._destroy_vm(vm,pool,provider) end it 'should check usage labels' do - expect(subject).to receive(:get_vm_usage_labels).with(vm) + redis_connection_pool.with do |redis| + expect(subject).to receive(:get_vm_usage_labels).with(vm, redis) + end subject._destroy_vm(vm,pool,provider) end @@ -925,7 +932,9 @@ EOT context 'when label evaluation is disabled' do it 'should do nothing' do - subject.get_vm_usage_labels(vm) + redis_connection_pool.with do |redis| + subject.get_vm_usage_labels(vm, redis) + end end end @@ -945,7 +954,9 @@ EOT it 'should return' do expect(subject).to receive(:get_vm_usage_labels).and_return(nil) - subject.get_vm_usage_labels(vm) + redis_connection_pool.with do |redis| + subject.get_vm_usage_labels(vm, redis) + end end end @@ -960,9 +971,11 @@ EOT end it 'should emit a metric' do - expect(metrics).to receive(:increment).with("usage.unauthenticated.#{template}") + redis_connection_pool.with do |redis| + expect(metrics).to receive(:increment).with("usage.unauthenticated.#{template}") - subject.get_vm_usage_labels(vm) + subject.get_vm_usage_labels(vm, redis) + end end end @@ -977,7 +990,9 @@ EOT it 'should emit a metric' do expect(metrics).to receive(:increment).with("usage.#{user}.#{template}") - subject.get_vm_usage_labels(vm) + redis_connection_pool.with do |redis| + subject.get_vm_usage_labels(vm, redis) + end end context 'with a user with period in name' do @@ -994,7 +1009,9 @@ EOT it 'should emit a metric with the character replaced' do expect(metrics).to receive(:increment).with(metric_string) - subject.get_vm_usage_labels(vm) + redis_connection_pool.with do |redis| + subject.get_vm_usage_labels(vm, redis) + end end it 'should include three nodes' do @@ -1024,13 +1041,17 @@ EOT let(:metric_string) { metric_string_sub.join('.') } before(:each) do - create_tag(vm, 'jenkins_build_url', jenkins_build_url) + redis_connection_pool.with do |redis| + create_tag(vm, 'jenkins_build_url', jenkins_build_url, redis) + end end it 'should emit a metric with information from the URL' do expect(metrics).to receive(:increment).with(metric_string) - subject.get_vm_usage_labels(vm) + redis_connection_pool.with do |redis| + subject.get_vm_usage_labels(vm, redis) + end end end @@ -1049,13 +1070,17 @@ EOT let(:metric_nodes) { expected_string.split('.') } before(:each) do - create_tag(vm, 'jenkins_build_url', jenkins_build_url) + redis_connection_pool.with do |redis| + create_tag(vm, 'jenkins_build_url', jenkins_build_url, redis) + end end it 'should emit a metric with information from the URL' do expect(metrics).to receive(:increment).with(expected_string) - subject.get_vm_usage_labels(vm) + redis_connection_pool.with do |redis| + subject.get_vm_usage_labels(vm, redis) + end end it 'should contain exactly nine nodes' do @@ -1074,13 +1099,17 @@ EOT let(:job_name) { value_stream_parts.join('_') } before(:each) do - create_tag(vm, 'jenkins_build_url', jenkins_build_url) + redis_connection_pool.with do |redis| + create_tag(vm, 'jenkins_build_url', jenkins_build_url, redis) + end end it 'should emit a metric with information from the URL without a build_component' do expect(metrics).to receive(:increment).with("usage.#{user}.#{instance}.#{value_stream}.#{branch}.#{project}.#{job_name}.#{template}") - subject.get_vm_usage_labels(vm) + redis_connection_pool.with do |redis| + subject.get_vm_usage_labels(vm, redis) + end end end end @@ -1287,7 +1316,7 @@ EOT allow(logger).to receive(:log) redis_connection_pool.with do |redis| - create_running_vm(pool,vm,token) + create_running_vm(pool,vm,redis,token) end end @@ -1574,13 +1603,17 @@ EOT end it 'should return the pool name' do - expect(subject.get_pool_name_for_vm(vm)).to eq(pool) + redis_connection_pool.with do |redis| + expect(subject.get_pool_name_for_vm(vm,redis)).to eq(pool) + end end end context 'Given an invalid VM' do it 'should return nil' do - expect(subject.get_pool_name_for_vm('does_not_exist')).to be_nil + redis_connection_pool.with do |redis| + expect(subject.get_pool_name_for_vm('does_not_exist',redis)).to be_nil + end end end end @@ -1749,7 +1782,9 @@ EOT context 'when VM in the queue does not exist' do before(:each) do - disk_task_vm(vm,"snapshot_#{vm}") + redis_connection_pool.with do |redis| + disk_task_vm(vm,"snapshot_#{vm}",redis) + end end it 'should log an error' do @@ -1768,8 +1803,8 @@ EOT context 'when specified provider does not exist' do before(:each) do redis_connection_pool.with do |redis| - disk_task_vm(vm,"snapshot_#{vm}") - create_running_vm(pool, vm, token) + disk_task_vm(vm,"snapshot_#{vm}",redis) + create_running_vm(pool, vm, redis, token) expect(subject).to receive(:get_provider_for_pool).and_return(nil) end end @@ -1791,7 +1826,7 @@ EOT before(:each) do ['vm1', 'vm2', 'vm3'].each do |vm_name| redis_connection_pool.with do |redis| - disk_task_vm(vm_name,"snapshot_#{vm_name}") + disk_task_vm(vm_name,"snapshot_#{vm_name}",redis) create_running_vm(pool, vm_name, redis, token) end end @@ -1895,7 +1930,9 @@ EOT context 'when VM in the queue does not exist' do before(:each) do - snapshot_vm(vm,"snapshot_#{vm}") + redis_connection_pool.with do |redis| + snapshot_vm(vm,"snapshot_#{vm}",redis) + end end it 'should log an error' do @@ -1914,7 +1951,7 @@ EOT context 'when specified provider does not exist' do before(:each) do redis_connection_pool.with do |redis| - snapshot_vm(vm,"snapshot_#{vm}") + snapshot_vm(vm,"snapshot_#{vm}",redis) create_running_vm(pool, vm, redis, token) expect(subject).to receive(:get_provider_for_pool).and_return(nil) end @@ -1937,7 +1974,7 @@ EOT before(:each) do ['vm1', 'vm2', 'vm3'].each do |vm_name| redis_connection_pool.with do |redis| - snapshot_vm(vm_name,"snapshot_#{vm_name}") + snapshot_vm(vm_name,"snapshot_#{vm_name}",redis) create_running_vm(pool, vm_name, redis, token) end end @@ -1973,7 +2010,9 @@ EOT context 'when VM in the queue does not exist' do before(:each) do - snapshot_revert_vm(vm,"snapshot_#{vm}") + redis_connection_pool.with do |redis| + snapshot_revert_vm(vm,"snapshot_#{vm}",redis) + end end it 'should log an error' do @@ -1992,7 +2031,7 @@ EOT context 'when specified provider does not exist' do before(:each) do redis_connection_pool.with do |redis| - snapshot_revert_vm(vm,"snapshot_#{vm}") + snapshot_revert_vm(vm,"snapshot_#{vm}",redis) create_running_vm(pool, vm, redis, token) expect(subject).to receive(:get_provider_for_pool).and_return(nil) end @@ -2015,7 +2054,7 @@ EOT before(:each) do ['vm1', 'vm2', 'vm3'].each do |vm_name| redis_connection_pool.with do |redis| - snapshot_revert_vm(vm_name,"snapshot_#{vm_name}") + snapshot_revert_vm(vm_name,"snapshot_#{vm_name}",redis) create_running_vm(pool, vm_name, redis, token) end end @@ -2214,9 +2253,9 @@ EOT end it 'should run prepare_template' do - expect(subject).to receive(:prepare_template).with(poolconfig, provider) - redis_connection_pool.with do |redis| + expect(subject).to receive(:prepare_template).with(poolconfig, provider, redis) + subject.update_pool_template(poolconfig, provider, new_template, current_template, redis) end end @@ -2257,8 +2296,9 @@ EOT let(:mutex) { Mutex.new } before(:each) do redis_connection_pool.with do |redis| - expect(redis).to receive(:scard).with("vmpooler__pending__#{pool}").and_return(1) - expect(redis).to receive(:scard).with("vmpooler__ready__#{pool}").and_return(2) + create_ready_vm(pool,'vm1',redis) + create_ready_vm(pool,'vm2',redis) + create_pending_vm(pool,'vm3',redis) end mutex.lock expect(subject).to receive(:pool_mutex).with(pool).and_return(mutex) @@ -2282,8 +2322,9 @@ EOT context 'with a total size greater than the pool size' do it 'should remove excess ready vms' do redis_connection_pool.with do |redis| - expect(redis).to receive(:scard).with("vmpooler__ready__#{pool}").and_return(4) - expect(redis).to receive(:scard).with("vmpooler__pending__#{pool}").and_return(0) + ['vm1','vm2','vm3','vm4'].each do |v| + create_ready_vm(pool,v,redis) + end end expect(subject).to receive(:move_vm_queue).exactly(2).times @@ -2294,11 +2335,11 @@ EOT redis_connection_pool.with do |redis| create_pending_vm(pool,'vm1',redis) create_pending_vm(pool,'vm2',redis) - create_ready_vm(pool, 'vm3',redis) - create_ready_vm(pool, 'vm4',redis) - create_ready_vm(pool, 'vm5',redis) + create_ready_vm(pool,'vm3',redis) + create_ready_vm(pool,'vm4',redis) + create_ready_vm(pool,'vm5',redis) + expect(subject).to receive(:move_vm_queue).exactly(3).times end - expect(subject).to receive(:move_vm_queue).exactly(3).times subject.remove_excess_vms(config[:pools][0]) end @@ -2347,7 +2388,9 @@ EOT context 'when template delta disk creation fails' do before(:each) do - allow(redis).to receive(:hset) + redis_connection_pool.with do |redis| + allow(redis).to receive(:hset) + end expect(provider).to receive(:create_template_delta_disks).and_raise("MockError") end diff --git a/spec/unit/providers/vsphere_spec.rb b/spec/unit/providers/vsphere_spec.rb index 2f14a8f..4cfaeeb 100644 --- a/spec/unit/providers/vsphere_spec.rb +++ b/spec/unit/providers/vsphere_spec.rb @@ -158,6 +158,9 @@ EOT end it 'should log a message that the vm is destroyed' do + # Ensure Time returns a consistent value so finish is predictable + # Otherwise finish occasionally increases to 0.01 and causes a failure + allow(Time).to receive(:now).and_return(Time.now) expect(logger).to receive(:log).with('s', "[-] [#{pool}] '#{vmname}' destroyed in #{finish} seconds") subject.destroy_vm_and_log(vmname, vm_object, pool, data_ttl)