Skip to content

Commit ca81284

Browse files
Merge pull request #45 from mattiaerre/tests-2nd-iteration
tests 2nd iteration
2 parents 1ddfb4d + e029570 commit ca81284

File tree

8 files changed

+139
-53
lines changed

8 files changed

+139
-53
lines changed

.eslintrc.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
"globals": {
44
"describe": false,
55
"it": false,
6-
"beforeEach": false
6+
"beforeEach": false,
7+
"before": false,
8+
"after": false
79
},
810
"rules": {
911
"import/no-extraneous-dependencies": [

examples/package.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414
"license": "MIT",
1515
"dependencies": {
1616
"express": "^4.14.0",
17-
"express-favicon-short-circuit": "^1.1.0",
18-
"on-headers": "^1.0.1",
19-
"pidusage": "^1.0.4",
20-
"socket.io": "^1.4.8"
17+
"express-favicon-short-circuit": "^1.1.0"
2118
},
2219
"scripts": {
2320
"start": "node index.js"
@@ -26,4 +23,4 @@
2623
"type": "git",
2724
"url": "https://github.com/RafalWilinski/express-status-monitor/tree/master/examples"
2825
}
29-
}
26+
}

helpers/gather-os-metrics.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ module.exports = (io, span) => {
3232
span.responses.push(defaultResponse);
3333
}
3434

35+
// todo: I think this check should be moved somewhere else
3536
if (span.os.length >= span.retention) span.os.shift();
3637
if (span.responses[0] && span.responses.length > span.retention) span.responses.shift();
3738

helpers/on-headers-listener.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module.exports = (statusCode, startTime, spans) => {
2+
const diff = process.hrtime(startTime);
3+
const responseTime = diff[0] * 1e3 + diff[1] * 1e-6;
4+
const category = Math.floor(statusCode / 100);
5+
6+
spans.forEach((span) => {
7+
const last = span.responses[span.responses.length - 1];
8+
if (last !== undefined && last.timestamp / 1000 + span.interval > Date.now() / 1000) {
9+
last[category]++;
10+
last.count++;
11+
last.mean = last.mean + ((responseTime - last.mean) / last.count);
12+
} else {
13+
span.responses.push({
14+
2: category === 2 ? 1 : 0,
15+
3: category === 3 ? 1 : 0,
16+
4: category === 4 ? 1 : 0,
17+
5: category === 5 ? 1 : 0,
18+
count: 1,
19+
mean: responseTime,
20+
timestamp: Date.now(),
21+
});
22+
}
23+
});
24+
};

helpers/socket-io-init.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/* eslint strict: "off" */
2+
'use strict';
3+
4+
const socketIo = require('socket.io');
5+
const gatherOsMetrics = require('./gather-os-metrics');
6+
7+
let io;
8+
9+
module.exports = (server, spans) => {
10+
if (io === null || io === undefined) {
11+
io = socketIo(server);
12+
13+
io.on('connection', (socket) => {
14+
socket.emit('start', spans);
15+
socket.on('change', () => {
16+
socket.emit('start', spans);
17+
});
18+
});
19+
20+
spans.forEach((span) => {
21+
span.os = [];
22+
span.responses = [];
23+
const interval = setInterval(() => gatherOsMetrics(io, span), span.interval * 1000);
24+
interval.unref(); // don't keep node.js process up
25+
});
26+
}
27+
};

index.js

Lines changed: 4 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ const fs = require('fs');
22
const path = require('path');
33
const onHeaders = require('on-headers');
44
const validate = require('./helpers/validate');
5-
const gatherOsMetrics = require('./helpers/gather-os-metrics');
6-
7-
let io;
5+
const onHeadersListener = require('./helpers/on-headers-listener');
6+
const socketIoInit = require('./helpers/socket-io-init');
87

