TEST_F(TransactionCoordinatorServiceTest, CoordinatorRetriesOnWriteConcernErrorToCommit) {
    auto coordinatorService = TransactionCoordinatorService::get(operationContext());
    coordinatorService->createCoordinator(operationContext(), _lsid, _txnNumber, kCommitDeadline);

    // Coordinator sends prepare.
    auto commitDecisionFuture = *coordinatorService->coordinateCommit(
        operationContext(), _lsid, _txnNumber, kTwoShardIdSet);

    // Both participants vote to commit.
    assertPrepareSentAndRespondWithSuccess();
    assertPrepareSentAndRespondWithSuccess();

    // One participant responds to commit with success.
    assertCommitSentAndRespondWithSuccess();

    // Coordinator retries commit against other participant until other participant responds without
    // writeConcern error.
    assertCommitSentAndRespondWithSuccessAndWriteConcernError();
    assertCommitSentAndRespondWithSuccessAndWriteConcernError();
    assertCommitSentAndRespondWithSuccessAndWriteConcernError();
    assertCommitSentAndRespondWithSuccessAndWriteConcernError();
    assertCommitSentAndRespondWithSuccessAndWriteConcernError();
    assertCommitSentAndRespondWithSuccess();

    // The transaction should now be committed.
    ASSERT_EQ(static_cast<int>(commitDecisionFuture.get()),
              static_cast<int>(txn::CommitDecision::kCommit));
}
TEST_F(TransactionCoordinatorCatalogTest, CreateFollowedByGetReturnsCoordinator) {
    LogicalSessionId lsid = makeLogicalSessionIdForTest();
    TxnNumber txnNumber = 1;
    createCoordinatorInCatalog(operationContext(), lsid, txnNumber);
    auto coordinatorInCatalog = coordinatorCatalog().get(operationContext(), lsid, txnNumber);
    ASSERT(coordinatorInCatalog != nullptr);
}
TEST_F(KeysManagerShardedTest, HasSeenKeysIsFalseUntilKeysAreFound) {
    const LogicalTime currentTime(Timestamp(100, 0));
    LogicalClock::get(operationContext())->setClusterTimeFromTrustedSource(currentTime);

    ASSERT_EQ(false, keyManager()->hasSeenKeys());

    {
        FailPointEnableBlock failKeyGenerationBlock("disableKeyGeneration");
        keyManager()->startMonitoring(getServiceContext());
        keyManager()->enableKeyGenerator(operationContext(), true);

        keyManager()->refreshNow(operationContext());
        auto keyStatus = keyManager()->getKeyForValidation(
            operationContext(), 1, LogicalTime(Timestamp(100, 0)));
        ASSERT_EQ(ErrorCodes::KeyNotFound, keyStatus.getStatus());

        ASSERT_EQ(false, keyManager()->hasSeenKeys());
    }

    // Once the failpoint is disabled, the generator can make keys again.
    keyManager()->refreshNow(operationContext());
    auto keyStatus = keyManager()->getKeyForSigning(nullptr, LogicalTime(Timestamp(100, 0)));
    ASSERT_OK(keyStatus.getStatus());

    ASSERT_EQ(true, keyManager()->hasSeenKeys());
}
TEST_F(KeysManagerShardedTest, ShouldStillBeAbleToUpdateCacheEvenIfItCantCreateKeys) {
    KeysCollectionDocument origKey1(
        1, "dummy", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(105, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), KeysCollectionDocument::ConfigNS, origKey1.toBSON()));

    // Set the time to be very ahead so the updater will be forced to create new keys.
    const LogicalTime fakeTime(Timestamp(20000, 0));
    LogicalClock::get(operationContext())->setClusterTimeFromTrustedSource(fakeTime);

    FailPointEnableBlock failWriteBlock("failCollectionInserts");

    {
        FailPointEnableBlock failQueryBlock("planExecutorAlwaysFails");
        keyManager()->startMonitoring(getServiceContext());
        keyManager()->enableKeyGenerator(operationContext(), true);
    }

    auto keyStatus =
        keyManager()->getKeyForValidation(operationContext(), 1, LogicalTime(Timestamp(100, 0)));
    ASSERT_OK(keyStatus.getStatus());

    auto key = keyStatus.getValue();
    ASSERT_EQ(1, key.getKeyId());
    ASSERT_EQ(origKey1.getKey(), key.getKey());
    ASSERT_EQ(Timestamp(105, 0), key.getExpiresAt().asTimestamp());
}
TEST_F(CacheReaderTest, GetKeyShouldReturnCorrectKeyAfterRefresh) {
    auto catalogClient = Grid::get(operationContext())->catalogClient(operationContext());
    KeysCollectionCacheReader reader("test", catalogClient);

    KeysCollectionDocument origKey1(
        1, "test", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(105, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), NamespaceString(KeysCollectionDocument::ConfigNS), origKey1.toBSON()));

    auto refreshStatus = reader.refresh(operationContext());
    ASSERT_OK(refreshStatus.getStatus());

    {
        auto key = refreshStatus.getValue();
        ASSERT_EQ(1, key.getKeyId());
        ASSERT_EQ(origKey1.getKey(), key.getKey());
        ASSERT_EQ("test", key.getPurpose());
        ASSERT_EQ(Timestamp(105, 0), key.getExpiresAt().asTimestamp());
    }

    auto status = reader.getKey(LogicalTime(Timestamp(1, 0)));
    ASSERT_OK(status.getStatus());

    {
        auto key = status.getValue();
        ASSERT_EQ(1, key.getKeyId());
        ASSERT_EQ(origKey1.getKey(), key.getKey());
        ASSERT_EQ("test", key.getPurpose());
        ASSERT_EQ(Timestamp(105, 0), key.getExpiresAt().asTimestamp());
    }
}
TEST_F(KeysManagerShardedTest, GetKeyForSigningShouldReturnRightOldKey) {
    keyManager()->startMonitoring(getServiceContext());

    KeysCollectionDocument origKey1(
        1, "dummy", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(105, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), KeysCollectionDocument::ConfigNS, origKey1.toBSON()));
    KeysCollectionDocument origKey2(
        2, "dummy", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(110, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), KeysCollectionDocument::ConfigNS, origKey2.toBSON()));

    keyManager()->refreshNow(operationContext());

    {
        auto keyStatus = keyManager()->getKeyForSigning(nullptr, LogicalTime(Timestamp(100, 0)));
        ASSERT_OK(keyStatus.getStatus());

        auto key = keyStatus.getValue();
        ASSERT_EQ(1, key.getKeyId());
        ASSERT_EQ(origKey1.getKey(), key.getKey());
        ASSERT_EQ(Timestamp(105, 0), key.getExpiresAt().asTimestamp());
    }

    {
        auto keyStatus = keyManager()->getKeyForSigning(nullptr, LogicalTime(Timestamp(105, 0)));
        ASSERT_OK(keyStatus.getStatus());

        auto key = keyStatus.getValue();
        ASSERT_EQ(2, key.getKeyId());
        ASSERT_EQ(origKey2.getKey(), key.getKey());
        ASSERT_EQ(Timestamp(110, 0), key.getExpiresAt().asTimestamp());
    }
}
TEST_F(KeysManagerShardedTest, GetKeyWithMultipleKeys) {
    keyManager()->startMonitoring(getServiceContext());

    KeysCollectionDocument origKey1(
        1, "dummy", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(105, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), KeysCollectionDocument::ConfigNS, origKey1.toBSON()));

    KeysCollectionDocument origKey2(
        2, "dummy", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(205, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), KeysCollectionDocument::ConfigNS, origKey2.toBSON()));

    auto keyStatus =
        keyManager()->getKeyForValidation(operationContext(), 1, LogicalTime(Timestamp(100, 0)));
    ASSERT_OK(keyStatus.getStatus());

    auto key = keyStatus.getValue();
    ASSERT_EQ(1, key.getKeyId());
    ASSERT_EQ(origKey1.getKey(), key.getKey());
    ASSERT_EQ(Timestamp(105, 0), key.getExpiresAt().asTimestamp());

    keyStatus =
        keyManager()->getKeyForValidation(operationContext(), 2, LogicalTime(Timestamp(100, 0)));
    ASSERT_OK(keyStatus.getStatus());

    key = keyStatus.getValue();
    ASSERT_EQ(2, key.getKeyId());
    ASSERT_EQ(origKey2.getKey(), key.getKey());
    ASSERT_EQ(Timestamp(205, 0), key.getExpiresAt().asTimestamp());
}
TEST_F(KeyGeneratorUpdateTest, ShouldCreate2KeysFromEmpty) {
    KeyGenerator generator("dummy", catalogClient(), Seconds(5));

    const LogicalTime currentTime(LogicalTime(Timestamp(100, 2)));
    LogicalClock::get(operationContext())->setClusterTimeFromTrustedSource(currentTime);

    auto generateStatus = generator.generateNewKeysIfNeeded(operationContext());
    ASSERT_OK(generateStatus);

    auto allKeys = getKeys(operationContext());

    ASSERT_EQ(2u, allKeys.size());

    const auto& key1 = allKeys.front();
    ASSERT_EQ(currentTime.asTimestamp().asLL(), key1.getKeyId());
    ASSERT_EQ("dummy", key1.getPurpose());
    ASSERT_EQ(Timestamp(105, 0), key1.getExpiresAt().asTimestamp());

    const auto& key2 = allKeys.back();
    ASSERT_EQ(currentTime.asTimestamp().asLL() + 1, key2.getKeyId());
    ASSERT_EQ("dummy", key2.getPurpose());
    ASSERT_EQ(Timestamp(110, 0), key2.getExpiresAt().asTimestamp());

    ASSERT_NE(key1.getKey(), key2.getKey());
}
TEST_F(CacheReaderTest, RefreshErrorsIfCacheIsEmpty) {
    auto catalogClient = Grid::get(operationContext())->catalogClient(operationContext());
    KeysCollectionCacheReader reader("test", catalogClient);
    auto status = reader.refresh(operationContext()).getStatus();
    ASSERT_EQ(ErrorCodes::KeyNotFound, status.code());
    ASSERT_FALSE(status.reason().empty());
}
TEST_F(TransactionCoordinatorServiceTest,
       CreateCoordinatorWithHigherTxnNumberThanOngoingCommittingTxnCommitsPreviousTxnAndSucceeds) {
    auto coordinatorService = TransactionCoordinatorService::get(operationContext());

    coordinatorService->createCoordinator(operationContext(), _lsid, _txnNumber, kCommitDeadline);

    // Progress the transaction up until the point where it has sent commit and is waiting for
    // commit acks.
    auto oldTxnCommitDecisionFuture = *coordinatorService->coordinateCommit(
        operationContext(), _lsid, _txnNumber, kTwoShardIdSet);

    // Simulate all participants acking prepare/voting to commit.
    assertPrepareSentAndRespondWithSuccess();
    assertPrepareSentAndRespondWithSuccess();

    // Create a coordinator for a higher transaction number in the same session. This should
    // "tryAbort" on the old coordinator which should NOT abort it since it's already waiting for
    // commit acks.
    coordinatorService->createCoordinator(
        operationContext(), _lsid, _txnNumber + 1, kCommitDeadline);
    auto newTxnCommitDecisionFuture = coordinatorService->coordinateCommit(
        operationContext(), _lsid, _txnNumber + 1, kTwoShardIdSet);

    // Finish committing the old transaction by sending it commit acks from both participants.
    assertCommitSentAndRespondWithSuccess();
    assertCommitSentAndRespondWithSuccess();

    // The old transaction should now be committed.
    ASSERT_EQ(static_cast<int>(oldTxnCommitDecisionFuture.get()),
              static_cast<int>(txn::CommitDecision::kCommit));
    commitTransaction(*coordinatorService, _lsid, _txnNumber + 1, kTwoShardIdSet);
}
TEST_F(KeysManagerShardedTest, GetKeyForValidationTimesOutIfRefresherIsNotRunning) {
    operationContext()->setDeadlineAfterNowBy(Microseconds(250 * 1000));

    ASSERT_THROWS(keyManager()
                      ->getKeyForValidation(operationContext(), 1, LogicalTime(Timestamp(100, 0)))
                      .status_with_transitional_ignore(),
                  DBException);
}
TEST_F(KeysManagerShardedTest, GetKeyForValidationTimesOutIfRefresherIsNotRunning) {
    operationContext()->setDeadlineAfterNowBy(Microseconds(250 * 1000),
                                              ErrorCodes::ExceededTimeLimit);

    ASSERT_THROWS(
        keyManager()->getKeyForValidation(operationContext(), 1, LogicalTime(Timestamp(100, 0))),
        DBException);
}
    void setUp() override {
        ConfigServerTestFixture::setUp();

        auto clockSource = stdx::make_unique<ClockSourceMock>();
        operationContext()->getServiceContext()->setFastClockSource(std::move(clockSource));
        _catalogClient = stdx::make_unique<KeysCollectionClientSharded>(
            Grid::get(operationContext())->catalogClient());
    }
