2 # Author: Peter K. Lee (peter@corenova.com)
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 config = require 'config'
10 assert = require 'assert'
11 forge = require 'yangforge'
12 app = forge.load '!yaml ../promise.yaml', async: false, pkgdir: __dirname
14 # this is javascript promise framework and not related to opnfv-promise
15 promise = require 'promise'
22 # in the future with YF 0.12.x
23 # app = forge.load('..').build('test')
25 # app.use 'proxy', target: x.x.x.x:5050, interface: 'restjson'
27 describe "promise", ->
29 # ensure we have valid OpenStack environment to test against
31 config.get 'openstack.auth.endpoint'
33 throw new Error "missing OpenStack environmental variables"
36 # below 'provider' is used across test suites
39 # Test Scenario 00 (FUTURE)
40 # describe "prepare OpenStack for testing", ->
42 # # ensure we have valid OpenStack environment to test against
44 # config.get 'openstack.auth.url'
46 # throw new Error "missing OpenStack environmental variables"
48 # os = forge.load '!yaml ../openstack.yaml', async: false, pkgdir: __dirname
49 # app.attach 'openstack', os.access 'openstack'
52 # describe "authenticate", ->
53 # it "should retrieve available service catalog", (done) ->
54 # app.access('openstack').invoke 'authenticate'
58 # .catch (err) -> done err
60 # describe "create-tenant", ->
61 # # create a new tenant for testing purposes
63 # describe "upload-image", ->
64 # # upload a new test image
69 describe "register OpenStack into resource pool", ->
73 describe "add-provider", ->
74 it "should add a new OpenStack provider without error", (done) ->
77 auth = config.get 'openstack.auth'
78 auth['provider-type'] = 'openstack'
80 app.access('opnfv-promise').invoke 'add-provider', auth
82 res.get('result').should.equal 'ok'
83 provider = id: res.get('provider-id')
84 # HACK - we delay by a second to allow time for discovering capacity and flavors
86 .catch (err) -> done err
88 it "should update promise.providers with a new entry", ->
89 app.get('opnfv-promise.promise.providers').should.have.length(1)
91 it "should contain a new ResourceProvider record in the store", ->
92 assert provider?.id?, "unable to check without ID"
93 provider = app.access('opnfv-promise').find('ResourceProvider', provider.id)
97 describe "increase-capacity", ->
98 it "should add more capacity to the reservation service without error", (done) ->
99 app.access('opnfv-promise').invoke 'increase-capacity',
107 res.get('result').should.equal 'ok'
108 pool = id: res.get('pool-id')
110 .catch (err) -> done err
112 it "should update promise.pools with a new entry", ->
113 app.get('opnfv-promise.promise.pools').should.have.length(1)
115 it "should contain a ResourcePool record in the store", ->
116 assert pool?.id?, "unable to check without ID"
117 pool = app.access('opnfv-promise').find('ResourcePool', pool.id)
121 describe "query-capacity", ->
122 it "should report total collections and utilizations", (done) ->
123 app.access('opnfv-promise').invoke 'query-capacity',
126 res.get('collections').should.be.Array
127 res.get('collections').length.should.be.above(0)
128 res.get('utilization').should.be.Array
129 res.get('utilization').length.should.be.above(0)
131 .catch (err) -> done err
133 it "should contain newly added capacity pool", (done) ->
134 app.access('opnfv-promise').invoke 'query-capacity',
137 res.get('collections').should.containEql "ResourcePool:#{pool.id}"
139 .catch (err) -> done err
142 describe "allocation without reservation", ->
145 describe "create-instance", ->
146 allocation = undefined
147 instance_id = undefined
150 # XXX - need to determine image and flavor to use in the given provider for this test
152 "unable to execute without registered 'provider'"
154 it "should create a new server in target provider without error", (done) ->
156 test = config.get 'openstack.test'
157 app.access('opnfv-promise').invoke 'create-instance',
158 'provider-id': provider.id
159 name: 'promise-test-no-reservation'
162 networks: [ test.network ]
165 res.get('result').should.equal 'ok'
166 instance_id = res.get('instance-id')
168 .catch (err) -> done err
170 it "should update promise.allocations with a new entry", ->
171 app.get('opnfv-promise.promise.allocations').length.should.be.above(0)
173 it "should contain a new ResourceAllocation record in the store", ->
174 assert instance_id?, "unable to check without ID"
175 allocation = app.access('opnfv-promise').find('ResourceAllocation', instance_id)
178 it "should reference the created server ID from the provider", ->
179 assert allocation?, "unable to check without record"
180 allocation.get('instance-ref').should.have.property('provider')
181 allocation.get('instance-ref').should.have.property('server')
183 it "should have low priority state", ->
184 assert allocation?, "unable to check without record"
185 allocation.get('priority').should.equal 'low'
188 describe "allocation using reservation for immediate use", ->
189 reservation = undefined
192 describe "create-reservation", ->
193 it "should create reservation record (no start/end) without error", (done) ->
194 app.access('opnfv-promise').invoke 'create-reservation',
201 res.get('result').should.equal 'ok'
202 reservation = id: res.get('reservation-id')
204 .catch (err) -> done err
206 it "should update promise.reservations with a new entry", ->
207 app.get('opnfv-promise.promise.reservations').length.should.be.above(0)
209 it "should contain a new ResourceReservation record in the store", ->
210 assert reservation?.id?, "unable to check without ID"
211 reservation = app.access('opnfv-promise').find('ResourceReservation', reservation.id)
215 describe "create-instance", ->
216 allocation = undefined
220 "unable to execute without registered 'provider'"
222 "unable to execute without valid reservation record"
224 it "should create a new server in target provider (with reservation) without error", (done) ->
226 test = config.get 'openstack.test'
227 app.access('opnfv-promise').invoke 'create-instance',
228 'provider-id': provider.id
229 name: 'promise-test-reservation'
232 networks: [ test.network ]
233 'reservation-id': reservation.id
236 res.get('result').should.equal 'ok'
237 allocation = id: res.get('instance-id')
239 .catch (err) -> done err
241 it "should contain a new ResourceAllocation record in the store", ->
242 assert allocation?.id?, "unable to check without ID"
243 allocation = app.access('opnfv-promise').find('ResourceAllocation', allocation.id)
246 it "should be referenced in the reservation record", ->
247 assert reservation? and allocation?, "unable to check without records"
248 reservation.get('allocations').should.containEql allocation.id
250 it "should have high priority state", ->
251 assert allocation?, "unable to check without record"
252 allocation.get('priority').should.equal 'high'
255 describe "reservation for future use", ->
256 reservation = undefined
259 # 7 days in the future
260 start.setTime (start.getTime() + 7*60*60*1000)
261 # 8 days in the future
262 end.setTime (end.getTime() + 8*60*60*1000)
265 describe "create-reservation", ->
266 it "should create reservation record (for future) without error", (done) ->
267 app.access('opnfv-promise').invoke 'create-reservation',
268 start: start.toJSON()
276 res.get('result').should.equal 'ok'
277 reservation = id: res.get('reservation-id')
279 .catch (err) -> done err
281 it "should update promise.reservations with a new entry", ->
282 app.get('opnfv-promise.promise.reservations').length.should.be.above(0)
284 it "should contain a new ResourceReservation record in the store", ->
285 assert reservation?.id?, "unable to check without ID"
286 reservation = app.access('opnfv-promise').find('ResourceReservation', reservation.id)
290 describe "query-reservation", ->
291 it "should contain newly created future reservation", (done) ->
292 app.access('opnfv-promise').invoke 'query-reservation',
294 start: start.toJSON()
297 res.get('reservations').should.containEql reservation.id
299 .catch (err) -> done err
302 describe "update-reservation", ->
303 it "should modify existing reservation without error", (done) ->
304 app.access('opnfv-promise').invoke 'update-reservation',
305 'reservation-id': reservation.id
312 res.get('result').should.equal 'ok'
314 .catch (err) -> done err
317 describe "cancel-reservation", ->
318 it "should modify existing reservation without error", (done) ->
319 app.access('opnfv-promise').invoke 'cancel-reservation',
320 'reservation-id': reservation.id
322 res.get('result').should.equal 'ok'
324 .catch (err) -> done err
326 it "should no longer contain record of the deleted reservation", ->
327 assert reservation?.id?, "unable to check without ID"
328 reservation = app.access('opnfv-promise').find('ResourceReservation', reservation.id)
329 assert not reservation?
332 describe "capacity planning", ->
335 describe "decrease-capacity", ->
338 # 30 days in the future
339 start.setTime (start.getTime() + 30*60*60*1000)
340 # 45 days in the future
341 end.setTime (end.getTime() + 45*60*60*1000)
343 it "should decrease available capacity from a provider in the future", (done) ->
344 app.access('opnfv-promise').invoke 'decrease-capacity',
350 start: start.toJSON()
353 res.get('result').should.equal 'ok'
355 .catch (err) -> done err
358 describe "increase-capacity", ->
361 # 14 days in the future
362 start.setTime (start.getTime() + 14*60*60*1000)
363 # 21 days in the future
364 end.setTime (end.getTime() + 21*60*60*1000)
366 it "should increase available capacity from a provider in the future", (done) ->
367 app.access('opnfv-promise').invoke 'decrease-capacity',
373 start: start.toJSON()
376 res.get('result').should.equal 'ok'
378 .catch (err) -> done err
380 # TC-13 (Should improve this TC)
381 describe "query-capacity", ->
382 it "should report available collections and utilizations", (done) ->
383 app.access('opnfv-promise').invoke 'query-capacity',
384 capacity: 'available'
386 res.get('collections').should.be.Array
387 res.get('collections').length.should.be.above(0)
388 res.get('utilization').should.be.Array
389 res.get('utilization').length.should.be.above(0)
391 .catch (err) -> done err
394 describe "reservation with conflict", ->
396 describe "create-reservation", ->
397 it "should fail to create immediate reservation record with proper error", (done) ->
398 app.access('opnfv-promise').invoke 'create-reservation',
404 res.get('result').should.equal 'conflict'
406 .catch (err) -> done err
408 it "should fail to create future reservation record with proper error", (done) ->
410 # 30 days in the future
411 start.setTime (start.getTime() + 30*60*60*1000)
413 app.access('opnfv-promise').invoke 'create-reservation',
418 start: start.toJSON()
420 res.get('result').should.equal 'conflict'
422 .catch (err) -> done err
425 describe "cleanup test allocations", ->
426 allocations = undefined
428 allocations = app.get('opnfv-promise.promise.allocations')
431 allocations.length.should.be.above(0)
433 describe "destroy-instance", ->
434 it "should successfully destroy all allocations", (done) ->
436 promises = allocations.map (x) ->
437 app.access('opnfv-promise').invoke 'destroy-instance',
443 x.get('result').should.equal 'ok'
445 .catch (err) -> done err