We're looking for funding - see Investors page.

Tests fail because the database is not ready

Issue: When swapping to CarbonRunner my tests using MongoMemoryReplSet stop working

Reason: Not waiting for the database to be properly initialized.

Bad examples

  • Using an even number of replica sets

     replSet = await MongoMemoryReplSet.create({
          replSet: { count: 4 }, // 4-member replica set
      });
    
  • Add a wait as suggested in the tests of mongodb-memory-server. e.g.

    await new Promise((resolve) => setTimeout(resolve, 2000));
    

Good solution

  • Use an odd number of replica sets
     replSet = await MongoMemoryReplSet.create({
          replSet: { count: 5 }, // 5-member replica set
      });
    
  • Wait for the database to initialize all replica sets
    
      const replicaCount = 5;
    
      async function waitUntilReady(uri, dbname) {
          let retries = 60;
          while (retries > 0) {
              retries -= 1;
    
              try {
                  const cl = new MongoClient(uri);
                  await cl.connect();
                  const db = client.db(dbname);
                  const admin = db.admin();
                  const status = await admin.replSetGetStatus();
                  const currentCount = status.members.filter(
                      (m) => m.stateStr === 'SECONDARY'
                  ).length;
    
                  if (currentCount !== replicaCount - 1) {
                      await new Promise((resolve) => setTimeout(resolve, 1000));
                      cl.close()
                      continue
                  }
    
                  cl.close()
                  return
              } catch (err) {
                  console.error(err)
                  await new Promise((resolve) => setTimeout(resolve, 1000));
              }
          }
      }
    
    
      beforeAll(async () => {
          replSet = await MongoMemoryReplSet.create({
              replSet: { count: replicaCount }, // 5-member replica set
          });
    
          const dbname = 'testdb';
    
          await replSet.waitUntilRunning();
    
          const uri = replSet.getUri();
          await waitUntilReady(uri, dbname)
    
          const cl = new MongoClient(uri);
          await cl.connect();
          const db = client.db(dbname);
          const admin = db.admin();
          const status = await admin.replSetGetStatus();
          expect(status.members.filter((m) => m.stateStr === 'PRIMARY')).toHaveLength(1);
          expect(status.members.filter((m) => m.stateStr === 'SECONDARY')).toHaveLength(4);
      }, 60 * 1000);
    

References:

- https://github.com/typegoose/mongodb-memory-server/issues/911
- https://typegoose.github.io/mongodb-memory-server/docs/guides/common-issues
- https://github.com/typegoose/mongodb-memory-server/blob/master/packages/mongodb-memory-server-core/src/__tests__/replset-multi.test.ts#L21