mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
117 lines
4.1 KiB
JavaScript
117 lines
4.1 KiB
JavaScript
'use strict';
|
|
|
|
const path = require('path');
|
|
const fsp = require('fs').promises;
|
|
const fse = require('fs-extra');
|
|
const proxyquire = require('proxyquire');
|
|
const { expect } = require('chai');
|
|
const { v1: uuid } = require('uuid');
|
|
const wait = require('timers-ext/promise/sleep');
|
|
const cacheDirPath = require('../../../../../lib/utils/telemetry/cache-path');
|
|
|
|
const telemetryUrl = 'https://..';
|
|
const isFilename = RegExp.prototype.test.bind(/^(?:\.[^.].*|\.\..+|[^.].*)$/);
|
|
|
|
describe('test/unit/lib/utils/telemetry/index.test.js', () => {
|
|
let storeLocally;
|
|
let send;
|
|
let expectedState = 'success';
|
|
let usedUrl;
|
|
let usedOptions;
|
|
|
|
const cacheEvent = async (timestamp = Date.now()) => {
|
|
await fse.writeJson(path.join(cacheDirPath, uuid()), { payload: {}, timestamp });
|
|
};
|
|
|
|
before(() => {
|
|
({ storeLocally, send } = proxyquire('../../../../../lib/utils/telemetry/index.js', {
|
|
'@serverless/utils/analytics-and-notfications-url': telemetryUrl,
|
|
'./are-disabled': false,
|
|
'node-fetch': async (url, options) => {
|
|
usedUrl = url;
|
|
usedOptions = options;
|
|
await wait(500);
|
|
switch (expectedState) {
|
|
case 'success':
|
|
return { status: 200, json: async () => [] };
|
|
case 'networkError':
|
|
throw Object.assign(new Error('Network error'), { code: 'NETWORK_ERROR' });
|
|
case 'responseBodyError':
|
|
return {
|
|
status: 200,
|
|
json: async () => {
|
|
throw Object.assign(new Error('Response body error'), {
|
|
code: 'RESPONSE_BODY_ERROR',
|
|
});
|
|
},
|
|
};
|
|
default:
|
|
throw new Error(`Unexpected state: ${expectedState}`);
|
|
}
|
|
},
|
|
}));
|
|
});
|
|
|
|
afterEach(async () => {
|
|
usedOptions = null;
|
|
usedUrl = null;
|
|
const dirFilenames = await fsp.readdir(cacheDirPath);
|
|
await Promise.all(
|
|
dirFilenames.map(async (filename) => fsp.unlink(path.join(cacheDirPath, filename)))
|
|
);
|
|
});
|
|
|
|
it('`storeLocally` should persist an event in cacheDir', async () => {
|
|
const payload = { test: 'payloadvalue' };
|
|
storeLocally(payload);
|
|
const dirFilenames = await fsp.readdir(cacheDirPath);
|
|
expect(dirFilenames.length).to.equal(1);
|
|
const persistedEvent = await fse.readJson(path.join(cacheDirPath, dirFilenames[0]));
|
|
expect(persistedEvent.payload).to.deep.equal({ ...payload, id: dirFilenames[0] });
|
|
expect(persistedEvent).to.have.property('timestamp');
|
|
});
|
|
|
|
it('Should cache failed requests and rerun then with `send`', async () => {
|
|
expectedState = 'networkError';
|
|
await cacheEvent();
|
|
await send();
|
|
expect(usedUrl).to.equal(telemetryUrl);
|
|
const dirFilenames = await fsp.readdir(cacheDirPath);
|
|
expect(dirFilenames.filter(isFilename).length).to.equal(1);
|
|
|
|
expectedState = 'success';
|
|
await send();
|
|
const dirFilenamesAfterSend = await fsp.readdir(cacheDirPath);
|
|
expect(dirFilenamesAfterSend.filter(isFilename).length).to.equal(0);
|
|
|
|
// Check that one event was send with request
|
|
expect(JSON.parse(usedOptions.body)).to.have.lengthOf(1);
|
|
});
|
|
|
|
it('Should ditch stale events at `send`', async () => {
|
|
await Promise.all([cacheEvent(0), cacheEvent(0), cacheEvent(), cacheEvent(), cacheEvent(0)]);
|
|
expectedState = 'success';
|
|
const dirFilenames = await fsp.readdir(cacheDirPath);
|
|
expect(dirFilenames.filter(isFilename).length).to.equal(5);
|
|
await send();
|
|
const dirFilenamesAfterSend = await fsp.readdir(cacheDirPath);
|
|
expect(dirFilenamesAfterSend.filter(isFilename).length).to.equal(0);
|
|
// Check if only two events were send with request
|
|
expect(JSON.parse(usedOptions.body)).to.have.lengthOf(2);
|
|
});
|
|
|
|
it('Should ignore body procesing error', async () => {
|
|
expectedState = 'responseBodyError';
|
|
await cacheEvent();
|
|
await send();
|
|
const dirFilenames = await fsp.readdir(cacheDirPath);
|
|
expect(dirFilenames.filter(isFilename).length).to.equal(0);
|
|
});
|
|
|
|
it('Should not send request when there are no events to send', async () => {
|
|
await send();
|
|
expect(usedUrl).to.be.null;
|
|
expect(usedOptions).to.be.null;
|
|
});
|
|
});
|