Skip to content

Commit 86d4ca1

Browse files
ci(NODE-6519,NODE-6702): fix flaky listIndexes APM test and rtt calculation test (#4464)
1 parent 3d047ed commit 86d4ca1

File tree

2 files changed

+58
-56
lines changed

2 files changed

+58
-56
lines changed

test/integration/command-logging-and-monitoring/command_monitoring.test.ts

+55-55
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
import { expect } from 'chai';
22

3-
import { ReadPreference } from '../../mongodb';
3+
import { type MongoClient, ObjectId, ReadPreference } from '../../mongodb';
44
import { filterForCommands, ignoreNsNotFound, setupDatabase } from '../shared';
55

66
describe('Command Monitoring', function () {
7+
let client: MongoClient;
8+
79
before(function () {
810
return setupDatabase(this.configuration);
911
});
1012

13+
afterEach(async function () {
14+
await client?.close();
15+
});
16+
1117
it('should correctly receive the APM events for an insert', {
1218
metadata: { requires: { topology: ['single', 'replicaset', 'sharded'] } },
1319

@@ -65,81 +71,75 @@ describe('Command Monitoring', function () {
6571
}
6672
});
6773

68-
it('should correctly receive the APM events for a listCollections command', {
69-
metadata: { requires: { topology: ['replicaset'], mongodb: '>=3.0.0' } },
74+
it('records APM events for a listIndexes command', async function () {
75+
const started = [];
76+
const succeeded = [];
77+
client = this.configuration.newClient(
78+
{ writeConcern: { w: 'majority' } },
79+
{ maxPoolSize: 1, monitorCommands: true }
80+
);
7081

71-
test: function () {
72-
const started = [];
73-
const succeeded = [];
74-
const client = this.configuration.newClient(
75-
{ writeConcern: { w: 1 } },
76-
{ maxPoolSize: 1, monitorCommands: true }
77-
);
82+
const desiredEvents = ['listIndexes'];
83+
client.on('commandStarted', filterForCommands(desiredEvents, started));
84+
client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));
7885

79-
client.on('commandStarted', filterForCommands('listCollections', started));
80-
client.on('commandSucceeded', filterForCommands('listCollections', succeeded));
86+
const db = client.db(new ObjectId().toHexString());
8187

82-
const db = client.db(this.configuration.db);
88+
const collection = db.collection('apm_test_list_collections');
89+
const session = client.startSession({ causalConsistency: true });
8390

84-
return db
85-
.collection('apm_test_list_collections')
86-
.insertOne({ a: 1 }, this.configuration.writeConcernMax())
87-
.then(r => {
88-
expect(r).property('insertedId').to.exist;
89-
return db.listCollections({}, { readPreference: ReadPreference.primary }).toArray();
90-
})
91-
.then(() => db.listCollections({}, { readPreference: ReadPreference.secondary }).toArray())
92-
.then(() => {
93-
expect(started).to.have.lengthOf(2);
94-
expect(started[0]).property('address').to.not.equal(started[1].address);
91+
const r = await collection.insertOne({ a: 1 }, { writeConcern: { w: 'majority' }, session });
92+
expect(r).property('insertedId').to.exist;
9593

96-
return client.close();
97-
});
98-
}
99-
});
94+
expect(await collection.listIndexes({ session }).toArray()).to.have.lengthOf(1);
10095

101-
it('should correctly receive the APM events for a listIndexes command', {
102-
metadata: { requires: { topology: ['replicaset'], mongodb: '>=3.0.0' } },
96+
const [{ commandName }] = started;
97+
expect(commandName).to.equal('listIndexes');
98+
});
10399

104-
test: function () {
100+
it(
101+
'records APM events for reads on secondaries',
102+
{ requires: { topology: ['replicaset'] } },
103+
async function () {
105104
const started = [];
106105
const succeeded = [];
107-
const client = this.configuration.newClient(
108-
{ writeConcern: { w: 1 } },
106+
client = this.configuration.newClient(
107+
{ writeConcern: { w: 'majority' } },
109108
{ maxPoolSize: 1, monitorCommands: true }
110109
);
111110

112111
const desiredEvents = ['listIndexes', 'find'];
113112
client.on('commandStarted', filterForCommands(desiredEvents, started));
114113
client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));
115114

116-
const db = client.db(this.configuration.db);
115+
const db = client.db(new ObjectId().toHexString());
117116

118-
return db
119-
.collection('apm_test_list_collections')
120-
.insertOne({ a: 1 }, this.configuration.writeConcernMax())
121-
.then(r => {
122-
expect(r).property('insertedId').to.exist;
117+
const collection = db.collection('apm_test_list_collections');
118+
const session = client.startSession({ causalConsistency: true });
123119

124-
return db
125-
.collection('apm_test_list_collections')
126-
.listIndexes({ readPreference: ReadPreference.PRIMARY })
127-
.toArray();
128-
})
129-
.then(() =>
130-
db
131-
.collection('apm_test_list_collections')
132-
.listIndexes({ readPreference: ReadPreference.SECONDARY })
133-
.toArray()
134-
)
135-
.then(() => {
136-
expect(started).to.have.lengthOf(2);
137-
expect(started[0]).property('address').to.not.equal(started[1].address);
120+
const r = await collection.insertOne({ a: 1 }, { writeConcern: { w: 'majority' }, session });
121+
expect(r).property('insertedId').to.exist;
138122

139-
return client.close();
123+
await collection
124+
.listIndexes({ readPreference: ReadPreference.PRIMARY, session })
125+
.toArray()
126+
.catch(e => {
127+
throw new Error('primary listIndexes failed', { cause: e });
140128
});
129+
130+
await collection
131+
.listIndexes({ readPreference: ReadPreference.SECONDARY, session })
132+
.toArray()
133+
.catch(() => {
134+
// reading with secondary read preference means the data may or may not have been propagated to the seconary
135+
// node yet. for this test, we are asserting that we did correctly send commands to different nodes, so
136+
// the actual outcome of this listIndexes doesn't matter.
137+
});
138+
139+
const [{ address: primaryAddress }, { address: secondaryAddress }] = started;
140+
expect(primaryAddress).not.to.equal(secondaryAddress);
141141
}
142-
});
142+
);
143143

144144
it('should correctly receive the APM events for a find with getmore and killcursor', {
145145
metadata: { requires: { topology: ['single', 'replicaset'] } },

test/integration/server-discovery-and-monitoring/server_discover_and_monitoring.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ describe('Monitoring rtt tests', function () {
5454
// @ts-expect-error accessing private method
5555
.stub(Connection.prototype, 'sendCommand')
5656
.callsFake(async function* (...args) {
57-
await setTimeout(DELAY_MS);
57+
// https://github.com/nodejs/node/issues/26578
58+
// setTimeout can result in the timeout being called in < the provided interval
59+
await setTimeout(DELAY_MS + 1);
5860
yield* stub.wrappedMethod.call(this, ...args);
5961
});
6062
await client.connect();

0 commit comments

Comments
 (0)