Exemplo n.º 1
0
TEST_F(ViewCatalogFixture, CreateViewCycles) {
    {
        const NamespaceString viewName("db.view1");
        const NamespaceString viewOn("db.view1");

        ASSERT_NOT_OK(
            viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
    }

    {
        const NamespaceString view1("db.view1");
        const NamespaceString view2("db.view2");
        const NamespaceString view3("db.view3");

        ASSERT_OK(viewCatalog.createView(opCtx.get(), view1, view2, emptyPipeline, emptyCollation));
        ASSERT_OK(viewCatalog.createView(opCtx.get(), view2, view3, emptyPipeline, emptyCollation));
        ASSERT_NOT_OK(
            viewCatalog.createView(opCtx.get(), view3, view1, emptyPipeline, emptyCollation));
    }
}
Exemplo n.º 2
0
TEST(QueryRequestTest, ForbidNonMetaSortOnFieldWithMetaProject) {
    QueryRequest badQR(testns);
    badQR.setProj(fromjson("{a: {$meta: \"textScore\"}}"));
    badQR.setSort(fromjson("{a: 1}"));
    ASSERT_NOT_OK(badQR.validate());

    QueryRequest goodQR(testns);
    goodQR.setProj(fromjson("{a: {$meta: \"textScore\"}}"));
    goodQR.setSort(fromjson("{b: 1}"));
    ASSERT_OK(goodQR.validate());
}
TEST(MatchExpressionParserTest, ExprFailsToParseWithinTopLevelOr) {
    auto query = fromjson("{$or: [{x: 1}, {$expr: {$eq: ['$a', 5]}}]}");
    const CollatorInterface* collator = nullptr;
    const boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest());
    ASSERT_NOT_OK(MatchExpressionParser::parse(query,
                                               collator,
                                               expCtx,
                                               ExtensionsCallbackNoop(),
                                               MatchExpressionParser::AllowedFeatures::kExpr)
                      .getStatus());
}
Exemplo n.º 4
0
TEST(DataRangeCursor, ConstDataRangeCursor) {
    char buf[14];

    DataView(buf).write<uint16_t>(1);
    DataView(buf).write<LittleEndian<uint32_t>>(2, sizeof(uint16_t));
    DataView(buf).write<BigEndian<uint64_t>>(3, sizeof(uint16_t) + sizeof(uint32_t));

    ConstDataRangeCursor cdrc(buf, buf + sizeof(buf));
    ConstDataRangeCursor backup(cdrc);

    ASSERT_EQUALS(static_cast<uint16_t>(1), cdrc.readAndAdvance<uint16_t>());
    ASSERT_EQUALS(static_cast<uint32_t>(2), cdrc.readAndAdvance<LittleEndian<uint32_t>>());
    ASSERT_EQUALS(static_cast<uint64_t>(3), cdrc.readAndAdvance<BigEndian<uint64_t>>());
    ASSERT_NOT_OK(cdrc.readAndAdvanceNoThrow<char>());

    // test skip()
    cdrc = backup;
    ASSERT_OK(cdrc.skipNoThrow<uint32_t>());
    ASSERT_OK(cdrc.advanceNoThrow(10));
    ASSERT_NOT_OK(cdrc.readAndAdvanceNoThrow<char>());
}
Exemplo n.º 5
0
    void run() {
        // "storageEngine" field has to be an object if present.
        ASSERT_NOT_OK(createIndex("unittest", _createSpec(12345)));

        // 'storageEngine' must not be empty.
        ASSERT_NOT_OK(createIndex("unittest", _createSpec(BSONObj())));

        // Every field under "storageEngine" must match a registered storage engine.
        ASSERT_NOT_OK(createIndex("unittest", _createSpec(BSON("unknownEngine" << BSONObj()))));

        // Testing with 'wiredTiger' because the registered storage engine factory
        // supports custom index options under 'storageEngine'.
        const std::string storageEngineName = "wiredTiger";

        // Run 'wiredTiger' tests if the storage engine is supported.
        if (isRegisteredStorageEngine(getGlobalServiceContext(), storageEngineName)) {
            // Every field under "storageEngine" has to be an object.
            ASSERT_NOT_OK(createIndex("unittest", _createSpec(BSON(storageEngineName << 1))));

            // Storage engine options must pass validation by the storage engine factory.
            // For 'wiredTiger', embedded document must contain 'configString'.
            ASSERT_NOT_OK(createIndex(
                "unittest", _createSpec(BSON(storageEngineName << BSON("unknown" << 1)))));

            // Configuration string for 'wiredTiger' must be a string.
            ASSERT_NOT_OK(createIndex(
                "unittest", _createSpec(BSON(storageEngineName << BSON("configString" << 1)))));

            // Valid 'wiredTiger' configuration.
            ASSERT_OK(createIndex(
                "unittest",
                _createSpec(BSON(storageEngineName << BSON("configString"
                                                           << "block_compressor=zlib")))));
        }
    }
