Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / ui / static / snf / js / tests.js @ c7aead0b

History | View | Annotate | Download (22.2 kB)

1 00469232 Kostas Papadimitriou
// Copyright 2011 GRNET S.A. All rights reserved.
2 00469232 Kostas Papadimitriou
// 
3 00469232 Kostas Papadimitriou
// Redistribution and use in source and binary forms, with or
4 00469232 Kostas Papadimitriou
// without modification, are permitted provided that the following
5 00469232 Kostas Papadimitriou
// conditions are met:
6 00469232 Kostas Papadimitriou
// 
7 00469232 Kostas Papadimitriou
//   1. Redistributions of source code must retain the above
8 00469232 Kostas Papadimitriou
//      copyright notice, this list of conditions and the following
9 00469232 Kostas Papadimitriou
//      disclaimer.
10 00469232 Kostas Papadimitriou
// 
11 00469232 Kostas Papadimitriou
//   2. Redistributions in binary form must reproduce the above
12 00469232 Kostas Papadimitriou
//      copyright notice, this list of conditions and the following
13 00469232 Kostas Papadimitriou
//      disclaimer in the documentation and/or other materials
14 00469232 Kostas Papadimitriou
//      provided with the distribution.
15 00469232 Kostas Papadimitriou
// 
16 00469232 Kostas Papadimitriou
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 00469232 Kostas Papadimitriou
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 00469232 Kostas Papadimitriou
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 00469232 Kostas Papadimitriou
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 00469232 Kostas Papadimitriou
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 00469232 Kostas Papadimitriou
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 00469232 Kostas Papadimitriou
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 00469232 Kostas Papadimitriou
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 00469232 Kostas Papadimitriou
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 00469232 Kostas Papadimitriou
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 00469232 Kostas Papadimitriou
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 00469232 Kostas Papadimitriou
// POSSIBILITY OF SUCH DAMAGE.
28 00469232 Kostas Papadimitriou
// 
29 00469232 Kostas Papadimitriou
// The views and conclusions contained in the software and
30 00469232 Kostas Papadimitriou
// documentation are those of the authors and should not be
31 00469232 Kostas Papadimitriou
// interpreted as representing official policies, either expressed
32 00469232 Kostas Papadimitriou
// or implied, of GRNET S.A.
33 00469232 Kostas Papadimitriou
// 
34 00469232 Kostas Papadimitriou
35 8d08f18a Kostas Papadimitriou
$(document).ready(function(){
36 8d08f18a Kostas Papadimitriou
37 8d08f18a Kostas Papadimitriou
    // shortcuts
38 8d08f18a Kostas Papadimitriou
    snf = synnefo;
39 8d08f18a Kostas Papadimitriou
    models = snf.models;
40 8d08f18a Kostas Papadimitriou
    util = snf.utils;
41 8d08f18a Kostas Papadimitriou
    views = snf.views;
42 8d08f18a Kostas Papadimitriou
    bb = Backbone;
43 8d08f18a Kostas Papadimitriou
    vms = snf.storage.vms;
44 8d08f18a Kostas Papadimitriou
    nets = snf.storage.networks;
45 8d08f18a Kostas Papadimitriou
46 1a1bac97 Kostas Papadimitriou
    synnefo.config.api_urls = {
47 1a1bac97 Kostas Papadimitriou
        'compute': '/api/v1.1', 
48 1a1bac97 Kostas Papadimitriou
        'glance':'/images/v1.1'
49 1a1bac97 Kostas Papadimitriou
    };
50 1e882dd7 Kostas Papadimitriou
    
51 1e882dd7 Kostas Papadimitriou
    // what messages to display based on vm status
52 1e882dd7 Kostas Papadimitriou
    synnefo.config.diagnostics_status_messages_map = {
53 1e882dd7 Kostas Papadimitriou
        'BUILD': ['image-helper-task-start', 'image-info'],
54 1e882dd7 Kostas Papadimitriou
        'ERROR': ['image-error']
55 1e882dd7 Kostas Papadimitriou
    };
56 1e882dd7 Kostas Papadimitriou
    synnefo.config.diagnostic_messages_tpls = {
57 1e882dd7 Kostas Papadimitriou
      'image-helper-task-start': "Running 'MESSAGE'"
58 1e882dd7 Kostas Papadimitriou
    };
59 1a1bac97 Kostas Papadimitriou
60 92bbc5b9 Kostas Papadimitriou
    snf.user = {'token': 'TESTTOKEN'}
61 92bbc5b9 Kostas Papadimitriou
62 8d08f18a Kostas Papadimitriou
    module("VM Model")
63 1e882dd7 Kostas Papadimitriou
    
64 1e882dd7 Kostas Papadimitriou
    test("vm diagnostics", function() {
65 1e882dd7 Kostas Papadimitriou
        synnefo.storage.images.add({
66 1e882dd7 Kostas Papadimitriou
          id:1, 
67 1e882dd7 Kostas Papadimitriou
          size: 100,
68 1e882dd7 Kostas Papadimitriou
          metadata:{
69 1e882dd7 Kostas Papadimitriou
            values: {
70 1e882dd7 Kostas Papadimitriou
              size: 100
71 1e882dd7 Kostas Papadimitriou
            }
72 1e882dd7 Kostas Papadimitriou
          }
73 1e882dd7 Kostas Papadimitriou
        });
74 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.add({id:1, imageRef:1});
75 1e882dd7 Kostas Papadimitriou
        var vm = synnefo.storage.vms.at(0);
76 1e882dd7 Kostas Papadimitriou
        var diagnostics = [{
77 1e882dd7 Kostas Papadimitriou
          source:'image-helper-task-start', 
78 1e882dd7 Kostas Papadimitriou
          message:'SSHCopyKey'
79 1e882dd7 Kostas Papadimitriou
        }];
80 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
81 1e882dd7 Kostas Papadimitriou
                                     progress: 0,
82 1e882dd7 Kostas Papadimitriou
                                     status: "BUILD"}], 
83 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
84 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), "init", 
85 1e882dd7 Kostas Papadimitriou
              "Show initial progress message");
86 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
87 1e882dd7 Kostas Papadimitriou
                                     progress: 10,
88 1e882dd7 Kostas Papadimitriou
                                     status: "BUILD"}], 
89 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
90 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), "10.00 MB, 100.00 MB, 10", 
91 1e882dd7 Kostas Papadimitriou
              "Construct message based on image size");
92 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
93 1e882dd7 Kostas Papadimitriou
                                     progress: 99,
94 1e882dd7 Kostas Papadimitriou
                                     status: "BUILD"}], 
95 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
96 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), "99.00 MB, 100.00 MB, 99", 
97 1e882dd7 Kostas Papadimitriou
              "Calculate 99% of image size and display image");
98 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
99 1e882dd7 Kostas Papadimitriou
                                     progress: 99,
100 1e882dd7 Kostas Papadimitriou
                                     status: "ERROR"}], 
101 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
102 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), null);
103 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
104 1e882dd7 Kostas Papadimitriou
                                     progress: 100,
105 1e882dd7 Kostas Papadimitriou
                                     status: "BUILD"}], 
106 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
107 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), "final", 
108 1e882dd7 Kostas Papadimitriou
              "Progress is 100, show finializing progress message");
109 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
110 1e882dd7 Kostas Papadimitriou
                                     progress: 100,
111 1e882dd7 Kostas Papadimitriou
                                     diagnostics: _.clone(diagnostics),
112 1e882dd7 Kostas Papadimitriou
                                     status: "BUILD"}], 
113 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
114 1e882dd7 Kostas Papadimitriou
115 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
116 1e882dd7 Kostas Papadimitriou
                                     progress: 100,
117 1e882dd7 Kostas Papadimitriou
                                     diagnostics: _.clone(diagnostics),
118 1e882dd7 Kostas Papadimitriou
                                     status: "BUILD"}], 
119 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
120 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), "Running 'SSHCopyKey'", 
121 1e882dd7 Kostas Papadimitriou
              "Diagnostics added, show first building diagnostic message");
122 1e882dd7 Kostas Papadimitriou
123 1e882dd7 Kostas Papadimitriou
        diagnostics.unshift({source:'unknown-source', message:'H&^^ACJJ'});
124 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
125 1e882dd7 Kostas Papadimitriou
                                     progress: 100,
126 1e882dd7 Kostas Papadimitriou
                                     diagnostics: _.clone(diagnostics),
127 1e882dd7 Kostas Papadimitriou
                                     status: "BUILD"}], 
128 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
129 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), "Running 'SSHCopyKey'", 
130 1e882dd7 Kostas Papadimitriou
              "Unwanted diagnostics get filtered out, progress message remains");
131 1e882dd7 Kostas Papadimitriou
132 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
133 1e882dd7 Kostas Papadimitriou
                                     progress: 100,
134 1e882dd7 Kostas Papadimitriou
                                     diagnostics: _.clone(diagnostics),
135 1e882dd7 Kostas Papadimitriou
                                     status: "ERROR"}], 
136 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
137 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), null, 
138 1e882dd7 Kostas Papadimitriou
              "In error state since no error diagnostic is set we get null");
139 1e882dd7 Kostas Papadimitriou
140 1e882dd7 Kostas Papadimitriou
        diagnostics.unshift({source:'image-error', message:'Image error'});
141 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
142 1e882dd7 Kostas Papadimitriou
                                     progress: 100,
143 1e882dd7 Kostas Papadimitriou
                                     diagnostics: _.clone(diagnostics),
144 1e882dd7 Kostas Papadimitriou
                                     status: "BUILD"}], 
145 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
146 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), "Running 'SSHCopyKey'");
147 1e882dd7 Kostas Papadimitriou
148 1e882dd7 Kostas Papadimitriou
        diagnostics.unshift({source:'image-error', message:'Image error'});
149 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
150 1e882dd7 Kostas Papadimitriou
                                     progress: 100,
151 1e882dd7 Kostas Papadimitriou
                                     diagnostics: _.clone(diagnostics),
152 1e882dd7 Kostas Papadimitriou
                                     status: "ERROR"}], 
153 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
154 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), "Image error");
155 1e882dd7 Kostas Papadimitriou
156 1e882dd7 Kostas Papadimitriou
        synnefo.storage.vms.update([{id:1, 
157 1e882dd7 Kostas Papadimitriou
                                     progress: 100,
158 1e882dd7 Kostas Papadimitriou
                                     diagnostics: _.clone(diagnostics),
159 1e882dd7 Kostas Papadimitriou
                                     status: "ACTIVE"}], 
160 1e882dd7 Kostas Papadimitriou
                                    {silent:false});
161 1e882dd7 Kostas Papadimitriou
        equal(vm.get('status_message'), null);
162 1e882dd7 Kostas Papadimitriou
163 1e882dd7 Kostas Papadimitriou
    });
