Skip to content

Commit 740e69b

Browse files
authored
refactor(test): use exponential backoff and retry some integration tests (#402)
* refactor(test): use exponential backoff and retry for integration tests * chore: remove p-retry dependency, in favor of this.retries * chore: slight tweak to retry logic * chore: add stagger as suggested
1 parent d2bfedc commit 740e69b

File tree

3 files changed

+41
-35
lines changed

3 files changed

+41
-35
lines changed

monitoring/snippets/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
"devDependencies": {
2121
"chai": "^4.2.0",
2222
"mocha": "^7.0.0",
23-
"p-retry": "^4.0.0",
2423
"uuid": "^7.0.0"
2524
}
2625
}

monitoring/snippets/test/metrics.test.js

+23-18
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ const monitoring = require('@google-cloud/monitoring');
1818
const {assert} = require('chai');
1919
const {describe, it} = require('mocha');
2020
const cp = require('child_process');
21-
const retry = require('p-retry');
2221

2322
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
2423

@@ -30,28 +29,32 @@ const filter = `metric.type="${computeMetricId}"`;
3029
const projectId = process.env.GCLOUD_PROJECT;
3130
const resourceId = 'cloudsql_database';
3231

33-
describe('metrics', () => {
32+
// A helper for delaying integration tests with an exponential backoff.
33+
// See examples like: https://github.com/googleapis/nodejs-monitoring/issues/190,
34+
// https://github.com/googleapis/nodejs-monitoring/issues/191.
35+
const delay = async test => {
36+
const retries = test.currentRetry();
37+
if (retries === 0) return; // no retry on the first failure.
38+
// see: https://cloud.google.com/storage/docs/exponential-backoff:
39+
const ms = Math.pow(2, retries) * 250 + Math.random() * 1000;
40+
return new Promise(done => {
41+
console.info(`retrying "${test.title}" in ${ms}ms`);
42+
setTimeout(done, ms);
43+
});
44+
};
45+
describe('metrics', async () => {
3446
it('should create a metric descriptors', () => {
3547
const output = execSync(`${cmd} create`);
3648
assert.include(output, 'Created custom Metric');
3749
assert.include(output, `Type: ${customMetricId}`);
3850
});
3951

40-
it('should list metric descriptors, including the new custom one', async () => {
41-
// The write above appears to be eventually consistent. This retry should
42-
// not be needed. The tracking bug is here:
43-
// https://github.com/googleapis/nodejs-monitoring/issues/190
44-
await retry(
45-
async () => {
46-
const output = execSync(`${cmd} list`);
47-
assert.include(output, customMetricId);
48-
assert.include(output, computeMetricId);
49-
},
50-
{
51-
retries: 10,
52-
onFailedAttempt: () => console.warn('Read failed, retrying...'),
53-
}
54-
);
52+
it('should list metric descriptors, including the new custom one', async function() {
53+
this.retries(8);
54+
await delay(this.test); // delay the start of the test, if this is a retry.
55+
const output = execSync(`${cmd} list`);
56+
assert.include(output, customMetricId);
57+
assert.include(output, computeMetricId);
5558
});
5659

5760
it('should get a metric descriptor', () => {
@@ -130,7 +133,9 @@ describe('metrics', () => {
130133
});
131134
});
132135

133-
it('should read time series data aggregated', async () => {
136+
it('should read time series data aggregated', async function() {
137+
this.retries(5);
138+
await delay(this.test); // delay the start of the test, if this is a retry.
134139
const [timeSeries] = await client.listTimeSeries({
135140
name: client.projectPath(projectId),
136141
filter: filter,

monitoring/snippets/test/quickstart.test.js

+18-16
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,26 @@
1717
const {assert} = require('chai');
1818
const {describe, it} = require('mocha');
1919
const cp = require('child_process');
20-
const retry = require('p-retry');
2120

2221
const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
23-
22+
// A helper for delaying integration tests with an exponential backoff.
23+
// See examples like: https://github.com/googleapis/nodejs-monitoring/issues/190,
24+
// https://github.com/googleapis/nodejs-monitoring/issues/191.
25+
const delay = async test => {
26+
const retries = test.currentRetry();
27+
if (retries === 0) return; // no retry on the first failure.
28+
// see: https://cloud.google.com/storage/docs/exponential-backoff:
29+
const ms = Math.pow(2, retries) * 250 + Math.random() * 1000;
30+
return new Promise(done => {
31+
console.info(`retrying "${test.title}" in ${ms}ms`);
32+
setTimeout(done, ms);
33+
});
34+
};
2435
describe('quickstart', () => {
25-
it('should run the quickstart', async () => {
26-
// The write in the quickstart appears to be very, very flaky.
27-
// This should not be needed. The tracking bug is here:
28-
// https://github.com/googleapis/nodejs-monitoring/issues/191
29-
await retry(
30-
async () => {
31-
const result = execSync('node quickstart');
32-
assert.match(result, /Done writing time series data/);
33-
},
34-
{
35-
retries: 10,
36-
onFailedAttempt: () => console.warn('Write failed, retrying...'),
37-
}
38-
);
36+
it('should run the quickstart', async function() {
37+
this.retries(8);
38+
await delay(this.test); // delay the start of the test, if this is a retry.
39+
const result = execSync('node quickstart');
40+
assert.match(result, /Done writing time series data/);
3941
});
4042
});

0 commit comments

Comments
 (0)