Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / tests.js @ 101e6604

History | View | Annotate | Download (14.1 kB)

1
$(document).ready(function(){
2

    
3
    // shortcuts
4
    snf = synnefo;
5
    models = snf.models;
6
    util = snf.utils;
7
    views = snf.views;
8
    bb = Backbone;
9
    vms = snf.storage.vms;
10
    nets = snf.storage.networks;
11

    
12
    module("VM Model")
13

    
14
    test("model change events", function(){
15
        expect(8);
16

    
17
        synnefo.storage.images.add({id:1,metadata:{values:{size:100}}});
18
        var v1 = new models.VM({'imageRef':1});
19
        v1.bind("change", function(){
20
            ok(1, "change event triggered")
21
            equals(v1.get("status"), "BUILD")
22
            equals(v1.get("state"), "BUILD_COPY")
23
        })
24
        v1.set({'status':'BUILD', 'progress':80, 'imageRef': 1});
25
        v1.unbind();
26

    
27
        v1.bind("change", function(){
28
            ok(1, "change event triggered")
29
            equals(v1.get("status"), "BUILD")
30
            equals(v1.get("state"), "DESTROY")
31
        })
32
        v1.set({'state':'DESTROY'});
33
        v1.unbind();
34

    
35
        v1.bind("change", function() {
36
            ok(1, "change event triggered")
37
            equals(v1.get("status"), "BUILD")
38
            equals(v1.get("state"), "BUILD_COPY")
39
        })
40
        v1.set({'status':'BUILD', 'progress':80, 'imageRef': 1});
41
        equals(v1.get("status"), "BUILD")
42
        equals(v1.get("state"), "DESTROY")
43
        v1.unbind();
44
    })
45

    
46
    test("model state transitions", function(){
47
        var vm = models.VM;
48
        
49
        var v1 = new vm();
50
        v1.set({status: 'BUILD_COPY'})
51
        equals(v1.get("state"), 'BUILD_COPY', "State is set");
52
        v1.set({status: 'DESTROY'})
53
        equals(v1.get("state"), 'DESTROY', "From buld to destroy");
54
        v1.set({status: 'BUILD'})
55
        equals(v1.get("state"), 'DESTROY', "Keep destroy state");
56

    
57
        v1 = new vm();
58
        v1.set({status: 'ACTIVE'})
59
        equals(v1.get("state"), 'ACTIVE', "State is set");
60

    
61
        v1.set({status: 'SHUTDOWN'})
62
        equals(v1.get("state"), 'SHUTDOWN', "From active to shutdown (should change)");
63

    
64
        v1.set({status: 'ACTIVE'})
65
        equals(v1.get("state"), 'SHUTDOWN', "From shutdown to active (should not change)");
66
        
67
        v1.set({status: 'STOPPED'})
68
        equals(v1.get("state"), 'STOPPED', "From shutdown to stopped (should change)");
69

    
70
        v1.set({status: 'ACTIVE'})
71
        equals(v1.get("state"), 'ACTIVE', "From stopped to active (should change)");
72
        v1.set({'status': 'STOPPED'})
73
        equals(v1.get('state'), 'STOPPED', "From shutdown to stopped should change");
74

    
75
        v1.set({'status': 'DESTROY'})
76
        equals(v1.get('state'), 'DESTROY', "From stopped to destory should set state to DESTROY");
77
        v1.set({'status': 'ACTIVE'})
78
        equals(v1.get('state'), 'DESTROY', "From destroy to active should keep state to DESTROY");
79
        v1.set({'status': 'REBOOT'})
80
        equals(v1.get('state'), 'DESTROY', "From destroy to active should keep state to DESTROY");
81
        v1.set({'status': 'DELETED'})
82
        equals(v1.get('state'), 'DELETED', "Destroy should be kept until DELETE or ERROR");
83

    
84
        v1 = new vm({status:'BUILD'});
85
        equals(v1.get('state'), 'BUILD', "new vm with build as initial status")
86
        equals(v1.get('status'), 'BUILD', "new vm with build as initial status")
87
        v1.set({status:'ACTIVE'})
88
        equals(v1.get('state'), 'ACTIVE', "active state has been set")
89
        equals(v1.get('status'), 'ACTIVE', "active status has been set")
90
    })
91

    
92

    
93
    test("building states", function(){
94
        synnefo.storage.images.add({id:1,metadata:{values:{size:100}}});
95
        var vm = models.VM;
96
        var v1 = new vm({'status':'BUILD','progress':0, 'imageRef':1});
97
        equals(v1.get('state'), 'BUILD_INIT', "progress 0 sets state to BUILD_INIT");
98
        equals(v1.get('status'), 'BUILD', "progress 0 sets status to BUILD");
99
        equals(v1.get('progress_message'), 'init', "message 'init'");
100
        v1.set({status:'BUILD', progress:50});
101
        equals(v1.get('state'), 'BUILD_COPY', "progress 50 sets state to BUILD_COPY");
102
        equals(v1.get('status'), 'BUILD', "progress 50 sets status to BUILD");
103
        equals(v1.get('progress_message'), '50.00 MB, 100.00 MB, 50', "message: 'final'");
104
        v1.set({status:'BUILD', progress:100});
105
        equals(v1.get('state'), 'BUILD_FINAL', "progress 100 sets state to BUILD_FINAL");
106
        equals(v1.get('status'), 'BUILD', "progress 100 sets status to BUILD");
107
        v1.set({status:'ACTIVE', progress:100});
108
        equals(v1.get('state'), 'ACTIVE', "ACTIVE set transition to ACTIVE");
109
        equals(v1.get('status'), 'ACTIVE', "ACTIVE set transition to ACTIVE");
110
        equals(v1.get('progress_message'), 'final', "message: 'final'");
111
    })
112

    
113
    test("active inactive states", function(){
114
    
115
        var vm = models.VM;
116
        var v1 = new vm();
117
        var v = {}
118
        var active = ['ACTIVE', 'BUILD', 'REBOOT'];
119
        for (v in active) {
120
            v = active[v];
121
            v1.set({status: v})
122
            equals(v1.is_active(), true, v + " status is active")
123
        }
124
        
125
        var v1 = new vm();
126
        var inactive = ['STOPPED', 'ERROR', 'UNKNOWN'];
127
        for (v in inactive) {
128
            v = inactive[v];
129
            v1.set({status: v})
130
            equals(v1.is_active(), false, v1.state() + " status is not active")
131
        }
132
    
133
    })
134

    
135
    test("transition event", function(){
136
        expect(9);
137

    
138
        var vm = new models.VM({status:'BUILD'});
139
        vm.bind("transition", function(data) {
140
            ok(true, "Transition triggered");
141
            equals(data.from, "BUILD")
142
            equals(data.to, "ACTIVE");
143
        })
144
        // trigger 1 time
145
        vm.set({status:'BUILD'});
146
        vm.set({status:'ACTIVE'});
147
        vm.unbind();
148
        
149
        // from build to active
150
        vm = new models.VM({status:'BUILD'});
151
        vm.bind("transition", function(data) {
152
            ok(true, "Transition triggered");
153
            equals(data.from, "BUILD")
154
            equals(data.to, "ACTIVE");
155
        })
156
        // trigger 1 time
157
        vm.set({status:'ACTIVE'});
158
        vm.unbind();
159

    
160
        // from active to shutdown
161
        vm = new models.VM({status:'SHUTDOWN'});
162
        vm.bind("transition", function(data) {
163
            ok(true, "Transition triggered");
164
            equals(data.from, "SHUTDOWN")
165
            equals(data.to, "STOPPED");
166
        })
167
        // trigger 1 time
168
        vm.set({status:'STOPPED'});
169
    })
170
    
171
    module("Collections");
172
        
173
    test("status model remove events", function(){
174
        vms.unbind();
175
        expect(1)
176

    
177
        vms.bind("change", function(){
178
            ok(-1, "change event should not get triggered");
179
        })
180

    
181
        vms.bind("remove", function(){
182
            ok(1, "remove event triggered")
183
        })
184

    
185
        var vm = new models.VM({id:1, status:"ACTIVE", name:"oldname"});
186
        vms.add(vm);
187
        
188
        // NO change/delete just DELETE event triggered
189
        vms.update([{id:1, status:"DELETED", name:"newname"}])
190
    });
191

    
192
    test("collection reset events", function() {
193
        expect(9);
194

    
195
        var testCollection = models.Collection.extend({
196
            url: '/testObject'
197
        });
198
        var collection = new testCollection();
199

    
200
        
201
        // reset on new entry after empty
202
        $.mockjax({
203
            url: '/testObject',
204
            responseTime: 50,
205
            responseText: [
206
                {id:1, attr1: 1, attr2: 2}
207
            ]
208
        }); 
209
        // THIS SHOULD NOT FIRE, since we force update method
210
        collection.bind("reset", function() {
211
            ok(1, "NOT EXPECTED: reset triggered on new entry while collection was empty");
212
        });
213
        collection.bind("add", function() {
214
            ok(1, "1: add triggered on new entry while collection was empty");
215
        });
216
        // THIS SHOULD NOT FIRE, model was added, not changed
217
        collection.bind("change", function() {
218
            ok(1, "NOT EXPECTED: change triggered on new entry while collection was empty");
219
        });
220
        collection.fetch({'async': false});
221
        equals(collection.length, 1, "2: collection contains 1 model");
222
        collection.unbind();
223
        $.mockjaxClear();
224
        
225
        // reset is called on change
226
        $.mockjax({
227
            url: '/testObject',
228
            responseTime: 50,
229
            responseText: [
230
                {id:1, attr1: 4, attr2: 2}
231
            ]
232
        });
233
        collection.bind("reset", function() {
234
            ok(1, "NOT EXPECTED: reset triggered on new entry while collection was empty");
235
        });
236
        collection.bind("add", function() {
237
            ok(1, "NOT EXPECTED: add triggered on new entry while collection was empty");
238
        });
239
        // THIS SHOULD NOT FIRE, model was added, not changed
240
        collection.bind("change", function() {
241
            ok(1, "3: change triggered on new entry while collection was empty");
242
        });
243
        collection.fetch({'async': false, refresh:true});
244
        equals(collection.length, 1, "4 collection contains 1 model");
245
        collection.unbind();
246
        $.mockjaxClear();
247

    
248
        // reset on second entry
249
        $.mockjax({
250
            url: '/testObject',
251
            responseTime: 50,
252
            responseText: [
253
                {id:1, attr1: 4, attr2: 2},
254
                {id:2, attr1: 1, attr2: 2}
255
            ]
256
        });
257
        collection.bind("reset", function() {
258
            ok(1, "NOT EXPECTED: reset triggered when new model arrived");
259
        })
260
        collection.bind("add", function() {
261
            ok(1, "5: add triggered when new model arrived");
262
        })
263
        collection.bind("change", function() {
264
            ok(1, "NOT EXPECTED: change triggered when new model arrived");
265
        }) 
266
        collection.fetch({async:false, refresh:true});
267
        equals(collection.length, 2, "6 new model added");
268
        collection.unbind();
269
        $.mockjaxClear();
270
        
271
        // reset does not remove
272
        $.mockjax({
273
            url: '/testObject',
274
            responseTime: 50,
275
            responseText: [
276
                {id:2, attr1: 1, attr2: 2}
277
            ]
278
        }); 
279
        collection.bind("reset", function() {
280
            ok(1, "NOT EXPECTED: reset triggered when model removed");
281
        })
282
        collection.bind("remove", function() {
283
            ok(1, "7: remove triggered when model removed");
284
        })
285
        collection.bind("change", function() {
286
            ok(1, "NOT EXPECTED: change triggered when model removed");
287
        })
288

    
289
        collection.fetch({async:false, refresh:true});
290
        equals(collection.length, 1, "8 one model removed");
291
        collection.unbind();
292
        $.mockjaxClear();
293

    
294
        // reset is not called on 304
295
        $.mockjax({
296
            url: '/testObject',
297
            responseTime: 50,
298
            status: 304,
299
            responseText: undefined
300
        }); 
301
        // NO event is triggered on 304
302
        collection.bind("reset", function() {
303
            ok(1, "WRONG: reset triggered on 304");
304
        });
305
        collection.bind("remove", function() {
306
            ok(1, "WRONG: remove triggered on 304");
307
        });
308
        collection.bind("change", function() {
309
            ok(1, "WRONG: remove triggered on 304");
310
        });
311
        collection.fetch({async:false, refresh:true});
312
        equals(collection.length, 1, "9 one model removed");
313
        collection.unbind();
314
        $.mockjaxClear();
315
    })
316

    
317

    
318
    module("network vm connections")
319
    test("network vm connections", function() {
320

    
321
        function _net(id, ip) {
322
            return {
323
                id: id,
324
                name: "net " + id,
325
                values:[{version:4, addr: ip}, {version:6, addr:ip}] 
326
            }
327
        }
328
        vms.add({id:1, name:"s1", linked_to_nets:[_net("p", "127")]});
329
        var vm = vms.at(0);
330
        
331
        nets.add({id:"p", nid:"p", name:"n1", linked_to:[1]});
332
        var n = nets.at(0);
333
    })
334

    
335
    module("images/flavors")
336
    test("Test DELETE state image retrieval", function() {
337
        snf.storage.images.reset();
338
        snf.storage.vms.reset();
339

    
340
        var images = snf.storage.images;
341
        var vms = snf.storage.vms;
342

    
343
        var img = images.add({name:"image 1", id:1}).last();
344
        var vm1 = vms.add({imageRef:1, name:"vm1"}).last();
345
        var vm2 = vms.add({imageRef:2, name:"vm2"}).last();
346
            
347
        equals(img, vm1.get_image());
348
        
349
        // reset is not called on 304
350
        $.mockjax({
351
            url: '/api/v1.1/images/2',
352
            responseTime: 50,
353
            status: 200,
354
            responseText: {image:{name:"image 2", id:2}}
355
        }); 
356
        
357
        
358
        equals(images.length, 1, "1 image exists");
359
        vm2.get_image();
360
        equals(images.get(2).get("name"), "image 2", "image data parsed");
361
        equals(images.length, 2);
362
    })
363

    
364
    test("Test DELETE state flavor retrieval", function() {
365
        snf.storage.flavors.reset();
366
        snf.storage.vms.reset();
367

    
368
        var flavors = snf.storage.flavors;
369
        var vms = snf.storage.vms;
370

    
371
        var flv = flavors.add({id:1, cpu:1, disk:1, ram:1024}).last();
372
        var vm1 = vms.add({flavorRef:1, name:"vm1"}).last();
373
        var vm2 = vms.add({flavorRef:2, name:"vm2"}).last();
374
            
375
        equals(flv, vm1.get_flavor());
376
        
377
        // reset is not called on 304
378
        $.mockjax({
379
            url: '/api/v1.1/flavors/2',
380
            responseTime: 50,
381
            status: 200,
382
            responseText: {flavor:{cpu:1, ram:2048, disk:100, id:2}}
383
        }); 
384
        
385
        
386
        equals(flavors.length, 1, "1 flavor exists");
387
        vm2.get_flavor();
388
        equals(flavors.get(2).get("ram"), 2048, "flavor data parsed");
389
        equals(flavors.length, 2);
390
    })
391

    
392
    test("actions list object", function(){
393
        var m = new models.Image();
394
        var l = new models.ParamsList(m, "actions");
395
        var count = 0;
396

    
397
        l.add("destroy");
398
        equals(l.has_action("destroy"), true);
399
        equals(l.contains("destroy"), true);
400

    
401
        l.add("destroy", 1, {});
402
        equals(l.has_action("destroy"), true);
403
        equals(l.contains("destroy", 1, {}), true);
404

    
405
        l.remove("destroy", 1, {});
406
        equals(l.contains("destroy", 1, {}), false);
407

    
408
        m.bind("change:actions", function() { count ++});
409
        l.add("destroy");
410
        
411
        equals(count, 0);
412
        l.add("destroy", 1, {});
413
        equals(count, 1);
414
    });
415
})