164 1e882dd7 Kostas Papadimitriou
165 8d08f18a Kostas Papadimitriou
166 8d08f18a Kostas Papadimitriou
    test("model change events", function(){
167 8d08f18a Kostas Papadimitriou
        expect(8);
168 8d08f18a Kostas Papadimitriou
169 8d08f18a Kostas Papadimitriou
        synnefo.storage.images.add({id:1,metadata:{values:{size:100}}});
170 8d08f18a Kostas Papadimitriou
        var v1 = new models.VM({'imageRef':1});
171 8d08f18a Kostas Papadimitriou
        v1.bind("change", function(){
172 8d08f18a Kostas Papadimitriou
            ok(1, "change event triggered")
173 92bbc5b9 Kostas Papadimitriou
            equal(v1.get("status"), "BUILD")
174 92bbc5b9 Kostas Papadimitriou
            equal(v1.get("state"), "BUILD_COPY")
175 8d08f18a Kostas Papadimitriou
        })
176 8d08f18a Kostas Papadimitriou
        v1.set({'status':'BUILD', 'progress':80, 'imageRef': 1});
177 8d08f18a Kostas Papadimitriou
        v1.unbind();
178 8d08f18a Kostas Papadimitriou
179 8d08f18a Kostas Papadimitriou
        v1.bind("change", function(){
180 8d08f18a Kostas Papadimitriou
            ok(1, "change event triggered")
181 92bbc5b9 Kostas Papadimitriou
            equal(v1.get("status"), "BUILD")
182 92bbc5b9 Kostas Papadimitriou
            equal(v1.get("state"), "DESTROY")
183 8d08f18a Kostas Papadimitriou
        })
184 8d08f18a Kostas Papadimitriou
        v1.set({'state':'DESTROY'});
185 8d08f18a Kostas Papadimitriou
        v1.unbind();
186 8d08f18a Kostas Papadimitriou
187 8d08f18a Kostas Papadimitriou
        v1.bind("change", function() {
188 8d08f18a Kostas Papadimitriou
            ok(1, "change event triggered")
189 92bbc5b9 Kostas Papadimitriou
            equal(v1.get("status"), "BUILD")
190 92bbc5b9 Kostas Papadimitriou
            equal(v1.get("state"), "BUILD_COPY")
191 8d08f18a Kostas Papadimitriou
        })
192 8d08f18a Kostas Papadimitriou
        v1.set({'status':'BUILD', 'progress':80, 'imageRef': 1});
193 92bbc5b9 Kostas Papadimitriou
        equal(v1.get("status"), "BUILD")
194 92bbc5b9 Kostas Papadimitriou
        equal(v1.get("state"), "DESTROY")
195 8d08f18a Kostas Papadimitriou
        v1.unbind();
196 8d08f18a Kostas Papadimitriou
    })
197 8d08f18a Kostas Papadimitriou
198 8d08f18a Kostas Papadimitriou
    test("model state transitions", function(){
199 8d08f18a Kostas Papadimitriou
        var vm = models.VM;
200 8d08f18a Kostas Papadimitriou
        
201 8d08f18a Kostas Papadimitriou
        var v1 = new vm();
202 8d08f18a Kostas Papadimitriou
        v1.set({status: 'BUILD_COPY'})
203 92bbc5b9 Kostas Papadimitriou
        equal(v1.get("state"), 'BUILD_COPY', "State is set");
204 8d08f18a Kostas Papadimitriou
        v1.set({status: 'DESTROY'})
205 92bbc5b9 Kostas Papadimitriou
        equal(v1.get("state"), 'DESTROY', "From buld to destroy");
206 8d08f18a Kostas Papadimitriou
        v1.set({status: 'BUILD'})
207 92bbc5b9 Kostas Papadimitriou
        equal(v1.get("state"), 'DESTROY', "Keep destroy state");
208 8d08f18a Kostas Papadimitriou
209 8d08f18a Kostas Papadimitriou
        v1 = new vm();
210 8d08f18a Kostas Papadimitriou
        v1.set({status: 'ACTIVE'})
211 92bbc5b9 Kostas Papadimitriou
        equal(v1.get("state"), 'ACTIVE', "State is set");
212 8d08f18a Kostas Papadimitriou
213 8d08f18a Kostas Papadimitriou
        v1.set({status: 'SHUTDOWN'})
214 92bbc5b9 Kostas Papadimitriou
        equal(v1.get("state"), 'SHUTDOWN', "From active to shutdown (should change)");
215 8d08f18a Kostas Papadimitriou
216 8d08f18a Kostas Papadimitriou
        v1.set({status: 'ACTIVE'})
217 92bbc5b9 Kostas Papadimitriou
        equal(v1.get("state"), 'SHUTDOWN', "From shutdown to active (should not change)");
218 8d08f18a Kostas Papadimitriou
        
219 8d08f18a Kostas Papadimitriou
        v1.set({status: 'STOPPED'})
220 92bbc5b9 Kostas Papadimitriou
        equal(v1.get("state"), 'STOPPED', "From shutdown to stopped (should change)");
221 8d08f18a Kostas Papadimitriou
222 8d08f18a Kostas Papadimitriou
        v1.set({status: 'ACTIVE'})
223 92bbc5b9 Kostas Papadimitriou
        equal(v1.get("state"), 'ACTIVE', "From stopped to active (should change)");
224 8d08f18a Kostas Papadimitriou
        v1.set({'status': 'STOPPED'})
225 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'STOPPED', "From shutdown to stopped should change");
226 8d08f18a Kostas Papadimitriou
227 8d08f18a Kostas Papadimitriou
        v1.set({'status': 'DESTROY'})
228 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'DESTROY', "From stopped to destory should set state to DESTROY");
229 8d08f18a Kostas Papadimitriou
        v1.set({'status': 'ACTIVE'})
230 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'DESTROY', "From destroy to active should keep state to DESTROY");
231 8d08f18a Kostas Papadimitriou
        v1.set({'status': 'REBOOT'})
232 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'DESTROY', "From destroy to active should keep state to DESTROY");
233 1420aae4 Kostas Papadimitriou
        v1.set({'status': 'DELETED'})
234 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'DELETED', "Destroy should be kept until DELETE or ERROR");
235 8d08f18a Kostas Papadimitriou
236 8d08f18a Kostas Papadimitriou
        v1 = new vm({status:'BUILD'});
237 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'BUILD', "new vm with build as initial status")
238 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('status'), 'BUILD', "new vm with build as initial status")
239 8d08f18a Kostas Papadimitriou
        v1.set({status:'ACTIVE'})
240 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'ACTIVE', "active state has been set")
241 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('status'), 'ACTIVE', "active status has been set")
242 8d08f18a Kostas Papadimitriou
    })
243 8d08f18a Kostas Papadimitriou
244 8d08f18a Kostas Papadimitriou
245 8d08f18a Kostas Papadimitriou
    test("building states", function(){
246 8d08f18a Kostas Papadimitriou
        synnefo.storage.images.add({id:1,metadata:{values:{size:100}}});
247 8d08f18a Kostas Papadimitriou
        var vm = models.VM;
248 8d08f18a Kostas Papadimitriou
        var v1 = new vm({'status':'BUILD','progress':0, 'imageRef':1});
249 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'BUILD_INIT', "progress 0 sets state to BUILD_INIT");
250 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('status'), 'BUILD', "progress 0 sets status to BUILD");
251 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('progress_message'), 'init', "message 'init'");
252 8d08f18a Kostas Papadimitriou
        v1.set({status:'BUILD', progress:50});
253 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'BUILD_COPY', "progress 50 sets state to BUILD_COPY");
254 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('status'), 'BUILD', "progress 50 sets status to BUILD");
255 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('progress_message'), '50.00 MB, 100.00 MB, 50', "message: 'final'");
256 8d08f18a Kostas Papadimitriou
        v1.set({status:'BUILD', progress:100});
257 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'BUILD_FINAL', "progress 100 sets state to BUILD_FINAL");
258 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('status'), 'BUILD', "progress 100 sets status to BUILD");
259 8d08f18a Kostas Papadimitriou
        v1.set({status:'ACTIVE', progress:100});
260 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('state'), 'ACTIVE', "ACTIVE set transition to ACTIVE");
261 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('status'), 'ACTIVE', "ACTIVE set transition to ACTIVE");
262 92bbc5b9 Kostas Papadimitriou
        equal(v1.get('progress_message'), 'final', "message: 'final'");
263 8d08f18a Kostas Papadimitriou
    })
264 8d08f18a Kostas Papadimitriou
265 8d08f18a Kostas Papadimitriou
    test("active inactive states", function(){
266 8d08f18a Kostas Papadimitriou
    
267 8d08f18a Kostas Papadimitriou
        var vm = models.VM;
268 8d08f18a Kostas Papadimitriou
        var v1 = new vm();
269 8d08f18a Kostas Papadimitriou
        var v = {}
270 8d08f18a Kostas Papadimitriou
        var active = ['ACTIVE', 'BUILD', 'REBOOT'];
271 8d08f18a Kostas Papadimitriou
        for (v in active) {
272 8d08f18a Kostas Papadimitriou
            v = active[v];
273 8d08f18a Kostas Papadimitriou
            v1.set({status: v})
274 92bbc5b9 Kostas Papadimitriou
            equal(v1.is_active(), true, v + " status is active")
275 8d08f18a Kostas Papadimitriou
        }
276 8d08f18a Kostas Papadimitriou
        
277 8d08f18a Kostas Papadimitriou
        var v1 = new vm();
278 8d08f18a Kostas Papadimitriou
        var inactive = ['STOPPED', 'ERROR', 'UNKNOWN'];
279 8d08f18a Kostas Papadimitriou
        for (v in inactive) {
280 8d08f18a Kostas Papadimitriou
            v = inactive[v];
281 8d08f18a Kostas Papadimitriou
            v1.set({status: v})
282 92bbc5b9 Kostas Papadimitriou
            equal(v1.is_active(), false, v1.state() + " status is not active")
283 8d08f18a Kostas Papadimitriou
        }
284 8d08f18a Kostas Papadimitriou
    
285 8d08f18a Kostas Papadimitriou
    })
286 8d08f18a Kostas Papadimitriou
287 8d08f18a Kostas Papadimitriou
    test("transition event", function(){
288 8d08f18a Kostas Papadimitriou
        expect(9);
289 8d08f18a Kostas Papadimitriou
290 8d08f18a Kostas Papadimitriou
        var vm = new models.VM({status:'BUILD'});
291 8d08f18a Kostas Papadimitriou
        vm.bind("transition", function(data) {
292 8d08f18a Kostas Papadimitriou
            ok(true, "Transition triggered");
293 92bbc5b9 Kostas Papadimitriou
            equal(data.from, "BUILD")
294 92bbc5b9 Kostas Papadimitriou
            equal(data.to, "ACTIVE");
295 8d08f18a Kostas Papadimitriou
        })
296 8d08f18a Kostas Papadimitriou
        // trigger 1 time
297 8d08f18a Kostas Papadimitriou
        vm.set({status:'BUILD'});
298 8d08f18a Kostas Papadimitriou
        vm.set({status:'ACTIVE'});
299 8d08f18a Kostas Papadimitriou
        vm.unbind();
300 8d08f18a Kostas Papadimitriou
        
301 8d08f18a Kostas Papadimitriou
        // from build to active
302 8d08f18a Kostas Papadimitriou
        vm = new models.VM({status:'BUILD'});
303 8d08f18a Kostas Papadimitriou
        vm.bind("transition", function(data) {
304 8d08f18a Kostas Papadimitriou
            ok(true, "Transition triggered");
305 92bbc5b9 Kostas Papadimitriou
            equal(data.from, "BUILD")
306 92bbc5b9 Kostas Papadimitriou
            equal(data.to, "ACTIVE");
307 8d08f18a Kostas Papadimitriou
        })
308 8d08f18a Kostas Papadimitriou
        // trigger 1 time
309 8d08f18a Kostas Papadimitriou
        vm.set({status:'ACTIVE'});
310 8d08f18a Kostas Papadimitriou
        vm.unbind();
311 8d08f18a Kostas Papadimitriou
312 8d08f18a Kostas Papadimitriou
        // from active to shutdown
313 8d08f18a Kostas Papadimitriou
        vm = new models.VM({status:'SHUTDOWN'});
314 8d08f18a Kostas Papadimitriou
        vm.bind("transition", function(data) {
315 8d08f18a Kostas Papadimitriou
            ok(true, "Transition triggered");
316 92bbc5b9 Kostas Papadimitriou
            equal(data.from, "SHUTDOWN")
317 92bbc5b9 Kostas Papadimitriou
            equal(data.to, "STOPPED");
318 8d08f18a Kostas Papadimitriou
        })
319 8d08f18a Kostas Papadimitriou
        // trigger 1 time
320 8d08f18a Kostas Papadimitriou
        vm.set({status:'STOPPED'});
321 8d08f18a Kostas Papadimitriou
    })
