Fix tests for changes

This commit is contained in:
kirby@puppetlabs.com 2020-04-30 12:22:31 -07:00
parent 90e09bfe1c
commit 2b96d7e476
10 changed files with 268 additions and 189 deletions

View file

@ -103,13 +103,26 @@ module Vmpooler
count_selection(selection) count_selection(selection)
end end
def fetch_single_vm(template) def fetch_single_vm(template)
template_backends = [template] template_backends = [template]
aliases = get_template_aliases(template) aliases = Vmpooler::API.settings.config[:alias]
if aliases if aliases
template_backends += aliases template_backends += aliases[template] if aliases[template].is_a?(Array)
weighted_pools = get_pool_weights(template_backends) 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 if weighted_pools.count == template_backends.count
pickup = Pickup.new(weighted_pools) pickup = Pickup.new(weighted_pools)

View file

@ -2,7 +2,6 @@
require 'vmpooler/providers' require 'vmpooler/providers'
require 'spicy-proton' require 'spicy-proton'
require 'redis'
module Vmpooler module Vmpooler
class PoolManager class PoolManager
@ -453,10 +452,11 @@ module Vmpooler
redis.multi redis.multi
redis.hget("vmpooler__vm__#{vm}", 'checkout') redis.hget("vmpooler__vm__#{vm}", 'checkout')
redis.hget("vmpooler__vm__#{vm}", 'tag:jenkins_build_url') 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') redis.hget("vmpooler__vm__#{vm}", 'template')
checkout, jenkins_build_url, user, poolname = redis.exec checkout, jenkins_build_url, user, poolname = redis.exec
return if checkout.nil? return if checkout.nil?
user ||= 'unauthenticated'
unless jenkins_build_url unless jenkins_build_url
user = user.gsub('.', '_') user = user.gsub('.', '_')
@ -491,7 +491,8 @@ module Vmpooler
$metrics.increment(metric_parts.join('.')) $metrics.increment(metric_parts.join('.'))
rescue StandardError => e 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 end
def component_to_test(match, labels_string) def component_to_test(match, labels_string)
@ -1040,7 +1041,7 @@ module Vmpooler
redis.scard("vmpooler__ready__#{pool['name']}") redis.scard("vmpooler__ready__#{pool['name']}")
redis.scard("vmpooler__pending__#{pool['name']}") redis.scard("vmpooler__pending__#{pool['name']}")
ready, pending = redis.exec 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.nil?
return if total == 0 return if total == 0

View file

@ -1,5 +1,12 @@
require 'mock_redis' require 'mock_redis'
def redis
unless @redis
@redis = MockRedis.new
end
@redis
end
# Mock an object which represents a Logger. This stops the proliferation # Mock an object which represents a Logger. This stops the proliferation
# of allow(logger).to .... expectations in tests. # of allow(logger).to .... expectations in tests.
class MockLogger class MockLogger
@ -87,38 +94,38 @@ def fetch_vm(vm)
redis.hgetall("vmpooler__vm__#{vm}") redis.hgetall("vmpooler__vm__#{vm}")
end end
def set_vm_data(vm, key, value) def set_vm_data(vm, key, value, redis)
redis.hset("vmpooler__vm__#{vm}", key, value) redis.hset("vmpooler__vm__#{vm}", key, value)
end 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.sadd('vmpooler__tasks__snapshot-revert', "#{vm}:#{snapshot}")
redis.hset("vmpooler__vm__#{vm}", "snapshot:#{snapshot}", "1") redis.hset("vmpooler__vm__#{vm}", "snapshot:#{snapshot}", "1")
end end
def snapshot_vm(vm, snapshot = '12345678901234567890123456789012') def snapshot_vm(vm, snapshot = '12345678901234567890123456789012', redis)
redis.sadd('vmpooler__tasks__snapshot', "#{vm}:#{snapshot}") redis.sadd('vmpooler__tasks__snapshot', "#{vm}:#{snapshot}")
redis.hset("vmpooler__vm__#{vm}", "snapshot:#{snapshot}", "1") redis.hset("vmpooler__vm__#{vm}", "snapshot:#{snapshot}", "1")
end 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}") redis.sadd('vmpooler__tasks__disk', "#{vm}:#{disk_size}")
end end
def has_vm_snapshot?(vm) def has_vm_snapshot?(vm, redis)
redis.smembers('vmpooler__tasks__snapshot').any? do |snapshot| redis.smembers('vmpooler__tasks__snapshot').any? do |snapshot|
instance, sha = snapshot.split(':') instance, _sha = snapshot.split(':')
vm == instance vm == instance
end end
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| redis.smembers('vmpooler__tasks__snapshot-revert').any? do |action|
instance, sha = action.split(':') instance, sha = action.split(':')
instance == vm and (snapshot ? (sha == snapshot) : true) instance == vm and (snapshot ? (sha == snapshot) : true)
end end
end end
def pool_has_ready_vm?(pool, vm) def pool_has_ready_vm?(pool, vm, redis)
!!redis.sismember('vmpooler__ready__' + pool, vm) !!redis.sismember('vmpooler__ready__' + pool, vm)
end end

View file

