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