322 8d08f18a Kostas Papadimitriou
    
323 8d08f18a Kostas Papadimitriou
    module("Collections");
324 8d08f18a Kostas Papadimitriou
        
325 8d08f18a Kostas Papadimitriou
    test("status model remove events", function(){
326 8d08f18a Kostas Papadimitriou
        vms.unbind();
327 8d08f18a Kostas Papadimitriou
        expect(1)
328 8d08f18a Kostas Papadimitriou
329 8d08f18a Kostas Papadimitriou
        vms.bind("change", function(){
330 8d08f18a Kostas Papadimitriou
            ok(-1, "change event should not get triggered");
331 8d08f18a Kostas Papadimitriou
        })
332 8d08f18a Kostas Papadimitriou
333 8d08f18a Kostas Papadimitriou
        vms.bind("remove", function(){
334 8d08f18a Kostas Papadimitriou
            ok(1, "remove event triggered")
335 8d08f18a Kostas Papadimitriou
        })
336 8d08f18a Kostas Papadimitriou
337 8d08f18a Kostas Papadimitriou
        var vm = new models.VM({id:1, status:"ACTIVE", name:"oldname"});
338 8d08f18a Kostas Papadimitriou
        vms.add(vm);
339 8d08f18a Kostas Papadimitriou
        
340 8d08f18a Kostas Papadimitriou
        // NO change/delete just DELETE event triggered
341 8d08f18a Kostas Papadimitriou
        vms.update([{id:1, status:"DELETED", name:"newname"}])
342 8d08f18a Kostas Papadimitriou
    });
