8000 fix(test): moved multiprocess test to tap · WebHu/log4js-node@074c04e · GitHub
[go: up one dir, main page]

Skip to content

Commit 074c04e

Browse files
author
Gareth Jones
committed
fix(test): moved multiprocess test to tap
1 parent 6026b1a commit 074c04e

File tree

2 files changed

+331
-328
lines changed

2 files changed

+331
-328
lines changed

test/tap/multiprocess-test.js

Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
'use strict';
2+
3+
const test = require('tap').test;
4+
const sandbox = require('sandboxed-module');
5+
6+
function makeFakeNet() {
7+
return {
8+
logEvents: [],
9+
data: [],
10+
cbs: {},
11+
createConnectionCalled: 0,
12+
fakeAppender: function (logEvent) {
13+
this.logEvents.push(logEvent);
14+
},
15+
createConnection: function (port, host) {
16+
const fakeNet = this;
17+
this.port = port;
18+
this.host = host;
19+
this.createConnectionCalled += 1;
20+
return {
21+
on: function (evt, cb) {
22+
fakeNet.cbs[evt] = cb;
23+
},
24+
write: function (data, encoding) {
25+
fakeNet.data.push(data);
26+
fakeNet.encoding = encoding;
27+
},
28+
end: function () {
29+
fakeNet.closeCalled = true;
30+
}
31+
};
32+
},
33+
createServer: function (cb) {
34+
const fakeNet = this;
35+
cb({
36+
remoteAddress: '1.2.3.4',
37+
remotePort: '1234',
38+
setEncoding: function (encoding) {
39+
fakeNet.encoding = encoding;
40+
},
41+
on: function (event, cb2) {
42+
fakeNet.cbs[event] = cb2;
43+
}
44+
});
45+
46+
return {
47+
listen: function (port, host) {
48+
fakeNet.port = port;
49+
fakeNet.host = host;
50+
}
51+
};
52+
}
53+
};
54+
}
55+
56+
test('Multiprocess Appender', (batch) => {
57+
batch.test('worker', (t) => {
58+
const fakeNet = makeFakeNet();
59+
60+
const appender = sandbox.require(
61+
'../../lib/appenders/multiprocess',
62+
{
63+
requires: {
64+
net: fakeNet
65+
}
66+
}
67+
).appender({ mode: 'worker', loggerPort: 1234, loggerHost: 'pants' });
68+
69+
// don't need a proper log event for the worker tests
70+
appender('before connect');
71+
fakeNet.cbs.connect();
72+
appender('after connect');
73+
fakeNet.cbs.close(true);
74+
appender('after error, before connect');
75+
fakeNet.cbs.connect();
76+
appender('after error, after connect');
77+
appender(new Error('Error test'));
78+
79+
const net = fakeNet;
80+
t.test('should open a socket to the loggerPort and loggerHost', (assert) => {
81+
assert.equal(net.port, 1234);
82+
assert.equal(net.host, 'pants');
83+
assert.end();
84+
});
85+
86+
t.test('should buffer messages written before socket is connected', (assert) => {
87+
assert.equal(net.data[0], JSON.stringify('before connect'));
88+
assert.end();
89+
});
90+
91+
t.test('should write log messages to socket as json strings with a terminator string', (assert) => {
92+
assert.equal(net.data[0], JSON.stringify('before connect'));
93+
assert.equal(net.data[1], '__LOG4JS__');
94+
assert.equal(net.data[2], JSON.stringify('after connect'));
95+
assert.equal(net.data[3], '__LOG4JS__');
96+
assert.equal(net.encoding, 'utf8');
97+
assert.end();
98+
});
99+
100+
t.test('should attempt to re-open the socket on error', (assert) => {
101+
assert.equal(net.data[4], JSON.stringify('after error, before connect'));
102+
assert.equal(net.data[5], '__LOG4JS__');
103+
assert.equal(net.data[6], JSON.stringify('after error, after connect'));
104+
assert.equal(net.data[7], '__LOG4JS__');
105+
assert.equal(net.createConnectionCalled, 2);
106+
assert.end();
107+
});
108+
109+
t.test('should serialize an Error correctly', (assert) => {
110+
assert.ok(
111+
JSON.parse(net.data[8]).stack,
112+
`Expected:\n\n${net.data[8]}\n\n to have a 'stack' property`
113+
);
114+
const actual = JSON.parse(net.data[8]).stack;
115+
assert.match(actual, /^Error: Error test/);
116+
assert.end();
117+
});
118+
t.end();
119+
});
120+
121+
batch.test('worker with timeout', (t) => {
122+
const fakeNet = makeFakeNet();
123+
124+
const appender = sandbox.require(
125+
'../../lib/appenders/multiprocess',
126+
{
127+
requires: {
128+
net: fakeNet
129+
}
130+
}
131+
).appender({ mode: 'worker' });
132+
133+
// don't need a proper log event for the worker tests
134+
appender('before connect');
135+
fakeNet.cbs.connect();
136+
appender('after connect');
137+
fakeNet.cbs.timeout();
138+
appender('after timeout, before close');
139+
fakeNet.cbs.close();
140+
appender('after close, before connect');
141+
fakeNet.cbs.connect();
142+
appender('after close, after connect');
143+
144+
const net = fakeNet;
145+
146+
t.test('should attempt to re-open the socket', (assert) => {
147+
// skipping the __LOG4JS__ separators
148+
assert.equal(net.data[0], JSON.stringify('before connect'));
149+
assert.equal(net.data[2], JSON.stringify('after connect'));
150+
assert.equal(net.data[4], JSON.stringify('after timeout, before close'));
151+
assert.equal(net.data[6], JSON.stringify('after close, before connect'));
152+
assert.equal(net.data[8], JSON.stringify('after close, after connect'));
153+
assert.equal(net.createConnectionCalled, 2);
154+
assert.end();
155+
});
156+
t.end();
157+
});
158+
159+
batch.test('worker defaults', (t) => {
160+
const fakeNet = makeFakeNet();
161+
162+
sandbox.require(
163+
'../../lib/appenders/multiprocess',
164+
{
165+
requires: {
166+
net: fakeNet
167+
}
168+
}
169+
).appender({ mode: 'worker' });
170+
171+
t.test('should open a socket to localhost:5000', (assert) => {
172+
assert.equal(fakeNet.port, 5000);
173+
assert.equal(fakeNet.host, 'localhost');
174+
assert.end();
175+
});
176+
t.end();
177+
});
178+
179+
batch.test('master', (t) => {
180+
const fakeNet = makeFakeNet();
181+
182+
const appender = sandbox.require(
183+
'../../lib/appenders/multiprocess',
184+
{
185+
requires: {
186+
net: fakeNet
187+
}
188+
}
189+
).appender({
190+
mode: 'master',
191+
loggerHost: 'server',
192+
loggerPort: 1234,
193+
actualAppender: fakeNet.fakeAppender.bind(fakeNet)
194+
});
195+
196+
appender('this should be sent to the actual appender directly');
197+
198+
const net = fakeNet;
199+
200+
t.test('should listen for log messages on loggerPort and loggerHost', (assert) => {
201+
assert.equal(net.port, 1234);
202+
assert.equal(net.host, 'server');
203+
assert.end();
204+
});
205+
206+
t.test('should return the underlying appender', (assert) => {
207+
assert.equal(net.logEvents[0], 'this should be sent to the actual appender directly');
208+
assert.end();
209+
});
210+
211+
t.test('when a client connects', (assert) => {
212+
const logString = `${JSON.stringify(
213+
{
214+
level: { level: 10000, levelStr: 'DEBUG' },
215+
data: ['some debug']
216+
}
217+
)}__LOG4JS__`;
218+
219+
net.cbs.data(
220+
`${JSON.stringify(
221+
{
222+
level: { level: 40000, levelStr: 'ERROR' },
223+
data: ['an error message']
224+
}
225+
)}__LOG4JS__`
226+
);
227+
net.cbs.data(logString.substring(0, 10));
228+
net.cbs.data(logString.substring(10));
229+
net.cbs.data(logString + logString + logString);
230+
net.cbs.end(
231+
`${JSON.stringify(
232+
{
233+
level: { level: 50000, levelStr: 'FATAL' },
234+
data: ["that's all folks"]
235+
}
236+
)}__LOG4JS__`
237+
);
238+
net.cbs.data('bad message__LOG4JS__');
239+
240+
// should parse log messages into log events and send to appender
241+
assert.equal(net.logEvents[1].level.toString(), 'ERROR');
242+
assert.equal(net.logEvents[1].data[0], 'an error message');
243+
assert.equal(net.logEvents[1].remoteAddress, '1.2.3.4');
244+
assert.equal(net.logEvents[1].remotePort, '1234');
245+
246+
// should parse log messages split into multiple chunks'
247+
assert.equal(net.logEvents[2].level.toString(), 'DEBUG');
248+
assert.equal(net.logEvents[2].data[0], 'some debug');
249+
assert.equal(net.logEvents[2].remoteAddress, '1.2.3.4');
250+
assert.equal(net.logEvents[2].remotePort, '1234');
251+
252+
// should parse multiple log messages in a single chunk'
253+
assert.equal(net.logEvents[3].data[0], 'some debug');
254+
assert.equal(net.logEvents[4].data[0], 'some debug');
255+
assert.equal(net.logEvents[5].data[0], 'some debug');
256+
257+
// should handle log messages sent as part of end event'
258+
assert.equal(net.logEvents[6].data[0], "that's all folks");
259+
260+
// should handle unparseable log messages
261+
assert.equal(net.logEvents[7].level.toString(), 'ERROR');
262+
assert.equal(net.logEvents[7].categoryName, 'log4js');
263+
assert.equal(net.logEvents[7].data[0], 'Unable to parse log:');
264+
assert.equal(net.logEvents[7].data[1], 'bad message');
265+
266+
assert.end();
267+
});
268+
t.end();
269+
});
270+
271+
batch.test('master defaults', (t) => {
272+
const fake 10000 Net = makeFakeNet();
273+
274+
sandbox.require(
275+
'../../lib/appenders/multiprocess',
276+
{
277+
requires: {
278+
net: fakeNet
279+
}
280+
}
281+
).appender({ mode: 'master' });
282+
283+
t.test('should listen for log messages on localhost:5000', (assert) => {
284+
assert.equal(fakeNet.port, 5000);
285+
assert.equal(fakeNet.host, 'localhost');
286+
assert.end();
287+
});
288+
t.end();
289+
});
290+
291+
batch.test('configure', (t) => {
292+
const results = {};
293+
const fakeNet = makeFakeNet();
294+
295+
sandbox.require(
296+
'../../lib/appenders/multiprocess',
297+
{
298+
requires: {
299+
net: fakeNet,
300+
'../log4js': {
301+
loadAppender: function (app) {
302+
results.appenderLoaded = app;
303+
},
304+
appenderMakers: {
305+
madeupappender: function (config, options) {
306+
results.config = config;
307+
results.options = options;
308+
}
309+
}
310+
}
311+
}
312+
}
313+
).configure(
314+
{
315+
mode: 'master',
316+
appender: {
317+
type: 'madeupappender',
318+
cheese: 'gouda'
319+
}
320+
},
321+
{ crackers: 'jacobs' }
322+
);
323+
324+
t.equal(results.appenderLoaded, 'madeupappender', 'should load underlying appender for master');
325+
t.equal(results.config.cheese, 'gouda', 'should pass config to underlying appender');
326+
t.equal(results.options.crackers, 'jacobs', 'should pass options to underlying appender');
327+
t.end();
328+
});
329+
330+
batch.end();
331+
});

0 commit comments

Comments
 (0)
0