1 |
|
2 |
|
3 |
|
4 |
|
5 | require('mocha');
|
6 | var should = require('should');
|
7 | var _ = require('lodash');
|
8 |
|
9 | var app = require(__dirname + '/../lib/application');
|
10 | var actors = require(__dirname + '/../lib/actors');
|
11 | var properties = require(__dirname + '/../lib/properties');
|
12 | var monitoring = require(__dirname + '/../lib/monitoring');
|
13 | var utils = {
|
14 | aid: require(__dirname + '/../lib/utils/aid')
|
15 | };
|
16 |
|
17 | describe('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 | });
|