343 8d08f18a Kostas Papadimitriou
344 8d08f18a Kostas Papadimitriou
    test("collection reset events", function() {
345 8d08f18a Kostas Papadimitriou
        expect(9);
346 8d08f18a Kostas Papadimitriou
347 8d08f18a Kostas Papadimitriou
        var testCollection = models.Collection.extend({
348 8d08f18a Kostas Papadimitriou
            url: '/testObject'
349 8d08f18a Kostas Papadimitriou
        });
350 8d08f18a Kostas Papadimitriou
        var collection = new testCollection();
351 8d08f18a Kostas Papadimitriou
352 8d08f18a Kostas Papadimitriou
        
353 8d08f18a Kostas Papadimitriou
        // reset on new entry after empty
354 8d08f18a Kostas Papadimitriou
        $.mockjax({
355 8d08f18a Kostas Papadimitriou
            url: '/testObject',
356 8d08f18a Kostas Papadimitriou
            responseTime: 50,
357 8d08f18a Kostas Papadimitriou
            responseText: [
358 8d08f18a Kostas Papadimitriou
                {id:1, attr1: 1, attr2: 2}
359 8d08f18a Kostas Papadimitriou
            ]
360 8d08f18a Kostas Papadimitriou
        }); 
361 8d08f18a Kostas Papadimitriou
        // THIS SHOULD NOT FIRE, since we force update method
362 8d08f18a Kostas Papadimitriou
        collection.bind("reset", function() {
363 8d08f18a Kostas Papadimitriou
            ok(1, "NOT EXPECTED: reset triggered on new entry while collection was empty");
364 8d08f18a Kostas Papadimitriou
        });
365 8d08f18a Kostas Papadimitriou
        collection.bind("add", function() {
366 8d08f18a Kostas Papadimitriou
            ok(1, "1: add triggered on new entry while collection was empty");
367 8d08f18a Kostas Papadimitriou
        });
368 8d08f18a Kostas Papadimitriou
        // THIS SHOULD NOT FIRE, model was added, not changed
369 8d08f18a Kostas Papadimitriou
        collection.bind("change", function() {
370 8d08f18a Kostas Papadimitriou
            ok(1, "NOT EXPECTED: change triggered on new entry while collection was empty");
371 8d08f18a Kostas Papadimitriou
        });
372 8d08f18a Kostas Papadimitriou
        collection.fetch({'async': false});
373 92bbc5b9 Kostas Papadimitriou
        equal(collection.length, 1, "2: collection contains 1 model");
374 8d08f18a Kostas Papadimitriou
        collection.unbind();
375 8d08f18a Kostas Papadimitriou
        $.mockjaxClear();
376 8d08f18a Kostas Papadimitriou
        
377 8d08f18a Kostas Papadimitriou
        // reset is called on change
378 8d08f18a Kostas Papadimitriou
        $.mockjax({
379 8d08f18a Kostas Papadimitriou
            url: '/testObject',
380 8d08f18a Kostas Papadimitriou
            responseTime: 50,
381 8d08f18a Kostas Papadimitriou
            responseText: [
382 8d08f18a Kostas Papadimitriou
                {id:1, attr1: 4, attr2: 2}
383 8d08f18a Kostas Papadimitriou
            ]
384 8d08f18a Kostas Papadimitriou
        });
385 8d08f18a Kostas Papadimitriou
        collection.bind("reset", function() {
386 8d08f18a Kostas Papadimitriou
            ok(1, "NOT EXPECTED: reset triggered on new entry while collection was empty");
387 8d08f18a Kostas Papadimitriou
        });
388 8d08f18a Kostas Papadimitriou
        collection.bind("add", function() {
389 8d08f18a Kostas Papadimitriou
            ok(1, "NOT EXPECTED: add triggered on new entry while collection was empty");
390 8d08f18a Kostas Papadimitriou
        });
391 8d08f18a Kostas Papadimitriou
        // THIS SHOULD NOT FIRE, model was added, not changed
392 8d08f18a Kostas Papadimitriou
        collection.bind("change", function() {
393 8d08f18a Kostas Papadimitriou
            ok(1, "3: change triggered on new entry while collection was empty");
394 8d08f18a Kostas Papadimitriou
        });
395 8d08f18a Kostas Papadimitriou
        collection.fetch({'async': false, refresh:true});
396 92bbc5b9 Kostas Papadimitriou
        equal(collection.length, 1, "4 collection contains 1 model");
397 8d08f18a Kostas Papadimitriou
        collection.unbind();
398 8d08f18a Kostas Papadimitriou
        $.mockjaxClear();
399 8d08f18a Kostas Papadimitriou
400 8d08f18a Kostas Papadimitriou
        // reset on second entry
401 8d08f18a Kostas Papadimitriou
        $.mockjax({
402 8d08f18a Kostas Papadimitriou
            url: '/testObject',
403 8d08f18a Kostas Papadimitriou
            responseTime: 50,
404 8d08f18a Kostas Papadimitriou
            responseText: [
405 8d08f18a Kostas Papadimitriou
                {id:1, attr1: 4, attr2: 2},
406 8d08f18a Kostas Papadimitriou
                {id:2, attr1: 1, attr2: 2}
407 8d08f18a Kostas Papadimitriou
            ]
408 8d08f18a Kostas Papadimitriou
        });
409 8d08f18a Kostas Papadimitriou
        collection.bind("reset", function() {
410 8d08f18a Kostas Papadimitriou
            ok(1, "NOT EXPECTED: reset triggered when new model arrived");
411 8d08f18a Kostas Papadimitriou
        })
412 8d08f18a Kostas Papadimitriou
        collection.bind("add", function() {
413 8d08f18a Kostas Papadimitriou
            ok(1, "5: add triggered when new model arrived");
414 8d08f18a Kostas Papadimitriou
        })
415 8d08f18a Kostas Papadimitriou
        collection.bind("change", function() {
416 8d08f18a Kostas Papadimitriou
            ok(1, "NOT EXPECTED: change triggered when new model arrived");
417 8d08f18a Kostas Papadimitriou
        }) 
418 8d08f18a Kostas Papadimitriou
        collection.fetch({async:false, refresh:true});
419 92bbc5b9 Kostas Papadimitriou
        equal(collection.length, 2, "6 new model added");
420 8d08f18a Kostas Papadimitriou
        collection.unbind();
421 8d08f18a Kostas Papadimitriou
        $.mockjaxClear();
422 8d08f18a Kostas Papadimitriou
        
423 8d08f18a Kostas Papadimitriou
        // reset does not remove
424 8d08f18a Kostas Papadimitriou
        $.mockjax({
425 8d08f18a Kostas Papadimitriou
            url: '/testObject',
426 8d08f18a Kostas Papadimitriou
            responseTime: 50,
427 8d08f18a Kostas Papadimitriou
            responseText: [
428 8d08f18a Kostas Papadimitriou
                {id:2, attr1: 1, attr2: 2}
429 8d08f18a Kostas Papadimitriou
            ]
430 8d08f18a Kostas Papadimitriou
        }); 
431 8d08f18a Kostas Papadimitriou
        collection.bind("reset", function() {
432 8d08f18a Kostas Papadimitriou
            ok(1, "NOT EXPECTED: reset triggered when model removed");
433 8d08f18a Kostas Papadimitriou
        })
434 8d08f18a Kostas Papadimitriou
        collection.bind("remove", function() {
435 8d08f18a Kostas Papadimitriou
            ok(1, "7: remove triggered when model removed");
436 8d08f18a Kostas Papadimitriou
        })
437 8d08f18a Kostas Papadimitriou
        collection.bind("change", function() {
438 8d08f18a Kostas Papadimitriou
            ok(1, "NOT EXPECTED: change triggered when model removed");
439 8d08f18a Kostas Papadimitriou
        })
440 8d08f18a Kostas Papadimitriou
441 8d08f18a Kostas Papadimitriou
        collection.fetch({async:false, refresh:true});
442 92bbc5b9 Kostas Papadimitriou
        equal(collection.length, 1, "8 one model removed");
443 8d08f18a Kostas Papadimitriou
        collection.unbind();
444 8d08f18a Kostas Papadimitriou
        $.mockjaxClear();
445 8d08f18a Kostas Papadimitriou
446 8d08f18a Kostas Papadimitriou
        // reset is not called on 304
447 8d08f18a Kostas Papadimitriou
        $.mockjax({
448 8d08f18a Kostas Papadimitriou
            url: '/testObject',
449 8d08f18a Kostas Papadimitriou
            responseTime: 50,
450 8d08f18a Kostas Papadimitriou
            status: 304,
451 8d08f18a Kostas Papadimitriou
            responseText: undefined
452 8d08f18a Kostas Papadimitriou
        }); 
453 8d08f18a Kostas Papadimitriou
        // NO event is triggered on 304
454 8d08f18a Kostas Papadimitriou
        collection.bind("reset", function() {
455 8d08f18a Kostas Papadimitriou
            ok(1, "WRONG: reset triggered on 304");
456 8d08f18a Kostas Papadimitriou
        });
457 8d08f18a Kostas Papadimitriou
        collection.bind("remove", function() {
458 8d08f18a Kostas Papadimitriou
            ok(1, "WRONG: remove triggered on 304");
459 8d08f18a Kostas Papadimitriou
        });
460 8d08f18a Kostas Papadimitriou
        collection.bind("change", function() {
461 8d08f18a Kostas Papadimitriou
            ok(1, "WRONG: remove triggered on 304");
462 8d08f18a Kostas Papadimitriou
        });
463 8d08f18a Kostas Papadimitriou
        collection.fetch({async:false, refresh:true});
464 92bbc5b9 Kostas Papadimitriou
        equal(collection.length, 1, "9 one model removed");
465 8d08f18a Kostas Papadimitriou
        collection.unbind();
466 8d08f18a Kostas Papadimitriou
        $.mockjaxClear();
467 8d08f18a Kostas Papadimitriou
    })
468 8d08f18a Kostas Papadimitriou
469 8d08f18a Kostas Papadimitriou
470 8d08f18a Kostas Papadimitriou
    module("network vm connections")
