# # Author: Peter K. Lee (peter@corenova.com) # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Apache License, Version 2.0 # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 # config = require 'config' assert = require 'assert' forge = require 'yangforge' app = forge.load '!yaml ../promise.yaml', async: false, pkgdir: __dirname # this is javascript promise framework and not related to opnfv-promise promise = require 'promise' if process.env.DEBUG debug = console.log else debug = -> # in the future with YF 0.12.x # app = forge.load('..').build('test') # app.set config # app.use 'proxy', target: x.x.x.x:5050, interface: 'restjson' describe "promise", -> before -> # ensure we have valid OpenStack environment to test against try config.get 'openstack.auth.endpoint' catch e throw new Error "missing OpenStack environmental variables" # below 'provider' is used across test suites provider = undefined # Test Scenario 00 (FUTURE) # describe "prepare OpenStack for testing", -> # before (done) -> # # ensure we have valid OpenStack environment to test against # try # config.get 'openstack.auth.url' # catch e # throw new Error "missing OpenStack environmental variables" # os = forge.load '!yaml ../openstack.yaml', async: false, pkgdir: __dirname # app.attach 'openstack', os.access 'openstack' # app.set config # describe "authenticate", -> # it "should retrieve available service catalog", (done) -> # app.access('openstack').invoke 'authenticate' # .then (res) -> # done() # .catch (err) -> done err # describe "create-tenant", -> # # create a new tenant for testing purposes # describe "upload-image", -> # # upload a new test image # Test Scenario 01 describe "register OpenStack into resource pool", -> pool = undefined # TC-01 describe "add-provider", -> it "should add a new OpenStack provider without error", (done) -> @timeout 5000 auth = config.get 'openstack.auth' auth['provider-type'] = 'openstack' app.access('opnfv-promise').invoke 'add-provider', auth .then (res) -> res.get('result').should.equal 'ok' provider = id: res.get('provider-id') # HACK - we delay by a second to allow time for discovering capacity and flavors setTimeout done, 1000 .catch (err) -> done err it "should update promise.providers with a new entry", -> app.get('opnfv-promise.promise.providers').should.have.length(1) it "should contain a new ResourceProvider record in the store", -> assert provider?.id?, "unable to check without ID" provider = app.access('opnfv-promise').find('ResourceProvider', provider.id) assert provider? # TC-02 describe "increase-capacity", -> it "should add more capacity to the reservation service without error", (done) -> app.access('opnfv-promise').invoke 'increase-capacity', source: provider capacity: cores: 20 ram: 51200 instances: 10 addresses: 10 .then (res) -> res.get('result').should.equal 'ok' pool = id: res.get('pool-id') done() .catch (err) -> done err it "should update promise.pools with a new entry", -> app.get('opnfv-promise.promise.pools').should.have.length(1) it "should contain a ResourcePool record in the store", -> assert pool?.id?, "unable to check without ID" pool = app.access('opnfv-promise').find('ResourcePool', pool.id) assert pool? # TC-03 describe "query-capacity", -> it "should report total collections and utilizations", (done) -> app.access('opnfv-promise').invoke 'query-capacity', capacity: 'total' .then (res) -> res.get('collections').should.be.Array res.get('collections').length.should.be.above(0) res.get('utilization').should.be.Array res.get('utilization').length.should.be.above(0) done() .catch (err) -> done err it "should contain newly added capacity pool", (done) -> app.access('opnfv-promise').invoke 'query-capacity', capacity: 'total' .then (res) -> res.get('collections').should.containEql "ResourcePool:#{pool.id}" done() .catch (err) -> done err # Test Scenario 02 describe "allocation without reservation", -> # TC-04 describe "create-instance", -> allocation = undefined instance_id = undefined before -> # XXX - need to determine image and flavor to use in the given provider for this test assert provider?, "unable to execute without registered 'provider'" it "should create a new server in target provider without error", (done) -> @timeout 5000 test = config.get 'openstack.test' app.access('opnfv-promise').invoke 'create-instance', 'provider-id': provider.id name: 'promise-test-no-reservation' image: test.image flavor: test.flavor networks: [ test.network ] .then (res) -> debug res.get() res.get('result').should.equal 'ok' instance_id = res.get('instance-id') done() .catch (err) -> done err it "should update promise.allocations with a new entry", -> app.get('opnfv-promise.promise.allocations').length.should.be.above(0) it "should contain a new ResourceAllocation record in the store", -> assert instance_id?, "unable to check without ID" allocation = app.access('opnfv-promise').find('ResourceAllocation', instance_id) assert allocation? it "should reference the created server ID from the provider", -> assert allocation?, "unable to check without record" allocation.get('instance-ref').should.have.property('provider') allocation.get('instance-ref').should.have.property('server') it "should have low priority state", -> assert allocation?, "unable to check without record" allocation.get('priority').should.equal 'low' # Test Scenario 03 describe "allocation using reservation for immediate use", -> reservation = undefined # TC-05 describe "create-reservation", -> it "should create reservation record (no start/end) without error", (done) -> app.access('opnfv-promise').invoke 'create-reservation', capacity: cores: 5 ram: 25600 addresses: 3 instances: 3 .then (res) -> res.get('result').should.equal 'ok' reservation = id: res.get('reservation-id') done() .catch (err) -> done err it "should update promise.reservations with a new entry", -> app.get('opnfv-promise.promise.reservations').length.should.be.above(0) it "should contain a new ResourceReservation record in the store", -> assert reservation?.id?, "unable to check without ID" reservation = app.access('opnfv-promise').find('ResourceReservation', reservation.id) assert reservation? # TC-06 describe "create-instance", -> allocation = undefined before -> assert provider?, "unable to execute without registered 'provider'" assert reservation?, "unable to execute without valid reservation record" it "should create a new server in target provider (with reservation) without error", (done) -> @timeout 5000 test = config.get 'openstack.test' app.access('opnfv-promise').invoke 'create-instance', 'provider-id': provider.id name: 'promise-test-reservation' image: test.image flavor: test.flavor networks: [ test.network ] 'reservation-id': reservation.id .then (res) -> debug res.get() res.get('result').should.equal 'ok' allocation = id: res.get('instance-id') done() .catch (err) -> done err it "should contain a new ResourceAllocation record in the store", -> assert allocation?.id?, "unable to check without ID" allocation = app.access('opnfv-promise').find('ResourceAllocation', allocation.id) assert allocation? it "should be referenced in the reservation record", -> assert reservation? and allocation?, "unable to check without records" reservation.get('allocations').should.containEql allocation.id it "should have high priority state", -> assert allocation?, "unable to check without record" allocation.get('priority').should.equal 'high' # Test Scenario 04 describe "reservation for future use", -> reservation = undefined start = new Date end = new Date # 7 days in the future start.setTime (start.getTime() + 7*60*60*1000) # 8 days in the future end.setTime (end.getTime() + 8*60*60*1000) # TC-07 describe "create-reservation", -> it "should create reservation record (for future) without error", (done) -> app.access('opnfv-promise').invoke 'create-reservation', start: start.toJSON() end: end.toJSON() capacity: cores: 1 ram: 12800 addresses: 1 instances: 1 .then (res) -> res.get('result').should.equal 'ok' reservation = id: res.get('reservation-id') done() .catch (err) -> done err it "should update promise.reservations with a new entry", -> app.get('opnfv-promise.promise.reservations').length.should.be.above(0) it "should contain a new ResourceReservation record in the store", -> assert reservation?.id?, "unable to check without ID" reservation = app.access('opnfv-promise').find('ResourceReservation', reservation.id) assert reservation? # TC-08 describe "query-reservation", -> it "should contain newly created future reservation", (done) -> app.access('opnfv-promise').invoke 'query-reservation', window: start: start.toJSON() end: end.toJSON() .then (res) -> res.get('reservations').should.containEql reservation.id done() .catch (err) -> done err # TC-09 describe "update-reservation", -> it "should modify existing reservation without error", (done) -> app.access('opnfv-promise').invoke 'update-reservation', 'reservation-id': reservation.id capacity: cores: 3 ram: 12800 addresses: 2 instances: 2 .then (res) -> res.get('result').should.equal 'ok' done() .catch (err) -> done err # TC-10 describe "cancel-reservation", -> it "should modify existing reservation without error", (done) -> app.access('opnfv-promise').invoke 'cancel-reservation', 'reservation-id': reservation.id .then (res) -> res.get('result').should.equal 'ok' done() .catch (err) -> done err it "should no longer contain record of the deleted reservation", -> assert reservation?.id?, "unable to check without ID" reservation = app.access('opnfv-promise').find('ResourceReservation', reservation.id) assert not reservation? # Test Scenario 05 describe "capacity planning", -> # TC-11 describe "decrease-capacity", -> start = new Date end = new Date # 30 days in the future start.setTime (start.getTime() + 30*60*60*1000) # 45 days in the future end.setTime (end.getTime() + 45*60*60*1000) it "should decrease available capacity from a provider in the future", (done) -> app.access('opnfv-promise').invoke 'decrease-capacity', source: provider capacity: cores: 5 ram: 17920 instances: 5 start: start.toJSON() end: end.toJSON() .then (res) -> res.get('result').should.equal 'ok' done() .catch (err) -> done err # TC-12 describe "increase-capacity", -> start = new Date end = new Date # 14 days in the future start.setTime (start.getTime() + 14*60*60*1000) # 21 days in the future end.setTime (end.getTime() + 21*60*60*1000) it "should increase available capacity from a provider in the future", (done) -> app.access('opnfv-promise').invoke 'decrease-capacity', source: provider capacity: cores: 1 ram: 3584 instances: 1 start: start.toJSON() end: end.toJSON() .then (res) -> res.get('result').should.equal 'ok' done() .catch (err) -> done err # TC-13 (Should improve this TC) describe "query-capacity", -> it "should report available collections and utilizations", (done) -> app.access('opnfv-promise').invoke 'query-capacity', capacity: 'available' .then (res) -> res.get('collections').should.be.Array res.get('collections').length.should.be.above(0) res.get('utilization').should.be.Array res.get('utilization').length.should.be.above(0) done() .catch (err) -> done err # Test Scenario 06 describe "reservation with conflict", -> # TC-14 describe "create-reservation", -> it "should fail to create immediate reservation record with proper error", (done) -> app.access('opnfv-promise').invoke 'create-reservation', capacity: cores: 5 ram: 17920 instances: 10 .then (res) -> res.get('result').should.equal 'conflict' done() .catch (err) -> done err it "should fail to create future reservation record with proper error", (done) -> start = new Date # 30 days in the future start.setTime (start.getTime() + 30*60*60*1000) app.access('opnfv-promise').invoke 'create-reservation', capacity: cores: 5 ram: 17920 instances: 10 start: start.toJSON() .then (res) -> res.get('result').should.equal 'conflict' done() .catch (err) -> done err # Test Scenario 07 describe "cleanup test allocations", -> allocations = undefined before -> allocations = app.get('opnfv-promise.promise.allocations') debug provider.get() debug allocations allocations.length.should.be.above(0) describe "destroy-instance", -> it "should successfully destroy all allocations", (done) -> @timeout 5000 promises = allocations.map (x) -> app.access('opnfv-promise').invoke 'destroy-instance', 'instance-id': x.id promise.all promises .then (res) -> res.forEach (x) -> debug x.get() x.get('result').should.equal 'ok' done() .catch (err) -> done err