@ -50,7 +50,7 @@ describe Vmpooler::API::V1 do
end end
it 'returns the number of ready vms for each pool' do 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/" get "#{prefix}/status/"
# of course /status doesn't conform to the weird standard everything else uses... # of course /status doesn't conform to the weird standard everything else uses...
@ -61,8 +61,8 @@ describe Vmpooler::API::V1 do
end end
it 'returns the number of running vms for each pool' do it 'returns the number of running vms for each pool' do
3.times {|i| create_running_vm("pool1", "vm-#{i}") } 3.times {|i| create_running_vm("pool1", "vm-#{i}", redis) }
4.times {|i| create_running_vm("pool2", "vm-#{i}") } 4.times {|i| create_running_vm("pool2", "vm-#{i}", redis) }
get "#{prefix}/status/" get "#{prefix}/status/"
@ -74,8 +74,8 @@ describe Vmpooler::API::V1 do
end end
it 'returns the number of pending vms for each pool' do it 'returns the number of pending vms for each pool' do
3.times {|i| create_pending_vm("pool1", "vm-#{i}") } 3.times {|i| create_pending_vm("pool1", "vm-#{i}", redis) }
4.times {|i| create_pending_vm("pool2", "vm-#{i}") } 4.times {|i| create_pending_vm("pool2", "vm-#{i}", redis) }
get "#{prefix}/status/" get "#{prefix}/status/"
@ -230,8 +230,8 @@ describe Vmpooler::API::V1 do
it 'returns the number of running VMs' do it 'returns the number of running VMs' do
get "#{prefix}/totalrunning" get "#{prefix}/totalrunning"
expect(last_response.header['Content-Type']).to eq('application/json') 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("pool1", "vm-#{i}", redis, redis) }
5.times {|i| create_running_vm("pool3", "vm-#{i}") } 5.times {|i| create_running_vm("pool3", "vm-#{i}", redis, redis) }
result = JSON.parse(last_response.body) result = JSON.parse(last_response.body)
expect(result["running"] == 10) expect(result["running"] == 10)
end end

View file

@ -41,7 +41,7 @@ describe Vmpooler::API::V1 do
describe 'PUT /vm/:hostname' do describe 'PUT /vm/:hostname' do
it 'allows tags to be set' do it 'allows tags to be set' do
create_vm('testhost') create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"tags":{"tested_by":"rspec"}}' put "#{prefix}/vm/testhost", '{"tags":{"tested_by":"rspec"}}'
expect_json(ok = true, http = 200) expect_json(ok = true, http = 200)
@ -49,7 +49,7 @@ describe Vmpooler::API::V1 do
end end
it 'skips empty tags' do it 'skips empty tags' do
create_vm('testhost') create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"tags":{"tested_by":""}}' put "#{prefix}/vm/testhost", '{"tags":{"tested_by":""}}'
expect_json(ok = true, http = 200) expect_json(ok = true, http = 200)
@ -57,7 +57,7 @@ describe Vmpooler::API::V1 do
end end
it 'does not set tags if request body format is invalid' do 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"}}' put "#{prefix}/vm/testhost", '{"tags":{"tested"}}'
expect_json(ok = false, http = 400) expect_json(ok = false, http = 400)
@ -69,7 +69,7 @@ describe Vmpooler::API::V1 do
app.settings.set :config, app.settings.set :config,
{ :config => { 'allowed_tags' => ['created_by', 'project', 'url'] } } { :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"}}' put "#{prefix}/vm/testhost", '{"tags":{"created_by":"rspec","tested_by":"rspec"}}'
expect_json(ok = false, http = 400) expect_json(ok = false, http = 400)
@ -84,7 +84,7 @@ describe Vmpooler::API::V1 do
} } } }
it 'correctly filters tags' do it 'correctly filters tags' do
create_vm('testhost') create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"tags":{"url":"foo.com/something.html"}}' put "#{prefix}/vm/testhost", '{"tags":{"url":"foo.com/something.html"}}'
expect_json(ok = true, http = 200) expect_json(ok = true, http = 200)
@ -93,7 +93,7 @@ describe Vmpooler::API::V1 do
end end
it "doesn't eat tags not matching filter" do it "doesn't eat tags not matching filter" do
create_vm('testhost') create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"tags":{"url":"foo.com"}}' put "#{prefix}/vm/testhost", '{"tags":{"url":"foo.com"}}'
expect_json(ok = true, http = 200) expect_json(ok = true, http = 200)
@ -105,7 +105,7 @@ describe Vmpooler::API::V1 do
let(:config) { { auth: false } } let(:config) { { auth: false } }
it 'allows VM lifetime to be modified without a token' do it 'allows VM lifetime to be modified without a token' do
create_vm('testhost') create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"1"}' put "#{prefix}/vm/testhost", '{"lifetime":"1"}'
expect_json(ok = true, http = 200) expect_json(ok = true, http = 200)
@ -115,7 +115,7 @@ describe Vmpooler::API::V1 do
end end
it 'does not allow a lifetime to be 0' do it 'does not allow a lifetime to be 0' do
create_vm('testhost') create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"0"}' put "#{prefix}/vm/testhost", '{"lifetime":"0"}'
expect_json(ok = false, http = 400) expect_json(ok = false, http = 400)
@ -125,7 +125,7 @@ describe Vmpooler::API::V1 do
end end
it 'does not enforce a lifetime' do it 'does not enforce a lifetime' do
create_vm('testhost') create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"20000"}' put "#{prefix}/vm/testhost", '{"lifetime":"20000"}'
expect_json(ok = true, http = 200) 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 it 'does not allow a lifetime to be initially past config max_lifetime_upper_limit' do
app.settings.set :config, app.settings.set :config,
{ :config => { 'max_lifetime_upper_limit' => 168 } } { :config => { 'max_lifetime_upper_limit' => 168 } }
create_vm('testhost') create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"200"}' put "#{prefix}/vm/testhost", '{"lifetime":"200"}'
expect_json(ok = false, http = 400) expect_json(ok = false, http = 400)
@ -146,6 +146,18 @@ describe Vmpooler::API::V1 do
expect(vm['lifetime']).to be_nil expect(vm['lifetime']).to be_nil
end 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 end
context '(auth configured)' do context '(auth configured)' do
@ -154,7 +166,7 @@ describe Vmpooler::API::V1 do
end end
it 'allows VM lifetime to be modified with a token' do it 'allows VM lifetime to be modified with a token' do
create_vm('testhost') create_vm('testhost', redis)
put "#{prefix}/vm/testhost", '{"lifetime":"1"}', { put "#{prefix}/vm/testhost", '{"lifetime":"1"}', {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345' 'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
@ -166,7 +178,7 @@ describe Vmpooler::API::V1 do
end end
it 'does not allows VM lifetime to be modified without a token' do 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"}' put "#{prefix}/vm/testhost", '{"lifetime":"1"}'
expect_json(ok = false, http = 401) expect_json(ok = false, http = 401)
@ -182,7 +194,7 @@ describe Vmpooler::API::V1 do
end end
it 'deletes an existing VM' do it 'deletes an existing VM' do
create_running_vm('pool1', 'testhost') create_running_vm('pool1', 'testhost', redis)
expect fetch_vm('testhost') expect fetch_vm('testhost')
delete "#{prefix}/vm/testhost" delete "#{prefix}/vm/testhost"
@ -198,7 +210,7 @@ describe Vmpooler::API::V1 do
context '(checked-out without token)' do context '(checked-out without token)' do
it 'deletes a VM without supplying a 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') expect fetch_vm('testhost')
delete "#{prefix}/vm/testhost" delete "#{prefix}/vm/testhost"
@ -209,7 +221,7 @@ describe Vmpooler::API::V1 do
context '(checked-out with token)' do context '(checked-out with token)' do
it 'fails to delete a VM without supplying a 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') expect fetch_vm('testhost')
delete "#{prefix}/vm/testhost" delete "#{prefix}/vm/testhost"
@ -218,7 +230,7 @@ describe Vmpooler::API::V1 do
end end
it 'deletes a VM when token is supplied' do 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') expect fetch_vm('testhost')
delete "#{prefix}/vm/testhost", "", { delete "#{prefix}/vm/testhost", "", {
@ -235,7 +247,7 @@ describe Vmpooler::API::V1 do
describe 'POST /vm/:hostname/snapshot' do describe 'POST /vm/:hostname/snapshot' do
context '(auth not configured)' do context '(auth not configured)' do
it 'creates a snapshot' do it 'creates a snapshot' do
create_vm('testhost') create_vm('testhost', redis)
post "#{prefix}/vm/testhost/snapshot" post "#{prefix}/vm/testhost/snapshot"
expect_json(ok = true, http = 202) expect_json(ok = true, http = 202)
expect(JSON.parse(last_response.body)['testhost']['snapshot'].length).to be(32) 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 it 'returns a 401 if not authed' do
post "#{prefix}/vm/testhost/snapshot" post "#{prefix}/vm/testhost/snapshot"
expect_json(ok = false, http = 401) expect_json(ok = false, http = 401)
expect !has_vm_snapshot?('testhost') expect !has_vm_snapshot?('testhost', redis)
end end
it 'creates a snapshot if authed' do it 'creates a snapshot if authed' do
create_vm('testhost') create_vm('testhost', redis)
snapshot_vm('testhost', 'testsnapshot') snapshot_vm('testhost', 'testsnapshot', redis)
post "#{prefix}/vm/testhost/snapshot", "", { post "#{prefix}/vm/testhost/snapshot", "", {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345' 'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
} }
expect_json(ok = true, http = 202) expect_json(ok = true, http = 202)
expect(JSON.parse(last_response.body)['testhost']['snapshot'].length).to be(32) 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 end
end end
@ -270,22 +282,22 @@ describe Vmpooler::API::V1 do
describe 'POST /vm/:hostname/snapshot/:snapshot' do describe 'POST /vm/:hostname/snapshot/:snapshot' do
context '(auth not configured)' do context '(auth not configured)' do
it 'reverts to a snapshot' do it 'reverts to a snapshot' do
create_vm('testhost') create_vm('testhost', redis)
snapshot_vm('testhost', 'testsnapshot') snapshot_vm('testhost', 'testsnapshot', redis)
post "#{prefix}/vm/testhost/snapshot/testsnapshot" post "#{prefix}/vm/testhost/snapshot/testsnapshot"
expect_json(ok = true, http = 202) expect_json(ok = true, http = 202)
expect vm_reverted_to_snapshot?('testhost', 'testsnapshot') expect vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot')
end end
it 'fails if the specified snapshot does not exist' do it 'fails if the specified snapshot does not exist' do
create_vm('testhost') create_vm('testhost', redis)
post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", { post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345' 'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
} }
expect_json(ok = false, http = 404) expect_json(ok = false, http = 404)
expect !vm_reverted_to_snapshot?('testhost', 'testsnapshot') expect !vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot')
end end
end end
@ -295,33 +307,33 @@ describe Vmpooler::API::V1 do
end end
it 'returns a 401 if not authed' do it 'returns a 401 if not authed' do
create_vm('testhost') create_vm('testhost', redis)
snapshot_vm('testhost', 'testsnapshot') snapshot_vm('testhost', 'testsnapshot', redis)
post "#{prefix}/vm/testhost/snapshot/testsnapshot" post "#{prefix}/vm/testhost/snapshot/testsnapshot"
expect_json(ok = false, http = 401) expect_json(ok = false, http = 401)
expect !vm_reverted_to_snapshot?('testhost', 'testsnapshot') expect !vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot')
end end
it 'fails if authed and the specified snapshot does not exist' do 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", "", { post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345' 'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
} }
expect_json(ok = false, http = 404) expect_json(ok = false, http = 404)
expect !vm_reverted_to_snapshot?('testhost', 'testsnapshot') expect !vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot')
end end
it 'reverts to a snapshot if authed' do it 'reverts to a snapshot if authed' do
create_vm('testhost') create_vm('testhost', redis)
snapshot_vm('testhost', 'testsnapshot') snapshot_vm('testhost', 'testsnapshot', redis)
post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", { post "#{prefix}/vm/testhost/snapshot/testsnapshot", "", {
'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345' 'HTTP_X_AUTH_TOKEN' => 'abcdefghijklmnopqrstuvwxyz012345'
} }
expect_json(ok = true, http = 202) expect_json(ok = true, http = 202)
expect vm_reverted_to_snapshot?('testhost', 'testsnapshot') expect vm_reverted_to_snapshot?('testhost', redis, 'testsnapshot')
end end
end end
end end