Exemplo n.º 6
0
TEST_F(CursorManagerTestCustomOpCtx,
       KillCursorWithSessionDoesNotKillCursorCreatedOutsideOfSession) {
    // Add a cursor with a session to the cursor manager.
    auto opCtx = _queryServiceContext->makeOperationContext();
    auto pinned = makeCursor(opCtx.get());
    auto cursorId = pinned.getCursor()->cursorid();

    // Killing the cursor with the correct cursorId but with an unrelated LogicalSessionId fails.
    auto lsid = makeLogicalSessionIdForTest();
    auto status = useCursorManager()->killCursor(opCtx.get(), cursorId, false, lsid, boost::none);
    ASSERT_NOT_OK(status);
    ASSERT_EQ(status.code(), ErrorCodes::CursorNotFound);
}
    // Insert the same key multiple times and verify that only 1 entry exists
    // in the index when duplicates are not allowed.
    TEST( SortedDataInterface, InsertSameKey ) {
        scoped_ptr<HarnessHelper> harnessHelper( newHarnessHelper() );
        scoped_ptr<SortedDataInterface> sorted( harnessHelper->newSortedDataInterface() );

        {
            scoped_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() );
            ASSERT( sorted->isEmpty( opCtx.get() ) );
        }

        {
            scoped_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() );
            {
                WriteUnitOfWork uow( opCtx.get() );
                ASSERT_OK( sorted->insert( opCtx.get(), key1, loc1, false ) );
                ASSERT_NOT_OK( sorted->insert( opCtx.get(), key1, loc2, false ) );
                uow.commit();
            }
        }

        {
            scoped_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() );
            ASSERT_EQUALS( 1, sorted->numEntries( opCtx.get() ) );
        }

        {
            scoped_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() );
            {
                WriteUnitOfWork uow( opCtx.get() );
                ASSERT_NOT_OK( sorted->insert( opCtx.get(), key1, loc2, false ) );
                uow.commit();
            }
        }

        {
            scoped_ptr<OperationContext> opCtx( harnessHelper->newOperationContext() );
            ASSERT_EQUALS( 1, sorted->numEntries( opCtx.get() ) );
        }
    }
