UNPKG

14.8 kBJavaScriptView Raw
1// Jasmine tests for servers availability related methods.
2// Here we test various kinds of unavailability with a fake UserAgent.
3
4var CodeGradX = require('../codegradxlib.js');
5
6var _ = require('lodash');
7var when = require('when');
8var rest = require('rest');
9var interceptor = require('rest/interceptor');
10
11describe('CodeGradX', function () {
12 it('should be loaded', function () {
13 expect(CodeGradX).toBeDefined();
14 });
15
16 function make_faildone (done) {
17 return function faildone (reason) {
18 var state = CodeGradX.getCurrentState();
19 state.debug(reason).show();
20 fail(reason);
21 done();
22 };
23 }
24
25 function initializer (state) {
26 state.servers = {
27 domain: '.localdomain',
28 names: ['a', 'e', 'x', 's'],
29 protocol: 'http',
30 a: {
31 suffix: '/alive',
32 0: {
33 host: "a0.localdomain",
34 enabled: false
35 },
36 1: {
37 host: "a1.localdomain",
38 enabled: false
39 }
40 },
41 e: {
42 suffix: '/alive',
43 0: {
44 host: "e0.localdomain",
45 enabled: false
46 },
47 1: {
48 host: "e1.localdomain",
49 enabled: false
50 }
51 },
52 x: {
53 protocol: 'https',
54 suffix: '/dbalive',
55 0: {
56 host: "x0.localdomain",
57 enabled: false
58 },
59 1: {
60 host: "x1.localdomain",
61 enabled: false
62 }
63 },
64 s: {
65 suffix: '/',
66 0: {
67 host: "s0.localdomain",
68 enabled: false
69 },
70 1: {
71 host: "s1.localdomain",
72 enabled: false
73 }
74 }
75 };
76 return state;
77 }
78
79/** make_fakeUserAgent creates HttpResponses (with only a status code)
80 as told by `history`. Once used, items in history are removed.
81*/
82
83 function make_fakeUserAgent (history) {
84 var fakeUserAgent = function (options) {
85 var state = CodeGradX.getCurrentState();
86 var i = _.findIndex(history, { path: options.path });
87 if ( i >= 0 ) {
88 state.debug("fakeUserAgent request " + options.path);
89 var item = history[i];
90 history.splice(i, 1);
91 if ( item.status > 0 ) {
92 var js = {
93 status: { code: item.status },
94 headers: {}
95 };
96 state.debug("fakeUserAgent response " + item.status);
97 return when(js).delay(100 * Math.random());
98 } else {
99 return when.reject("Non responding server " + options.path);
100 }
101 } else {
102 // History was probably incomplete:
103 return when.reject("Unexpected URL " + options.path);
104 }
105 };
106 CodeGradX.getCurrentState().log = new CodeGradX.Log();
107 return fakeUserAgent;
108 }
109
110 it('should create a State', function (done) {
111 var state = new CodeGradX.State(initializer);
112 expect(state).toBeDefined();
113 expect(state instanceof CodeGradX.State).toBeTruthy();
114 done();
115 });
116
117 it('checks A servers: a0 ok', function (done) {
118 // since no A server is initially available, check a0 and a1.
119 var state = new CodeGradX.State(initializer);
120 var faildone = make_faildone(done);
121 state.userAgent = make_fakeUserAgent([
122 // implicit via checkServer('a', 0)
123 { path: 'http://a0.localdomain/alive',
124 status: 200
125 },
126 // implicit via checkServer('a', 1)
127 { path: 'http://a1.localdomain/alive',
128 status: 400
129 }
130 ]);
131 expect(state).toBeDefined();
132 state.checkServers('a').then(function (descriptions) {
133 expect(descriptions).toBe(state.servers.a);
134 expect(descriptions[0].enabled).toBeTruthy();
135 expect(descriptions[0].lastError).not.toBeDefined();
136 expect(descriptions[1].enabled).toBeFalsy();
137 done();
138 }, faildone);
139 });
140
141 it('checks A servers: a0 and a1 ok', function (done) {
142 // since no A server is initially available, check a0 and a1.
143 var state = new CodeGradX.State(initializer);
144 var faildone = make_faildone(done);
145 state.userAgent = make_fakeUserAgent([
146 // implicit via checkServer('a', 0)
147 { path: 'http://a0.localdomain/alive',
148 status: 200
149 },
150 // implicit via checkServer('a', 1)
151 { path: 'http://a1.localdomain/alive',
152 status: 200
153 }
154 ]);
155 expect(state).toBeDefined();
156 state.checkServers('a').then(function (descriptions) {
157 expect(descriptions).toBe(state.servers.a);
158 expect(descriptions[0].enabled).toBeTruthy();
159 expect(descriptions[0].lastError).not.toBeDefined();
160 expect(descriptions[1].enabled).toBeTruthy();
161 expect(descriptions[1].lastError).not.toBeDefined();
162 done();
163 }, faildone);
164 });
165
166 it('request an A server once via a0', function (done) {
167 // since no A server is initially available, this will force a
168 // checkServers('a') which in turn will trigger checkServer('a', 0)
169 // and checkServer('a', 1).
170 var state = new CodeGradX.State(initializer);
171 var faildone = make_faildone(done);
172 state.userAgent = make_fakeUserAgent([
173 // implicit via checkServer('a', 0)
174 { path: 'http://a0.localdomain/alive',
175 status: 200
176 },
177 // implicit via checkServer('a', 1)
178 { path: 'http://a1.localdomain/alive',
179 status: 400
180 },
181 { path: 'http://a0.localdomain/foobar',
182 status: 201
183 }
184 ]);
185 expect(state).toBeDefined();
186 state.sendAXServer('a', {
187 path: '/foobar'
188 }).then(function (response) {
189 expect(response.status.code).toBe(201);
190 expect(state.servers.a[0].enabled).toBeTruthy();
191 expect(state.servers.a[1].enabled).toBeFalsy();
192 done();
193 }, faildone);
194 });
195
196 it('request an A server twice via a0 while a1 ko', function (done) {
197 // since no A server is initially available, this will force a
198 // checkServers('a') which in turn will trigger checkServer('a', 0)
199 // and checkServer('a', 1).
200 var state = new CodeGradX.State(initializer);
201 var faildone = make_faildone(done);
202 state.userAgent = make_fakeUserAgent([
203 // implicit via checkServer('a', 0)
204 { path: 'http://a0.localdomain/alive',
205 status: 202
206 },
207 // implicit via checkServer('a', 1)
208 { path: 'http://a1.localdomain/alive',
209 status: 0
210 },
211 { path: 'http://a0.localdomain/foo',
212 status: 203
213 },
214 { path: 'http://a0.localdomain/bar',
215 status: 204
216 }
217 ]);
218 expect(state).toBeDefined();
219 state.sendAXServer('a', {
220 path: '/foo'
221 }).then(function (response) {
222 expect(response.status.code).toBe(203);
223 expect(state.servers.a[0].enabled).toBeTruthy();
224 expect(state.servers.a[1].enabled).toBeFalsy();
225 state.sendAXServer('a', {
226 path: '/bar'
227 }).then(function (response2) {
228 expect(response2.status.code).toBe(204);
229 expect(state.servers.a[0].enabled).toBeTruthy();
230 expect(state.servers.a[1].enabled).toBeFalsy();
231 done();
232 }, faildone);
233 }, faildone);
234 });
235
236 it('request an A server twice via a0 while a1 ok', function (done) {
237 // since no A server is initially available, this will force a
238 // checkServers('a') which in turn will trigger checkServer('a', 0)
239 // and checkServer('a', 1).
240 var state = new CodeGradX.State(initializer);
241 var faildone = make_faildone(done);
242 state.userAgent = make_fakeUserAgent([
243 // implicit via checkServer('a', 0)
244 { path: 'http://a0.localdomain/alive',
245 status: 205
246 },
247 // implicit via checkServer('a', 1)
248 { path: 'http://a1.localdomain/alive',
249 status: 206
250 },
251 { path: 'http://a0.localdomain/foo',
252 status: 207
253 },
254 { path: 'http://a0.localdomain/bar',
255 status: 208
256 }
257 ]);
258 expect(state).toBeDefined();
259 state.sendAXServer('a', {
260 path: '/foo'
261 }).then(function (response) {
262 expect(response.status.code).toBe(207);
263 expect(state.servers.a[0].enabled).toBeTruthy();
264 expect(state.servers.a[1].enabled).toBeTruthy();
265 state.sendAXServer('a', {
266 path: '/bar'
267 }).then(function (response2) {
268 expect(response2.status.code).toBe(208);
269 expect(state.servers.a[0].enabled).toBeTruthy();
270 expect(state.servers.a[1].enabled).toBeTruthy();
271 done();
272 }, faildone);
273 }, faildone);
274 });
275
276 it('request an A server twice via a0 then a1 (always ok)', function (done) {
277 // since no A server is initially available, this will force a
278 // checkServers('a') which in turn will trigger checkServer('a', 0)
279 // and checkServer('a', 1).
280 var state = new CodeGradX.State(initializer);
281 var faildone = make_faildone(done);
282 state.log.size = 50;
283 state.userAgent = make_fakeUserAgent([
284 // implicit via checkServer('a', 0)
285 { path: 'http://a0.localdomain/alive',
286 status: 209
287 },
288 // implicit via checkServer('a', 1)
289 { path: 'http://a1.localdomain/alive',
290 status: 210
291 },
292 // 1st request: ok
293 { path: 'http://a0.localdomain/foo',
294 status: 211
295 },
296 // 2nd request: ko since a0 subitly failed!
297 { path: 'http://a0.localdomain/bar',
298 status: 0
299 },
300 // checkServers('a') again: a0 still ko
301 { path: 'http://a0.localdomain/alive',
302 status: 402
303 },
304 // checkServers('a') again, a1 now ok
305 { path: 'http://a1.localdomain/alive',
306 status: 212
307 },
308 // 2nd request again: ok
309 { path: 'http://a1.localdomain/bar',
310 status: 213
311 }
312 ]);
313 expect(state).toBeDefined();
314 state.sendAXServer('a', {
315 path: '/foo'
316 }).then(function (response) {
317 expect(response.status.code).toBe(211);
318 expect(state.servers.a[0].enabled).toBeTruthy();
319 expect(state.servers.a[1].enabled).toBeTruthy();
320 state.sendAXServer('a', {
321 path: '/bar'
322 }).then(function (response2) {
323 expect(response2.status.code).toBe(213);
324 expect(state.servers.a[1].enabled).toBeTruthy();
325 expect(state.servers.a[0].enabled).toBeFalsy();
326 done();
327 }, faildone);
328 }, faildone);
329 });
330
331 it('request an A server twice via a0 then a1 (resurrecting)', function (done) {
332 // since no A server is initially available, this will force a
333 // checkServers('a') which in turn will trigger checkServer('a', 0)
334 // and checkServer('a', 1).
335 var state = new CodeGradX.State(initializer);
336 var faildone = make_faildone(done);
337 state.log.size = 50;
338 state.userAgent = make_fakeUserAgent([
339 // implicit via checkServer('a', 0)
340 { path: 'http://a0.localdomain/alive',
341 status: 214
342 },
343 // implicit via checkServer('a', 1)
344 { path: 'http://a1.localdomain/alive',
345 status: 0
346 },
347 // 1st request: ok
348 { path: 'http://a0.localdomain/foo',
349 status: 215
350 },
351 // 2nd request: ko since a0 subitly failed!
352 { path: 'http://a0.localdomain/bar',
353 status: 0
354 },
355 // checkServers('a') again: a0 still ko
356 { path: 'http://a0.localdomain/alive',
357 status: 404
358 },
359 // checkServers('a') again, a1 now ok
360 { path: 'http://a1.localdomain/alive',
361 status: 216
362 },
363 // 2nd request again: ok
364 { path: 'http://a1.localdomain/bar',
365 status: 217
366 }
367 ]);
368 expect(state).toBeDefined();
369 state.sendAXServer('a', {
370 path: '/foo'
371 }).then(function (response) {
372 expect(response.status.code).toBe(215);
373 expect(state.servers.a[0].enabled).toBeTruthy();
374 expect(state.servers.a[1].enabled).toBeFalsy();
375 state.sendAXServer('a', {
376 path: '/bar'
377 }).then(function (response2) {
378 expect(response2.status.code).toBe(217);
379 expect(state.servers.a[1].enabled).toBeTruthy();
380 expect(state.servers.a[0].enabled).toBeFalsy();
381 done();
382 }, faildone);
383 }, faildone);
384 });
385
386 it('request an A server twice via a0 then a1 dying', function (done) {
387 // since no A server is initially available, this will force a
388 // checkServers('a') which in turn will trigger checkServer('a', 0)
389 // and checkServer('a', 1).
390 var state = new CodeGradX.State(initializer);
391 var faildone = make_faildone(done);
392 state.log.size = 50;
393 state.userAgent = make_fakeUserAgent([
394 // implicit via checkServer('a', 0)
395 { path: 'http://a0.localdomain/alive',
396 status: 218
397 },
398 // implicit via checkServer('a', 1)
399 { path: 'http://a1.localdomain/alive',
400 status: 0
401 },
402 // 1st request: ok
403 { path: 'http://a0.localdomain/foo',
404 status: 219
405 },
406 // 2nd request: ko since a0 subitly failed!
407 { path: 'http://a0.localdomain/bar',
408 status: 0
409 },
410 // checkServers('a') again: a0 still ko
411 { path: 'http://a0.localdomain/alive',
412 status: 405
413 },
414 // checkServers('a') again, a1 now ok
415 { path: 'http://a1.localdomain/alive',
416 status: 220
417 },
418 // 2nd request again, now towards a1: ok
419 { path: 'http://a1.localdomain/bar',
420 status: 221
421 },
422 // 3rd request again: ko
423 { path: 'http://a1.localdomain/hux',
424 status: 0
425 },
426 // checkServers('a') again: a0 still ko
427 { path: 'http://a0.localdomain/alive',
428 status: 0
429 },
430 // checkServers('a') again, a1 still ko
431 { path: 'http://a1.localdomain/alive',
432 status: 406
433 }
434 ]);
435 expect(state).toBeDefined();
436 state.sendAXServer('a', {
437 path: '/foo'
438 }).then(function (response) {
439 expect(response.status.code).toBe(219);
440 expect(state.servers.a[0].enabled).toBeTruthy();
441 expect(state.servers.a[1].enabled).toBeFalsy();
442 return state.sendAXServer('a', {
443 path: '/bar'
444 }).then(function (response2) {
445 expect(response2.status.code).toBe(221);
446 expect(state.servers.a[1].enabled).toBeTruthy();
447 expect(state.servers.a[0].enabled).toBeFalsy();
448 return state.sendAXServer('a', {
449 path: '/hux'
450 }).then(function (response3) {
451 faildone("should not answer");
452 }).catch(function (reason) {
453 // all servers unavailable
454 expect(state.servers.a[0].enabled).toBeFalsy();
455 expect(state.servers.a[1].enabled).toBeFalsy();
456 //console.log(reason);
457 //state.log.show();
458 done();
459 });
460 }, faildone);
461 }, faildone);
462 });
463
464});