471 8d08f18a Kostas Papadimitriou
    test("network vm connections", function() {
472 8d08f18a Kostas Papadimitriou
        function _net(id, ip) {
473 8d08f18a Kostas Papadimitriou
            return {
474 8d08f18a Kostas Papadimitriou
                id: id,
475 8d08f18a Kostas Papadimitriou
                name: "net " + id,
476 8d08f18a Kostas Papadimitriou
                values:[{version:4, addr: ip}, {version:6, addr:ip}] 
477 8d08f18a Kostas Papadimitriou
            }
478 8d08f18a Kostas Papadimitriou
        }
479 8d08f18a Kostas Papadimitriou
        vms.add({id:1, name:"s1", linked_to_nets:[_net("p", "127")]});
480 8d08f18a Kostas Papadimitriou
        var vm = vms.at(0);
481 8d08f18a Kostas Papadimitriou
        
482 8d08f18a Kostas Papadimitriou
        nets.add({id:"p", nid:"p", name:"n1", linked_to:[1]});
483 8d08f18a Kostas Papadimitriou
        var n = nets.at(0);
484 8d08f18a Kostas Papadimitriou
    })
485 1420aae4 Kostas Papadimitriou
486 1420aae4 Kostas Papadimitriou
    module("images/flavors")
487 1420aae4 Kostas Papadimitriou
    test("Test DELETE state image retrieval", function() {
488 1420aae4 Kostas Papadimitriou
        snf.storage.images.reset();
489 1420aae4 Kostas Papadimitriou
        snf.storage.vms.reset();
490 1420aae4 Kostas Papadimitriou
491 1420aae4 Kostas Papadimitriou
        var images = snf.storage.images;
492 1420aae4 Kostas Papadimitriou
        var vms = snf.storage.vms;
493 1420aae4 Kostas Papadimitriou
494 1420aae4 Kostas Papadimitriou
        var img = images.add({name:"image 1", id:1}).last();
495 1420aae4 Kostas Papadimitriou
        var vm1 = vms.add({imageRef:1, name:"vm1"}).last();
496 1420aae4 Kostas Papadimitriou
        var vm2 = vms.add({imageRef:2, name:"vm2"}).last();
497 1420aae4 Kostas Papadimitriou
            
498 92bbc5b9 Kostas Papadimitriou
        vm1.get_image(function(i){
499 92bbc5b9 Kostas Papadimitriou
            equal(i, img);
500 92bbc5b9 Kostas Papadimitriou
        });
501 1420aae4 Kostas Papadimitriou
        
502 1420aae4 Kostas Papadimitriou
        // reset is not called on 304
503 1420aae4 Kostas Papadimitriou
        $.mockjax({
504 1420aae4 Kostas Papadimitriou
            url: '/api/v1.1/images/2',
505 1420aae4 Kostas Papadimitriou
            responseTime: 50,
506 1420aae4 Kostas Papadimitriou
            status: 200,
507 1420aae4 Kostas Papadimitriou
            responseText: {image:{name:"image 2", id:2}}
508 1420aae4 Kostas Papadimitriou
        }); 
509 1420aae4 Kostas Papadimitriou
        
510 1420aae4 Kostas Papadimitriou
        
511 92bbc5b9 Kostas Papadimitriou
        equal(images.length, 1, "1 image exists");
512 92bbc5b9 Kostas Papadimitriou
        vm2.get_image(function(i){
513 92bbc5b9 Kostas Papadimitriou
            equal(images.get(2).get("name"), "image 2", "image data parsed");
514 92bbc5b9 Kostas Papadimitriou
            equal(images.length, 2);
515 92bbc5b9 Kostas Papadimitriou
        });
516 1420aae4 Kostas Papadimitriou
    })
517 1420aae4 Kostas Papadimitriou
518 1420aae4 Kostas Papadimitriou
    test("Test DELETE state flavor retrieval", function() {
519 1420aae4 Kostas Papadimitriou
        snf.storage.flavors.reset();
520 1420aae4 Kostas Papadimitriou
        snf.storage.vms.reset();
521 1420aae4 Kostas Papadimitriou
522 1420aae4 Kostas Papadimitriou
        var flavors = snf.storage.flavors;
523 1420aae4 Kostas Papadimitriou
        var vms = snf.storage.vms;
524 1420aae4 Kostas Papadimitriou
525 1420aae4 Kostas Papadimitriou
        var flv = flavors.add({id:1, cpu:1, disk:1, ram:1024}).last();
526 1420aae4 Kostas Papadimitriou
        var vm1 = vms.add({flavorRef:1, name:"vm1"}).last();
527 1420aae4 Kostas Papadimitriou
        var vm2 = vms.add({flavorRef:2, name:"vm2"}).last();
528 1420aae4 Kostas Papadimitriou
            
529 92bbc5b9 Kostas Papadimitriou
        equal(flv, vm1.get_flavor());
530 1420aae4 Kostas Papadimitriou
        
531 1420aae4 Kostas Papadimitriou
        // reset is not called on 304
532 1420aae4 Kostas Papadimitriou
        $.mockjax({
533 1420aae4 Kostas Papadimitriou
            url: '/api/v1.1/flavors/2',
534 1420aae4 Kostas Papadimitriou
            responseTime: 50,
535 1420aae4 Kostas Papadimitriou
            status: 200,
536 1420aae4 Kostas Papadimitriou
            responseText: {flavor:{cpu:1, ram:2048, disk:100, id:2}}
537 1420aae4 Kostas Papadimitriou
        }); 
538 1420aae4 Kostas Papadimitriou
        
539 1420aae4 Kostas Papadimitriou
        
540 92bbc5b9 Kostas Papadimitriou
        equal(flavors.length, 1, "1 flavor exists");
541 1420aae4 Kostas Papadimitriou
        vm2.get_flavor();
542 92bbc5b9 Kostas Papadimitriou
        equal(flavors.get(2).get("ram"), 2048, "flavor data parsed");
543 92bbc5b9 Kostas Papadimitriou
        equal(flavors.length, 2);
544 1420aae4 Kostas Papadimitriou
    })
