db7e8d6eb49336c9273717754aaf4a7331082bfc
[promise.git] / deprecated / source / test / promise-intents.coffee
1 #
2 # Author: Peter K. Lee (peter@corenova.com)
3 #
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
8 #
9 config = require 'config'
10 assert = require 'assert'
11 forge  = require 'yangforge'
12 app = forge.load '!yaml ../promise.yaml', async: false, pkgdir: __dirname
13
14 # this is javascript promise framework and not related to opnfv-promise
15 promise = require 'promise'
16
17 if process.env.DEBUG
18   debug = console.log
19 else
20   debug = ->
21
22 # in the future with YF 0.12.x
23 # app = forge.load('..').build('test')
24 # app.set config
25 # app.use 'proxy', target: x.x.x.x:5050, interface: 'restjson'
26
27 describe "promise", ->
28   before ->
29     # ensure we have valid OpenStack environment to test against
30     try
31       config.get 'openstack.auth.endpoint'
32     catch e
33       throw new Error "missing OpenStack environmental variables"
34
35
36   # below 'provider' is used across test suites
37   provider = undefined
38
39   # Test Scenario 00 (FUTURE)
40   # describe "prepare OpenStack for testing", ->
41   #   before (done) ->
42   #     # ensure we have valid OpenStack environment to test against
43   #     try
44   #       config.get 'openstack.auth.url'
45   #     catch e
46   #       throw new Error "missing OpenStack environmental variables"
47
48   #     os = forge.load '!yaml ../openstack.yaml', async: false, pkgdir: __dirname
49   #     app.attach 'openstack', os.access 'openstack'
50   #     app.set config
51
52   #   describe "authenticate", ->
53   #     it "should retrieve available service catalog", (done) ->
54   #       app.access('openstack').invoke 'authenticate'
55   #       .then (res) ->
56
57   #         done()
58   #       .catch (err) -> done err
59
60   #   describe "create-tenant", ->
61   #     # create a new tenant for testing purposes
62
63   #   describe "upload-image", ->
64   #     # upload a new test image
65
66
67
68   # Test Scenario 01
69   describe "register OpenStack into resource pool", ->
70     pool = undefined
71
72     # TC-01
73     describe "add-provider", ->
74       it "should add a new OpenStack provider without error", (done) ->
75         @timeout 5000
76
77         auth = config.get 'openstack.auth'
78         auth['provider-type'] = 'openstack'
79
80         app.access('opnfv-promise').invoke 'add-provider', auth
81         .then (res) ->
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
85           setTimeout done, 1000
86         .catch (err) -> done err
87
88       it "should update promise.providers with a new entry", ->
89         app.get('opnfv-promise.promise.providers').should.have.length(1)
90
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)
94         assert provider?
95
96     # TC-02
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',
100           source: provider
101           capacity:
102             cores: 20
103             ram: 51200
104             instances: 10
105             addresses: 10
106         .then (res) ->
107           res.get('result').should.equal 'ok'
108           pool = id: res.get('pool-id')
109           done()
110         .catch (err) -> done err
111
112       it "should update promise.pools with a new entry", ->
113         app.get('opnfv-promise.promise.pools').should.have.length(1)
114
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)
118         assert pool?
119
120     # TC-03
121     describe "query-capacity", ->
122       it "should report total collections and utilizations", (done) ->
123         app.access('opnfv-promise').invoke 'query-capacity',
124           capacity: 'total'
125         .then (res) ->
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)
130           done()
131         .catch (err) -> done err
132
133       it "should contain newly added capacity pool", (done) ->
134         app.access('opnfv-promise').invoke 'query-capacity',
135           capacity: 'total'
136         .then (res) ->
137           res.get('collections').should.containEql "ResourcePool:#{pool.id}"
138           done()
139         .catch (err) -> done err
140
141   # Test Scenario 02
142   describe "allocation without reservation", ->
143
144     # TC-04
145     describe "create-instance", ->
146       allocation = undefined
147       instance_id = undefined
148
149       before ->
150         # XXX - need to determine image and flavor to use in the given provider for this test
151         assert provider?,
152           "unable to execute without registered 'provider'"
153
154       it "should create a new server in target provider without error", (done) ->
155         @timeout 5000
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'
160           image:   test.image
161           flavor:  test.flavor
162           networks: [ test.network ]
163         .then (res) ->
164           debug res.get()
165           res.get('result').should.equal 'ok'
166           instance_id = res.get('instance-id')
167           done()
168         .catch (err) -> done err
169
170       it "should update promise.allocations with a new entry", ->
171         app.get('opnfv-promise.promise.allocations').length.should.be.above(0)
172
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)
176         assert allocation?
177
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')
182
183       it "should have low priority state", ->
184         assert allocation?, "unable to check without record"
185         allocation.get('priority').should.equal 'low'
186
187   # Test Scenario 03
188   describe "allocation using reservation for immediate use", ->
189     reservation = undefined
190
191     # TC-05
192     describe "create-reservation", ->
193       it "should create reservation record (no start/end) without error", (done) ->
194         app.access('opnfv-promise').invoke 'create-reservation',
195           capacity:
196             cores: 5
197             ram: 25600
198             addresses: 3
199             instances: 3
200         .then (res) ->
201           res.get('result').should.equal 'ok'
202           reservation = id: res.get('reservation-id')
203           done()
204         .catch (err) -> done err
205
206       it "should update promise.reservations with a new entry", ->
207         app.get('opnfv-promise.promise.reservations').length.should.be.above(0)
208
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)
212         assert reservation?
213
214     # TC-06
215     describe "create-instance", ->
216       allocation = undefined
217
218       before ->
219         assert provider?,
220           "unable to execute without registered 'provider'"
221         assert reservation?,
222           "unable to execute without valid reservation record"
223
224       it "should create a new server in target provider (with reservation) without error", (done) ->
225         @timeout 5000
226         test = config.get 'openstack.test'
227         app.access('opnfv-promise').invoke 'create-instance',
228           'provider-id': provider.id
229           name: 'promise-test-reservation'
230           image:  test.image
231           flavor: test.flavor
232           networks: [ test.network ]
233           'reservation-id': reservation.id
234         .then (res) ->
235           debug res.get()
236           res.get('result').should.equal 'ok'
237           allocation = id: res.get('instance-id')
238           done()
239         .catch (err) -> done err
240
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)
244         assert allocation?
245
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
249
250       it "should have high priority state", ->
251         assert allocation?, "unable to check without record"
252         allocation.get('priority').should.equal 'high'
253
254   # Test Scenario 04
255   describe "reservation for future use", ->
256     reservation = undefined
257     start = new Date
258     end   = new Date
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)
263
264     # TC-07
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()
269           end: end.toJSON()
270           capacity:
271             cores: 1
272             ram: 12800
273             addresses: 1
274             instances: 1
275         .then (res) ->
276           res.get('result').should.equal 'ok'
277           reservation = id: res.get('reservation-id')
278           done()
279         .catch (err) -> done err
280
281       it "should update promise.reservations with a new entry", ->
282         app.get('opnfv-promise.promise.reservations').length.should.be.above(0)
283
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)
287         assert reservation?
288
289     # TC-08
290     describe "query-reservation", ->
291       it "should contain newly created future reservation", (done) ->
292         app.access('opnfv-promise').invoke 'query-reservation',
293           window:
294             start: start.toJSON()
295             end: end.toJSON()
296         .then (res) ->
297           res.get('reservations').should.containEql reservation.id
298           done()
299         .catch (err) -> done err
300
301     # TC-09
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
306           capacity:
307             cores: 3
308             ram: 12800
309             addresses: 2
310             instances: 2
311         .then (res) ->
312           res.get('result').should.equal 'ok'
313           done()
314         .catch (err) -> done err
315
316     # TC-10
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
321         .then (res) ->
322           res.get('result').should.equal 'ok'
323           done()
324         .catch (err) -> done err
325
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?
330
331   # Test Scenario 05
332   describe "capacity planning", ->
333
334     # TC-11
335     describe "decrease-capacity", ->
336       start = new Date
337       end   = new Date
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)
342
343       it "should decrease available capacity from a provider in the future", (done) ->
344         app.access('opnfv-promise').invoke 'decrease-capacity',
345           source: provider
346           capacity:
347             cores: 5
348             ram: 17920
349             instances: 5
350           start: start.toJSON()
351           end: end.toJSON()
352         .then (res) ->
353           res.get('result').should.equal 'ok'
354           done()
355         .catch (err) -> done err
356
357     # TC-12
358     describe "increase-capacity", ->
359       start = new Date
360       end   = new Date
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)
365
366       it "should increase available capacity from a provider in the future", (done) ->
367         app.access('opnfv-promise').invoke 'decrease-capacity',
368           source: provider
369           capacity:
370             cores: 1
371             ram: 3584
372             instances: 1
373           start: start.toJSON()
374           end: end.toJSON()
375         .then (res) ->
376           res.get('result').should.equal 'ok'
377           done()
378         .catch (err) -> done err
379
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'
385         .then (res) ->
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)
390           done()
391         .catch (err) -> done err
392
393   # Test Scenario 06
394   describe "reservation with conflict", ->
395     # TC-14
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',
399           capacity:
400             cores: 5
401             ram: 17920
402             instances: 10
403         .then (res) ->
404           res.get('result').should.equal 'conflict'
405           done()
406         .catch (err) -> done err
407
408       it "should fail to create future reservation record with proper error", (done) ->
409         start = new Date
410         # 30 days in the future
411         start.setTime (start.getTime() + 30*60*60*1000)
412
413         app.access('opnfv-promise').invoke 'create-reservation',
414           capacity:
415             cores: 5
416             ram: 17920
417             instances: 10
418           start: start.toJSON()
419         .then (res) ->
420           res.get('result').should.equal 'conflict'
421           done()
422         .catch (err) -> done err
423
424   # Test Scenario 07
425   describe "cleanup test allocations", ->
426     allocations = undefined
427     before ->
428       allocations = app.get('opnfv-promise.promise.allocations')
429       debug provider.get()
430       debug allocations
431       allocations.length.should.be.above(0)
432
433     describe "destroy-instance", ->
434       it "should successfully destroy all allocations", (done) ->
435         @timeout 5000
436         promises = allocations.map (x) ->
437           app.access('opnfv-promise').invoke 'destroy-instance',
438             'instance-id': x.id
439         promise.all promises
440         .then (res) ->
441           res.forEach (x) ->
442             debug x.get()
443             x.get('result').should.equal 'ok'
444           done()
445         .catch (err) -> done err