void AsyncMockStreamFactory::MockStream::simulateServer(
    rpc::Protocol proto,
    const stdx::function<RemoteCommandResponse(RemoteCommandRequest)> replyFunc) {
    std::exception_ptr ex;
    uint32_t messageId = 0;

    RemoteCommandResponse resp;
    {
        WriteEvent write{this};

        std::vector<uint8_t> messageData = popWrite();
        Message msg(messageData.data(), false);

        auto parsedRequest = rpc::makeRequest(&msg);
        ASSERT(parsedRequest->getProtocol() == proto);

        RemoteCommandRequest rcr(target(), *parsedRequest);

        messageId = msg.header().getId();

        // So we can allow ASSERTs in replyFunc, we capture any exceptions, but rethrow
        // them later to prevent deadlock
        try {
            resp = replyFunc(std::move(rcr));
        } catch (...) {
            ex = std::current_exception();
        }
    }

    auto replyBuilder = rpc::makeReplyBuilder(proto);
    replyBuilder->setMetadata(resp.metadata);
    replyBuilder->setCommandReply(resp.data);

    auto replyMsg = replyBuilder->done();
    replyMsg->header().setResponseTo(messageId);

    {
        // The first read will be for the header.
        ReadEvent read{this};
        auto hdrBytes = reinterpret_cast<const uint8_t*>(replyMsg->header().view2ptr());
        pushRead({hdrBytes, hdrBytes + sizeof(MSGHEADER::Value)});
    }

    {
        // The second read will be for the message data.
        ReadEvent read{this};
        auto dataBytes = reinterpret_cast<const uint8_t*>(replyMsg->buf());
        auto pastHeader = dataBytes;
        std::advance(pastHeader, sizeof(MSGHEADER::Value));
        pushRead({pastHeader, dataBytes + static_cast<std::size_t>(replyMsg->size())});
    }

    if (ex) {
        // Rethrow ASSERTS after the NIA completes it's Write-Read-Read sequence.
        std::rethrow_exception(ex);
    }
}
Example #2
0
MockRemoteDBServer::MockRemoteDBServer(const string& hostAndPort)
    : _isRunning(true),
      _hostAndPort(hostAndPort),
      _delayMilliSec(0),
      _cmdCount(0),
      _queryCount(0),
      _instanceID(0) {
    insert(IdentityNS, BSON(HostField(hostAndPort)), 0);
    setCommandReply("dbStats", BSON(HostField(hostAndPort)));
}
Example #3
0
void MockRemoteDBServer::setCommandReply(const string& cmdName, const mongo::BSONObj& replyObj) {
    vector<BSONObj> replySequence;
    replySequence.push_back(replyObj);
    setCommandReply(cmdName, replySequence);
}