1 |
|
2 |
|
3 |
|
4 | var CodeGradX = require('../codegradxlib.js');
|
5 |
|
6 | var _ = require('lodash');
|
7 | var when = require('when');
|
8 | var rest = require('rest');
|
9 | var interceptor = require('rest/interceptor');
|
10 |
|
11 | describe('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 |
|
80 |
|
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 |
|
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 |
|
119 | var state = new CodeGradX.State(initializer);
|
120 | var faildone = make_faildone(done);
|
121 | state.userAgent = make_fakeUserAgent([
|
122 |
|
123 | { path: 'http://a0.localdomain/alive',
|
124 | status: 200
|
125 | },
|
126 |
|
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 |
|
143 | var state = new CodeGradX.State(initializer);
|
144 | var faildone = make_faildone(done);
|
145 | state.userAgent = make_fakeUserAgent([
|
146 |
|
147 | { path: 'http://a0.localdomain/alive',
|
148 | status: 200
|
149 | },
|
150 |
|
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 |
|
168 |
|
169 |
|
170 | var state = new CodeGradX.State(initializer);
|
171 | var faildone = make_faildone(done);
|
172 | state.userAgent = make_fakeUserAgent([
|
173 |
|
174 | { path: 'http://a0.localdomain/alive',
|
175 | status: 200
|
176 | },
|
177 |
|
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 |
|
198 |
|
199 |
|
200 | var state = new CodeGradX.State(initializer);
|
201 | var faildone = make_faildone(done);
|
202 | state.userAgent = make_fakeUserAgent([
|
203 |
|
204 | { path: 'http://a0.localdomain/alive',
|
205 | status: 202
|
206 | },
|
207 |
|
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 |
|
238 |
|
239 |
|
240 | var state = new CodeGradX.State(initializer);
|
241 | var faildone = make_faildone(done);
|
242 | state.userAgent = make_fakeUserAgent([
|
243 |
|
244 | { path: 'http://a0.localdomain/alive',
|
245 | status: 205
|
246 | },
|
247 |
|
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 |
|
278 |
|
279 |
|
280 | var state = new CodeGradX.State(initializer);
|
281 | var faildone = make_faildone(done);
|
282 | state.log.size = 50;
|
283 | state.userAgent = make_fakeUserAgent([
|
284 |
|
285 | { path: 'http://a0.localdomain/alive',
|
286 | status: 209
|
287 | },
|
288 |
|
289 | { path: 'http://a1.localdomain/alive',
|
290 | status: 210
|
291 | },
|
292 |
|
293 | { path: 'http://a0.localdomain/foo',
|
294 | status: 211
|
295 | },
|
296 |
|
297 | { path: 'http://a0.localdomain/bar',
|
298 | status: 0
|
299 | },
|
300 |
|
301 | { path: 'http://a0.localdomain/alive',
|
302 | status: 402
|
303 | },
|
304 |
|
305 | { path: 'http://a1.localdomain/alive',
|
306 | status: 212
|
307 | },
|
308 |
|
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 |
|
333 |
|
334 |
|
335 | var state = new CodeGradX.State(initializer);
|
336 | var faildone = make_faildone(done);
|
337 | state.log.size = 50;
|
338 | state.userAgent = make_fakeUserAgent([
|
339 |
|
340 | { path: 'http://a0.localdomain/alive',
|
341 | status: 214
|
342 | },
|
343 |
|
344 | { path: 'http://a1.localdomain/alive',
|
345 | status: 0
|
346 | },
|
347 |
|
348 | { path: 'http://a0.localdomain/foo',
|
349 | status: 215
|
350 | },
|
351 |
|
352 | { path: 'http://a0.localdomain/bar',
|
353 | status: 0
|
354 | },
|
355 |
|
356 | { path: 'http://a0.localdomain/alive',
|
357 | status: 404
|
358 | },
|
359 |
|
360 | { path: 'http://a1.localdomain/alive',
|
361 | status: 216
|
362 | },
|
363 |
|
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 |
|
388 |
|
389 |
|
390 | var state = new CodeGradX.State(initializer);
|
391 | var faildone = make_faildone(done);
|
392 | state.log.size = 50;
|
393 | state.userAgent = make_fakeUserAgent([
|
394 |
|
395 | { path: 'http://a0.localdomain/alive',
|
396 | status: 218
|
397 | },
|
398 |
|
399 | { path: 'http://a1.localdomain/alive',
|
400 | status: 0
|
401 | },
|
402 |
|
403 | { path: 'http://a0.localdomain/foo',
|
404 | status: 219
|
405 | },
|
406 |
|
407 | { path: 'http://a0.localdomain/bar',
|
408 | status: 0
|
409 | },
|
410 |
|
411 | { path: 'http://a0.localdomain/alive',
|
412 | status: 405
|
413 | },
|
414 |
|
415 | { path: 'http://a1.localdomain/alive',
|
416 | status: 220
|
417 | },
|
418 |
|
419 | { path: 'http://a1.localdomain/bar',
|
420 | status: 221
|
421 | },
|
422 |
|
423 | { path: 'http://a1.localdomain/hux',
|
424 | status: 0
|
425 | },
|
426 |
|
427 | { path: 'http://a0.localdomain/alive',
|
428 | status: 0
|
429 | },
|
430 |
|
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 |
|
454 | expect(state.servers.a[0].enabled).toBeFalsy();
|
455 | expect(state.servers.a[1].enabled).toBeFalsy();
|
456 |
|
457 |
|
458 | done();
|
459 | });
|
460 | }, faildone);
|
461 | }, faildone);
|
462 | });
|
463 |
|
464 | });
|