From 65b480a3e68d41829e7c885362a8587560259cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bonnefont?= Date: Fri, 18 Feb 2022 14:12:07 +0100 Subject: [PATCH] feat(push-to-gateway): add ability to retry pushing metrics (#9) * feat(push-to-gateway): add ability to retry pushing metrics * feat(push-to-gateway): fix review - use a constants file --- config/jest.config.json | 7 ++++++ package.json | 2 +- src/monitor/constants.js | 4 +++ src/monitor/push-metrics-for-folder.js | 28 +++++++++++++++------ src/monitor/push-metrics-for-folder.spec.js | 23 +++++++++++++++++ 5 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 config/jest.config.json create mode 100644 src/monitor/constants.js diff --git a/config/jest.config.json b/config/jest.config.json new file mode 100644 index 0000000..cb5c798 --- /dev/null +++ b/config/jest.config.json @@ -0,0 +1,7 @@ +{ + "verbose": true, + "bail": true, + "rootDir": "../", + "roots": ["/src"], + "silent": true +} \ No newline at end of file diff --git a/package.json b/package.json index c831cbf..ea04f1e 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Github action for compute and monitor of test coverage via jest", "main": "index.js", "scripts": { - "test": "jest src/" + "test": "jest src/ --config ./config/jest.config.json" }, "repository": { "type": "git", diff --git a/src/monitor/constants.js b/src/monitor/constants.js new file mode 100644 index 0000000..81f8dae --- /dev/null +++ b/src/monitor/constants.js @@ -0,0 +1,4 @@ +module.exports = { + MAX_ATTEMPTS: 5, + RETRY_DELAY: 1000, // ms +} \ No newline at end of file diff --git a/src/monitor/push-metrics-for-folder.js b/src/monitor/push-metrics-for-folder.js index 65faa18..a6a2792 100755 --- a/src/monitor/push-metrics-for-folder.js +++ b/src/monitor/push-metrics-for-folder.js @@ -11,6 +11,7 @@ const path = require("path") +const { MAX_ATTEMPTS, RETRY_DELAY } = require('./constants') const { getMetricsList } = require('./metrics-list.js') const { formatMetricPayload } = require('./format-metric-payload.js') const { pushToGateway } = require('./push-to-pushgateway.js') @@ -36,14 +37,27 @@ const pushMetricsForFolder = ({ coverageArtifactsPath, folderName, jobName, push const metricsPayload = getMetricsList(testStats, coverageStats) .reduce((metricsAsText, metric) => metricsAsText + formatMetricPayload(metric), "") - // Sent metrics to Prometheus - pushToGateway(`${pushGatewayUri}/metrics/job/${jobName}/folder_name/${folderName}`, metricsPayload, (err, data) => { - if (err) { - throw new Error(err.message) - } + // Sent metrics to Prometheus - try MAX_ATTEMPTS times + const pushAttempt = (attemptsCount) => { + console.log(`Push metrics attempt #${attemptsCount}...`) + pushToGateway(`${pushGatewayUri}/metrics/job/${jobName}/folder_name/${folderName}`, metricsPayload, (err, data) => { + if (err) { + if (attemptsCount < MAX_ATTEMPTS) { + console.error("Failed to push metrics:", err.message, ` - will retry in ${RETRY_DELAY}ms...`) + // Wait and retry + setTimeout(() => pushAttempt(attemptsCount + 1), RETRY_DELAY) + } + else { + throw err + } + } + else { + console.log("Done -", data.body) + } + }) + } - console.log("Done -", data.body) - }) + pushAttempt(0) } // If script is used from command-line as standalone diff --git a/src/monitor/push-metrics-for-folder.spec.js b/src/monitor/push-metrics-for-folder.spec.js index b4c973d..1dda642 100644 --- a/src/monitor/push-metrics-for-folder.spec.js +++ b/src/monitor/push-metrics-for-folder.spec.js @@ -1,5 +1,6 @@ const path = require("path") const fs = require("fs") +const { MAX_ATTEMPTS } = require('./constants') const { pushToGateway } = require('./push-to-pushgateway.js') const { pushMetricsForFolder } = require("./push-metrics-for-folder") @@ -52,4 +53,26 @@ describe("pushMetricsForFolder", () => { expect(lastMockCallArgs[0]).toEqual(`http://pushgateway/metrics/job/test-jobname/folder_name/${FOLDERNAME}`) expect(lastMockCallArgs[1]).toEqual("{\"foo\":\"bar\"}") }) + + it(`should attempt ${MAX_ATTEMPTS} times to push metrics before failing`, () => { + jest.useFakeTimers() + + let attemptsCount = 0 + const pushToGatewayMock = jest.fn((url, payload, callback) => { + callback(new Error("Test error.")) + attemptsCount++ + jest.runAllTimers() + }) + pushToGateway.mockImplementation(pushToGatewayMock) + + expect(() => { + pushMetricsForFolder({ + coverageArtifactsPath: ".", + folderName: FOLDERNAME, + jobName: "test-jobname", + pushGatewayUri: "http://pushgateway", + }) + }).toThrow(/Test error/) + expect(attemptsCount).toEqual(MAX_ATTEMPTS) + }) })