98
const middlewareWrapper = (config) => {
109
config = validate(config);
@@ -17,55 +16,13 @@ const middlewareWrapper = (config) => {
1716
.replace(/{{style}}/g, fs.readFileSync(path.join(__dirname, '/style.css')));
1817

1918
return (req, res, next) => {
20-
if (io === null || io === undefined) {
21-
22-
io = require('socket.io')(req.socket.server);
23-
24-
io.on('connection', (socket) => {
25-
socket.emit('start', config.spans);
26-
socket.on('change', function () {
27-
socket.emit('start', config.spans);
28-
});
29-
});
30-
31-
config.spans.forEach((span) => {
32-
span.os = [];
33-
span.responses = [];
34-
const interval = setInterval(() => gatherOsMetrics(io, span), span.interval * 1000);
35-
interval.unref(); // don't keep node.js process up
36-
});
37-
}
19+
socketIoInit(req.socket.server, config.spans);
3820

3921
const startTime = process.hrtime();
4022
if (req.path === config.path) {
4123
res.send(renderedHtml);
4224
} else {
43-
onHeaders(res, () => {
44-
const diff = process.hrtime(startTime);
45-
const responseTime = diff[0] * 1e3 + diff[1] * 1e-6;
46-
const category = Math.floor(res.statusCode / 100);
47-
48-
config.spans.forEach((span) => {
49-
const last = span.responses[span.responses.length - 1];
50-
if (last !== undefined &&
51-
last.timestamp / 1000 + span.interval > Date.now() / 1000) {
52-
last[category]++;
53-
last.count++;
54-
last.mean = last.mean + ((responseTime - last.mean) / last.count);
55-
} else {
56-
span.responses.push({
57-
'2': category === 2 ? 1 : 0,
58-
'3': category === 3 ? 1 : 0,
59-
'4': category === 4 ? 1 : 0,
60-
'5': category === 5 ? 1 : 0,
61-
count: 1,
62-
mean: responseTime,
63-
timestamp: Date.now()
64-
});
65-
}
66-
});
67-
});
68-
25+
onHeaders(res, () => { onHeadersListener(res.statusCode, startTime, config.spans) });
6926
next();
7027
}
7128
};
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
const chai = require('chai');
2+
const sinon = require('sinon');
3+
4+
chai.should();
5+
6+
const onHeadersListener = require('../../helpers/on-headers-listener');
7+
const defaultConfig = require('../../helpers/default-config');
8+
9+
describe('helpers', () => {
10+
describe('on-headers-listener', () => {
11+
describe('when invoked', () => {
12+
const clock = sinon.useFakeTimers();
13+
const spans = defaultConfig.spans;
14+
15+
before(() => {
16+
spans.forEach((span) => {
17+
span.responses = [];
18+
});
19+
});
20+
21+
after(() => {
22+
clock.restore();
23+
});
24+
25+
it('then for all spans, responses length should equal 1', () => {
26+
onHeadersListener(404, process.hrtime(), spans);
27+
28+
spans.forEach((span) => {
29+
span.responses.length.should.equal(1);
30+
});
31+
});
32+
33+
describe('when invoked after 1 second', () => {
34+
it('then for span interval 1, responses length should equal 2', () => {
35+
clock.tick(1000);
36+
onHeadersListener(500, process.hrtime(), spans);
37+
38+
spans.forEach((span) => {
39+
if (span.interval === 1) {
40+
span.responses.length.should.equal(2);
41+
} else {
42+
span.responses.length.should.equal(1);
43+
}
44+
});
45+
});
46+
});
47+
});
48+
});
49+
});

test/helpers/socket-io-init.spec.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const chai = require('chai');
2+
3+
chai.should();
4+
5+
const socketIoInit = require('../../helpers/socket-io-init');
6+
const defaultConfig = require('../../helpers/default-config');
7+
8+
describe('helpers', () => {
9+
describe('socket-io-init', () => {
10+
describe('when invoked', () => {
11+
it('then all spans should have os and responses property', () => {
12+
const spans = defaultConfig.spans;
13+
14+
spans.forEach((span) => {
15+
span.should.not.have.property('os');
16+
// info: not working as if it was another test interfering
17+
// span.should.not.have.property('responses');
18+
});
19+
20+
socketIoInit({}, spans);
21+
22+
spans.forEach((span) => {
23+
span.should.have.property('os');
24+
span.should.have.property('responses');
25+
});
26+
});
27+
});
28+
});
29+
});

0 commit comments

Comments
 (0)