TEST_F(TransactionCoordinatorCatalogTest, SecondCreateForSessionDoesNotOverwriteFirstCreate) {
    LogicalSessionId lsid = makeLogicalSessionIdForTest();
    TxnNumber txnNumber1 = 1;
    TxnNumber txnNumber2 = 2;
    createCoordinatorInCatalog(operationContext(), lsid, txnNumber1);
    createCoordinatorInCatalog(operationContext(), lsid, txnNumber2);

    auto coordinator1InCatalog = coordinatorCatalog().get(operationContext(), lsid, txnNumber1);
    ASSERT(coordinator1InCatalog != nullptr);
}
TEST_F(TransactionCoordinatorServiceTest, CoordinateCommitReturnsNoneIfCoordinatorWasRemoved) {
    auto coordinatorService = TransactionCoordinatorService::get(operationContext());

    coordinatorService->createCoordinator(operationContext(), _lsid, _txnNumber, kCommitDeadline);
    commitTransaction(*coordinatorService, _lsid, _txnNumber, kTwoShardIdSet);

    auto commitDecisionFuture =
        coordinatorService->coordinateCommit(operationContext(), _lsid, _txnNumber, kTwoShardIdSet);
    ASSERT(boost::none == commitDecisionFuture);
}
TEST_F(TransactionCoordinatorServiceTest,
       RetryingCreateCoordinatorForSameLsidAndTxnNumberSucceeds) {
    auto coordinatorService = TransactionCoordinatorService::get(operationContext());

    coordinatorService->createCoordinator(operationContext(), _lsid, _txnNumber, kCommitDeadline);
    // Retry create. This should succeed but not replace the old coordinator.
    coordinatorService->createCoordinator(operationContext(), _lsid, _txnNumber, kCommitDeadline);

    commitTransaction(*coordinatorService, _lsid, _txnNumber, kTwoShardIdSet);
}
TEST_F(TransactionCoordinatorServiceTest,
       CreateCoordinatorForExistingSessionWithPreviouslyCommittedTxnSucceeds) {
    auto coordinatorService = TransactionCoordinatorService::get(operationContext());

    coordinatorService->createCoordinator(operationContext(), _lsid, _txnNumber, kCommitDeadline);
    commitTransaction(*coordinatorService, _lsid, _txnNumber, kTwoShardIdSet);

    coordinatorService->createCoordinator(
        operationContext(), _lsid, _txnNumber + 1, kCommitDeadline);
    commitTransaction(*coordinatorService, _lsid, _txnNumber + 1, kTwoShardIdSet);
}
TEST_F(CacheTest, RefreshCanIncrementallyGetNewKeys) {
    KeysCollectionCache cache("test", catalogClient());

    KeysCollectionDocument origKey0(
        0, "test", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(100, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), KeysCollectionDocument::ConfigNS, origKey0.toBSON()));

    {
        auto refreshStatus = cache.refresh(operationContext());
        ASSERT_OK(refreshStatus.getStatus());


        auto key = refreshStatus.getValue();
        ASSERT_EQ(0, key.getKeyId());
        ASSERT_EQ(origKey0.getKey(), key.getKey());
        ASSERT_EQ("test", key.getPurpose());
        ASSERT_EQ(Timestamp(100, 0), key.getExpiresAt().asTimestamp());

        auto keyStatus = cache.getKey(LogicalTime(Timestamp(112, 1)));
        ASSERT_EQ(ErrorCodes::KeyNotFound, keyStatus.getStatus());
    }

    KeysCollectionDocument origKey1(
        1, "test", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(105, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), KeysCollectionDocument::ConfigNS, origKey1.toBSON()));

    KeysCollectionDocument origKey2(
        2, "test", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(110, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), KeysCollectionDocument::ConfigNS, origKey2.toBSON()));

    {
        auto refreshStatus = cache.refresh(operationContext());
        ASSERT_OK(refreshStatus.getStatus());

        auto key = refreshStatus.getValue();
        ASSERT_EQ(2, key.getKeyId());
        ASSERT_EQ(origKey2.getKey(), key.getKey());
        ASSERT_EQ("test", key.getPurpose());
        ASSERT_EQ(Timestamp(110, 0), key.getExpiresAt().asTimestamp());
    }

    {
        auto keyStatus = cache.getKey(LogicalTime(Timestamp(108, 1)));

        auto key = keyStatus.getValue();
        ASSERT_EQ(2, key.getKeyId());
        ASSERT_EQ(origKey2.getKey(), key.getKey());
        ASSERT_EQ("test", key.getPurpose());
        ASSERT_EQ(Timestamp(110, 0), key.getExpiresAt().asTimestamp());
    }
}
TEST_F(KeyGeneratorUpdateTest, ShouldPropagateWriteError) {
    KeyGenerator generator("dummy", catalogClient(), Seconds(5));

    const LogicalTime currentTime(LogicalTime(Timestamp(100, 2)));
    LogicalClock::get(operationContext())->setClusterTimeFromTrustedSource(currentTime);

    FailPointEnableBlock failWriteBlock("failCollectionInserts");

    auto generateStatus = generator.generateNewKeysIfNeeded(operationContext());
    ASSERT_EQ(ErrorCodes::FailPointEnabled, generateStatus);
}
TEST_F(KeysManagerShardedTest, GetKeyShouldErrorIfKeyIdMismatchKey) {
    keyManager()->startMonitoring(getServiceContext());

    KeysCollectionDocument origKey1(
        1, "dummy", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(105, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), KeysCollectionDocument::ConfigNS, origKey1.toBSON()));

    auto keyStatus =
        keyManager()->getKeyForValidation(operationContext(), 2, LogicalTime(Timestamp(100, 0)));
    ASSERT_EQ(ErrorCodes::KeyNotFound, keyStatus.getStatus());
}
    void setUp() override {
        ConfigServerTestFixture::setUp();

        serverGlobalParams.featureCompatibility.version.store(
            ServerGlobalParams::FeatureCompatibility::Version::k36);
        serverGlobalParams.featureCompatibility.validateFeaturesAsMaster.store(true);

        auto clockSource = stdx::make_unique<ClockSourceMock>();
        operationContext()->getServiceContext()->setFastClockSource(std::move(clockSource));
        auto catalogClient = Grid::get(operationContext())->catalogClient();
        _keyManager =
            stdx::make_unique<KeysCollectionManagerSharding>("dummy", catalogClient, Seconds(1));
    }
