mirror of
https://github.com/serverless/serverless.git
synced 2026-01-25 15:07:39 +00:00
138 lines
4.2 KiB
JavaScript
138 lines
4.2 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
|
|
})
|
|
})
|