summaryrefslogtreecommitdiff
path: root/src/mongo/db/views/view_catalog_test.cpp
diff options
context:
space:
mode:
authorGregory Wlodarek <gregory.wlodarek@mongodb.com>2019-07-12 09:50:46 -0400
committerGregory Wlodarek <gregory.wlodarek@mongodb.com>2019-07-15 10:47:12 -0400
commit71fced4ef1bdbc1e5b517057eb15be256eaf0ba7 (patch)
treeeaa12252283a4702203f9865796a73ede5b011b3 /src/mongo/db/views/view_catalog_test.cpp
parent903207938dc05f9e3f4ca546232d8a7ceda99e4c (diff)
downloadmongo-71fced4ef1bdbc1e5b517057eb15be256eaf0ba7.tar.gz
SERVER-41041 ViewCatalog should actively reload after changes
Diffstat (limited to 'src/mongo/db/views/view_catalog_test.cpp')
-rw-r--r--src/mongo/db/views/view_catalog_test.cpp394
1 files changed, 208 insertions, 186 deletions
diff --git a/src/mongo/db/views/view_catalog_test.cpp b/src/mongo/db/views/view_catalog_test.cpp
index 6737a38b6a1..87aa9340ba8 100644
--- a/src/mongo/db/views/view_catalog_test.cpp
+++ b/src/mongo/db/views/view_catalog_test.cpp
@@ -39,7 +39,9 @@
#include "mongo/bson/bsonmisc.h"
#include "mongo/bson/bsonobj.h"
#include "mongo/bson/bsonobjbuilder.h"
+#include "mongo/db/catalog/catalog_test_fixture.h"
#include "mongo/db/catalog/collection_catalog.h"
+#include "mongo/db/catalog_raii.h"
#include "mongo/db/concurrency/lock_manager_defs.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
@@ -74,61 +76,103 @@ constexpr auto kLargeString =
const auto kOneKiBMatchStage = BSON("$match" << BSON("data" << kLargeString));
const auto kTinyMatchStage = BSON("$match" << BSONObj());
-class DurableViewCatalogDummy final : public DurableViewCatalog {
+class ViewCatalogFixture : public CatalogTestFixture {
public:
- explicit DurableViewCatalogDummy() : _upsertCount(0), _iterateCount(0) {}
- static const std::string name;
+ void setUp() override {
+ CatalogTestFixture::setUp();
+
+ WriteUnitOfWork wuow(operationContext());
+ AutoGetOrCreateDb autoDb(operationContext(), "db", MODE_X);
+ _db = autoDb.getDb();
+ invariant(_db);
+
+ auto durableViewCatalogUnique = std::make_unique<DurableViewCatalogImpl>(_db);
+ durableViewCatalog = durableViewCatalogUnique.get();
- using Callback = std::function<Status(const BSONObj& view)>;
- virtual void iterate(OperationContext* opCtx, Callback callback) {
- ++_iterateCount;
+ _viewCatalog = ViewCatalog::get(_db);
+
+ // Create the system views collection for the database.
+ ASSERT(_db->createCollection(
+ operationContext(),
+ NamespaceString("db", NamespaceString::kSystemDotViewsCollectionName)));
+
+ // Create any additional databases used throughout the test.
+ ASSERT(AutoGetOrCreateDb(operationContext(), "db1", MODE_X).getDb());
+ ASSERT(AutoGetOrCreateDb(operationContext(), "db2", MODE_X).getDb());
+ wuow.commit();
}
- virtual void iterateIgnoreInvalidEntries(OperationContext* opCtx, Callback callback) {
- ++_iterateCount;
+
+ void tearDown() {
+ CatalogTestFixture::tearDown();
}
- virtual void upsert(OperationContext* opCtx, const NamespaceString& name, const BSONObj& view) {
- ++_upsertCount;
+
+ ViewCatalog* getViewCatalog() const {
+ return _viewCatalog;
}
- virtual void remove(OperationContext* opCtx, const NamespaceString& name) {}
- virtual const std::string& getName() const {
- return name;
- };
- int getUpsertCount() {
- return _upsertCount;
+ Status createView(OperationContext* opCtx,
+ const NamespaceString& viewName,
+ const NamespaceString& viewOn,
+ const BSONArray& pipeline,
+ const BSONObj& collation) {
+ Lock::DBLock dbLock(operationContext(), viewName.db(), MODE_IX);
+ Lock::CollectionLock collLock(operationContext(), viewName, MODE_IX);
+ Lock::CollectionLock sysCollLock(
+ operationContext(),
+ NamespaceString(viewName.db(), NamespaceString::kSystemDotViewsCollectionName),
+ MODE_X);
+
+ WriteUnitOfWork wuow(opCtx);
+ Status s = _viewCatalog->createView(opCtx, viewName, viewOn, pipeline, collation);
+ wuow.commit();
+
+ return s;
}
- int getIterateCount() {
- return _iterateCount;
+ Status modifyView(OperationContext* opCtx,
+ const NamespaceString& viewName,
+ const NamespaceString& viewOn,
+ const BSONArray& pipeline) {
+ Lock::DBLock dbLock(operationContext(), viewName.db(), MODE_X);
+ Lock::CollectionLock collLock(operationContext(), viewName, MODE_IX);
+ Lock::CollectionLock sysCollLock(
+ operationContext(),
+ NamespaceString(viewName.db(), NamespaceString::kSystemDotViewsCollectionName),
+ MODE_X);
+
+ WriteUnitOfWork wuow(opCtx);
+ Status s = _viewCatalog->modifyView(opCtx, viewName, viewOn, pipeline);
+ wuow.commit();
+
+ return s;
}
-private:
- int _upsertCount;
- int _iterateCount;
-};
+ Status dropView(OperationContext* opCtx, const NamespaceString& viewName) {
+ Lock::DBLock dbLock(operationContext(), viewName.db(), MODE_IX);
+ Lock::CollectionLock collLock(operationContext(), viewName, MODE_IX);
+ Lock::CollectionLock sysCollLock(
+ operationContext(),
+ NamespaceString(viewName.db(), NamespaceString::kSystemDotViewsCollectionName),
+ MODE_X);
-const std::string DurableViewCatalogDummy::name = "dummy";
+ WriteUnitOfWork wuow(opCtx);
+ Status s = _viewCatalog->dropView(opCtx, viewName);
+ wuow.commit();
-class ViewCatalogFixture : public unittest::Test {
-public:
- ViewCatalogFixture()
- : _queryServiceContext(std::make_unique<QueryTestServiceContext>()),
- opCtx(_queryServiceContext->makeOperationContext()),
- viewCatalog(std::move(durableViewCatalogUnique)) {}
+ return s;
+ }
+
+ std::shared_ptr<ViewDefinition> lookup(OperationContext* opCtx, StringData ns) {
+ Lock::DBLock dbLock(operationContext(), NamespaceString(ns).db(), MODE_IS);
+ return _viewCatalog->lookup(operationContext(), ns);
+ }
private:
- std::unique_ptr<QueryTestServiceContext> _queryServiceContext;
+ Database* _db;
+ ViewCatalog* _viewCatalog;
protected:
- ServiceContext* getServiceContext() const {
- return _queryServiceContext->getServiceContext();
- }
-
- std::unique_ptr<DurableViewCatalogDummy> durableViewCatalogUnique =
- std::make_unique<DurableViewCatalogDummy>();
- DurableViewCatalogDummy* durableViewCatalog = durableViewCatalogUnique.get();
- ServiceContext::UniqueOperationContext opCtx;
- ViewCatalog viewCatalog;
+ DurableViewCatalogImpl* durableViewCatalog;
const BSONArray emptyPipeline;
const BSONObj emptyCollation;
};
@@ -137,7 +181,7 @@ protected:
class ReplViewCatalogFixture : public ViewCatalogFixture {
public:
void setUp() override {
- Test::setUp();
+ ViewCatalogFixture::setUp();
auto service = getServiceContext();
repl::ReplSettings settings;
@@ -156,47 +200,44 @@ TEST_F(ViewCatalogFixture, CreateExistingView) {
const NamespaceString viewName("db.view");
const NamespaceString viewOn("db.coll");
- ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
- ASSERT_NOT_OK(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_NOT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
}
TEST_F(ViewCatalogFixture, CreateViewOnDifferentDatabase) {
const NamespaceString viewName("db1.view");
const NamespaceString viewOn("db2.coll");
- ASSERT_NOT_OK(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_NOT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
}
TEST_F(ViewCatalogFixture, CanCreateViewWithExprPredicate) {
const NamespaceString viewOn("db.coll");
- ASSERT_OK(viewCatalog.createView(opCtx.get(),
- NamespaceString("db.view1"),
- viewOn,
- BSON_ARRAY(BSON("$match" << BSON("$expr" << 1))),
- emptyCollation));
-
- ASSERT_OK(viewCatalog.createView(
- opCtx.get(),
- NamespaceString("db.view2"),
- viewOn,
- BSON_ARRAY(
- BSON("$facet" << BSON("output" << BSON_ARRAY(BSON("$match" << BSON("$expr" << 1)))))),
- emptyCollation));
+ ASSERT_OK(createView(operationContext(),
+ NamespaceString("db.view1"),
+ viewOn,
+ BSON_ARRAY(BSON("$match" << BSON("$expr" << 1))),
+ emptyCollation));
+
+ ASSERT_OK(createView(operationContext(),
+ NamespaceString("db.view2"),
+ viewOn,
+ BSON_ARRAY(BSON("$facet" << BSON("output" << BSON_ARRAY(BSON(
+ "$match" << BSON("$expr" << 1)))))),
+ emptyCollation));
}
TEST_F(ViewCatalogFixture, CanCreateViewWithJSONSchemaPredicate) {
const NamespaceString viewOn("db.coll");
- ASSERT_OK(viewCatalog.createView(
- opCtx.get(),
+ ASSERT_OK(createView(
+ operationContext(),
NamespaceString("db.view1"),
viewOn,
BSON_ARRAY(BSON("$match" << BSON("$jsonSchema" << BSON("required" << BSON_ARRAY("x"))))),
emptyCollation));
- ASSERT_OK(viewCatalog.createView(
- opCtx.get(),
+ ASSERT_OK(createView(
+ operationContext(),
NamespaceString("db.view2"),
viewOn,
BSON_ARRAY(BSON(
@@ -208,16 +249,16 @@ TEST_F(ViewCatalogFixture, CanCreateViewWithJSONSchemaPredicate) {
TEST_F(ViewCatalogFixture, CanCreateViewWithLookupUsingPipelineSyntax) {
const NamespaceString viewOn("db.coll");
- ASSERT_OK(viewCatalog.createView(opCtx.get(),
- NamespaceString("db.view"),
- viewOn,
- BSON_ARRAY(BSON("$lookup" << BSON("from"
- << "fcoll"
- << "as"
- << "as"
- << "pipeline"
- << BSONArray()))),
- emptyCollation));
+ ASSERT_OK(createView(operationContext(),
+ NamespaceString("db.view"),
+ viewOn,
+ BSON_ARRAY(BSON("$lookup" << BSON("from"
+ << "fcoll"
+ << "as"
+ << "as"
+ << "pipeline"
+ << BSONArray()))),
+ emptyCollation));
}
TEST_F(ViewCatalogFixture, CreateViewWithPipelineFailsOnInvalidStageName) {
@@ -225,9 +266,8 @@ TEST_F(ViewCatalogFixture, CreateViewWithPipelineFailsOnInvalidStageName) {
const NamespaceString viewOn("db.coll");
auto invalidPipeline = BSON_ARRAY(BSON("INVALID_STAGE_NAME" << 1));
- ASSERT_THROWS(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, invalidPipeline, emptyCollation),
- AssertionException);
+ ASSERT_THROWS(createView(operationContext(), viewName, viewOn, invalidPipeline, emptyCollation),
+ AssertionException);
}
TEST_F(ReplViewCatalogFixture, CreateViewWithPipelineFailsOnIneligibleStage) {
@@ -238,7 +278,7 @@ TEST_F(ReplViewCatalogFixture, CreateViewWithPipelineFailsOnIneligibleStage) {
auto invalidPipeline = BSON_ARRAY(BSON("$changeStream" << BSONObj()));
ASSERT_THROWS_CODE(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, invalidPipeline, emptyCollation),
+ createView(operationContext(), viewName, viewOn, invalidPipeline, emptyCollation),
AssertionException,
ErrorCodes::OptionNotSupportedOnView);
}
@@ -252,7 +292,7 @@ TEST_F(ReplViewCatalogFixture, CreateViewWithPipelineFailsOnIneligibleStagePersi
<< "someOtherCollection"));
ASSERT_THROWS_CODE(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, invalidPipeline, emptyCollation),
+ createView(operationContext(), viewName, viewOn, invalidPipeline, emptyCollation),
AssertionException,
ErrorCodes::OptionNotSupportedOnView);
@@ -260,7 +300,7 @@ TEST_F(ReplViewCatalogFixture, CreateViewWithPipelineFailsOnIneligibleStagePersi
<< "someOtherCollection"));
ASSERT_THROWS_CODE(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, invalidPipeline, emptyCollation),
+ createView(operationContext(), viewName, viewOn, invalidPipeline, emptyCollation),
AssertionException,
ErrorCodes::OptionNotSupportedOnView);
}
@@ -269,8 +309,7 @@ TEST_F(ViewCatalogFixture, CreateViewOnInvalidCollectionName) {
const NamespaceString viewName("db.view");
const NamespaceString viewOn("db.$coll");
- ASSERT_NOT_OK(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_NOT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
}
TEST_F(ViewCatalogFixture, ExceedMaxViewDepthInOrder) {
@@ -281,15 +320,13 @@ TEST_F(ViewCatalogFixture, ExceedMaxViewDepthInOrder) {
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));
+ ASSERT_OK(createView(operationContext(), 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));
+ ASSERT_NOT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
}
TEST_F(ViewCatalogFixture, ExceedMaxViewDepthByJoining) {
@@ -301,23 +338,20 @@ TEST_F(ViewCatalogFixture, ExceedMaxViewDepthByJoining) {
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));
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
}
for (i = 1; i < size + 1; i++) {
const NamespaceString viewName(str::stream() << ns << (size + i));
const NamespaceString viewOn(str::stream() << ns << (size + i + 1));
- ASSERT_OK(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
}
const NamespaceString viewName(str::stream() << ns << size);
const NamespaceString viewOn(str::stream() << ns << (size + 1));
- ASSERT_NOT_OK(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_NOT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
}
TEST_F(ViewCatalogFixture, CreateViewCycles) {
@@ -326,7 +360,7 @@ TEST_F(ViewCatalogFixture, CreateViewCycles) {
const NamespaceString viewOn("db.view1");
ASSERT_NOT_OK(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
}
{
@@ -334,10 +368,9 @@ TEST_F(ViewCatalogFixture, CreateViewCycles) {
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));
+ ASSERT_OK(createView(operationContext(), view1, view2, emptyPipeline, emptyCollation));
+ ASSERT_OK(createView(operationContext(), view2, view3, emptyPipeline, emptyCollation));
+ ASSERT_NOT_OK(createView(operationContext(), view3, view1, emptyPipeline, emptyCollation));
}
}
@@ -357,7 +390,7 @@ TEST_F(ViewCatalogFixture, CanSuccessfullyCreateViewWhosePipelineIsExactlyAtMaxS
const NamespaceString viewOn("db.coll");
const BSONObj collation;
- ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, builder.arr(), collation));
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, builder.arr(), collation));
}
TEST_F(ViewCatalogFixture, CannotCreateViewWhosePipelineExceedsMaxSizeInBytes) {
@@ -374,7 +407,7 @@ TEST_F(ViewCatalogFixture, CannotCreateViewWhosePipelineExceedsMaxSizeInBytes) {
const NamespaceString viewOn("db.coll");
const BSONObj collation;
- ASSERT_NOT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, builder.arr(), collation));
+ ASSERT_NOT_OK(createView(operationContext(), viewName, viewOn, builder.arr(), collation));
}
TEST_F(ViewCatalogFixture, CannotCreateViewIfItsFullyResolvedPipelineWouldExceedMaxSizeInBytes) {
@@ -394,34 +427,34 @@ TEST_F(ViewCatalogFixture, CannotCreateViewIfItsFullyResolvedPipelineWouldExceed
const BSONObj collation1;
const BSONObj collation2;
- ASSERT_OK(viewCatalog.createView(opCtx.get(), view1, viewOn, builder1.arr(), collation1));
- ASSERT_NOT_OK(viewCatalog.createView(opCtx.get(), view2, view1, builder2.arr(), collation2));
+ ASSERT_OK(createView(operationContext(), view1, viewOn, builder1.arr(), collation1));
+ ASSERT_NOT_OK(createView(operationContext(), view2, view1, builder2.arr(), collation2));
}
TEST_F(ViewCatalogFixture, DropMissingView) {
NamespaceString viewName("db.view");
- ASSERT_NOT_OK(viewCatalog.dropView(opCtx.get(), viewName));
+ ASSERT_NOT_OK(dropView(operationContext(), viewName));
}
TEST_F(ViewCatalogFixture, ModifyMissingView) {
const NamespaceString viewName("db.view");
const NamespaceString viewOn("db.coll");
- ASSERT_NOT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline));
+ ASSERT_NOT_OK(modifyView(operationContext(), viewName, viewOn, emptyPipeline));
}
TEST_F(ViewCatalogFixture, ModifyViewOnDifferentDatabase) {
const NamespaceString viewName("db1.view");
const NamespaceString viewOn("db2.coll");
- ASSERT_NOT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline));
+ ASSERT_NOT_OK(modifyView(operationContext(), viewName, viewOn, emptyPipeline));
}
TEST_F(ViewCatalogFixture, ModifyViewOnInvalidCollectionName) {
const NamespaceString viewName("db.view");
const NamespaceString viewOn("db.$coll");
- ASSERT_NOT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline));
+ ASSERT_NOT_OK(modifyView(operationContext(), viewName, viewOn, emptyPipeline));
}
TEST_F(ReplViewCatalogFixture, ModifyViewWithPipelineFailsOnIneligibleStage) {
@@ -432,35 +465,35 @@ TEST_F(ReplViewCatalogFixture, ModifyViewWithPipelineFailsOnIneligibleStage) {
auto invalidPipeline = BSON_ARRAY(BSON("$changeStream" << BSONObj()));
// Create the initial, valid view.
- ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, validPipeline, emptyCollation));
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, validPipeline, emptyCollation));
// Now attempt to replace it with a pipeline containing $changeStream.
- ASSERT_THROWS_CODE(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, invalidPipeline),
+ ASSERT_THROWS_CODE(modifyView(operationContext(), viewName, viewOn, invalidPipeline),
AssertionException,
ErrorCodes::OptionNotSupportedOnView);
}
TEST_F(ViewCatalogFixture, LookupMissingView) {
- ASSERT(!viewCatalog.lookup(opCtx.get(), "db.view"_sd));
+ ASSERT(!lookup(operationContext(), "db.view"_sd));
}
TEST_F(ViewCatalogFixture, LookupExistingView) {
const NamespaceString viewName("db.view");
const NamespaceString viewOn("db.coll");
- ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
- ASSERT(viewCatalog.lookup(opCtx.get(), "db.view"_sd));
+ ASSERT(lookup(operationContext(), "db.view"_sd));
}
TEST_F(ViewCatalogFixture, LookupRIDExistingView) {
const NamespaceString viewName("db.view");
const NamespaceString viewOn("db.coll");
- ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd);
- auto& collectionCatalog = CollectionCatalog::get(opCtx.get());
+ auto& collectionCatalog = CollectionCatalog::get(operationContext());
ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == "db.view");
}
@@ -468,12 +501,19 @@ TEST_F(ViewCatalogFixture, LookupRIDExistingViewRollback) {
const NamespaceString viewName("db.view");
const NamespaceString viewOn("db.coll");
{
- WriteUnitOfWork wunit(opCtx.get());
- ASSERT_OK(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ Lock::DBLock dbLock(operationContext(), viewName.db(), MODE_X);
+ Lock::CollectionLock collLock(operationContext(), viewName, MODE_IX);
+ Lock::CollectionLock sysCollLock(
+ operationContext(),
+ NamespaceString(viewName.db(), NamespaceString::kSystemDotViewsCollectionName),
+ MODE_X);
+
+ WriteUnitOfWork wunit(operationContext());
+ ASSERT_OK(getViewCatalog()->createView(
+ operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
}
auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd);
- auto& collectionCatalog = CollectionCatalog::get(opCtx.get());
+ auto& collectionCatalog = CollectionCatalog::get(operationContext());
ASSERT(!collectionCatalog.lookupResourceName(resourceID));
}
@@ -481,11 +521,11 @@ TEST_F(ViewCatalogFixture, LookupRIDAfterDrop) {
const NamespaceString viewName("db.view");
const NamespaceString viewOn("db.coll");
- ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
- ASSERT_OK(viewCatalog.dropView(opCtx.get(), viewName));
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_OK(dropView(operationContext(), viewName));
auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd);
- auto& collectionCatalog = CollectionCatalog::get(opCtx.get());
+ auto& collectionCatalog = CollectionCatalog::get(operationContext());
ASSERT(!collectionCatalog.lookupResourceName(resourceID));
}
@@ -494,18 +534,24 @@ TEST_F(ViewCatalogFixture, LookupRIDAfterDropRollback) {
const NamespaceString viewOn("db.coll");
auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd);
- auto& collectionCatalog = CollectionCatalog::get(opCtx.get());
+ auto& collectionCatalog = CollectionCatalog::get(operationContext());
{
- WriteUnitOfWork wunit(opCtx.get());
- ASSERT_OK(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ WriteUnitOfWork wunit(operationContext());
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns());
wunit.commit();
}
{
- WriteUnitOfWork wunit(opCtx.get());
- ASSERT_OK(viewCatalog.dropView(opCtx.get(), viewName));
+ Lock::DBLock dbLock(operationContext(), viewName.db(), MODE_X);
+ Lock::CollectionLock collLock(operationContext(), viewName, MODE_IX);
+ Lock::CollectionLock sysCollLock(
+ operationContext(),
+ NamespaceString(viewName.db(), NamespaceString::kSystemDotViewsCollectionName),
+ MODE_X);
+
+ WriteUnitOfWork wunit(operationContext());
+ ASSERT_OK(getViewCatalog()->dropView(operationContext(), viewName));
}
ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns());
@@ -516,9 +562,9 @@ TEST_F(ViewCatalogFixture, LookupRIDAfterModify) {
const NamespaceString viewOn("db.coll");
auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd);
- auto& collectionCatalog = CollectionCatalog::get(opCtx.get());
- ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
- ASSERT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline));
+ auto& collectionCatalog = CollectionCatalog::get(operationContext());
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_OK(modifyView(operationContext(), viewName, viewOn, emptyPipeline));
ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns());
}
@@ -527,17 +573,24 @@ TEST_F(ViewCatalogFixture, LookupRIDAfterModifyRollback) {
const NamespaceString viewOn("db.coll");
auto resourceID = ResourceId(RESOURCE_COLLECTION, "db.view"_sd);
- auto& collectionCatalog = CollectionCatalog::get(opCtx.get());
+ auto& collectionCatalog = CollectionCatalog::get(operationContext());
{
- WriteUnitOfWork wunit(opCtx.get());
- ASSERT_OK(
- viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
+ WriteUnitOfWork wunit(operationContext());
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns());
wunit.commit();
}
{
- WriteUnitOfWork wunit(opCtx.get());
- ASSERT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline));
+ Lock::DBLock dbLock(operationContext(), viewName.db(), MODE_X);
+ Lock::CollectionLock collLock(operationContext(), viewName, MODE_IX);
+ Lock::CollectionLock sysCollLock(
+ operationContext(),
+ NamespaceString(viewName.db(), NamespaceString::kSystemDotViewsCollectionName),
+ MODE_X);
+
+ WriteUnitOfWork wunit(operationContext());
+ ASSERT_OK(
+ getViewCatalog()->modifyView(operationContext(), viewName, viewOn, emptyPipeline));
ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns());
}
ASSERT(collectionCatalog.lookupResourceName(resourceID).get() == viewName.ns());
@@ -547,32 +600,10 @@ TEST_F(ViewCatalogFixture, CreateViewThenDropAndLookup) {
const NamespaceString viewName("db.view");
const NamespaceString viewOn("db.coll");
- ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
- ASSERT_OK(viewCatalog.dropView(opCtx.get(), viewName));
-
- ASSERT(!viewCatalog.lookup(opCtx.get(), "db.view"_sd));
-}
-
-TEST_F(ViewCatalogFixture, ModifyTenTimes) {
- const char* ns = "db.view";
- int i;
-
- for (i = 0; i < 5; 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));
- }
-
- for (i = 0; i < 5; i++) {
- const NamespaceString viewName(str::stream() << ns << i);
- const NamespaceString viewOn(str::stream() << ns << (i + 1));
-
- ASSERT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline));
- }
+ ASSERT_OK(createView(operationContext(), viewName, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_OK(dropView(operationContext(), viewName));
- ASSERT_EQ(10, durableViewCatalog->getUpsertCount());
+ ASSERT(!lookup(operationContext(), "db.view"_sd));
}
TEST_F(ViewCatalogFixture, Iterate) {
@@ -581,13 +612,14 @@ TEST_F(ViewCatalogFixture, Iterate) {
const NamespaceString view3("db.view3");
const NamespaceString viewOn("db.coll");
- ASSERT_OK(viewCatalog.createView(opCtx.get(), view1, viewOn, emptyPipeline, emptyCollation));
- ASSERT_OK(viewCatalog.createView(opCtx.get(), view2, viewOn, emptyPipeline, emptyCollation));
- ASSERT_OK(viewCatalog.createView(opCtx.get(), view3, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_OK(createView(operationContext(), view1, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_OK(createView(operationContext(), view2, viewOn, emptyPipeline, emptyCollation));
+ ASSERT_OK(createView(operationContext(), view3, viewOn, emptyPipeline, emptyCollation));
std::set<std::string> viewNames = {"db.view1", "db.view2", "db.view3"};
- viewCatalog.iterate(opCtx.get(), [&viewNames](const ViewDefinition& view) {
+ Lock::DBLock dbLock(operationContext(), "db", MODE_IX);
+ getViewCatalog()->iterate(operationContext(), [&viewNames](const ViewDefinition& view) {
std::string name = view.name().toString();
ASSERT(viewNames.end() != viewNames.find(name));
viewNames.erase(name);
@@ -609,11 +641,12 @@ TEST_F(ViewCatalogFixture, ResolveViewCorrectPipeline) {
pipeline2 << BSON("$match" << BSON("foo" << 2));
pipeline3 << BSON("$match" << BSON("foo" << 3));
- ASSERT_OK(viewCatalog.createView(opCtx.get(), view1, viewOn, pipeline1.arr(), emptyCollation));
- ASSERT_OK(viewCatalog.createView(opCtx.get(), view2, view1, pipeline2.arr(), emptyCollation));
- ASSERT_OK(viewCatalog.createView(opCtx.get(), view3, view2, pipeline3.arr(), emptyCollation));
+ ASSERT_OK(createView(operationContext(), view1, viewOn, pipeline1.arr(), emptyCollation));
+ ASSERT_OK(createView(operationContext(), view2, view1, pipeline2.arr(), emptyCollation));
+ ASSERT_OK(createView(operationContext(), view3, view2, pipeline3.arr(), emptyCollation));
- auto resolvedView = viewCatalog.resolveView(opCtx.get(), view3);
+ Lock::DBLock dbLock(operationContext(), "db", MODE_IX);
+ auto resolvedView = getViewCatalog()->resolveView(operationContext(), view3);
ASSERT(resolvedView.isOK());
std::vector<BSONObj> expected = {BSON("$match" << BSON("foo" << 1)),
@@ -632,7 +665,9 @@ TEST_F(ViewCatalogFixture, ResolveViewCorrectPipeline) {
TEST_F(ViewCatalogFixture, ResolveViewOnCollectionNamespace) {
const NamespaceString collectionNamespace("db.coll");
- auto resolvedView = uassertStatusOK(viewCatalog.resolveView(opCtx.get(), collectionNamespace));
+ Lock::DBLock dbLock(operationContext(), "db", MODE_IS);
+ auto resolvedView =
+ uassertStatusOK(getViewCatalog()->resolveView(operationContext(), collectionNamespace));
ASSERT_EQ(resolvedView.getNamespace(), collectionNamespace);
ASSERT_EQ(resolvedView.getPipeline().size(), 0U);
@@ -649,12 +684,13 @@ TEST_F(ViewCatalogFixture, ResolveViewCorrectlyExtractsDefaultCollation) {
pipeline2 << BSON("$match" << BSON("foo" << 2));
BSONObj collation = BSON("locale"
- << "mock_reverse_string");
+ << "en_US");
- ASSERT_OK(viewCatalog.createView(opCtx.get(), view1, viewOn, pipeline1.arr(), collation));
- ASSERT_OK(viewCatalog.createView(opCtx.get(), view2, view1, pipeline2.arr(), collation));
+ ASSERT_OK(createView(operationContext(), view1, viewOn, pipeline1.arr(), collation));
+ ASSERT_OK(createView(operationContext(), view2, view1, pipeline2.arr(), collation));
- auto resolvedView = viewCatalog.resolveView(opCtx.get(), view2);
+ Lock::DBLock dbLock(operationContext(), "db", MODE_IS);
+ auto resolvedView = getViewCatalog()->resolveView(operationContext(), view2);
ASSERT(resolvedView.isOK());
ASSERT_EQ(resolvedView.getValue().getNamespace(), viewOn);
@@ -667,26 +703,12 @@ TEST_F(ViewCatalogFixture, ResolveViewCorrectlyExtractsDefaultCollation) {
ASSERT(SimpleBSONObjComparator::kInstance.evaluate(expected[i] == result[i]));
}
- auto expectedCollation =
- CollatorFactoryInterface::get(opCtx->getServiceContext())->makeFromBSON(collation);
+ auto expectedCollation = CollatorFactoryInterface::get(operationContext()->getServiceContext())
+ ->makeFromBSON(collation);
ASSERT_OK(expectedCollation.getStatus());
ASSERT_BSONOBJ_EQ(resolvedView.getValue().getDefaultCollation(),
expectedCollation.getValue()->getSpec().toBSON());
}
-TEST_F(ViewCatalogFixture, InvalidateThenReload) {
- const NamespaceString viewName("db.view");
- const NamespaceString viewOn("db.coll");
-
- ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
- ASSERT_EQ(1, durableViewCatalog->getIterateCount());
-
- ASSERT(viewCatalog.lookup(opCtx.get(), "db.view"_sd));
- ASSERT_EQ(1, durableViewCatalog->getIterateCount());
-
- viewCatalog.invalidate();
- ASSERT_OK(viewCatalog.reloadIfNeeded(opCtx.get()));
- ASSERT_EQ(2, durableViewCatalog->getIterateCount());
-}
} // namespace
} // namespace mongo