View file

@ -42,7 +42,7 @@ describe Vmpooler::API::V1 do
describe 'GET /vm/:hostname' do describe 'GET /vm/:hostname' do
it 'returns correct information on a running vm' 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}" get "#{prefix}/vm/#{vmname}"
expect_json(ok = true, http = 200) expect_json(ok = true, http = 200)
response_body = (JSON.parse(last_response.body)[vmname]) response_body = (JSON.parse(last_response.body)[vmname])
@ -63,7 +63,7 @@ describe Vmpooler::API::V1 do
let(:socket) { double('socket') } let(:socket) { double('socket') }
it 'returns a single VM' do 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) allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket)
post "#{prefix}/vm", '{"pool1":"1"}' post "#{prefix}/vm", '{"pool1":"1"}'
@ -80,7 +80,7 @@ describe Vmpooler::API::V1 do
end end
it 'returns a single VM for an alias' do 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) 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.delete(:alias)
Vmpooler::API.settings.config[:pool_names] = ['pool1', 'pool2'] 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"
post "#{prefix}/vm/pool1" post "#{prefix}/vm/pool1"
@ -117,7 +117,7 @@ describe Vmpooler::API::V1 do
end end
it 'returns 503 for empty pool referenced by alias' do 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"
post "#{prefix}/vm/poolone" post "#{prefix}/vm/poolone"
@ -128,8 +128,8 @@ describe Vmpooler::API::V1 do
end end
it 'returns multiple VMs' do it 'returns multiple VMs' do
create_ready_vm 'pool1', vmname create_ready_vm 'pool1', vmname, redis
create_ready_vm 'pool2', 'qrstuvwxyz012345' create_ready_vm 'pool2', 'qrstuvwxyz012345', redis
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket)
@ -150,9 +150,9 @@ describe Vmpooler::API::V1 do
end end
it 'returns multiple VMs even when multiple instances from the same pool are requested' do it 'returns multiple VMs even when multiple instances from the same pool are requested' do
create_ready_vm 'pool1', '1abcdefghijklmnop' create_ready_vm 'pool1', '1abcdefghijklmnop', redis
create_ready_vm 'pool1', '2abcdefghijklmnop' create_ready_vm 'pool1', '2abcdefghijklmnop', redis
create_ready_vm 'pool2', 'qrstuvwxyz012345' create_ready_vm 'pool2', 'qrstuvwxyz012345', redis
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket)
@ -177,11 +177,11 @@ describe Vmpooler::API::V1 do
end end
it 'returns multiple VMs even when multiple instances from multiple pools are requested' do it 'returns multiple VMs even when multiple instances from multiple pools are requested' do
create_ready_vm 'pool1', '1abcdefghijklmnop' create_ready_vm 'pool1', '1abcdefghijklmnop', redis
create_ready_vm 'pool1', '2abcdefghijklmnop' create_ready_vm 'pool1', '2abcdefghijklmnop', redis
create_ready_vm 'pool2', '1qrstuvwxyz012345' create_ready_vm 'pool2', '1qrstuvwxyz012345', redis
create_ready_vm 'pool2', '2qrstuvwxyz012345' create_ready_vm 'pool2', '2qrstuvwxyz012345', redis
create_ready_vm 'pool2', '3qrstuvwxyz012345' create_ready_vm 'pool2', '3qrstuvwxyz012345', redis
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) 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 it 'returns VMs from multiple backend pools requested by an alias' do
Vmpooler::API.settings.config[:alias]['genericpool'] = ['pool1', 'pool2', 'pool3'] Vmpooler::API.settings.config[:alias]['genericpool'] = ['pool1', 'pool2', 'pool3']
create_ready_vm 'pool1', '1abcdefghijklmnop' create_ready_vm 'pool1', '1abcdefghijklmnop', redis
create_ready_vm 'pool2', '2abcdefghijklmnop' create_ready_vm 'pool2', '2abcdefghijklmnop', redis
create_ready_vm 'pool3', '1qrstuvwxyz012345' create_ready_vm 'pool3', '1qrstuvwxyz012345', redis
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket)
@ -231,9 +231,9 @@ describe Vmpooler::API::V1 do
end end
it 'returns the first VM that was moved to the ready state when checking out a VM' do 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', '1abcdefghijklmnop', redis
create_ready_vm 'pool1', '2abcdefghijklmnop' create_ready_vm 'pool1', '2abcdefghijklmnop', redis
create_ready_vm 'pool1', '3abcdefghijklmnop' create_ready_vm 'pool1', '3abcdefghijklmnop', redis
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket)
@ -251,7 +251,7 @@ describe Vmpooler::API::V1 do
end end
it 'fails when not all requested vms can be allocated' do 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"}' post "#{prefix}/vm", '{"pool1":"1","pool2":"1"}'
@ -262,7 +262,7 @@ describe Vmpooler::API::V1 do
end end
it 'returns any checked out vms to their pools when not all requested vms can be allocated' do 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) 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(last_response.body).to eq(JSON.pretty_generate(expected))
expect_json(ok = false, http = 503) 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 end
it 'fails when not all requested vms can be allocated, when requesting multiple instances from a pool' do 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"}' post "#{prefix}/vm", '{"pool1":"2","pool2":"1"}'
@ -288,7 +288,7 @@ describe Vmpooler::API::V1 do
end 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 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) 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(last_response.body).to eq(JSON.pretty_generate(expected))
expect_json(ok = false, http = 503) 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 end
it 'fails when not all requested vms can be allocated, when requesting multiple instances from multiple pools' do 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"}' post "#{prefix}/vm", '{"pool1":"2","pool2":"3"}'
@ -314,8 +314,8 @@ describe Vmpooler::API::V1 do
end 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 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', '1abcdefghijklmnop', redis
create_ready_vm 'pool1', '2abcdefghijklmnop' create_ready_vm 'pool1', '2abcdefghijklmnop', redis
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) 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(last_response.body).to eq(JSON.pretty_generate(expected))
expect_json(ok = false, http = 503) 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)
expect(pool_has_ready_vm?('pool1', '2abcdefghijklmnop')).to eq(true) expect(pool_has_ready_vm?('pool1', '2abcdefghijklmnop', redis)).to eq(true)
end end
it 'returns the second VM when the first fails to respond' do it 'returns the second VM when the first fails to respond' do
create_ready_vm 'pool1', vmname create_ready_vm 'pool1', vmname, redis
create_ready_vm 'pool1', "2#{vmname}" 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(vmname, nil).and_raise('mockerror')
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).with("2#{vmname}", nil).and_return(socket) 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(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 end
context '(auth not configured)' do context '(auth not configured)' do
it 'does not extend VM lifetime if auth token is provided' do it 'does not extend VM lifetime if auth token is provided' do
app.settings.set :config, auth: false 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) 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 it 'extends VM lifetime if auth token is provided' do
app.settings.set :config, auth: true 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) 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 it 'does not extend VM lifetime if auth token is not provided' do
app.settings.set :config, auth: true 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) allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket)

