mirror of
https://github.com/puppetlabs/vmpooler.git
synced 2026-01-26 18:08:42 -05:00
[QENG-3919] Make vmpooler checkouts be all or nothing (#153)
* (QENG-3919) spike for implementation of all-or-nothing checkout * Fix two botched variable references * Aggregate API helper methods * Add specs for failed multi-vm allocation API endpoints * (QENG-3919) Add tests for multiple vm requests * (QENG-3919) Add (failing) specs for POST /vm/pool1+pool2 usages This exposes the old (bad) behavior on this other code path. Will fix this up next. * (QENG-3919) Bring query params version in line with JSON post version Not clear to me why these had to be implemented so differently. * (QENG-3919) extract common method from both methods of VM allocation * (QENG-3919) Naming fix, cosmetic cleanups I mean, I presume all these commits are going to get squashed away on merge anyway. * (QENG-3919) Update API docs We consider it a bug that the actual behavior was not this behavior, but the documentation was also silent on this point. * (QENG-3919) minor readability tweak in refactored method * (QENG-3919) Clean up interim comments re: status codes * (QENG-3919) Drop now-orphaned `checkout_vm` method We kept this up-to-date while we were upgrading and refactoring, but, turns out, this method is no longer called anywhere. 💀 🔥 * (QENG-3919) Return 503 status on failed allocation Making sure we go back to the original functionality, which was: - status 200 when vms successfully allocated - status 404 when a pool name is unknown - status 404 when no pool name is specified - status 503 when vm allocation failed * (QENG-3919) add net-ldap to Gemfile Maybe we shouldn't foil-ball gems onto servers. * (QENG-3919) Turns out, spush isn't a redis command And hence we see once again the weakness of mockist tests. * (QENG-3919) Pin the net-ldap gem to 0.11 for the jrubies, etc. * (QENG-3919) Correct an old spelling error in spec descriptions * (QENG-3919) Further tweak net-ldap version * (QENG-3919) return_single_vm -> return_vm_to_ready_state cc @shermdog
This commit is contained in:
parent
b59a1f8886
commit
5aaab7c5c2
4 changed files with 310 additions and 79 deletions
|
|
@ -239,7 +239,7 @@ describe Vmpooler::API::V1 do
|
|||
expect_json(ok = true, http = 200)
|
||||
end
|
||||
|
||||
it 'fails on nonexistant pools' do
|
||||
it 'fails on nonexistent pools' do
|
||||
expect(redis).to receive(:exists).with("vmpooler__ready__poolpoolpool").and_return(false)
|
||||
|
||||
post "#{prefix}/vm", '{"poolpoolpool":"1"}'
|
||||
|
|
@ -265,6 +265,120 @@ describe Vmpooler::API::V1 do
|
|||
expect_json(ok = true, http = 200)
|
||||
end
|
||||
|
||||
it 'returns multiple VMs even when multiple instances from the same pool are requested' do
|
||||
post "#{prefix}/vm", '{"pool1":"2","pool2":"1"}'
|
||||
|
||||
expected = {
|
||||
ok: true,
|
||||
pool1: {
|
||||
hostname: [ 'abcdefghijklmnop', 'abcdefghijklmnop' ]
|
||||
},
|
||||
pool2: {
|
||||
hostname: 'qrstuvwxyz012345'
|
||||
}
|
||||
}
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
|
||||
expect_json(ok = true, http = 200)
|
||||
end
|
||||
|
||||
it 'returns multiple VMs even when multiple instances from multiple pools are requested' do
|
||||
post "#{prefix}/vm", '{"pool1":"2","pool2":"3"}'
|
||||
|
||||
expected = {
|
||||
ok: true,
|
||||
pool1: {
|
||||
hostname: [ 'abcdefghijklmnop', 'abcdefghijklmnop' ]
|
||||
},
|
||||
pool2: {
|
||||
hostname: [ 'qrstuvwxyz012345', 'qrstuvwxyz012345', 'qrstuvwxyz012345' ]
|
||||
}
|
||||
}
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
|
||||
expect_json(ok = true, http = 200)
|
||||
end
|
||||
|
||||
it 'fails when not all requested vms can be allocated' do
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
allow(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop")
|
||||
|
||||
post "#{prefix}/vm", '{"pool1":"1","pool2":"1"}'
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
end
|
||||
|
||||
it 'returns any checked out vms to their pools when not all requested vms can be allocated' do
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
expect(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop")
|
||||
|
||||
post "#{prefix}/vm", '{"pool1":"1","pool2":"1"}'
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
end
|
||||
|
||||
it 'fails when not all requested vms can be allocated, when requesting multiple instances from a pool' do
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
allow(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop")
|
||||
|
||||
post "#{prefix}/vm", '{"pool1":"2","pool2":"1"}'
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
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
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
expect(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop").exactly(2).times
|
||||
|
||||
post "#{prefix}/vm", '{"pool1":"2","pool2":"1"}'
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
end
|
||||
|
||||
it 'fails when not all requested vms can be allocated, when requesting multiple instances from multiple pools' do
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
allow(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop")
|
||||
|
||||
post "#{prefix}/vm", '{"pool1":"2","pool2":"3"}'
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
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
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
expect(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop").exactly(2).times
|
||||
|
||||
post "#{prefix}/vm", '{"pool1":"2","pool2":"3"}'
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
end
|
||||
|
||||
context '(auth not configured)' do
|
||||
let(:config) { { auth: false } }
|
||||
|
||||
|
|
@ -391,7 +505,7 @@ describe Vmpooler::API::V1 do
|
|||
expect_json(ok = true, http = 200)
|
||||
end
|
||||
|
||||
it 'fails on nonexistant pools' do
|
||||
it 'fails on nonexistent pools' do
|
||||
expect(redis).to receive(:exists).with("vmpooler__ready__poolpoolpool").and_return(false)
|
||||
|
||||
post "#{prefix}/vm/poolpoolpool", ''
|
||||
|
|
@ -417,6 +531,120 @@ describe Vmpooler::API::V1 do
|
|||
expect_json(ok = true, http = 200)
|
||||
end
|
||||
|
||||
it 'returns multiple VMs even when multiple instances from the same pool are requested' do
|
||||
post "#{prefix}/vm/pool1+pool1+pool2", ''
|
||||
|
||||
expected = {
|
||||
ok: true,
|
||||
pool1: {
|
||||
hostname: [ 'abcdefghijklmnop', 'abcdefghijklmnop' ]
|
||||
},
|
||||
pool2: {
|
||||
hostname: 'qrstuvwxyz012345'
|
||||
}
|
||||
}
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
|
||||
expect_json(ok = true, http = 200)
|
||||
end
|
||||
|
||||
it 'returns multiple VMs even when multiple instances from multiple pools are requested' do
|
||||
post "#{prefix}/vm/pool1+pool1+pool2+pool2+pool2", ''
|
||||
|
||||
expected = {
|
||||
ok: true,
|
||||
pool1: {
|
||||
hostname: [ 'abcdefghijklmnop', 'abcdefghijklmnop' ]
|
||||
},
|
||||
pool2: {
|
||||
hostname: [ 'qrstuvwxyz012345', 'qrstuvwxyz012345', 'qrstuvwxyz012345' ]
|
||||
}
|
||||
}
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
|
||||
expect_json(ok = true, http = 200)
|
||||
end
|
||||
|
||||
it 'fails when not all requested vms can be allocated' do
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
allow(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop")
|
||||
|
||||
post "#{prefix}/vm/pool1+pool2", ''
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
end
|
||||
|
||||
it 'returns any checked out vms to their pools when not all requested vms can be allocated' do
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
expect(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop")
|
||||
|
||||
post "#{prefix}/vm/pool1+pool2", ''
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
end
|
||||
|
||||
it 'fails when not all requested vms can be allocated, when requesting multiple instances from a pool' do
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
allow(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop")
|
||||
|
||||
post "#{prefix}/vm/pool1+pool1+pool2", ''
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
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
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
expect(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop").exactly(2).times
|
||||
|
||||
post "#{prefix}/vm/pool1+pool1+pool2", ''
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
end
|
||||
|
||||
it 'fails when not all requested vms can be allocated, when requesting multiple instances from multiple pools' do
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
allow(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop")
|
||||
|
||||
post "#{prefix}/vm/pool1+pool1+pool2+pool2+pool2", ''
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
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
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool1').and_return 'abcdefghijklmnop'
|
||||
allow(redis).to receive(:spop).with('vmpooler__ready__pool2').and_return nil
|
||||
expect(redis).to receive(:sadd).with("vmpooler__ready__pool1", "abcdefghijklmnop").exactly(2).times
|
||||
|
||||
post "#{prefix}/vm/pool1+pool1+pool2+pool2+pool2", ''
|
||||
|
||||
expected = { ok: false }
|
||||
|
||||
expect(last_response.body).to eq(JSON.pretty_generate(expected))
|
||||
expect_json(ok = false, http = 503)
|
||||
end
|
||||
|
||||
context '(auth not configured)' do
|
||||
let(:config) { { auth: false } }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue