Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@hmcts/nodejs-healthcheck

Package Overview
Dependencies
Maintainers
16
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@hmcts/nodejs-healthcheck - npm Package Compare versions

Comparing version 1.6.0 to 1.7.0

.eslintrc.js

80

healthcheck/checks.js
'use strict'
const request = require('superagent'),
outputs = require('./outputs');
const request = require('superagent')
const outputs = require('./outputs')
class WebCheck {
constructor(url, options={}) {
this.url = url;
this.callback = options.callback || this.defaultCallback;
this.timeout = options.timeout || 2000;
this.deadline = options.deadline || 5000;
constructor (url, options = {}) {
this.url = url
this.callback = options.callback || this.defaultCallback
this.timeout = options.timeout || 2000
this.deadline = options.deadline || 5000
this.ca = options.ca
}
static create(url, options={}) {
return new WebCheck(url, options);
static create (url, options = {}) {
return new WebCheck(url, options)
}
defaultCallback(err, res) {
return !err && res.status === 200 ? outputs.up() : outputs.down(err);
defaultCallback (err, res) {
return !err && res.status === 200 ? outputs.up() : outputs.down(err)
}
call() {
call () {
return new Promise((resolve) => {

@@ -29,41 +28,39 @@ request

.ca(this.ca)
.timeout({response: this.timeout, deadline: this.deadline})
.timeout({ response: this.timeout, deadline: this.deadline })
.end((err, res) => {
resolve(this.callback(err, res));
});
});
resolve(this.callback(err, res))
})
})
}
}
class RawCheck {
constructor(callback) {
this.callback = callback;
constructor (callback) {
this.callback = callback
}
static create(callback) {
return new RawCheck(callback);
static create (callback) {
return new RawCheck(callback)
}
call(req, res) {
call (req, res) {
return new Promise((resolve) => {
resolve(this.callback(req, res));
});
resolve(this.callback(req, res))
})
}
}
class CompositeCheck {
constructor(checks) {
this.checks = checks;
constructor (checks) {
this.checks = checks
}
static create(checks) {
return new CompositeCheck(checks);
static create (checks) {
return new CompositeCheck(checks)
}
call(req, res) {
let checks = Object.entries(this.checks),
promises = checks.map(check => check[1].call(req, res)),
all = Promise.all(promises);
call (req, res) {
const checks = Object.entries(this.checks)
const promises = checks.map(check => check[1].call(req, res))
const all = Promise.all(promises)

@@ -75,13 +72,12 @@ return new Promise(resolve => {

.map((result, i) => [checks[i][0], result])
.reduce((prev, curr) => Object.assign(prev, {[curr[0]]: curr[1]}), {}))
});
});
.reduce((prev, curr) => Object.assign(prev, { [curr[0]]: curr[1] }), {}))
})
})
}
}
module.exports = {
"WebCheck": WebCheck,
"RawCheck": RawCheck,
"CompositeCheck": CompositeCheck,
};
WebCheck: WebCheck,
RawCheck: RawCheck,
CompositeCheck: CompositeCheck
}

@@ -6,9 +6,10 @@ 'use strict'

function addTo(app, config) {
function addTo (app, config) {
app.get('/health', routes.configure(config))
app.get('/health/liveness', (req, res) => res.json(outputs.status(outputs.UP)))
app.get('/health/readiness', routes.checkReadiness(config.readinessChecks))
}
module.exports = {
'addTo': addTo
addTo: addTo
}
'use strict'
const UP = "UP",
DOWN = "DOWN";
const UP = 'UP'
const DOWN = 'DOWN'
function up(extra={}) {
return status(true, extra);
function up (extra = {}) {
return status(true, extra)
}
function down(extra={}) {
return status(false, extra);
function down (extra = {}) {
return status(false, extra)
}
function status(s, extra={}) {
function status (s, extra = {}) {
return Object.assign({}, extra, {
"status": s ? UP : DOWN,
});
status: s ? UP : DOWN
})
}
module.exports = {
"up": up,
"down": down,
"status": status,
"UP": UP,
"DOWN": DOWN,
};
up: up,
down: down,
status: status,
UP: UP,
DOWN: DOWN
}

@@ -1,10 +0,10 @@

'use strict';
const checks = require('./checks'),
outputs = require('./outputs'),
versionFile = require('./versionFile');
'use strict'
const checks = require('./checks')
const outputs = require('./outputs')
const versionFile = require('./versionFile')
const { Logger } = require('@hmcts/nodejs-logging');
const logger = Logger.getLogger('@hmcts/nodejs-logging/routes');
const { Logger } = require('@hmcts/nodejs-logging')
const logger = Logger.getLogger('@hmcts/nodejs-logging/routes')
function getBuildInfo(extra) {
function getBuildInfo (extra) {
return Promise.all([

@@ -15,20 +15,20 @@ versionFile.version(),

]).then(([version, commit, date]) => {
let buildInfo = {
environment: process.env.PACKAGES_ENVIRONMENT || process.env.REFORM_ENVIRONMENT || "unknown",
project: process.env.PACKAGES_PROJECT || process.env.REFORM_TEAM || "unknown",
name: process.env.PACKAGES_NAME || process.env.REFORM_SERVICE_NAME || "unknown",
const buildInfo = {
environment: process.env.PACKAGES_ENVIRONMENT || process.env.REFORM_ENVIRONMENT || 'unknown',
project: process.env.PACKAGES_PROJECT || process.env.REFORM_TEAM || 'unknown',
name: process.env.PACKAGES_NAME || process.env.REFORM_SERVICE_NAME || 'unknown',
version,
commit,
date
};
}
if (extra) {
return Object.assign(buildInfo, { extra });
return Object.assign(buildInfo, { extra })
} else {
return buildInfo;
return buildInfo
}
});
})
}
function configure(config) {
const check = new checks.CompositeCheck(config.checks);
function configure (config) {
const check = new checks.CompositeCheck(config.checks)

@@ -40,3 +40,3 @@ return (req, res) => {

const allOk = Object.values(results)
.every(result => result.status === outputs.UP);
.every(result => result.status === outputs.UP)
const output = Object.assign(

@@ -46,19 +46,44 @@ outputs.status(allOk),

{ buildInfo }
);
const status = allOk ? 200 : 500;
)
const status = allOk ? 200 : 500
if (!allOk) {
const downHealthChecks = Object.values(results)
.filter(result => result.status === outputs.DOWN);
.filter(result => result.status === outputs.DOWN)
logger.error('Health check failed, result for down endpoints: ', JSON.stringify(downHealthChecks));
logger.error('Health check failed, result for down endpoints: ', JSON.stringify(downHealthChecks))
}
res.status(status).json(output);
});
res.status(status).json(output)
})
}
}
function checkReadiness (readinessChecks = {}) {
const check = new checks.CompositeCheck(readinessChecks)
return (req, res) => {
return Promise
.resolve(check.call(req, res))
.then((results) => {
const allOk = Object.values(results)
.every((result) => result.status === outputs.UP)
const output = Object.assign(
outputs.status(allOk),
results
)
const status = allOk ? 200 : 500
if (!allOk) {
const downHealthChecks = Object.values(results)
.filter((result) => result.status === outputs.DOWN)
logger.error('Health check failed, result for down endpoints: ', JSON.stringify(downHealthChecks))
}
res.status(status).json(output)
})
}
}
module.exports = {
"getBuildInfo": getBuildInfo,
"configure": configure,
};
getBuildInfo: getBuildInfo,
configure: configure,
checkReadiness: checkReadiness
}

@@ -1,34 +0,34 @@

const fs = require('fs').promises;
const yaml = require('js-yaml');
const fs = require('fs').promises
const yaml = require('js-yaml')
let defaultObj;
let defaultObj
const versionFile = () => {
const versionFilePath = `${process.env.NODE_PATH || '.'}/version`;
const versionFilePath = `${process.env.NODE_PATH || '.'}/version`
defaultObj = {
defaultObj = {
version: process.env.PACKAGES_VERSION || 'unknown',
commit: 'unknown',
date: 'unknown'
};
}
return fs.readFile(versionFilePath)
.then(yaml.safeLoad)
.catch((err) => defaultObj);
};
.catch((err) => defaultObj)
}
const version = () => {
return versionFile().then(props => {
return (props.version) ? (props.number) ? props.version + "-" + props.number : props.version : defaultObj.version
});
};
return (props.version) ? (props.number) ? props.version + '-' + props.number : props.version : defaultObj.version
})
}
const commit = () => {
return versionFile().then(props => props.commit || defaultObj.commit);
};
return versionFile().then(props => props.commit || defaultObj.commit)
}
const date = () => {
return versionFile().then(props => props.date || defaultObj.date);
};
return versionFile().then(props => props.date || defaultObj.date)
}
module.exports = { version, commit, date };
module.exports = { version, commit, date }
'use strict'
const checks = require('./healthcheck/checks'),
outputs = require('./healthcheck/outputs'),
routes = require('./healthcheck/routes'),
install = require('./healthcheck/install');
const checks = require('./healthcheck/checks')
const outputs = require('./healthcheck/outputs')
const routes = require('./healthcheck/routes')
const install = require('./healthcheck/install')
module.exports = {
"addTo": install.addTo,
"configure": routes.configure,
addTo: install.addTo,
configure: routes.configure,
// outputs
"up": outputs.up,
"down": outputs.down,
"status": outputs.status,
up: outputs.up,
down: outputs.down,
status: outputs.status,
// checks
"web": checks.WebCheck.create,
"raw": checks.RawCheck.create,
};
web: checks.WebCheck.create,
raw: checks.RawCheck.create
}
{
"name": "@hmcts/nodejs-healthcheck",
"version": "1.6.0",
"version": "1.7.0",
"description": "Healthcheck endpoint for Reform nodejs applications",

@@ -10,3 +10,4 @@ "main": "index.js",

"scripts": {
"test": "mocha test/unit/* --reporter spec"
"test": "mocha test/unit/* --reporter spec",
"lint": "eslint ."
},

@@ -27,2 +28,8 @@ "repository": {

"chai-as-promised": "^7.1.1",
"eslint": "^7.1.0",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"express": "^4.16.4",

@@ -29,0 +36,0 @@ "mocha": "7",

@@ -7,2 +7,8 @@ # Nodejs Healthcheck

It exposes 3 endpoints:
1. `/health` - Returns 200 by default along with `buildInfo`, can optionally include result evaluating all `checks` passed in config.
2. `/health/livness` - Returns 200 always.
3. `/health/readiness` - Returns 200 by default , can optionally include result evaluating all `readinessChecks` passed in config.
## Usage

@@ -13,5 +19,27 @@

```javascript
const healthcheck = require('@hmcts/nodejs-healthcheck');
const config = {
checks: {
mySimpleWebCheck: healthcheck.web("https://example.com/status"),
myComplexWebCheck: healthcheck.web("https://example.com/other", {
callback: (err, res) => {
return res.body.status == "good" ? healthcheck.up() : healthcheck.down()
},
timeout: 5000,
deadline: 10000,
}),
myRawCheck: healthcheck.raw(() => {
return myInternalCheck() ? healthcheck.up() : healthcheck.down()
})
},
buildInfo: {
myCustomBuildInfo: "yay"
}
};
healthcheck.addTo(app, config);
```
app.get("/status", healthcheck.configure({
You can optionally include [readiness checks](#what-to-include-in-readiness-checks).
```javascript
const config = {
checks: {

@@ -30,8 +58,30 @@ mySimpleWebCheck: healthcheck.web("https://example.com/status"),

},
readinessChecks: {
mySimpleWebCheck: healthcheck.web("https://example.com/status")
},
buildInfo: {
myCustomBuildInfo: "yay"
}
}));
};
healthcheck.addTo(app, config);
```
## what to include in readiness checks
- On Kubernetes, readiness probes will be called periodically throughout the lifetime of the container. Container will be made temporarily unavailable from serving traffic when the readiness check fails.
- The requests won't even reach your application to handle errors. So, it is very important to consider what checks should be included into readiness probe.
- While adding all dependant services to readiness check can help in identifying any misconfiguration during startup, it could cause unwanted downtime for the application.
- K8s introduced startUp Probes (Alpha in 1.16 ) to handle startup cases separately.
Based on above, you should include a dependency into readiness checks only if they are exclusive/hard dependencies for your service. Unavailability of soft dependencies needs to be handled in code to give appropriate customer experience.
Good example for check to be included in readiness:
- A private cache / database like `Redis` or `Elastic Search` which are exclusive to the application (not shared).
Bad example for check to be included in readiness:
- Any shared components like IDAM, S2S or CCD.
## Publishing

@@ -38,0 +88,0 @@

@@ -1,13 +0,13 @@

const chai = require('chai');
const chaiAsPromised = require("chai-as-promised");
const expect = chai.expect;
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
chai.should();
chai.use(sinonChai);
chai.use(chaiAsPromised);
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
const expect = chai.expect
const sinon = require('sinon')
const sinonChai = require('sinon-chai')
chai.should()
chai.use(sinonChai)
chai.use(chaiAsPromised)
module.exports = {
expect,
sinon
};
expect,
sinon
}
'use strict'
const {expect, sinon} = require('../chai-sinon'),
checks = require('../../healthcheck/checks'),
nock = require('nock');
const { expect, sinon } = require('../chai-sinon')
const checks = require('../../healthcheck/checks')
const nock = require('nock')
describe('Checks', () => {
let check;
let check
describe('web', () => {
let request;
let request
describe('basic web check', () => {
beforeEach(() => {
check = checks.WebCheck.create("https://example.com/status");
request = nock('https://example.com').get('/status');
});
check = checks.WebCheck.create('https://example.com/status')
request = nock('https://example.com').get('/status')
})
it("should return status UP on HTTP 200 OK", (done) => {
request.reply(200, "OK");
it('should return status UP on HTTP 200 OK', (done) => {
request.reply(200, 'OK')
check.call().then((result) => {
expect(result).to.eql({"status": "UP"});
done();
});
expect(result).to.eql({ status: 'UP' })
done()
})
});
[201, 400, 500, 503].forEach((code) => {
it("should return status DOWN on HTTP " + code, (done) => {
request.reply(code, "SOMETHING");
it('should return status DOWN on HTTP ' + code, (done) => {
request.reply(code, 'SOMETHING')
check.call().then((result) => {
expect(result).to.contain({"status": "DOWN"});
done();
});
});
});
expect(result).to.contain({ status: 'DOWN' })
done()
})
})
})
})
});
describe("custom web check", () => {
describe('custom web check', () => {
beforeEach(() => {
check = new checks.WebCheck("https://example.com/status", {
check = new checks.WebCheck('https://example.com/status', {
callback: (err, res) => {
if (res.body.status === "good") {
return {"status": "UP"};
if (res.body.status === 'good') {
return { status: 'UP' }
} else {
return {"status": "DOWN"};
return { status: 'DOWN' }
}
}
});
request = nock('https://example.com').get('/status');
});
})
request = nock('https://example.com').get('/status')
})
it("should return down on down condition", (done) => {
request.reply(200, {"status": "bad"});
it('should return down on down condition', (done) => {
request.reply(200, { status: 'bad' })
check.call().then((result) => {
expect(result).to.eql({"status": "DOWN"});
done();
});
});
expect(result).to.eql({ status: 'DOWN' })
done()
})
})
it("should return up on up condition", (done) => {
request.reply(500, {"status": "good"});
it('should return up on up condition', (done) => {
request.reply(500, { status: 'good' })
check.call().then((result) => {
expect(result).to.eql({"status": "UP"});
done();
});
});
expect(result).to.eql({ status: 'UP' })
done()
})
})
})
})
});
});
describe('raw', () => {
describe('basic raw check', () => {
it('should output exactly what is provided', (done) => {
let f = () => { return true; }
check = new checks.RawCheck(f);
const f = () => { return true }
check = new checks.RawCheck(f)
check.call().then((result) => {
expect(result).to.eql(true);
done();
});
});
expect(result).to.eql(true)
done()
})
})
it('passes the express req and res to the callback', () => {
const expressRequest = sinon.spy();
const expressResponse = sinon.spy();
const expressRequest = sinon.spy()
const expressResponse = sinon.spy()
const check = new checks.RawCheck((req, res) => {
expect(req).to.eql(expressRequest);
expect(res).to.eql(expressResponse);
});
return check.call(expressRequest, expressResponse);
});
expect(req).to.eql(expressRequest)
expect(res).to.eql(expressResponse)
})
return check.call(expressRequest, expressResponse)
})
})
})
});
});
describe('composite', () => {
describe('basic composite check', () => {
it('should output a map of composed check results', (done) => {
let f1 = () => { return "f1"; }
let f2 = () => { return "f2"; }
const f1 = () => { return 'f1' }
const f2 = () => { return 'f2' }
check = new checks.CompositeCheck({
"c1": checks.RawCheck.create(f1),
"c2": checks.RawCheck.create(f2),
});
c1: checks.RawCheck.create(f1),
c2: checks.RawCheck.create(f2)
})
check.call().then((result) => {
expect(result).to.eql({
"c1": "f1",
"c2": "f2",
});
done();
});
});
c1: 'f1',
c2: 'f2'
})
done()
})
})
it('passes the express req and res to the child checks', (done) => {
const expressRequest = sinon.spy();
const expressResponse = sinon.spy();
const expressRequest = sinon.spy()
const expressResponse = sinon.spy()
const childCheck = new checks.RawCheck((req, res) => {
expect(req).to.eql(expressRequest);
expect(res).to.eql(expressResponse);
done();
});
expect(req).to.eql(expressRequest)
expect(res).to.eql(expressResponse)
done()
})
const check = new checks.CompositeCheck({
'child': childCheck
});
child: childCheck
})
check.call(expressRequest, expressResponse);
});
});
});
});
check.call(expressRequest, expressResponse)
})
})
})
})
'use strict'
const request = require('supertest');
const express = require('express');
const app = express();
const install = require('../../healthcheck/install');
const {expect, sinon} = require('../chai-sinon');
const request = require('supertest')
const express = require('express')
const app = express()
const install = require('../../healthcheck/install')
const { expect } = require('../chai-sinon')
let validConfig = {
const validConfig = {
checks: {},

@@ -14,25 +14,25 @@ buildInfo: {

}
};
}
before(() => {
install.addTo(app, validConfig);
});
install.addTo(app, validConfig)
})
describe('Testing liveness', function() {
it('should return 200 OK', function(done) {
request(app)
.get('/health/liveness')
.expect(200)
.end((err, res) => {
if (err) {
return done(err);
}
expect(res.body.status).to.be.equal('UP');
done();
});
});
});
describe('Testing liveness', function () {
it('should return 200 OK', function (done) {
request(app)
.get('/health/liveness')
.expect(200)
.end((err, res) => {
if (err) {
return done(err)
}
expect(res.body.status).to.be.equal('UP')
done()
})
})
})
describe('Testing Readiness for 200 OK', function() {
it('should return 200 OK', function(done) {
describe('Testing health for 200 OK', function () {
it('should return 200 OK', function (done) {
request(app)

@@ -43,9 +43,23 @@ .get('/health')

if (err) {
return done(err);
return done(err)
}
expect(res.body.status).to.be.equal('UP');
done();
});
});
});
expect(res.body.status).to.be.equal('UP')
done()
})
})
})
describe('Testing readiness for 200 OK', function () {
it('should return 200 OK', function (done) {
request(app)
.get('/health/readiness')
.expect(200)
.end((err, res) => {
if (err) {
return done(err)
}
expect(res.body.status).to.be.equal('UP')
done()
})
})
})
'use strict'
const {expect, sinon} = require('../chai-sinon'),
outputs = require('../../healthcheck/outputs');
const { expect } = require('../chai-sinon')
const outputs = require('../../healthcheck/outputs')
describe('Status output', () => {
it('should output up', () => {
expect(outputs.up()).to.eql({"status": "UP"});
});
expect(outputs.up()).to.eql({ status: 'UP' })
})
it('should output down', () => {
expect(outputs.down()).to.eql({"status": "DOWN"});
});
expect(outputs.down()).to.eql({ status: 'DOWN' })
})
it('should output up with extra properties', () => {
expect(outputs.up({"extra": "value"})).to.eql({"status": "UP", "extra": "value"});
});
expect(outputs.up({ extra: 'value' })).to.eql({ status: 'UP', extra: 'value' })
})
it('should output down with extra properties', () => {
expect(outputs.down({"extra": "value"})).to.eql({"status": "DOWN", "extra": "value"});
});
expect(outputs.down({ extra: 'value' })).to.eql({ status: 'DOWN', extra: 'value' })
})
it('should not allow status to be overwritten', () => {
expect(outputs.up({"status": "DOWN"})).to.eql({"status": "UP"});
});
});
expect(outputs.up({ status: 'DOWN' })).to.eql({ status: 'UP' })
})
})
'use strict'
/* global describe, beforeEach, afterEach, it */
const {expect, sinon} = require('../chai-sinon'),
routes = require('../../healthcheck/routes'),
checks = require('../../healthcheck/checks'),
outputs = require('../../healthcheck/outputs'),
versionFile = require('../../healthcheck/versionFile'),
nock = require('nock');
const { expect, sinon } = require('../chai-sinon')
const routes = require('../../healthcheck/routes')
const checks = require('../../healthcheck/checks')
const outputs = require('../../healthcheck/outputs')
const versionFile = require('../../healthcheck/versionFile')
describe('Routes', () => {
let originalEnv = {};
const originalEnv = {}
const envKeys = [
'PACKAGES_ENVIRONMENT', 'PACKAGES_PROJECT', 'PACKAGES_NAME'
];
]
beforeEach(() => {
sinon.stub(versionFile, 'commit');
sinon.stub(versionFile, 'date');
sinon.stub(versionFile, 'version');
versionFile.commit.resolves('abc1234');
versionFile.date.resolves('Jan 1 1970');
versionFile.version.resolves('1.4.3-42');
sinon.stub(versionFile, 'commit')
sinon.stub(versionFile, 'date')
sinon.stub(versionFile, 'version')
versionFile.commit.resolves('abc1234')
versionFile.date.resolves('Jan 1 1970')
versionFile.version.resolves('1.4.3-42')
envKeys.forEach(key => {
originalEnv[key] = process.env[key];
process.env[key] = "test " + key;
});
});
originalEnv[key] = process.env[key]
process.env[key] = 'test ' + key
})
})
afterEach(() => {
versionFile.commit.restore();
versionFile.date.restore();
versionFile.version.restore();
versionFile.commit.restore()
versionFile.date.restore()
versionFile.version.restore()
envKeys.forEach(key => {
if (typeof originalEnv[key] === "undefined") {
delete process.env[key];
if (typeof originalEnv[key] === 'undefined') {
delete process.env[key]
} else {
process.env[key] = originalEnv[key];
process.env[key] = originalEnv[key]
}
});
});
})
})
describe('getBuildInfo', () => {
it('should add build info from environment', () => {
return expect(routes.getBuildInfo()).to.eventually.eql({
environment: "test PACKAGES_ENVIRONMENT",
project: "test PACKAGES_PROJECT",
name: "test PACKAGES_NAME",
version: "1.4.3-42",
environment: 'test PACKAGES_ENVIRONMENT',
project: 'test PACKAGES_PROJECT',
name: 'test PACKAGES_NAME',
version: '1.4.3-42',
commit: 'abc1234',
date: 'Jan 1 1970'
});
});
})
})
it('should include extra build info', () => {
const extra = routes.getBuildInfo({ foo: "bar" }).then(_ => _.extra);
return expect(extra).to.eventually.eql({ foo: "bar" });
});
const extra = routes.getBuildInfo({ foo: 'bar' }).then(_ => _.extra)
return expect(extra).to.eventually.eql({ foo: 'bar' })
})
})
});
describe('configure', () => {
let makeCheck = isOk => checks.RawCheck.create(() => isOk ? outputs.up() : outputs.down());
let makeReqRes = (expectedStatus, expectedJson) => {
let req = sinon.spy(),
res = {};
const makeCheck = isOk => checks.RawCheck.create(() => isOk ? outputs.up() : outputs.down())
const makeReqRes = (expectedStatus, expectedJson) => {
const req = sinon.spy()
const res = {}
res.status = status => {
expect(status).to.eql(expectedStatus);
return res;
};
expect(status).to.eql(expectedStatus)
return res
}
res.json = json => {
expect(json).to.eql(expectedJson);
return res;
};
return [req, res];
};
expect(json).to.eql(expectedJson)
return res
}
return [req, res]
}
it('should return 200 OK if all checks pass', () => {
let route = routes.configure({
const route = routes.configure({
checks: {
check1: makeCheck(true),
check2: makeCheck(true),
check2: makeCheck(true)
}
});
let [req, res] = makeReqRes(200, {
})
const [req, res] = makeReqRes(200, {
status: outputs.UP,
check1: {status: "UP"},
check2: {status: "UP"},
check1: { status: 'UP' },
check2: { status: 'UP' },
buildInfo: {
environment: "test PACKAGES_ENVIRONMENT",
project: "test PACKAGES_PROJECT",
name: "test PACKAGES_NAME",
version: "1.4.3-42",
environment: 'test PACKAGES_ENVIRONMENT',
project: 'test PACKAGES_PROJECT',
name: 'test PACKAGES_NAME',
version: '1.4.3-42',
commit: 'abc1234',
date: 'Jan 1 1970'
}
});
})
return route(req, res);
});
return route(req, res)
})
it('should return 500 DOWN if any checks fail', () => {
let route = routes.configure({
const route = routes.configure({
checks: {
check1: makeCheck(false),
check2: makeCheck(true),
check2: makeCheck(true)
}
});
let [req, res] = makeReqRes(500, {
status: "DOWN",
check1: {status: "DOWN"},
check2: {status: "UP"},
})
const [req, res] = makeReqRes(500, {
status: 'DOWN',
check1: { status: 'DOWN' },
check2: { status: 'UP' },
buildInfo: {
environment: "test PACKAGES_ENVIRONMENT",
project: "test PACKAGES_PROJECT",
name: "test PACKAGES_NAME",
version: "1.4.3-42",
environment: 'test PACKAGES_ENVIRONMENT',
project: 'test PACKAGES_PROJECT',
name: 'test PACKAGES_NAME',
version: '1.4.3-42',
commit: 'abc1234',
date: 'Jan 1 1970'
}
});
})
return route(req, res);
return route(req, res)
})
});
it('should return 200 and UP if readiness check is undefined', () => {
const route = routes.checkReadiness()
const [req, res] = makeReqRes(200, {
status: 'UP'
})
return route(req, res)
})
it('should return 200 OK if all checks pass', () => {
const route = routes.checkReadiness({
check1: makeCheck(true),
check2: makeCheck(true)
})
const [req, res] = makeReqRes(200, {
status: outputs.UP,
check1: { status: 'UP' },
check2: { status: 'UP' }
})
return route(req, res)
})
it('should return 500 DOWN if any readiness checks fail', () => {
const route = routes.checkReadiness({
check1: makeCheck(false),
check2: makeCheck(true)
})
const [req, res] = makeReqRes(500, {
status: 'DOWN',
check1: { status: 'DOWN' },
check2: { status: 'UP' }
})
return route(req, res)
})
it('should return the extra build info', () => {
let route = routes.configure({
const route = routes.configure({
checks: {

@@ -136,26 +167,24 @@ check1: makeCheck(true)

buildInfo: {
foo: "bar"
foo: 'bar'
}
});
let [req, res] = makeReqRes(200, {
status: "UP",
check1: {status: "UP"},
})
const [req, res] = makeReqRes(200, {
status: 'UP',
check1: { status: 'UP' },
buildInfo: {
environment: "test PACKAGES_ENVIRONMENT",
project: "test PACKAGES_PROJECT",
name: "test PACKAGES_NAME",
version: "1.4.3-42",
environment: 'test PACKAGES_ENVIRONMENT',
project: 'test PACKAGES_PROJECT',
name: 'test PACKAGES_NAME',
version: '1.4.3-42',
commit: 'abc1234',
date: 'Jan 1 1970',
extra: {
foo: "bar"
foo: 'bar'
}
}
});
})
return route(req, res);
});
});
});
return route(req, res)
})
})
})
'use strict'
/* global describe, beforeEach, afterEach, it */
const {expect, sinon} = require('../chai-sinon');
const fs = require('fs').promises;
const versionFile = require('../../healthcheck/versionFile');
const { expect, sinon } = require('../chai-sinon')
const fs = require('fs').promises
const versionFile = require('../../healthcheck/versionFile')
describe('versionFile', () => {
beforeEach(() => {
sinon.stub(fs, 'readFile');
});
sinon.stub(fs, 'readFile')
})
afterEach(() => {
fs.readFile.restore();
});
fs.readFile.restore()
})
describe('version', () => {
it('should resolve the version', () => {
fs.readFile.resolves('version: 1.4.3\nnumber: 42');
return expect(versionFile.version()).to.eventually.eql('1.4.3-42');
});
fs.readFile.resolves('version: 1.4.3\nnumber: 42')
return expect(versionFile.version()).to.eventually.eql('1.4.3-42')
})
it('should resolve the version even if build is missing', () => {
fs.readFile.resolves('version: 1.4.3');
return expect(versionFile.version()).to.eventually.eql('1.4.3');
});
fs.readFile.resolves('version: 1.4.3')
return expect(versionFile.version()).to.eventually.eql('1.4.3')
})
it('should resolve "unknown" if no version present in version file but build is there', () => {
fs.readFile.resolves('build: 42');
return expect(versionFile.version()).to.eventually.eql('unknown');
});
fs.readFile.resolves('build: 42')
return expect(versionFile.version()).to.eventually.eql('unknown')
})
it('should resolve "unknown" if no versionFile present', () => {
fs.readFile.rejects('no file found');
return expect(versionFile.version()).to.eventually.eql('unknown');
});
fs.readFile.rejects('no file found')
return expect(versionFile.version()).to.eventually.eql('unknown')
})
it('should resolve "unknown" if no version present in version file', () => {
fs.readFile.resolves('foo: bar');
return expect(versionFile.version()).to.eventually.eql('unknown');
});
fs.readFile.resolves('foo: bar')
return expect(versionFile.version()).to.eventually.eql('unknown')
})
describe('version with Environment Variables', () => {
let versionFileWithEnv
let versionFileWithEnv
beforeEach(() => {
process.env["PACKAGES_VERSION"] = 'v1.42'
process.env.PACKAGES_VERSION = 'v1.42'
versionFileWithEnv = require('../../healthcheck/versionFile')
});
process.env.PACKAGES_VERSION = 'v1.42'
process.env.PACKAGES_VERSION = 'v1.42'
versionFileWithEnv = require('../../healthcheck/versionFile')
})
afterEach(() => {
delete process.env.PACKAGES_VERSION
delete process.env["PACKAGES_VERSION"]
});
delete process.env.PACKAGES_VERSION
})
it('should resolve the version to Version even with Environment Variables', () => {
fs.readFile.resolves('version: 1.4.3\nnumber: 42');
return expect(versionFileWithEnv.version()).to.eventually.eql('1.4.3-42');
});
it('should resolve the version to Version even with Environment Variables', () => {
fs.readFile.resolves('version: 1.4.3\nnumber: 42')
return expect(versionFileWithEnv.version()).to.eventually.eql('1.4.3-42')
})
it('should resolve the version even if build is missing even with Environment Variables', () => {
fs.readFile.resolves('version: 1.4.3');
return expect(versionFile.version()).to.eventually.eql('1.4.3');
});
it('should resolve the version even if build is missing even with Environment Variables', () => {
fs.readFile.resolves('version: 1.4.3')
return expect(versionFile.version()).to.eventually.eql('1.4.3')
})
it('should resolve the version to Environment Variables if no version present in version file but build is there', () => {
fs.readFile.resolves('number: 42');
return expect(versionFile.version()).to.eventually.eql('v1.42');
});
it('should resolve the version to Environment Variables if no version present in version file but build is there', () => {
fs.readFile.resolves('number: 42')
return expect(versionFile.version()).to.eventually.eql('v1.42')
})
it('should resolve the version to Environment Variables "v1.42" when versionFile has no version', () => {
fs.readFile.resolves('foo: bar');
return expect(versionFileWithEnv.version()).to.eventually.eql('v1.42');
});
it('should resolve the version to Environment Variables "v1.42" when versionFile has no version', () => {
fs.readFile.resolves('foo: bar')
return expect(versionFileWithEnv.version()).to.eventually.eql('v1.42')
})
it('should resolve the version to Environment Variables "v1.42" when no versionFile exists', () => {
fs.readFile.rejects('no file found');
return expect(versionFileWithEnv.version()).to.eventually.eql('v1.42');
});
it('should resolve the version to Environment Variables "v1.42" when no versionFile exists', () => {
fs.readFile.rejects('no file found')
return expect(versionFileWithEnv.version()).to.eventually.eql('v1.42')
})
})
})
});
});
describe('commit', () => {
it('should resolve the commit sha', () => {
fs.readFile.resolves('commit: abc1234');
return expect(versionFile.commit()).to.eventually.eql('abc1234');
});
fs.readFile.resolves('commit: abc1234')
return expect(versionFile.commit()).to.eventually.eql('abc1234')
})
it('should resolve "unknown" if no versionFile present', () => {
fs.readFile.rejects('no file found');
return expect(versionFile.commit()).to.eventually.eql('unknown');
});
fs.readFile.rejects('no file found')
return expect(versionFile.commit()).to.eventually.eql('unknown')
})
it('should resolve "unknown" if no commit present in version file', () => {
fs.readFile.resolves('foo: bar');
return expect(versionFile.commit()).to.eventually.eql('unknown');
});
});
fs.readFile.resolves('foo: bar')
return expect(versionFile.commit()).to.eventually.eql('unknown')
})
})
describe('date', () => {
it('should resolve the built date', () => {
fs.readFile.resolves('date: Jan 1 1970');
return expect(versionFile.date()).to.eventually.eql('Jan 1 1970');
});
fs.readFile.resolves('date: Jan 1 1970')
return expect(versionFile.date()).to.eventually.eql('Jan 1 1970')
})
it('should resolve "unknown" if no versionFile present', () => {
fs.readFile.rejects('no file found');
return expect(versionFile.date()).to.eventually.eql('unknown');
});
fs.readFile.rejects('no file found')
return expect(versionFile.date()).to.eventually.eql('unknown')
})
it('should resolve "unknown" if no commit present in version file', () => {
fs.readFile.resolves('foo: bar');
return expect(versionFile.date()).to.eventually.eql('unknown');
});
});
});
fs.readFile.resolves('foo: bar')
return expect(versionFile.date()).to.eventually.eql('unknown')
})
})
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc