UNPKG

10.9 kBJavaScriptView Raw
1/*
2 * The process.nextTick in those tests are used to avoid AssertionError to be caught by a try/catch in the tested code.
3 */
4
5require('mocha');
6var should = require('should');
7var _ = require('lodash');
8
9var app = require(__dirname + '/../lib/application');
10var actors = require(__dirname + '/../lib/actors');
11var properties = require(__dirname + '/../lib/properties');
12var monitoring = require(__dirname + '/../lib/monitoring');
13var utils = {
14 aid: require(__dirname + '/../lib/utils/aid')
15};
16
17describe('framework patterns', function () {
18
19 beforeEach(function (done) {
20 app.start({discoveryAddr: 'udp://224.0.0.1:5555'}, done);
21 });
22
23 afterEach(function (done) {
24 app.removeActor('sample');
25 app.removeActor('fake');
26 app.stop(done);
27 });
28
29 describe('application mecanisms', function () {
30
31 it('inproc request/reply sample->tmp', function (done) {
32 var count = 0;
33 var id = '';
34 app.addActor('sample', function (req) {
35 count++;
36 var _this = this;
37 process.nextTick(function () {
38 should.exist(req, 'actor sample : req should exist');
39 req.should.have.keys('from', 'to', 'content', 'timeout', 'cb', 'date', 'id', 'headers', 'reply');
40 utils.aid.bare(_this.id).should.be.eql('sample', 'actor sample : this.id should be "sample"');
41 utils.aid.bare(req.from).should.be.eql('tmp', 'actor sample : req.from should be "tmp"');
42 utils.aid.bare(req.to).should.be.eql('sample', 'actor sample : req.to should be "sample"');
43 req.content.should.be.eql('hello', 'actor sample : req.content should be "hello"');
44 req.timeout.should.be.eql(1500, 'actor sample : req.timeout should be "2000"');
45 req.cb.should.be.eql(true, 'actor sample : req.cb.should.be "true"');
46 req.date.should.have.type('number', 'actor sample : req.date should be a number');
47 req.headers.should.have.type('object', 'actor sample : req.headers should be an object');
48 req.headers.should.be.empty;
49 req.id.should.have.type('string', 'actor sample : req.id should be a string');
50 id = req.id;
51 req.reply.should.have.type('function', 'actor sample : req.reply should be a function');
52 req.reply(null, 'hi');
53 });
54 });
55
56 app.send('tmp', 'sample', 'hello', 1500, function (err, res) {
57 process.nextTick(function () {
58 should.exist(res, 'actor tmp : res should exist');
59 res.should.have.keys('from', 'to', 'content', 'err', 'date', 'id', 'headers');
60 should.not.exist(res.err, 'actor tmp : res.error should be null');
61 utils.aid.bare(res.from).should.be.eql('sample', 'actor tmp : res.from should be "sample"');
62 utils.aid.bare(res.to).should.be.eql('tmp', 'actor tmp : res.to should be "tmp"');
63 res.content.should.be.eql('hi', 'actor tmp : res.content should be "hi"');
64 res.date.should.have.type('number', 'actor tmp : res.date should be a number');
65 res.headers.should.have.type('object', 'actor tmp : res.headers should be an object');
66 res.headers.should.be.empty;
67 res.id.should.have.type('string', 'actor tmp : res.id should be a string');
68 res.id.should.be.eql(id, 'actor tmp : res.id should be the same as req.id at actor sample');
69 count.should.be.eql(1, 'actor tmp : actor sample code should have been invoked once');
70 done();
71 });
72 });
73 });
74
75 it('send failure due to a timeout', function (done) {
76 app.send('tmp', 'sample', 'hello', 1, function (err) {
77 process.nextTick(function () {
78 should.exist(err, 'actor tmp : err should exist (timeout expected)');
79 err.should.have.key('code');
80 err.code.should.be.eql('TIMEOUT', 'actor tmp : err.code should be "TIMEOUT"');
81 done();
82 });
83 });
84 });
85
86 it('middlewares', function (done) {
87 var counts = {
88 'req_out': 0,
89 'req_in': 0,
90 'res_out': 0,
91 'res_in': 0
92 };
93 app.use(function (type, msg, next) {
94 process.nextTick(function () {
95 type.should.be.type('string', 'middleware : type should be a string');
96 _.keys(counts).should.containEql(type, 'middleware : type should be in ' + _.keys(counts));
97 msg.should.be.type('object', 'middleware : msg should be an object');
98 next.should.be.type('function', 'middleware : next should be a function');
99 counts[type]++;
100 next();
101 });
102 });
103
104 app.addActor('sample', function (req) {
105 req.reply();
106 });
107
108 app.send('tmp', 'sample', 'hello', function (err) {
109 process.nextTick(function () {
110 should.not.exist(err, 'actor tmp : err should not exist');
111 _.forEach(counts, function (value, key) {
112 value.should.be.eql(1, 'actor tmp : counts["' + key + '"] should be 1');
113 });
114 done();
115 });
116 });
117 });
118 });
119
120 describe('monitoring API', function () {
121 afterEach(function (done) {
122 monitoring.removeAllListeners();
123 done();
124 });
125
126 describe('events & status access', function () {
127 var discoveryTimeout = properties.discoveryTimeout;
128 var discoveryMaxInterval = properties.discoveryMaxInterval;
129 var discoveryMinInterval = properties.discoveryMinInterval;
130
131 before(function (done) {
132 properties.discoveryTimeout = 210;
133 properties.discoveryMinInterval = 100;
134 properties.discoveryMaxInterval = 100;
135 done();
136 });
137
138 after(function (done) {
139 properties.discoveryTimeout = discoveryTimeout;
140 properties.discoveryMinInterval = discoveryMaxInterval;
141 properties.discoveryMaxInterval = discoveryMinInterval;
142 done();
143 });
144
145 it('events & status through monitoring API (inproc communication)', function (done) {
146 var counts = {
147 actorAdded: 0,
148 actorRemoved: 0,
149 reqSent: 0,
150 reqReceived: 0,
151 resSent: 0,
152 resReceived: 0,
153 discoveryStart: 0,
154 discoveryStop: 0,
155 discovery: 0
156 };
157
158 var aids = monitoring.actors();
159 should.exist(aids);
160 aids.should.be.instanceOf(Array);
161 var initActorsCount = aids.length;
162
163 monitoring.on('actor added', function (aid, scope) {
164 counts.actorAdded++;
165 aid.should.have.type('string', 'Actor added aid should be a string');
166 scope.should.be.eql('process', 'Actor added scope should be "process"');
167 });
168
169 monitoring.on('actor removed', function (aid, scope) {
170 counts.actorRemoved++;
171 aid.should.have.type('string', 'Actor removed aid should be a string');
172 scope.should.be.eql('process', 'Actor removed scope should be "process"');
173 });
174
175 monitoring.on('req sent', function (req) {
176 should.exist(req, 'Req sent should exist');
177 req.should.have.type('object', 'Req sent should be an object');
178 counts.reqSent++;
179 });
180
181 monitoring.on('req received', function (req) {
182 should.exist(req, 'Req received should exist');
183 req.should.have.type('object', 'Req received should be an object');
184 counts.reqReceived++;
185 });
186
187 monitoring.on('res sent', function (res) {
188 should.exist(res, 'Res sent should exist');
189 res.should.have.type('object', 'Res sent should be an object');
190 counts.resSent++;
191 });
192
193 monitoring.on('res received', function (req) {
194 should.exist(req, 'Res received should exist');
195 req.should.have.type('object', 'Res received should be an object');
196 counts.resReceived++;
197 });
198
199 monitoring.on('discovery started', function (aid) {
200 should.exist(aid);
201 aid.should.be.eql('sample');
202 var discoveries = monitoring.discoveries();
203 should.exist(discoveries);
204 discoveries.should.have.type('object');
205 discoveries.should.have.key(aid);
206 counts.discoveryStart++;
207 });
208
209 monitoring.on('discovery stopped', function (aid) {
210 should.exist(aid);
211 aid.should.be.eql('sample');
212 var discoveries = monitoring.discoveries();
213 should.exist(discoveries);
214 discoveries.should.have.type('object');
215 counts.discoveryStop++;
216 });
217
218 monitoring.on('discovery', function (aid) {
219 should.exist(aid);
220 aid.should.be.eql('sample');
221 counts.discovery++;
222 });
223
224 app.addActor('sample', function (req) {
225 req.reply();
226 });
227
228 aids = monitoring.actors();
229 aids.should.have.length(initActorsCount + 1);
230 utils.aid.bare(aids[initActorsCount]).should.be.eql('sample');
231
232 app.send('tmp', 'sample', 'Hello', function () {
233 app.removeActor('sample');
234 process.nextTick(function () {
235 counts.actorAdded.should.be.eql(1, 'One actor should have been added');
236 counts.actorRemoved.should.be.eql(1, 'One actor should have been removed');
237 counts.reqSent.should.be.eql(1, 'One request should have been sent');
238 counts.reqReceived.should.be.eql(1, 'One request should have been received');
239 counts.resSent.should.be.eql(1, 'One response should have been sent');
240 counts.resReceived.should.be.eql(1, 'One response should have been received');
241
242 setTimeout(function () {
243 counts.discoveryStart.should.be.eql(1, 'One discovery should have been started');
244 counts.discoveryStop.should.be.eql(1, 'One discovery should have been stopped');
245 counts.discovery.should.be.eql(3, '4 discoveries should have been processed');
246 done();
247 }, 310);
248 });
249 });
250 });
251 });
252
253 describe('container ping', function () {
254 var containerPingTimeout = properties.containerPingTimeout;
255
256 before(function (done) {
257 properties.containerPingTimeout = 100;
258 done();
259 });
260
261 after(function (done) {
262 properties.containerPingTimeout = containerPingTimeout;
263 done();
264 });
265
266 it('ping my own container', function (done) {
267 monitoring.pingContainer(properties.ID, function (err) {
268 process.nextTick(function () {
269 should.not.exist(err);
270 });
271 done();
272 });
273 });
274
275 it('ping fake container', function (done) {
276 monitoring.pingContainer('fake', function (err) {
277 process.nextTick(function () {
278 should.exist(err);
279 err.should.have.type('object');
280 err.should.have.key('code');
281 err.code.should.be.eql('TIMEOUT');
282 done();
283 });
284 });
285 });
286 });
287 });
288});