TEST_F(EnableShardingTest, succeedsWhenTheDatabaseIsAlreadySharded) {
    ShardType shard;
    shard.setName("shard0");
    shard.setHost("shard0:12");

    ASSERT_OK(setupShards(vector<ShardType>{shard}));

    setupDatabase("db5", shard.getName(), true);

    auto status =
        ShardingCatalogManager::get(operationContext())->enableSharding(operationContext(), "db5");
    ASSERT_OK(status);
}
TEST_F(TransactionCoordinatorServiceTestSingleTxn,
       ConcurrentCallsToCoordinateCommitReturnSameDecisionOnAbort) {

    auto commitDecisionFuture1 = *coordinatorService()->coordinateCommit(
        operationContext(), _lsid, _txnNumber, kTwoShardIdSet);
    auto commitDecisionFuture2 = *coordinatorService()->coordinateCommit(
        operationContext(), _lsid, _txnNumber, kTwoShardIdSet);

    abortTransaction(*coordinatorService(), _lsid, _txnNumber, kTwoShardIdSet, kTwoShardIdList[0]);

    ASSERT_EQ(static_cast<int>(commitDecisionFuture1.get()),
              static_cast<int>(commitDecisionFuture2.get()));
}
    void setUp() override {
        ConfigServerTestFixture::setUp();

        auto clockSource = stdx::make_unique<ClockSourceMock>();
        // Timestamps of "0 seconds" are not allowed, so we must advance our clock mock to the first
        // real second.
        clockSource->advance(Seconds(1));

        operationContext()->getServiceContext()->setFastClockSource(std::move(clockSource));
        auto catalogClient = stdx::make_unique<KeysCollectionClientSharded>(
            Grid::get(operationContext())->catalogClient());
        _keyManager =
            stdx::make_unique<KeysCollectionManager>("dummy", std::move(catalogClient), Seconds(1));
    }