545 101e6604 Kostas Papadimitriou
546 101e6604 Kostas Papadimitriou
    test("actions list object", function(){
547 101e6604 Kostas Papadimitriou
        var m = new models.Image();
548 101e6604 Kostas Papadimitriou
        var l = new models.ParamsList(m, "actions");
549 101e6604 Kostas Papadimitriou
        var count = 0;
550 101e6604 Kostas Papadimitriou
551 101e6604 Kostas Papadimitriou
        l.add("destroy");
552 92bbc5b9 Kostas Papadimitriou
        equal(l.has_action("destroy"), true);
553 92bbc5b9 Kostas Papadimitriou
        equal(l.contains("destroy"), true);
554 101e6604 Kostas Papadimitriou
555 101e6604 Kostas Papadimitriou
        l.add("destroy", 1, {});
556 92bbc5b9 Kostas Papadimitriou
        equal(l.has_action("destroy"), true);
557 92bbc5b9 Kostas Papadimitriou
        equal(l.contains("destroy", 1, {}), true);
558 101e6604 Kostas Papadimitriou
559 101e6604 Kostas Papadimitriou
        l.remove("destroy", 1, {});
560 92bbc5b9 Kostas Papadimitriou
        equal(l.contains("destroy", 1, {}), false);
561 101e6604 Kostas Papadimitriou
562 101e6604 Kostas Papadimitriou
        m.bind("change:actions", function() { count ++});
563 101e6604 Kostas Papadimitriou
        l.add("destroy");
564 101e6604 Kostas Papadimitriou
        
565 92bbc5b9 Kostas Papadimitriou
        equal(count, 0);
566 101e6604 Kostas Papadimitriou
        l.add("destroy", 1, {});
567 92bbc5b9 Kostas Papadimitriou
        equal(count, 1);
568 101e6604 Kostas Papadimitriou
    });
569 aeadb7bf Kostas Papadimitriou
570 aeadb7bf Kostas Papadimitriou
    module("update handlers")
571 aeadb7bf Kostas Papadimitriou
    test("update handlers", function() {
572 aeadb7bf Kostas Papadimitriou
        // this test is based on multiple timeouts
573 aeadb7bf Kostas Papadimitriou
        // so the results might differ between different browsers
574 aeadb7bf Kostas Papadimitriou
        // or browser load
575 aeadb7bf Kostas Papadimitriou
        stop();
576 aeadb7bf Kostas Papadimitriou
577 aeadb7bf Kostas Papadimitriou
        var counter = 0;
578 aeadb7bf Kostas Papadimitriou
        var cb = function() {
579 aeadb7bf Kostas Papadimitriou
            counter++;
580 aeadb7bf Kostas Papadimitriou
        }
581 aeadb7bf Kostas Papadimitriou
        
582 aeadb7bf Kostas Papadimitriou
        var opts = {
583 aeadb7bf Kostas Papadimitriou
            callback:cb,
584 aeadb7bf Kostas Papadimitriou
            interval: 10,
585 aeadb7bf Kostas Papadimitriou
            fast: 5,
586 aeadb7bf Kostas Papadimitriou
            increase: 5,
587 aeadb7bf Kostas Papadimitriou
            max: 15,
588 aeadb7bf Kostas Papadimitriou
            increase_after_calls: 3,
589 aeadb7bf Kostas Papadimitriou
            initial_call: false
590 aeadb7bf Kostas Papadimitriou
        }
591 aeadb7bf Kostas Papadimitriou
592 aeadb7bf Kostas Papadimitriou
        var h = new snf.api.updateHandler(opts);
593 aeadb7bf Kostas Papadimitriou
        h.start();
594 aeadb7bf Kostas Papadimitriou
595 aeadb7bf Kostas Papadimitriou
        var add = $.browser.msie ? 8 : 0;
596 aeadb7bf Kostas Papadimitriou
597 aeadb7bf Kostas Papadimitriou
        window.setTimeout(function(){
598 aeadb7bf Kostas Papadimitriou
            h.stop();
599 aeadb7bf Kostas Papadimitriou
            start();
600 aeadb7bf Kostas Papadimitriou
            // 4 calls, limit reached
601 92bbc5b9 Kostas Papadimitriou
            equal(counter, 4, "normal calls");
602 92bbc5b9 Kostas Papadimitriou
            equal(h.interval, opts.max, "limit reached");
603 aeadb7bf Kostas Papadimitriou
604 aeadb7bf Kostas Papadimitriou
            stop();
605 aeadb7bf Kostas Papadimitriou
            h.start(false);
606 aeadb7bf Kostas Papadimitriou
            h.faster();
607 aeadb7bf Kostas Papadimitriou
            window.setTimeout(function(){
608 aeadb7bf Kostas Papadimitriou
                // 11 calls, limit reached
609 aeadb7bf Kostas Papadimitriou
                start();
610 92bbc5b9 Kostas Papadimitriou
                equal(counter, 11, "faster calls");
611 92bbc5b9 Kostas Papadimitriou
                equal(h.interval, opts.max, "limit reached");
612 aeadb7bf Kostas Papadimitriou
                h.stop();
613 aeadb7bf Kostas Papadimitriou
                stop();
614 aeadb7bf Kostas Papadimitriou
                window.setTimeout(function(){
615 aeadb7bf Kostas Papadimitriou
                    // no additional calls because we stopped it
616 aeadb7bf Kostas Papadimitriou
                    start();
617 92bbc5b9 Kostas Papadimitriou
                    equal(counter, 11, "no additional calls")
618 aeadb7bf Kostas Papadimitriou
                }, 50 + add)
619 aeadb7bf Kostas Papadimitriou
            }, 50 + add)
620 aeadb7bf Kostas Papadimitriou
        }, 43 + add)
621 aeadb7bf Kostas Papadimitriou
    })
622 8d08f18a Kostas Papadimitriou
})