View file

@ -19,7 +19,8 @@ describe Vmpooler::API::V1 do
}, },
pools: [ pools: [
{'name' => 'pool1', 'size' => 5}, {'name' => 'pool1', 'size' => 5},
{'name' => 'pool2', 'size' => 10} {'name' => 'pool2', 'size' => 10},
{'name' => 'poolone', 'size' => 0}
], ],
statsd: { 'prefix' => 'stats_prefix'}, statsd: { 'prefix' => 'stats_prefix'},
alias: { 'poolone' => 'pool1' }, alias: { 'poolone' => 'pool1' },
@ -42,7 +43,7 @@ describe Vmpooler::API::V1 do
describe 'POST /vm/:template' do describe 'POST /vm/:template' do
it 'returns a single VM' 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) allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket)
@ -60,7 +61,7 @@ describe Vmpooler::API::V1 do
end end
it 'returns a single VM for an alias' do 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) 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.delete(:alias)
Vmpooler::API.settings.config[:pool_names] = ['pool1', 'pool2'] 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"
post "#{prefix}/vm/pool1" post "#{prefix}/vm/pool1"
@ -97,8 +98,7 @@ describe Vmpooler::API::V1 do
end end
it 'returns 503 for empty pool referenced by alias' do it 'returns 503 for empty pool referenced by alias' do
create_ready_vm 'pool1', 'abcdefghijklmnop' create_ready_vm 'pool1', 'abcdefghijklmnop', redis
post "#{prefix}/vm/poolone"
post "#{prefix}/vm/poolone" post "#{prefix}/vm/poolone"
expected = { ok: false } expected = { ok: false }
@ -108,8 +108,8 @@ describe Vmpooler::API::V1 do
end end
it 'returns multiple VMs' do it 'returns multiple VMs' do
create_ready_vm 'pool1', 'abcdefghijklmnop' create_ready_vm 'pool1', 'abcdefghijklmnop', redis
create_ready_vm 'pool2', 'qrstuvwxyz012345' create_ready_vm 'pool2', 'qrstuvwxyz012345', redis
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket)
@ -130,12 +130,12 @@ describe Vmpooler::API::V1 do
end end
it 'returns multiple VMs even when multiple instances from multiple pools are requested' do it 'returns multiple VMs even when multiple instances from multiple pools are requested' do
create_ready_vm 'pool1', '1abcdefghijklmnop' create_ready_vm 'pool1', '1abcdefghijklmnop', redis
create_ready_vm 'pool1', '2abcdefghijklmnop' create_ready_vm 'pool1', '2abcdefghijklmnop', redis
create_ready_vm 'pool2', '1qrstuvwxyz012345' create_ready_vm 'pool2', '1qrstuvwxyz012345', redis
create_ready_vm 'pool2', '2qrstuvwxyz012345' create_ready_vm 'pool2', '2qrstuvwxyz012345', redis
create_ready_vm 'pool2', '3qrstuvwxyz012345' create_ready_vm 'pool2', '3qrstuvwxyz012345', redis
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket)
@ -159,7 +159,7 @@ describe Vmpooler::API::V1 do
end end
it 'fails when not all requested vms can be allocated' do 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", '' post "#{prefix}/vm/pool1+pool2", ''
@ -170,7 +170,7 @@ describe Vmpooler::API::V1 do
end end
it 'returns any checked out vms to their pools when not all requested vms can be allocated' do 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) 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(last_response.body).to eq(JSON.pretty_generate(expected))
expect_json(ok = false, http = 503) 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 end
it 'fails when not all requested vms can be allocated, when requesting multiple instances from a pool' do 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', 'abcdefghijklmnop', redis
create_ready_vm 'pool1', '0123456789012345' create_ready_vm 'pool1', '0123456789012345', redis
post "#{prefix}/vm/pool1+pool1+pool2", '' post "#{prefix}/vm/pool1+pool1+pool2", ''
@ -197,8 +197,8 @@ describe Vmpooler::API::V1 do
end 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 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', 'abcdefghijklmnop', redis
create_ready_vm 'pool1', '0123456789012345' create_ready_vm 'pool1', '0123456789012345', redis
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) 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(last_response.body).to eq(JSON.pretty_generate(expected))
expect_json(ok = false, http = 503) 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)
expect(pool_has_ready_vm?('pool1', '0123456789012345')).to eq(true) expect(pool_has_ready_vm?('pool1', '0123456789012345', redis)).to eq(true)
end end
it 'fails when not all requested vms can be allocated, when requesting multiple instances from multiple pools' do 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 'pool1', 'abcdefghijklmnop', redis
create_ready_vm 'pool2', '0123456789012345' create_ready_vm 'pool2', '0123456789012345', redis
post "#{prefix}/vm/pool1+pool1+pool2+pool2+pool2", '' post "#{prefix}/vm/pool1+pool1+pool2+pool2+pool2", ''
@ -226,8 +226,8 @@ describe Vmpooler::API::V1 do
end 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 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 'pool1', 'abcdefghijklmnop', redis
create_ready_vm 'pool2', '0123456789012345' create_ready_vm 'pool2', '0123456789012345', redis
allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket) 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(last_response.body).to eq(JSON.pretty_generate(expected))
expect_json(ok = false, http = 503) 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)
expect(pool_has_ready_vm?('pool2', '0123456789012345')).to eq(true) expect(pool_has_ready_vm?('pool2', '0123456789012345', redis)).to eq(true)
end end
context '(auth not configured)' do context '(auth not configured)' do
it 'does not extend VM lifetime if auth token is provided' do it 'does not extend VM lifetime if auth token is provided' do
app.settings.set :config, auth: false 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) 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 it 'extends VM lifetime if auth token is provided' do
app.settings.set :config, auth: true 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) 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 it 'does not extend VM lifetime if auth token is not provided' do
app.settings.set :config, auth: true 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) allow_any_instance_of(Vmpooler::API::Helpers).to receive(:open_socket).and_return(socket)