TEST_F(KeysManagerShardedTest, ShouldCreateKeysIfKeyGeneratorEnabled) {
    keyManager()->startMonitoring(getServiceContext());

    const LogicalTime currentTime(LogicalTime(Timestamp(100, 0)));
    LogicalClock::get(operationContext())->setClusterTimeFromTrustedSource(currentTime);

    keyManager()->enableKeyGenerator(operationContext(), true);
    keyManager()->refreshNow(operationContext());

    auto keyStatus = keyManager()->getKeyForSigning(nullptr, LogicalTime(Timestamp(100, 100)));
    ASSERT_OK(keyStatus.getStatus());

    auto key = keyStatus.getValue();
    ASSERT_EQ(Timestamp(101, 0), key.getExpiresAt().asTimestamp());
}
TEST_F(KeysManagerShardedTest, GetKeyForValidationErrorsIfKeyDoesntExist) {
    keyManager()->startMonitoring(getServiceContext());

    auto keyStatus =
        keyManager()->getKeyForValidation(operationContext(), 1, LogicalTime(Timestamp(100, 0)));
    ASSERT_EQ(ErrorCodes::KeyNotFound, keyStatus.getStatus());
}
TEST_F(TransactionCoordinatorServiceTest,
       CoordinatorIsCanceledIfDeadlinePassesAndHasNotReceivedParticipantList) {
    auto coordinatorService = TransactionCoordinatorService::get(operationContext());
    const auto deadline = executor()->now() + Milliseconds(1000 * 60 * 10 /* 10 hours */);
    coordinatorService->createCoordinator(operationContext(), _lsid, _txnNumber, deadline);

    // Reach the deadline.
    network()->enterNetwork();
    network()->advanceTime(deadline);
    network()->exitNetwork();

    // The coordinator should no longer exist.
    ASSERT(boost::none ==
           coordinatorService->coordinateCommit(
               operationContext(), _lsid, _txnNumber, kTwoShardIdSet));
}
TEST_F(KeyGeneratorUpdateTest, ShouldNotCreateKeysWithDisableKeyGenerationFailPoint) {
    KeyGenerator generator("dummy", catalogClient(), Seconds(5));

    const LogicalTime currentTime(LogicalTime(Timestamp(100, 0)));
    LogicalClock::get(operationContext())->setClusterTimeFromTrustedSource(currentTime);

    {
        FailPointEnableBlock failKeyGenerationBlock("disableKeyGeneration");

        auto generateStatus = generator.generateNewKeysIfNeeded(operationContext());
        ASSERT_EQ(ErrorCodes::FailPointEnabled, generateStatus);
    }

    auto allKeys = getKeys(operationContext());

    ASSERT_EQ(0U, allKeys.size());
}
TEST_F(KeysManagerShardedTest, ShouldNotReturnKeysInFeatureCompatibilityVersion34) {
    serverGlobalParams.featureCompatibility.version.store(
        ServerGlobalParams::FeatureCompatibility::Version::k34);

    keyManager()->startMonitoring(getServiceContext());
    keyManager()->enableKeyGenerator(operationContext(), true);

    KeysCollectionDocument origKey(
        1, "dummy", TimeProofService::generateRandomKey(), LogicalTime(Timestamp(105, 0)));
    ASSERT_OK(insertToConfigCollection(
        operationContext(), NamespaceString(KeysCollectionDocument::ConfigNS), origKey.toBSON()));

    keyManager()->refreshNow(operationContext());

    auto keyStatus =
        keyManager()->getKeyForValidation(operationContext(), 1, LogicalTime(Timestamp(100, 0)));
    ASSERT_EQ(ErrorCodes::KeyNotFound, keyStatus.getStatus());
}
TEST_F(TransactionCoordinatorServiceTestSingleTxn,
       CoordinateCommitWithNoVotesReturnsNotReadyFuture) {

    auto commitDecisionFuture = *coordinatorService()->coordinateCommit(
        operationContext(), _lsid, _txnNumber, kTwoShardIdSet);

    ASSERT_FALSE(commitDecisionFuture.isReady());
    // To prevent invariant failure in TransactionCoordinator that all futures have been completed.
    abortTransaction(*coordinatorService(), _lsid, _txnNumber, kTwoShardIdSet, kTwoShardIdList[0]);
}