diff options
author | Yoonsoo Kim <yoonsoo.kim@mongodb.com> | 2022-09-28 17:59:27 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-09-28 19:17:19 +0000 |
commit | bef2975bdd054b9c9826b7a4bac1fda2cb174be3 (patch) | |
tree | 166bcb1d9fb5860876c316c3ec328d47f7334794 /src/mongo/db/catalog/create_collection_test.cpp | |
parent | a61ed7a6f6c702224ba822dfd8a4caeba335efcd (diff) | |
download | mongo-bef2975bdd054b9c9826b7a4bac1fda2cb174be3.tar.gz |
SERVER-69685 Add `createVirtualCollection` API
Diffstat (limited to 'src/mongo/db/catalog/create_collection_test.cpp')
-rw-r--r-- | src/mongo/db/catalog/create_collection_test.cpp | 144 |
1 files changed, 142 insertions, 2 deletions
diff --git a/src/mongo/db/catalog/create_collection_test.cpp b/src/mongo/db/catalog/create_collection_test.cpp index 63c472f1ecd..c1b47d20166 100644 --- a/src/mongo/db/catalog/create_collection_test.cpp +++ b/src/mongo/db/catalog/create_collection_test.cpp @@ -27,28 +27,32 @@ * it in the license file. */ +#include "mongo/base/error_codes.h" #include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_write_path.h" #include "mongo/db/catalog/create_collection.h" #include "mongo/db/catalog/database_holder.h" +#include "mongo/db/catalog/virtual_collection_impl.h" +#include "mongo/db/catalog/virtual_collection_options.h" #include "mongo/db/concurrency/exception_util.h" #include "mongo/db/db_raii.h" #include "mongo/db/jsobj.h" #include "mongo/db/repl/replication_coordinator_mock.h" #include "mongo/db/repl/storage_interface_impl.h" #include "mongo/db/service_context_d_test_fixture.h" +#include "mongo/stdx/utility.h" #include "mongo/unittest/unittest.h" +#include "mongo/util/assert_util.h" #include "mongo/util/uuid.h" namespace mongo { namespace { class CreateCollectionTest : public ServiceContextMongoDTest { -private: +protected: void setUp() override; void tearDown() override; -protected: void validateValidator(const std::string& validatorStr, int expectedError); // Use StorageInterface to access storage features below catalog interface. @@ -76,6 +80,18 @@ void CreateCollectionTest::tearDown() { ServiceContextMongoDTest::tearDown(); } +class CreateVirtualCollectionTest : public CreateCollectionTest { +private: + void setUp() override { + CreateCollectionTest::setUp(); + computeModeEnabled = true; + } + void tearDown() override { + computeModeEnabled = false; + CreateCollectionTest::tearDown(); + } +}; + /** * Creates an OperationContext. */ @@ -126,6 +142,26 @@ CollectionOptions getCollectionOptions(OperationContext* opCtx, const NamespaceS } /** + * Returns a VirtualCollectionImpl if the underlying implementation object is a virtual collection. + */ +const VirtualCollectionImpl* getVirtualCollection(OperationContext* opCtx, + const NamespaceString& nss) { + AutoGetCollectionForRead collection(opCtx, nss); + return dynamic_cast<const VirtualCollectionImpl*>(collection.getCollection().get()); +} + +/** + * Returns virtual collection options. + */ +VirtualCollectionOptions getVirtualCollectionOptions(OperationContext* opCtx, + const NamespaceString& nss) { + auto vcollPtr = getVirtualCollection(opCtx, nss); + ASSERT_TRUE(vcollPtr) << "Collection must be a virtual collection"; + + return vcollPtr->getVirtualCollectionOptions(); +} + +/** * Returns UUID of collection. */ UUID getCollectionUuid(OperationContext* opCtx, const NamespaceString& nss) { @@ -288,5 +324,109 @@ TEST_F(CreateCollectionTest, ValidationDisabledForTemporaryReshardingCollection) ASSERT_OK(status); } +const auto kValidUrl1 = + ExternalDataSourceMetadata::kDefaultFileUrlPrefix.toString() + "named_pipe1"; +const auto kValidUrl2 = + ExternalDataSourceMetadata::kDefaultFileUrlPrefix.toString() + "named_pipe2"; + +TEST_F(CreateVirtualCollectionTest, VirtualCollectionOptionsWithOneSource) { + NamespaceString vcollNss("myDb", "vcoll.name"); + auto opCtx = makeOpCtx(); + + Lock::GlobalLock lk(opCtx.get(), MODE_X); // Satisfy low-level locking invariants. + VirtualCollectionOptions reqVcollOpts; + reqVcollOpts.dataSources.emplace_back(kValidUrl1, StorageType::pipe, FileType::bson); + ASSERT_OK(createVirtualCollection(opCtx.get(), vcollNss, reqVcollOpts)); + ASSERT_TRUE(getVirtualCollection(opCtx.get(), vcollNss)); + + ASSERT_EQ(stdx::to_underlying(getCollectionOptions(opCtx.get(), vcollNss).autoIndexId), + stdx::to_underlying(CollectionOptions::NO)); + + auto vcollOpts = getVirtualCollectionOptions(opCtx.get(), vcollNss); + ASSERT_EQ(vcollOpts.dataSources.size(), 1); + ASSERT_EQ(vcollOpts.dataSources[0].url, kValidUrl1); + ASSERT_EQ(stdx::to_underlying(vcollOpts.dataSources[0].storageType), + stdx::to_underlying(StorageType::pipe)); + ASSERT_EQ(stdx::to_underlying(vcollOpts.dataSources[0].fileType), + stdx::to_underlying(FileType::bson)); +} + +TEST_F(CreateVirtualCollectionTest, VirtualCollectionOptionsWithMultiSource) { + NamespaceString vcollNss("myDb", "vcoll.name"); + auto opCtx = makeOpCtx(); + + Lock::GlobalLock lk(opCtx.get(), MODE_X); // Satisfy low-level locking invariants. + VirtualCollectionOptions reqVcollOpts; + reqVcollOpts.dataSources.emplace_back(kValidUrl1, StorageType::pipe, FileType::bson); + reqVcollOpts.dataSources.emplace_back(kValidUrl2, StorageType::pipe, FileType::bson); + + ASSERT_OK(createVirtualCollection(opCtx.get(), vcollNss, reqVcollOpts)); + ASSERT_TRUE(getVirtualCollection(opCtx.get(), vcollNss)); + + ASSERT_EQ(stdx::to_underlying(getCollectionOptions(opCtx.get(), vcollNss).autoIndexId), + stdx::to_underlying(CollectionOptions::NO)); + + auto vcollOpts = getVirtualCollectionOptions(opCtx.get(), vcollNss); + ASSERT_EQ(vcollOpts.dataSources.size(), 2); + for (int i = 0; i < 2; ++i) { + ASSERT_EQ(vcollOpts.dataSources[i].url, reqVcollOpts.dataSources[i].url); + ASSERT_EQ(stdx::to_underlying(vcollOpts.dataSources[i].storageType), + stdx::to_underlying(StorageType::pipe)); + ASSERT_EQ(stdx::to_underlying(vcollOpts.dataSources[i].fileType), + stdx::to_underlying(FileType::bson)); + } +} + +TEST_F(CreateVirtualCollectionTest, InvalidVirtualCollectionOptions) { + using namespace fmt::literals; + + NamespaceString vcollNss("myDb", "vcoll.name"); + auto opCtx = makeOpCtx(); + + Lock::GlobalLock lk(opCtx.get(), MODE_X); // Satisfy low-level locking invariants. + + { + bool exceptionOccurred = false; + VirtualCollectionOptions reqVcollOpts; + constexpr auto kInvalidUrl = "file:///abc/named_pipe"_sd; + try { + reqVcollOpts.dataSources.emplace_back(kInvalidUrl, StorageType::pipe, FileType::bson); + } catch (const DBException&) { + exceptionOccurred = true; + } + + ASSERT_TRUE(exceptionOccurred) + << "Invalid 'url': {} must fail but succeeded"_format(kInvalidUrl); + } + + { + bool exceptionOccurred = false; + VirtualCollectionOptions reqVcollOpts; + constexpr auto kInvalidStorageType = StorageType(2); + try { + reqVcollOpts.dataSources.emplace_back(kValidUrl1, kInvalidStorageType, FileType::bson); + } catch (const DBException&) { + exceptionOccurred = true; + } + + ASSERT_TRUE(exceptionOccurred) + << "Unknown 'storageType': {} must fail but succeeded"_format( + stdx::to_underlying(kInvalidStorageType)); + } + + { + bool exceptionOccurred = false; + VirtualCollectionOptions reqVcollOpts; + constexpr auto kInvalidFileType = FileType(2); + try { + reqVcollOpts.dataSources.emplace_back(kValidUrl1, StorageType::pipe, kInvalidFileType); + } catch (const DBException&) { + exceptionOccurred = true; + } + + ASSERT_TRUE(exceptionOccurred) << "Unknown 'fileType': {} must fail but succeeded"_format( + stdx::to_underlying(kInvalidFileType)); + } +} } // namespace } // namespace mongo |