Exemplo n.º 8
0
TEST(CollectionOptions, Validator) {
    CollectionOptions options;

    ASSERT_NOT_OK(options.parse(fromjson("{validator: 'notAnObject'}")));

    ASSERT_OK(options.parse(fromjson("{validator: {a: 1}}")));
    ASSERT_BSONOBJ_EQ(options.validator, fromjson("{a: 1}"));

    options.validator = fromjson("{b: 1}");
    ASSERT_BSONOBJ_EQ(options.toBSON()["validator"].Obj(), fromjson("{b: 1}"));

    CollectionOptions defaultOptions;
    ASSERT_BSONOBJ_EQ(defaultOptions.validator, BSONObj());
    ASSERT(!defaultOptions.toBSON()["validator"]);
}
Exemplo n.º 9
0
TEST(CollectionOptions, SizeNumberLimits) {
    CollectionOptions options;
    ASSERT_OK(options.parse(fromjson("{size: 'a'}")));
    ASSERT_EQ(options.cappedSize, 0);


    ASSERT_OK(options.parse(fromjson("{size: '-1'}")));
    ASSERT_EQ(options.cappedSize, 0);

    ASSERT_OK(options.parse(fromjson("{size: '-9999999999999999999999999999999'}")));
    ASSERT_EQ(options.cappedSize, 0);

    // The test for size is redundant since size returns a status that's not ok if it's larger
    // than a petabyte, which is smaller than LLONG_MAX anyways. We test that here.
    ASSERT_NOT_OK(options.parse(fromjson("{size: 9999999999999999}")));
}
Exemplo n.º 10
0
TEST(DataRangeCursor, DataRangeCursor) {
    char buf[100] = {0};

    DataRangeCursor dc(buf, buf + 14);

    ASSERT_OK(dc.writeAndAdvanceNoThrow<uint16_t>(1));
    ASSERT_OK(dc.writeAndAdvanceNoThrow<LittleEndian<uint32_t>>(2));
    ASSERT_OK(dc.writeAndAdvanceNoThrow<BigEndian<uint64_t>>(3));
    ASSERT_NOT_OK(dc.writeAndAdvanceNoThrow<char>(1));

    ConstDataRangeCursor cdrc(buf, buf + sizeof(buf));

    ASSERT_EQUALS(static_cast<uint16_t>(1), cdrc.readAndAdvance<uint16_t>());
    ASSERT_EQUALS(static_cast<uint32_t>(2), cdrc.readAndAdvance<LittleEndian<uint32_t>>());
    ASSERT_EQUALS(static_cast<uint64_t>(3), cdrc.readAndAdvance<BigEndian<uint64_t>>());
    ASSERT_EQUALS(static_cast<char>(0), cdrc.readAndAdvance<char>());
}
Exemplo n.º 11
0
// Test a bad file
TEST(FTDCFileTest, TestBadFile) {
    unittest::TempDir tempdir("metrics_testpath");
    boost::filesystem::path p(tempdir.path());
    p /= kTestFile;

    std::ofstream stream(p.c_str());
    // This test case caused us to allocate more memory then the size of the file the first time I
    // tried it
    stream << "Hello World";

    stream.close();

    FTDCFileReader reader;
    ASSERT_OK(reader.open(p));

    auto sw = reader.hasNext();
    ASSERT_NOT_OK(sw);
}
Exemplo n.º 12
0
TEST_F(ViewCatalogFixture, ExceedMaxViewDepthInOrder) {
    const char* ns = "db.view";
    int i = 0;

    for (; i < ViewGraph::kMaxViewDepth; i++) {
        const NamespaceString viewName(str::stream() << ns << i);
        const NamespaceString viewOn(str::stream() << ns << (i + 1));

        ASSERT_OK(
            viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
    }

    const NamespaceString viewName(str::stream() << ns << i);
    const NamespaceString viewOn(str::stream() << ns << (i + 1));

    ASSERT_NOT_OK(
        viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
}
Exemplo n.º 13
0
TEST(QueryRequestTest, ParseCommandForbidNonMetaSortOnFieldWithMetaProject) {
    BSONObj cmdObj;

    cmdObj = fromjson(
        "{find: 'testns',"
        "projection: {a: {$meta: 'textScore'}},"
        "sort: {a: 1}}");
    const NamespaceString nss("test.testns");
    bool isExplain = false;
    auto result = QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain);
    ASSERT_NOT_OK(result.getStatus());

    cmdObj = fromjson(
        "{find: 'testns',"
        "projection: {a: {$meta: 'textScore'}},"
        "sort: {b: 1}}");
    ASSERT_OK(QueryRequest::makeFromFindCommand(nss, cmdObj, isExplain).getStatus());
}
Exemplo n.º 14
0
TEST_F(CursorManagerTestCustomOpCtx, KillCursorRespectsSessionId) {
    // Add a cursor with a session to the cursor manager.
    auto lsid = makeLogicalSessionIdForTest();
    auto opCtx = _queryServiceContext->makeOperationContext(lsid, boost::none);
    auto pinned = makeCursor(opCtx.get());
    auto cursorId = pinned.getCursor()->cursorid();

    // Killing the cursor with incorrect LogicalSessionId fails.
    pinned.release();
    auto wrongLsid = makeLogicalSessionIdForTest();
    auto status =
        useCursorManager()->killCursor(opCtx.get(), cursorId, false, wrongLsid, boost::none);
    ASSERT_NOT_OK(status);
    ASSERT_EQ(status.code(), ErrorCodes::CursorNotFound);

    // Killing the cursor with the correct LogicalSessionId works.
    ASSERT_OK(useCursorManager()->killCursor(opCtx.get(), cursorId, false, lsid, boost::none));
}
Exemplo n.º 15
0
TEST_F(ViewCatalogFixture, CreateViewWithPipelineExceedingMaxSize) {
    BSONArrayBuilder builder;

    int objsize = BSON("$match" << BSON("x"
                                        << "foo"))
                      .objsize();

    int pipelineSize = 0;

    for (; pipelineSize < ViewGraph::kMaxViewPipelineSizeBytes + 1; pipelineSize += objsize) {
        builder << BSON("$match" << BSON("x"
                                         << "foo"));
    }

    const NamespaceString viewName("db.view");
    const NamespaceString viewOn("db.coll");
    const BSONObj collation;

    auto pipeline = builder.arr();

    ASSERT_NOT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, pipeline, collation));
}
Exemplo n.º 16
0
TEST_F(KVStorageEngineTest, ReconcileIdentsTest) {
    auto opCtx = cc().makeOperationContext();

    // Add a collection, `db.coll1` to both the KVCatalog and KVEngine. The returned value is the
    // `ident` name given to the collection.
    auto swIdentName = createCollection(opCtx.get(), NamespaceString("db.coll1"));
    ASSERT_OK(swIdentName);
    // Create a table in the KVEngine not reflected in the KVCatalog. This should be dropped when
    // reconciling.
    ASSERT_OK(createCollTable(opCtx.get(), NamespaceString("db.coll2")));
    ASSERT_OK(reconcile(opCtx.get()).getStatus());
    auto identsVec = getAllKVEngineIdents(opCtx.get());
    auto idents = std::set<std::string>(identsVec.begin(), identsVec.end());
    // There are two idents. `_mdb_catalog` and the ident for `db.coll1`.
    ASSERT_EQUALS(static_cast<const unsigned long>(2), idents.size());
    ASSERT_TRUE(idents.find(swIdentName.getValue()) != idents.end());
    ASSERT_TRUE(idents.find("_mdb_catalog") != idents.end());

    // Create a catalog entry for the `_id` index. Drop the created the table.
    ASSERT_OK(createIndex(opCtx.get(), NamespaceString("db.coll1"), "_id"));
    ASSERT_OK(dropIndexTable(opCtx.get(), NamespaceString("db.coll1"), "_id"));
    // The reconcile response should include this index as needing to be rebuilt.
    auto reconcileStatus = reconcile(opCtx.get());
    ASSERT_OK(reconcileStatus.getStatus());
    ASSERT_EQUALS(static_cast<const unsigned long>(1), reconcileStatus.getValue().size());
    StorageEngine::CollectionIndexNamePair& toRebuild = reconcileStatus.getValue()[0];
    ASSERT_EQUALS("db.coll1", toRebuild.first);
    ASSERT_EQUALS("_id", toRebuild.second);

    // Now drop the `db.coll1` table, while leaving the KVCatalog entry.
    ASSERT_OK(dropIdent(opCtx.get(), swIdentName.getValue()));
    ASSERT_EQUALS(static_cast<const unsigned long>(1), getAllKVEngineIdents(opCtx.get()).size());

    // Reconciling this should result in an error.
    reconcileStatus = reconcile(opCtx.get());
    ASSERT_NOT_OK(reconcileStatus.getStatus());
    ASSERT_EQUALS(ErrorCodes::UnrecoverableRollbackError, reconcileStatus.getStatus());
}
Exemplo n.º 17
0
 void run() {
     // Create a new collection.
     Database* db = _ctx.ctx().db();
     db->dropCollection( _ns );
     Collection* coll = db->createCollection( _ns );
     // Drop all indexes including id index.
     coll->getIndexCatalog()->dropAllIndexes( true );
     // Insert some documents with enforceQuota=true.
     int32_t nDocs = 1000;
     for( int32_t i = 0; i < nDocs; ++i ) {
         coll->insertDocument( BSON( "a" << i ), true );
     }
     // Initialize curop.
     cc().curop()->reset();
     // Request an interrupt.
     killCurrentOp.killAll();
     BSONObj indexInfo = BSON( "key" << BSON( "a" << 1 ) << "ns" << _ns << "name" << "a_1" );
     // The call is interrupted because mayInterrupt == true.
     Status status = coll->getIndexCatalog()->createIndex( indexInfo, true );
     ASSERT_NOT_OK( status.code() );
     // The new index is not listed in the index catalog because the index build failed.
     ASSERT( !coll->getIndexCatalog()->findIndexByName( "a_1" ) );
 }
