@@ -9,6 +9,7 @@ const {
 const { loadSpecTests } = require('../spec');
 const { expect } = require('chai');
 const { ReadPreference } = require('../../src/read_preference');
+const { runUnifiedTest } = require('./unified-spec-runner/runner');
 
 describe('APM', function () {
   before(function () {
'use strict';

const {
  setupDatabase,
  filterForCommands,
  filterOutCommands,
  ignoreNsNotFound
} = require('./shared');
const { loadSpecTests } = require('../spec');
const { expect } = require('chai');
const { ReadPreference } = require('../../src/read_preference');

describe('APM', function () {
  before(function () {
    return setupDatabase(this.configuration);
  });

  it('should correctly receive the APM events for an insert', {
    metadata: { requires: { topology: ['single', 'replicaset', 'sharded'] } },

    test: function () {
      const started = [];
      const succeeded = [];
      const client = this.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      client.on('commandStarted', filterForCommands('insert', started));
      client.on('commandSucceeded', filterForCommands('insert', succeeded));

      return client
        .connect()
        .then(client => client.db(this.configuration.db).collection('apm_test').insertOne({ a: 1 }))
        .then(r => {
          expect(r).property('insertedId').to.exist;
          expect(started.length).to.equal(1);
          expect(started[0].commandName).to.equal('insert');
          expect(started[0].command.insert).to.equal('apm_test');
          expect(succeeded.length).to.equal(1);
          return client.close();
        });
    }
  });

  it('should correctly handle cursor.close when no cursor existed', {
    metadata: { requires: { topology: ['single', 'replicaset'] } },

    test: function () {
      const started = [];
      const succeeded = [];
      const self = this;
      const client = this.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      client.on('commandStarted', filterForCommands('insert', started));
      client.on('commandSucceeded', filterForCommands('insert', succeeded));

      return client.connect().then(client => {
        const db = client.db(self.configuration.db);
        const collection = db.collection('apm_test_cursor');
        return collection.insertMany([{ a: 1 }, { a: 2 }, { a: 3 }]).then(r => {
          expect(r).property('insertedCount').to.equal(3);
          const cursor = collection.find({});
          return cursor.count().then(() => {
            cursor.close(); // <-- Will cause error in APM module.
            return client.close();
          });
        });
      });
    }
  });

  it('should correctly receive the APM events for a listCollections command', {
    metadata: { requires: { topology: ['replicaset'], mongodb: '>=3.0.0' } },

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      client.on('commandStarted', filterForCommands('listCollections', started));
      client.on('commandSucceeded', filterForCommands('listCollections', succeeded));

      return client
        .connect()
        .then(client => {
          const db = client.db(self.configuration.db);

          return db
            .collection('apm_test_list_collections')
            .insertOne({ a: 1 }, self.configuration.writeConcernMax())
            .then(r => {
              expect(r).property('insertedId').to.exist;
              return db.listCollections({}, { readPreference: ReadPreference.primary }).toArray();
            })
            .then(() =>
              db.listCollections({}, { readPreference: ReadPreference.secondary }).toArray()
            )
            .then(() => {
              expect(started).to.have.lengthOf(2);
              expect(started[0]).property('address').to.not.equal(started[1].address);

              return client.close();
            });
        })
        .catch(err => expect(err).to.not.exist);
    }
  });

  // NODE-3308
  it.skip('should correctly receive the APM events for a listIndexes command', {
    metadata: { requires: { topology: ['replicaset'], mongodb: '>=3.0.0' } },

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

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

      return client.connect().then(() => {
        const db = client.db(self.configuration.db);

        return db
          .collection('apm_test_list_collections')
          .insertOne({ a: 1 }, self.configuration.writeConcernMax())
          .then(r => {
            expect(r).property('insertedId').to.exist;

            return db
              .collection('apm_test_list_collections')
              .listIndexes({ readPreference: ReadPreference.PRIMARY })
              .toArray();
          })
          .then(() =>
            db
              .collection('apm_test_list_collections')
              .listIndexes({ readPreference: ReadPreference.SECONDARY })
              .toArray()
          )
          .then(() => {
            expect(started).to.have.lengthOf(2);
            expect(started[0]).property('address').to.not.equal(started[1].address);

            return client.close();
          });
      });
    }
  });

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

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const failed = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      const desiredEvents = ['find', 'getMore', 'killCursors'];
      client.on('commandStarted', filterForCommands(desiredEvents, started));
      client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));
      client.on('commandFailed', filterForCommands(desiredEvents, failed));

      return client.connect().then(client => {
        const db = client.db(self.configuration.db);

        // Drop the collection
        return db
          .collection('apm_test_2')
          .drop()
          .catch(ignoreNsNotFound)
          .then(() => {
            // Insert test documents
            return db
              .collection('apm_test_2')
              .insertMany([{ a: 1 }, { a: 1 }, { a: 1 }, { a: 1 }, { a: 1 }, { a: 1 }], {
                writeConcern: { w: 1 }
              });
          })
          .then(r => {
            expect(r).property('insertedCount').to.equal(6);
            return db
              .collection('apm_test_2')
              .find({ a: 1 })
              .project({ _id: 1, a: 1 })
              .hint({ _id: 1 })
              .skip(1)
              .limit(100)
              .batchSize(2)
              .comment('some comment')
              .maxTimeMS(5000)
              .withReadPreference(ReadPreference.PRIMARY)
              .addCursorFlag('noCursorTimeout', true)
              .toArray();
          })
          .then(docs => {
            // Assert basic documents
            expect(docs).to.have.length(5);
            expect(started).to.have.length(3);
            expect(succeeded).to.have.length(3);
            expect(failed).to.have.length(0);

            // Success messages
            expect(succeeded[0].reply).to.not.be.null;
            expect(succeeded[0].operationId).to.equal(succeeded[1].operationId);
            expect(succeeded[0].operationId).to.equal(succeeded[2].operationId);
            expect(succeeded[1].reply).to.not.be.null;
            expect(succeeded[2].reply).to.not.be.null;

            // Started
            expect(started[0].operationId).to.equal(started[1].operationId);
            expect(started[0].operationId).to.equal(started[2].operationId);

            return client.close();
          });
      });
    }
  });

  it('should correctly receive the APM failure event for find', {
    metadata: { requires: { topology: ['single', 'replicaset'], mongodb: '>=2.6.0' } },

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const failed = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      const desiredEvents = ['find', 'getMore', 'killCursors'];
      client.on('commandStarted', filterForCommands(desiredEvents, started));
      client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));
      client.on('commandFailed', filterForCommands(desiredEvents, failed));

      return client.connect().then(client => {
        const db = client.db(self.configuration.db);

        // Drop the collection
        return db
          .collection('apm_test_2')
          .drop()
          .catch(ignoreNsNotFound)
          .then(() => {
            // Insert test documents
            return db
              .collection('apm_test_2')
              .insertMany([{ a: 1 }, { a: 1 }, { a: 1 }, { a: 1 }, { a: 1 }, { a: 1 }]);
          })
          .then(r => {
            expect(r).property('insertedCount').to.equal(6);
            return db
              .collection('apm_test_2')
              .find({ $illegalfield: 1 })
              .project({ _id: 1, a: 1 })
              .hint({ _id: 1 })
              .skip(1)
              .limit(100)
              .batchSize(2)
              .comment('some comment')
              .maxTimeMS(5000)
              .withReadPreference(ReadPreference.PRIMARY)
              .addCursorFlag('noCursorTimeout', true)
              .toArray();
          })
          .then(() => {
            throw new Error('this should not happen');
          })
          .catch(() => {
            expect(failed).to.have.length(1);
            return client.close();
          });
      });
    }
  });

  it('should correctly receive the APM events for a bulk operation', {
    metadata: { requires: { topology: ['single', 'replicaset'] } },

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      const desiredEvents = ['insert', 'update', 'delete'];
      client.on('commandStarted', filterForCommands(desiredEvents, started));
      client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));

      return client.connect().then(client => {
        const db = client.db(self.configuration.db);
        return db
          .collection('apm_test_3')
          .bulkWrite(
            [
              { insertOne: { document: { a: 1 } } },
              { updateOne: { filter: { a: 2 }, update: { $set: { a: 2 } }, upsert: true } },
              { deleteOne: { filter: { c: 1 } } }
            ],
            { ordered: true }
          )
          .then(() => {
            expect(started).to.have.length(3);
            expect(succeeded).to.have.length(3);
            expect(started[0].operationId).to.equal(started[1].operationId);
            expect(started[0].operationId).to.equal(started[2].operationId);
            expect(succeeded[0].operationId).to.equal(succeeded[1].operationId);
            expect(succeeded[0].operationId).to.equal(succeeded[2].operationId);
            return client.close();
          });
      });
    }
  });

  it('should correctly receive the APM explain command', {
    metadata: { requires: { topology: ['single', 'replicaset'] } },

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const failed = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      const desiredEvents = ['find', 'getMore', 'killCursors', 'explain'];
      client.on('commandStarted', filterForCommands(desiredEvents, started));
      client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));
      client.on('commandFailed', filterForCommands(desiredEvents, failed));

      return client.connect().then(client => {
        const db = client.db(self.configuration.db);

        return db
          .collection('apm_test_2')
          .drop()
          .catch(ignoreNsNotFound)
          .then(() =>
            db
              .collection('apm_test_2')
              .insertMany([{ a: 1 }, { a: 1 }, { a: 1 }, { a: 1 }, { a: 1 }, { a: 1 }], {
                writeConcern: { w: 1 }
              })
          )
          .then(r => {
            expect(r).property('insertedCount').to.equal(6);
            return db.collection('apm_test_2').find({ a: 1 }).explain();
          })
          .then(explain => {
            expect(explain).to.not.be.null;
            expect(started).to.have.length(1);
            expect(started[0].commandName).to.equal('explain');
            expect(started[0].command.explain.find).to.equal('apm_test_2');
            expect(succeeded).to.have.length(1);
            expect(succeeded[0].commandName).to.equal('explain');
            expect(started[0].operationId).to.equal(succeeded[0].operationId);
            return client.close();
          });
      });
    }
  });

  it('should correctly filter out sensitive commands', {
    metadata: { requires: { topology: ['single', 'replicaset'] } },

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const failed = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      const desiredEvents = ['getnonce'];
      client.on('commandStarted', filterForCommands(desiredEvents, started));
      client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));
      client.on('commandFailed', filterForCommands(desiredEvents, failed));

      return client
        .connect()
        .then(client => client.db(self.configuration.db).command({ getnonce: true }))
        .then(r => {
          expect(r).to.exist;
          expect(started).to.have.length(1);
          expect(succeeded).to.have.length(1);
          expect(failed).to.have.length(0);
          expect(started[0].commandObj).to.eql({ getnonce: true });
          expect(succeeded[0].reply).to.eql({});
          return client.close();
        });
    }
  });

  it('should correctly receive the APM events for an updateOne', {
    metadata: { requires: { topology: ['single', 'replicaset'] } },

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      const desiredEvents = ['update'];
      client.on('commandStarted', filterForCommands(desiredEvents, started));
      client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));

      return client
        .connect()
        .then(client =>
          client
            .db(self.configuration.db)
            .collection('apm_test_u_1')
            .updateOne({ a: 1 }, { $set: { b: 1 } }, { upsert: true })
        )
        .then(r => {
          expect(r).to.exist;
          expect(started).to.have.length(1);
          expect(started[0].commandName).to.equal('update');
          expect(started[0].command.update).to.equal('apm_test_u_1');
          expect(succeeded).to.have.length(1);
          return client.close();
        });
    }
  });

  it('should correctly receive the APM events for an updateMany', {
    metadata: { requires: { topology: ['single', 'replicaset'] } },

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      const desiredEvents = ['update'];
      client.on('commandStarted', filterForCommands(desiredEvents, started));
      client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));

      return client
        .connect()
        .then(client =>
          client
            .db(self.configuration.db)
            .collection('apm_test_u_2')
            .updateMany({ a: 1 }, { $set: { b: 1 } }, { upsert: true })
        )
        .then(r => {
          expect(r).to.exist;
          expect(started).to.have.length(1);
          expect(started[0].commandName).to.equal('update');
          expect(started[0].command.update).to.equal('apm_test_u_2');
          expect(succeeded).to.have.length(1);
          return client.close();
        });
    }
  });

  it('should correctly receive the APM events for deleteOne', {
    metadata: { requires: { topology: ['single', 'replicaset'] } },

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      const desiredEvents = ['delete'];
      client.on('commandStarted', filterForCommands(desiredEvents, started));
      client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));

      return client
        .connect()
        .then(client =>
          client.db(self.configuration.db).collection('apm_test_u_3').deleteOne({ a: 1 })
        )
        .then(r => {
          expect(r).to.exist;
          expect(started).to.have.length(1);
          expect(started[0].commandName).to.equal('delete');
          expect(started[0].command.delete).to.equal('apm_test_u_3');
          expect(succeeded).to.have.length(1);
          return client.close();
        });
    }
  });

  it('should ensure killcursor commands are sent on 3.0 or earlier when APM is enabled', {
    metadata: { requires: { topology: ['single', 'replicaset'], mongodb: '<=3.0.x' } },

    test: function () {
      const self = this;
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      return client.connect().then(client => {
        const db = client.db(self.configuration.db);
        const admindb = db.admin();
        let cursorCountBefore;
        let cursorCountAfter;

        const collection = db.collection('apm_killcursor_tests');

        // make sure collection has records (more than 2)
        return collection
          .insertMany([{ a: 1 }, { a: 2 }, { a: 3 }])
          .then(r => {
            expect(r).to.exist;
            return admindb.serverStatus();
          })
          .then(result => {
            cursorCountBefore = result.cursors.clientCursors_size;
            let cursor = collection.find({}).limit(2);
            return cursor.toArray().then(r => {
              expect(r).to.exist;
              return cursor.close();
            });
          })
          .then(() => admindb.serverStatus())
          .then(result => {
            cursorCountAfter = result.cursors.clientCursors_size;
            expect(cursorCountBefore).to.equal(cursorCountAfter);
            return client.close();
          });
      });
    }
  });

  it('should correctly decorate the apm result for aggregation with cursorId', {
    metadata: { requires: { topology: ['single', 'replicaset'], mongodb: '>=3.0.0' } },

    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];

      // Generate docs
      const docs = [];
      for (let i = 0; i < 2500; i++) docs.push({ a: i });

      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      const desiredEvents = ['aggregate', 'getMore'];
      client.on('commandStarted', filterForCommands(desiredEvents, started));
      client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));

      return client.connect().then(() => {
        const db = client.db(self.configuration.db);
        return db
          .collection('apm_test_u_4')
          .drop()
          .catch(ignoreNsNotFound)
          .then(() => db.collection('apm_test_u_4').insertMany(docs))
          .then(r => {
            expect(r).to.exist;
            return db
              .collection('apm_test_u_4')
              .aggregate([{ $match: {} }])
              .toArray();
          })
          .then(r => {
            expect(r).to.exist;
            expect(started).to.have.length(4);
            expect(succeeded).to.have.length(4);
            const cursors = succeeded.map(x => x.reply.cursor);

            // Check we have a cursor
            expect(cursors[0].id).to.exist;
            expect(cursors[0].id.toString()).to.equal(cursors[1].id.toString());
            expect(cursors[3].id.toString()).to.equal('0');

            return client.close();
          });
      });
    }
  });

  it('should correctly decorate the apm result for listCollections with cursorId', {
    metadata: { requires: { topology: ['single', 'replicaset'], mongodb: '>=3.0.0' } },
    test: function () {
      const self = this;
      const started = [];
      const succeeded = [];
      const client = self.configuration.newClient(
        { writeConcern: { w: 1 } },
        { maxPoolSize: 1, monitorCommands: true }
      );

      const desiredEvents = ['listCollections'];
      client.on('commandStarted', filterForCommands(desiredEvents, started));
      client.on('commandSucceeded', filterForCommands(desiredEvents, succeeded));

      return client.connect().then(client => {
        const db = client.db(self.configuration.db);

        const promises = [];
        for (let i = 0; i < 20; i++) {
          promises.push(db.collection('_mass_collection_' + i).insertOne({ a: 1 }));
        }

        return Promise.all(promises)
          .then(r => {
            expect(r).to.exist;

            return db.listCollections().batchSize(10).toArray();
          })
          .then(r => {
            expect(r).to.exist;
            expect(started).to.have.length(1);
            expect(succeeded).to.have.length(1);

            const cursors = succeeded.map(x => x.reply.cursor);
            expect(cursors[0].id).to.exist;

            return client.close();
          });
      });
    }
  });

  // NODE-1502
  it('should not allow mutation of internal state from commands returned by event monitoring', function () {
    const started = [];
    const succeeded = [];
    const client = this.configuration.newClient(
      { writeConcern: { w: 1 } },
      { maxPoolSize: 1, monitorCommands: true }
    );
    client.on('commandStarted', filterForCommands('insert', started));
    client.on('commandSucceeded', filterForCommands('insert', succeeded));
    let documentToInsert = { a: { b: 1 } };
    return client
      .connect()
      .then(client => {
        const db = client.db(this.configuration.db);
        return db.collection('apm_test').insertOne(documentToInsert);
      })
      .then(r => {
        expect(r).to.have.property('insertedId').that.is.an('object');
        expect(started).to.have.lengthOf(1);
        // Check if contents of returned document are equal to document inserted (by value)
        expect(documentToInsert).to.deep.equal(started[0].command.documents[0]);
        // Check if the returned document is a clone of the original. This confirms that the
        // reference is not the same.
        expect(documentToInsert !== started[0].command.documents[0]).to.equal(true);
        expect(documentToInsert.a !== started[0].command.documents[0].a).to.equal(true);

        started[0].command.documents[0].a.b = 2;
        expect(documentToInsert.a.b).to.equal(1);

        expect(started[0].commandName).to.equal('insert');
        expect(started[0].command.insert).to.equal('apm_test');
        expect(succeeded).to.have.lengthOf(1);
        return client.close();
      });
  });

  describe('spec tests', function () {
    before(function () {
      return setupDatabase(this.configuration);
    });

    // TODO: The worst part about this custom validation method is that it does not
    //       provide the rich context of failure location that chai gives us out of
    //       the box. I investigated extending chai, however their internal implementation
    //       does not reuse other internal methods, so we'd have to bring lodash in.
    //       It may be worth seeing if we can improve on this, as we might need the
    //       behavior in other future YAML tests.
    const maybeLong = val => (typeof val.equals === 'function' ? val.toNumber() : val);
    function apmExpect(actual, expected, parentKey) {
      Object.keys(expected).forEach(key => {
        expect(actual).to.include.key(key);

        // TODO: This is a workaround that works because all sorts in the specs
        // are objects with one key; ideally we'd want to adjust the spec definitions
        // to indicate whether order matters for any given key and set general
        // expectations accordingly (see NODE-3235)
        if (key === 'sort') {
          expect(actual[key]).to.be.instanceOf(Map);
          expect(Object.keys(expected[key])).to.have.lengthOf(1);
          expect(actual[key].size).to.equal(1);
          expect(actual[key].get(Object.keys(expected[key])[0])).to.equal(
            Object.values(expected[key])[0]
          );
          return;
        }

        if (Array.isArray(expected[key])) {
          expect(actual[key]).to.be.instanceOf(Array);
          expect(actual[key]).to.have.lengthOf(expected[key].length);
          for (let i = 0; i < expected[key].length; ++i) {
            apmExpect(actual[key][i], expected[key][i], key);
          }

          return;
        }

        if (expected[key] === 42 || expected[key] === '42' || expected[key] === '') {
          if (key === 'code' && expected[key] === 42) {
            expect(actual[key]).to.be.greaterThan(0);
          }

          if (key === 'errmsg' && expected[key] === '') {
            expect(actual[key]).to.have.lengthOf.at.least(1); // >= 1
          }

          if (key === 'getmore' || (parentKey === 'cursor' && key === 'id')) {
            expect(maybeLong(actual[key])).to.be.greaterThan(0);
          }

          return;
        }

        // cheap isPlainObject clone
        if (Object.prototype.toString.call(expected[key]) === '[object Object]') {
          apmExpect(actual[key], expected[key], key);
          return;
        }

        // otherwise compare the values
        expect(maybeLong(actual[key]), key).to.deep.equal(expected[key]);
      });
    }

    function validateCommandStartedEvent(expected, event) {
      expect(event.commandName).to.equal(expected.command_name);
      expect(event.databaseName).to.equal(expected.database_name);
      apmExpect(event.command, expected.command);
    }

    function validateCommandSucceededEvent(expected, event) {
      expect(event.commandName).to.equal(expected.command_name);
      apmExpect(event.reply, expected.reply);
    }

    function validateCommandFailedEvent(expected, event) {
      expect(event.commandName).to.equal(expected.command_name);
    }

    function validateExpectations(expectation, results) {
      if (expectation.command_started_event) {
        validateCommandStartedEvent(expectation.command_started_event, results.starts.shift());
      } else if (expectation.command_succeeded_event) {
        validateCommandSucceededEvent(
          expectation.command_succeeded_event,
          results.successes.shift()
        );
      } else if (expectation.command_failed_event) {
        validateCommandFailedEvent(expectation.command_failed_event, results.failures.shift());
      }
    }

    function executeOperation(client, scenario, test) {
      // Get the operation
      const operation = test.operation;
      // Get the command name
      const commandName = operation.name;
      // Get the arguments
      const args = operation.arguments || {};
      // Get the database instance
      const db = client.db(scenario.database_name);
      // Get the collection
      const collection = db.collection(scenario.collection_name);
      // Parameters
      const params = [];
      // Options
      let options = null;
      // Get the data
      const data = scenario.data;
      // Command Monitoring context
      const monitoringResults = {
        successes: [],
        failures: [],
        starts: []
      };

      // Drop the collection
      return collection
        .drop()
        .catch(err => {
          // potentially skip this error
          if (!err.message.match(/ns not found/)) throw err;
        })
        .then(() => collection.insertMany(data))
        .then(r => {
          expect(data).to.have.length(Object.keys(r.insertedIds).length);

          // Set up the listeners
          client.on(
            'commandStarted',
            filterOutCommands(['ismaster', 'endSessions'], monitoringResults.starts)
          );
          client.on(
            'commandFailed',
            filterOutCommands(['ismaster', 'endSessions'], monitoringResults.failures)
          );
          client.on(
            'commandSucceeded',
            filterOutCommands(['ismaster', 'endSessions'], monitoringResults.successes)
          );

          // Unpack the operation
          if (args.options) options = args.options;
          if (args.filter) params.push(args.filter);
          if (args.deletes) params.push(args.deletes);
          if (args.document) params.push(args.document);
          if (args.documents) params.push(args.documents);
          if (args.update) params.push(args.update);
          if (args.requests) {
            if (operation.name !== 'bulkWrite') {
              params.push(args.requests);
            } else {
              params.push(
                args.requests.map(r => {
                  return { [r.name]: r.arguments.document || r.arguments };
                })
              );
            }
          }

          if (args.writeConcern) {
            options = options || {};
            options.writeConcern = args.writeConcern;
          }

          if (typeof args.ordered === 'boolean') {
            if (options == null) {
              options = { ordered: args.ordered };
            } else {
              options.ordered = args.ordered;
            }
          }

          if (typeof args.upsert === 'boolean') {
            if (options == null) {
              options = { upsert: args.upsert };
            } else {
              options.upsert = args.upsert;
            }
          }

          // Find command is special needs to executed using toArray
          if (operation.name === 'find') {
            let cursor = collection[commandName]();

            // Set the options
            if (args.filter) cursor = cursor.filter(args.filter);
            if (args.batchSize) cursor = cursor.batchSize(args.batchSize);
            if (args.limit) cursor = cursor.limit(args.limit);
            if (args.skip) cursor = cursor.skip(args.skip);
            if (args.sort) cursor = cursor.sort(args.sort);

            // Set any modifiers
            if (args.modifiers) {
              for (let modifier in args.modifiers) {
                cursor.addQueryModifier(modifier, args.modifiers[modifier]);
              }
            }

            // Execute find
            return cursor
              .toArray()
              .catch(() => {} /* ignore */)
              .then(() =>
                test.expectations.forEach(expectation =>
                  validateExpectations(expectation, monitoringResults)
                )
              );
          }
          // Add options if they exists
          if (options) params.push(options);

          // Execute the operation
          const coll = operation.collectionOptions
            ? db.collection(scenario.collection_name, operation.collectionOptions)
            : db.collection(scenario.collection_name);

          const promise = coll[commandName].apply(coll, params);
          return promise
            .catch(() => {} /* ignore */)
            .then(() =>
              test.expectations.forEach(expectation =>
                validateExpectations(expectation, monitoringResults)
              )
            );
        });
    }

    loadSpecTests('apm').forEach(scenario => {
      if (scenario.name === 'command') return; // FIXME(NODE-3074): remove when `count` spec tests have been fixed
      describe(scenario.name, function () {
        scenario.tests.forEach(test => {
          const requirements = { topology: ['single', 'replicaset', 'sharded'] };
          if (test.ignore_if_server_version_greater_than) {
            requirements.mongodb = `<${test.ignore_if_server_version_greater_than}`;
          } else if (test.ignore_if_server_version_less_than) {
            requirements.mongodb = `>${test.ignore_if_server_version_less_than}`;
          }

          if (test.ignore_if_topology_type) {
            requirements.topology = requirements.topology.filter(
              top => test.ignore_if_topology_type.indexOf(top) < 0
            );
          }

          it(test.description, {
            metadata: { requires: requirements },
            test: function () {
              if (
                test.description ===
                'A successful find event with a getmore and the server kills the cursor'
              ) {
                this.skip();
              }

              const client = this.configuration.newClient({}, { monitorCommands: true });
              return client.connect().then(client => {
                expect(client).to.exist;
                return executeOperation(client, scenario, test).then(() => client.close());
              });
            }
          });
        });
      });
    });
  });
});

Maybe we rename this to `command_monitoring.test.js` to match the directory name change? Or would you rather do that as part of the greater test cleanup? I'm fine either way.