-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathtransactions-convenient-api.prose.test.ts
More file actions
87 lines (72 loc) · 2.66 KB
/
transactions-convenient-api.prose.test.ts
File metadata and controls
87 lines (72 loc) · 2.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { expect } from 'chai';
import { test } from 'mocha';
import * as sinon from 'sinon';
import { type ClientSession, type Collection, type MongoClient } from '../../../src';
import { configureFailPoint, type FailCommandFailPoint, measureDuration } from '../../tools/utils';
const failCommand: FailCommandFailPoint = {
configureFailPoint: 'failCommand',
mode: {
times: 13
},
data: {
failCommands: ['commitTransaction'],
errorCode: 251 // no such transaction
}
};
describe('Retry Backoff is Enforced', function () {
// 1. let client be a MongoClient
let client: MongoClient;
// 2. let coll be a collection
let collection: Collection;
beforeEach(async function () {
client = this.configuration.newClient();
collection = client.db('foo').collection('bar');
});
afterEach(async function () {
sinon.restore();
await client?.close();
});
test(
'works',
{
requires: {
mongodb: '>=4.4', // failCommand
topology: '!single' // transactions can't run on standalone servers
}
},
async function () {
const randomStub = sinon.stub(Math, 'random');
// 3.i Configure the random number generator used for jitter to always return 0
randomStub.returns(0);
// 3.ii Configure a fail point that forces 13 retries
await configureFailPoint(this.configuration, failCommand);
// 3.iii
const callback = async (s: ClientSession) => {
await collection.insertOne({}, { session: s });
};
// 3.iv Let no_backoff_time be the duration of the withTransaction API call
const { duration: noBackoffTime } = await measureDuration(() => {
return client.withSession(async s => {
await s.withTransaction(callback);
});
});
// 4.i Configure the random number generator used for jitter to always return 1.
randomStub.returns(1);
// 4.ii Configure a fail point that forces 13 retries like in step 3.2.
await configureFailPoint(this.configuration, failCommand);
// 4.iii Use the same callback defined in 3.3.
// 4.iv Let with_backoff_time be the duration of the withTransaction API call
const { duration: fullBackoffDuration } = await measureDuration(() => {
return client.withSession(async s => {
await s.withTransaction(callback);
});
});
// 5. Compare the two time between the two runs.
// The sum of 13 backoffs is roughly 1.8 seconds. There is a half-second window to account for potential variance between the two runs.
expect(fullBackoffDuration).to.be.within(
noBackoffTime + 1800 - 500,
noBackoffTime + 1800 + 500
);
}
);
});