Exemplo n.º 18
0
        void run() {
            Client::WriteContext ctx(&_txn, ns());
            addIndex(BSON("a" << "2d" << "b" << 1));
            addIndex(BSON("a" << "2d"));

            BSONObj query = fromjson("{$or: [{a: {$geoWithin: {$centerSphere: [[0,0],10]}}},"
                                            "{a: {$geoWithin: {$centerSphere: [[1,1],10]}}}]}");

            CanonicalQuery* cq;
            ASSERT_OK(CanonicalQuery::canonicalize(ns(), query, &cq));

            Collection* collection = ctx.ctx().db()->getCollection(&_txn, ns());

            // Get planner params.
            QueryPlannerParams plannerParams;
            fillOutPlannerParams(&_txn, collection, cq, &plannerParams);

            // We expect creation of the subplan stage to fail.
            WorkingSet ws;
            SubplanStage* subplan;
            ASSERT_NOT_OK(SubplanStage::make(&_txn, collection, &ws, plannerParams, cq, &subplan));

            ctx.commit();
        }
Exemplo n.º 19
0
TEST(CollectionOptions, FailToParseCollationThatIsNotAnObject) {
    CollectionOptions options;
    ASSERT_NOT_OK(options.parse(fromjson("{collation: 'notAnObject'}")));
}
Exemplo n.º 20
0
TEST(CollectionOptions, FailToParseCollationThatIsAnEmptyObject) {
    CollectionOptions options;
    ASSERT_NOT_OK(options.parse(fromjson("{collation: {}}")));
}
Exemplo n.º 21
0
TEST(SSLManager, MongoDBRolesParser) {
    /*
    openssl asn1parse -genconf mongodbroles.cnf -out foo.der

    -------- mongodbroles.cnf --------
    asn1 = SET:MongoDBAuthorizationGrant

    [MongoDBAuthorizationGrant]
    grant1 = SEQUENCE:MongoDBRole

    [MongoDBRole]
    role  = UTF8:role_name
    database = UTF8:Third field
    */
    // Positive: Simple parsing test
    {
        unsigned char derData[] = {0x31, 0x1a, 0x30, 0x18, 0x0c, 0x09, 0x72, 0x6f, 0x6c, 0x65,
                                   0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x0c, 0x0b, 0x54, 0x68, 0x69,
                                   0x72, 0x64, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64};
        auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData),
                                                    std::extent<decltype(derData)>::value));
        ASSERT_OK(swPeer.getStatus());
        auto item = *(swPeer.getValue().begin());
        ASSERT_EQ(item.getRole(), "role_name");
        ASSERT_EQ(item.getDB(), "Third field");
    }

    // Positive: Very long role_name, and long form lengths
    {
        unsigned char derData[] = {
            0x31, 0x82, 0x01, 0x3e, 0x30, 0x82, 0x01, 0x3a, 0x0c, 0x82, 0x01, 0x29, 0x72, 0x6f,
            0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61,
            0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c,
            0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
            0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65,
            0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
            0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f,
            0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72,
            0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e,
            0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f,
            0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61,
            0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c,
            0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
            0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65,
            0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
            0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f,
            0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72,
            0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e,
            0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f,
            0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61,
            0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c,
            0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
            0x65, 0x0c, 0x0b, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64};
        auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData),
                                                    std::extent<decltype(derData)>::value));
        ASSERT_OK(swPeer.getStatus());

        auto item = *(swPeer.getValue().begin());
        ASSERT_EQ(item.getRole(),
                  "role_namerole_namerole_namerole_namerole_namerole_namerole_namerole_namerole_"
                  "namerole_namerole_namerole_namerole_namerole_namerole_namerole_namerole_"
                  "namerole_namerole_namerole_namerole_namerole_namerole_namerole_namerole_"
                  "namerole_namerole_namerole_namerole_namerole_namerole_namerole_namerole_name");
        ASSERT_EQ(item.getDB(), "Third field");
    }

    // Negative: Encode MAX_INT64 into a length
    {
        unsigned char derData[] = {0x31, 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                                   0xff, 0x3e, 0x18, 0x0c, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x5f,
                                   0x6e, 0x61, 0x6d, 0x65, 0x0c, 0x0b, 0x54, 0x68, 0x69, 0x72,
                                   0x64, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64};

        auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData),
                                                    std::extent<decltype(derData)>::value));
        ASSERT_NOT_OK(swPeer.getStatus());
    }

    // Negative: Runt, only a tag
    {
        unsigned char derData[] = {0x31};
        auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData),
                                                    std::extent<decltype(derData)>::value));
        ASSERT_NOT_OK(swPeer.getStatus());
    }

    // Negative: Runt, only a tag and short length
    {
        unsigned char derData[] = {0x31, 0x0b};
        auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData),
                                                    std::extent<decltype(derData)>::value));
        ASSERT_NOT_OK(swPeer.getStatus());
    }

    // Negative: Runt, only a tag and long length with wrong missing length
    {
        unsigned char derData[] = {
            0x31, 0x88, 0xff, 0xff,
        };
        auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData),
                                                    std::extent<decltype(derData)>::value));
        ASSERT_NOT_OK(swPeer.getStatus());
    }

    // Negative: Runt, only a tag and long length
    {
        unsigned char derData[] = {
            0x31, 0x82, 0xff, 0xff,
        };
        auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData),
                                                    std::extent<decltype(derData)>::value));
        ASSERT_NOT_OK(swPeer.getStatus());
    }

    // Negative: Single UTF8 String
    {
        unsigned char derData[] = {
            0x0c, 0x0b, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64};
        auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData),
                                                    std::extent<decltype(derData)>::value));
        ASSERT_NOT_OK(swPeer.getStatus());
    }

    // Negative: Unknown type - IAString
    {
        unsigned char derData[] = {
            0x16, 0x0b, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64};
        auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData),
                                                    std::extent<decltype(derData)>::value));
        ASSERT_NOT_OK(swPeer.getStatus());
    }

    // Positive: two roles
    {
        unsigned char derData[] = {0x31, 0x2b, 0x30, 0x0f, 0x0c, 0x06, 0x62, 0x61, 0x63,
                                   0x6b, 0x75, 0x70, 0x0c, 0x05, 0x61, 0x64, 0x6d, 0x69,
                                   0x6e, 0x30, 0x18, 0x0c, 0x0f, 0x72, 0x65, 0x61, 0x64,
                                   0x41, 0x6e, 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61,
                                   0x73, 0x65, 0x0c, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e};
        auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData),
                                                    std::extent<decltype(derData)>::value));
        ASSERT_OK(swPeer.getStatus());

        auto roles = getSortedRoles(swPeer.getValue());
        ASSERT_EQ(roles[0].getRole(), "backup");
        ASSERT_EQ(roles[0].getDB(), "admin");
        ASSERT_EQ(roles[1].getRole(), "readAnyDatabase");
        ASSERT_EQ(roles[1].getDB(), "admin");
    }
}
Exemplo n.º 22
0
    void run() {
        AutoGetCollectionForRead ctx(&_txn, nss.ns());
        Collection* collection = ctx.getCollection();
        ASSERT(collection);

        // Query can be answered by either index on "a" or index on "b".
        auto statusWithCQ = CanonicalQuery::canonicalize(nss, fromjson("{a: {$gte: 8}, b: 1}"));
        ASSERT_OK(statusWithCQ.getStatus());
        const std::unique_ptr<CanonicalQuery> cq = std::move(statusWithCQ.getValue());

        // We shouldn't have anything in the plan cache for this shape yet.
        PlanCache* cache = collection->infoCache()->getPlanCache();
        ASSERT(cache);
        CachedSolution* rawCachedSolution;
        ASSERT_NOT_OK(cache->get(*cq, &rawCachedSolution));

        // Get planner params.
        QueryPlannerParams plannerParams;
        fillOutPlannerParams(&_txn, collection, cq.get(), &plannerParams);

        // Set up queued data stage to take a long time before returning EOF. Should be long
        // enough to trigger a replan.
        const size_t decisionWorks = 10;
        const size_t mockWorks =
            1U + static_cast<size_t>(internalQueryCacheEvictionRatio * decisionWorks);
        auto mockChild = stdx::make_unique<QueuedDataStage>(&_txn, &_ws);
        for (size_t i = 0; i < mockWorks; i++) {
            mockChild->pushBack(PlanStage::NEED_TIME);
        }

        CachedPlanStage cachedPlanStage(
            &_txn, collection, &_ws, cq.get(), plannerParams, decisionWorks, mockChild.release());

        // This should succeed after triggering a replan.
        PlanYieldPolicy yieldPolicy(nullptr, PlanExecutor::YIELD_MANUAL);
        ASSERT_OK(cachedPlanStage.pickBestPlan(&yieldPolicy));

        // Make sure that we get 2 legit results back.
        size_t numResults = 0;
        PlanStage::StageState state = PlanStage::NEED_TIME;
        while (state != PlanStage::IS_EOF) {
            WorkingSetID id = WorkingSet::INVALID_ID;
            state = cachedPlanStage.work(&id);

            ASSERT_NE(state, PlanStage::FAILURE);
            ASSERT_NE(state, PlanStage::DEAD);

            if (state == PlanStage::ADVANCED) {
                WorkingSetMember* member = _ws.get(id);
                ASSERT(cq->root()->matchesBSON(member->obj.value()));
                numResults++;
            }
        }

        ASSERT_EQ(numResults, 2U);

        // This time we expect to find something in the plan cache. Replans after hitting the
        // works threshold result in a cache entry.
        ASSERT_OK(cache->get(*cq, &rawCachedSolution));
        const std::unique_ptr<CachedSolution> cachedSolution(rawCachedSolution);
    }