View file

@ -56,11 +56,11 @@ describe Vmpooler::API do
context 'without history param' do context 'without history param' do
it 'returns basic JSON' do it 'returns basic JSON' do
create_ready_vm('pool1', 'vm1') create_ready_vm('pool1', 'vm1', redis)
create_ready_vm('pool1', 'vm2') create_ready_vm('pool1', 'vm2', redis)
create_ready_vm('pool1', 'vm3') create_ready_vm('pool1', 'vm3', redis)
create_ready_vm('pool2', 'vm4') create_ready_vm('pool2', 'vm4', redis)
create_ready_vm('pool2', 'vm5') create_ready_vm('pool2', 'vm5', redis)
get '/dashboard/stats/vmpooler/pool' get '/dashboard/stats/vmpooler/pool'
@ -90,11 +90,11 @@ describe Vmpooler::API do
end end
it 'returns JSON with history when redis has values' do it 'returns JSON with history when redis has values' do
create_ready_vm('pool1', 'vm1') create_ready_vm('pool1', 'vm1', redis)
create_ready_vm('pool1', 'vm2') create_ready_vm('pool1', 'vm2', redis)
create_ready_vm('pool1', 'vm3') create_ready_vm('pool1', 'vm3', redis)
create_ready_vm('pool2', 'vm4') create_ready_vm('pool2', 'vm4', redis)
create_ready_vm('pool2', 'vm5') create_ready_vm('pool2', 'vm5', redis)
get '/dashboard/stats/vmpooler/pool', :history => true get '/dashboard/stats/vmpooler/pool', :history => true
@ -140,18 +140,18 @@ describe Vmpooler::API do
end end
it 'adds major correctly' do it 'adds major correctly' do
create_running_vm('pool-1', 'vm1') create_running_vm('pool-1', 'vm1', redis)
create_running_vm('pool-1', 'vm2') create_running_vm('pool-1', 'vm2', redis)
create_running_vm('pool-1', 'vm3') create_running_vm('pool-1', 'vm3', redis)
create_running_vm('pool-2', 'vm4') create_running_vm('pool-2', 'vm4', redis)
create_running_vm('pool-2', 'vm5') create_running_vm('pool-2', 'vm5', redis)
create_running_vm('pool-2', 'vm6') create_running_vm('pool-2', 'vm6', redis)
create_running_vm('pool-2', 'vm7') create_running_vm('pool-2', 'vm7', redis)
create_running_vm('pool-2', 'vm8') create_running_vm('pool-2', 'vm8', redis)
create_running_vm('diffpool-1', 'vm9') create_running_vm('diffpool-1', 'vm9', redis)
create_running_vm('diffpool-1', 'vm10') create_running_vm('diffpool-1', 'vm10', redis)
get '/dashboard/stats/vmpooler/running' get '/dashboard/stats/vmpooler/running'

View file

@ -8,7 +8,6 @@ require 'mock_redis'
RSpec::Matchers.define :a_pool_with_name_of do |value| RSpec::Matchers.define :a_pool_with_name_of do |value|
match { |actual| actual['name'] == value } match { |actual| actual['name'] == value }
end end
describe 'Pool Manager' do describe 'Pool Manager' do
let(:logger) { MockLogger.new } let(:logger) { MockLogger.new }
let(:metrics) { Vmpooler::DummyStatsd.new } let(:metrics) { Vmpooler::DummyStatsd.new }
@ -276,7 +275,7 @@ EOT
redis_connection_pool.with do |redis| redis_connection_pool.with do |redis|
expect(redis.hget('vmpooler__boot__' + Date.today.to_s, pool + ':' + vm)).to be_nil expect(redis.hget('vmpooler__boot__' + Date.today.to_s, pool + ':' + vm)).to be_nil
subject.move_pending_vm_to_ready(vm, pool, redis) 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
end end
@ -661,7 +660,7 @@ EOT
end end
it 'calls _clone_vm' do 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) subject.clone_vm(pool_object,provider)
end end
@ -669,7 +668,7 @@ EOT
it 'logs a message if an error is raised' do it 'logs a message if an error is raised' do
allow(logger).to receive(:log) allow(logger).to receive(:log)
expect(logger).to receive(:log).with('s',"[!] [#{pool}] failed while cloning VM with an error: MockError") 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/) expect{subject.clone_vm(pool,provider)}.to raise_error(/MockError/)
end end
@ -696,10 +695,13 @@ EOT
context 'with no errors during cloning' do context 'with no errors during cloning' do
before(:each) do before(:each) do
allow(metrics).to receive(:timing)
expect(metrics).to receive(:timing).with(/clone\./,/0/) expect(metrics).to receive(:timing).with(/clone\./,/0/)
expect(provider).to receive(:create_vm).with(pool, String) expect(provider).to receive(:create_vm).with(pool, String)
allow(logger).to receive(:log) 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 end
it 'should create a cloning VM' do it 'should create a cloning VM' do
@ -745,7 +747,9 @@ EOT
before(:each) do before(:each) do
expect(provider).to receive(:create_vm).with(pool, String).and_raise('MockError') expect(provider).to receive(:create_vm).with(pool, String).and_raise('MockError')
allow(logger).to receive(:log) 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 end
it 'should not create a cloning VM' do it 'should not create a cloning VM' do
@ -865,13 +869,16 @@ EOT
it 'should emit a timing metric' do it 'should emit a timing metric' do
allow(subject).to receive(:get_vm_usage_labels) allow(subject).to receive(:get_vm_usage_labels)
allow(metrics).to receive(:timing)
expect(metrics).to receive(:timing).with("destroy.#{pool}", String) expect(metrics).to receive(:timing).with("destroy.#{pool}", String)
subject._destroy_vm(vm,pool,provider) subject._destroy_vm(vm,pool,provider)
end end
it 'should check usage labels' do 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) subject._destroy_vm(vm,pool,provider)
end end
@ -925,7 +932,9 @@ EOT
context 'when label evaluation is disabled' do context 'when label evaluation is disabled' do
it 'should do nothing' 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
end end
@ -945,7 +954,9 @@ EOT
it 'should return' do it 'should return' do
expect(subject).to receive(:get_vm_usage_labels).and_return(nil) 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
end end
@ -960,9 +971,11 @@ EOT
end end
it 'should emit a metric' do it 'should emit a metric' do
redis_connection_pool.with do |redis|
expect(metrics).to receive(:increment).with("usage.unauthenticated.#{template}") 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
end end
@ -977,7 +990,9 @@ EOT
it 'should emit a metric' do it 'should emit a metric' do
expect(metrics).to receive(:increment).with("usage.#{user}.#{template}") 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 end
context 'with a user with period in name' do context 'with a user with period in name' do
@ -994,7 +1009,9 @@ EOT
it 'should emit a metric with the character replaced' do it 'should emit a metric with the character replaced' do
expect(metrics).to receive(:increment).with(metric_string) 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
it 'should include three nodes' do it 'should include three nodes' do
@ -1024,13 +1041,17 @@ EOT
let(:metric_string) { metric_string_sub.join('.') } let(:metric_string) { metric_string_sub.join('.') }
before(:each) do 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 end
it 'should emit a metric with information from the URL' do it 'should emit a metric with information from the URL' do
expect(metrics).to receive(:increment).with(metric_string) 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
end end
@ -1049,13 +1070,17 @@ EOT
let(:metric_nodes) { expected_string.split('.') } let(:metric_nodes) { expected_string.split('.') }
before(:each) do 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 end
it 'should emit a metric with information from the URL' do it 'should emit a metric with information from the URL' do
expect(metrics).to receive(:increment).with(expected_string) 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 end
it 'should contain exactly nine nodes' do it 'should contain exactly nine nodes' do
@ -1074,13 +1099,17 @@ EOT
let(:job_name) { value_stream_parts.join('_') } let(:job_name) { value_stream_parts.join('_') }
before(:each) do 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 end
it 'should emit a metric with information from the URL without a build_component' do 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}") 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 end
end end
@ -1287,7 +1316,7 @@ EOT
allow(logger).to receive(:log) allow(logger).to receive(:log)
redis_connection_pool.with do |redis| redis_connection_pool.with do |redis|
create_running_vm(pool,vm,token) create_running_vm(pool,vm,redis,token)
end end
end end
@ -1574,13 +1603,17 @@ EOT
end end
it 'should return the pool name' do 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
end end
context 'Given an invalid VM' do context 'Given an invalid VM' do
it 'should return nil' 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 end
end end
@ -1749,7 +1782,9 @@ EOT
context 'when VM in the queue does not exist' do context 'when VM in the queue does not exist' do
before(:each) 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 end
it 'should log an error' do it 'should log an error' do
@ -1768,8 +1803,8 @@ EOT
context 'when specified provider does not exist' do context 'when specified provider does not exist' do
before(:each) do before(:each) do
redis_connection_pool.with do |redis| redis_connection_pool.with do |redis|
disk_task_vm(vm,"snapshot_#{vm}") disk_task_vm(vm,"snapshot_#{vm}",redis)
create_running_vm(pool, vm, token) create_running_vm(pool, vm, redis, token)
expect(subject).to receive(:get_provider_for_pool).and_return(nil) expect(subject).to receive(:get_provider_for_pool).and_return(nil)
end end
end end
@ -1791,7 +1826,7 @@ EOT
before(:each) do before(:each) do
['vm1', 'vm2', 'vm3'].each do |vm_name| ['vm1', 'vm2', 'vm3'].each do |vm_name|
redis_connection_pool.with do |redis| 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) create_running_vm(pool, vm_name, redis, token)
end end
end end
@ -1895,7 +1930,9 @@ EOT
context 'when VM in the queue does not exist' do context 'when VM in the queue does not exist' do
before(:each) do before(:each) do
snapshot_vm(vm,"snapshot_#{vm}") redis_connection_pool.with do |redis|
snapshot_vm(vm,"snapshot_#{vm}",redis)
end
end end
it 'should log an error' do it 'should log an error' do
@ -1914,7 +1951,7 @@ EOT
context 'when specified provider does not exist' do context 'when specified provider does not exist' do
before(:each) do before(:each) do
redis_connection_pool.with do |redis| redis_connection_pool.with do |redis|
snapshot_vm(vm,"snapshot_#{vm}") snapshot_vm(vm,"snapshot_#{vm}",redis)
create_running_vm(pool, vm, redis, token) create_running_vm(pool, vm, redis, token)
expect(subject).to receive(:get_provider_for_pool).and_return(nil) expect(subject).to receive(:get_provider_for_pool).and_return(nil)
end end
@ -1937,7 +1974,7 @@ EOT
before(:each) do before(:each) do
['vm1', 'vm2', 'vm3'].each do |vm_name| ['vm1', 'vm2', 'vm3'].each do |vm_name|
redis_connection_pool.with do |redis| 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) create_running_vm(pool, vm_name, redis, token)
end end
end end
@ -1973,7 +2010,9 @@ EOT
context 'when VM in the queue does not exist' do context 'when VM in the queue does not exist' do
before(:each) 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 end
it 'should log an error' do it 'should log an error' do
@ -1992,7 +2031,7 @@ EOT
context 'when specified provider does not exist' do context 'when specified provider does not exist' do
before(:each) do before(:each) do
redis_connection_pool.with do |redis| 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) create_running_vm(pool, vm, redis, token)
expect(subject).to receive(:get_provider_for_pool).and_return(nil) expect(subject).to receive(:get_provider_for_pool).and_return(nil)
end end
@ -2015,7 +2054,7 @@ EOT
before(:each) do before(:each) do
['vm1', 'vm2', 'vm3'].each do |vm_name| ['vm1', 'vm2', 'vm3'].each do |vm_name|
redis_connection_pool.with do |redis| 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) create_running_vm(pool, vm_name, redis, token)
end end
end end
@ -2214,9 +2253,9 @@ EOT
end end
it 'should run prepare_template' do it 'should run prepare_template' do
expect(subject).to receive(:prepare_template).with(poolconfig, provider)
redis_connection_pool.with do |redis| 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) subject.update_pool_template(poolconfig, provider, new_template, current_template, redis)
end end
end end
@ -2257,8 +2296,9 @@ EOT
let(:mutex) { Mutex.new } let(:mutex) { Mutex.new }
before(:each) do before(:each) do
redis_connection_pool.with do |redis| redis_connection_pool.with do |redis|
expect(redis).to receive(:scard).with("vmpooler__pending__#{pool}").and_return(1) create_ready_vm(pool,'vm1',redis)
expect(redis).to receive(:scard).with("vmpooler__ready__#{pool}").and_return(2) create_ready_vm(pool,'vm2',redis)
create_pending_vm(pool,'vm3',redis)
end end
mutex.lock mutex.lock
expect(subject).to receive(:pool_mutex).with(pool).and_return(mutex) 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 context 'with a total size greater than the pool size' do
it 'should remove excess ready vms' do it 'should remove excess ready vms' do
redis_connection_pool.with do |redis| redis_connection_pool.with do |redis|
expect(redis).to receive(:scard).with("vmpooler__ready__#{pool}").and_return(4) ['vm1','vm2','vm3','vm4'].each do |v|
expect(redis).to receive(:scard).with("vmpooler__pending__#{pool}").and_return(0) create_ready_vm(pool,v,redis)
end
end end
expect(subject).to receive(:move_vm_queue).exactly(2).times expect(subject).to receive(:move_vm_queue).exactly(2).times
@ -2294,11 +2335,11 @@ EOT
redis_connection_pool.with do |redis| redis_connection_pool.with do |redis|
create_pending_vm(pool,'vm1',redis) create_pending_vm(pool,'vm1',redis)
create_pending_vm(pool,'vm2',redis) create_pending_vm(pool,'vm2',redis)
create_ready_vm(pool, 'vm3',redis) create_ready_vm(pool,'vm3',redis)
create_ready_vm(pool, 'vm4',redis) create_ready_vm(pool,'vm4',redis)
create_ready_vm(pool, 'vm5',redis) create_ready_vm(pool,'vm5',redis)
end
expect(subject).to receive(:move_vm_queue).exactly(3).times expect(subject).to receive(:move_vm_queue).exactly(3).times
end
subject.remove_excess_vms(config[:pools][0]) subject.remove_excess_vms(config[:pools][0])
end end
@ -2347,7 +2388,9 @@ EOT
context 'when template delta disk creation fails' do context 'when template delta disk creation fails' do
before(:each) do before(:each) do
redis_connection_pool.with do |redis|
allow(redis).to receive(:hset) allow(redis).to receive(:hset)
end
expect(provider).to receive(:create_template_delta_disks).and_raise("MockError") expect(provider).to receive(:create_template_delta_disks).and_raise("MockError")
end end

View file

@ -158,6 +158,9 @@ EOT
end end
it 'should log a message that the vm is destroyed' do 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") expect(logger).to receive(:log).with('s', "[-] [#{pool}] '#{vmname}' destroyed in #{finish} seconds")
subject.destroy_vm_and_log(vmname, vm_object, pool, data_ttl) subject.destroy_vm_and_log(vmname, vm_object, pool, data_ttl)