summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/create_collection_test.cpp
diff options
context:
space:
mode:
authorYoonsoo Kim <yoonsoo.kim@mongodb.com>2022-09-28 17:59:27 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-09-28 19:17:19 +0000
commitbef2975bdd054b9c9826b7a4bac1fda2cb174be3 (patch)
tree166bcb1d9fb5860876c316c3ec328d47f7334794 /src/mongo/db/catalog/create_collection_test.cpp
parenta61ed7a6f6c702224ba822dfd8a4caeba335efcd (diff)
downloadmongo-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.cpp144
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