Exemplo n.º 23
0
TEST_F(ViewCatalogFixture, ModifyViewOnInvalidCollectionName) {
    const NamespaceString viewName("db.view");
    const NamespaceString viewOn("db.$coll");

    ASSERT_NOT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline));
}
Exemplo n.º 24
0
TEST(CollectionOptions, UnknownTopLevelOptionFailsToParse) {
    CollectionOptions options;
    auto status = options.parse(fromjson("{invalidOption: 1}"));
    ASSERT_NOT_OK(status);
    ASSERT_EQ(status.code(), ErrorCodes::InvalidOptions);
}
Exemplo n.º 25
0
TEST(CollectionOptions, PipelineFieldRequiresViewOn) {
    CollectionOptions options;
    ASSERT_NOT_OK(options.parse(fromjson("{pipeline: [{$match: {}}]}")));
}
Exemplo n.º 26
0
TEST_F(ViewCatalogFixture, DropMissingView) {
    NamespaceString viewName("db.view");
    ASSERT_NOT_OK(viewCatalog.dropView(opCtx.get(), viewName));
}
Exemplo n.º 27
0
TEST(CollectionOptions, UnknownOptionRejectedIfCreateOptionNotPresent) {
    CollectionOptions options;
    auto status = options.parse(fromjson("{invalidOption: 1}"));
    ASSERT_NOT_OK(status);
    ASSERT_EQ(status.code(), ErrorCodes::InvalidOptions);
}
Exemplo n.º 28
0
TEST_F(ViewCatalogFixture, ModifyMissingView) {
    const NamespaceString viewName("db.view");
    const NamespaceString viewOn("db.coll");

    ASSERT_NOT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline));
}
Exemplo n.º 29
0
TEST(CollectionOptions, ErrorBadMax) {
    ASSERT_NOT_OK(CollectionOptions().parse(BSON("capped" << true << "max" << (1LL << 31))));
}
Exemplo n.º 30
0
TEST_F(ViewCatalogFixture, ModifyViewOnDifferentDatabase) {
    const NamespaceString viewName("db1.view");
    const NamespaceString viewOn("db2.coll");

    ASSERT_NOT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline));
}