SERVER-108453: Clean up malformed extensions and add two end-to-end startup failure test cases (#40123)
GitOrigin-RevId: d83d540d106759d6f1e6525764513d7c73daaacd
This commit is contained in:
parent
0079e4c653
commit
1bd40dc8ad
@ -430,6 +430,10 @@ mongo_install(
|
||||
extensions_with_config(
|
||||
name = "dist_test_extensions",
|
||||
srcs = [
|
||||
# Any extension that we intend to load in extensions passthrough tests and in the
|
||||
# extension-enabled variant MUST have the "_mongo_extension" suffix for the
|
||||
# find_extensions.sh script to recognize it.
|
||||
|
||||
# TODO SERVER-108821: Remove the comment below once extension stages are no longer
|
||||
# listed by $listMqlEntities.
|
||||
# Any extension added here will result in the with-extensions Evergreen variant
|
||||
@ -440,6 +444,11 @@ extensions_with_config(
|
||||
# TODO SERVER-109108: Remove this entry when the bar extension is no longer needed.
|
||||
"//src/mongo/db/extension/test_examples:bar_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:foo_mongo_extension",
|
||||
|
||||
# Any extension that is just loaded in a no-passthrough test MUST NOT have the
|
||||
# "_mongo_extension" suffix.
|
||||
"//src/mongo/db/extension/test_examples:no_symbol_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:duplicate_stage_descriptor_bad_extension",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@ -1494,3 +1494,87 @@ def mongo_cc_fuzzer_test(
|
||||
exec_properties = exec_properties,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
# Note: For these extensions to load successfully in the server, they must be built with
|
||||
# --allocator=system. Otherwise, the extensions will get a local instance of tcmalloc which
|
||||
# fails to run properly because there isn't enough TLS space available for both the host and
|
||||
# extension's tcmalloc. In transitions.bzl, we define a Bazel transition for managing the allocator
|
||||
# and other extension-specific options.
|
||||
def mongo_cc_extension_shared_library(
|
||||
name,
|
||||
srcs = [],
|
||||
deps = [],
|
||||
header_deps = [],
|
||||
visibility = None,
|
||||
data = [],
|
||||
tags = [],
|
||||
copts = [],
|
||||
linkopts = [],
|
||||
includes = [],
|
||||
linkstatic = False,
|
||||
local_defines = [],
|
||||
target_compatible_with = [],
|
||||
defines = [],
|
||||
additional_linker_inputs = [],
|
||||
features = [],
|
||||
exec_properties = {},
|
||||
**kwargs):
|
||||
mongo_cc_library(
|
||||
name = name,
|
||||
srcs = srcs,
|
||||
deps = deps + [
|
||||
"//src/mongo/db/extension/public:api",
|
||||
"//src/mongo/db/extension/sdk:sdk_cpp",
|
||||
],
|
||||
header_deps = header_deps,
|
||||
visibility = visibility,
|
||||
data = data,
|
||||
tags = tags,
|
||||
copts = copts,
|
||||
linkopts = linkopts,
|
||||
includes = includes,
|
||||
linkstatic = linkstatic,
|
||||
local_defines = local_defines,
|
||||
defines = defines,
|
||||
features = features,
|
||||
exec_properties = exec_properties,
|
||||
additional_linker_inputs = additional_linker_inputs + select({
|
||||
"@platforms//os:linux": [
|
||||
":test_extensions.version_script.lds",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}) + select({
|
||||
"@platforms//os:macos": [
|
||||
":test_extensions.exported_symbols_list.lds",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
# linkshared produces a shared library as the output.
|
||||
# TODO SERVER-109255 Make sure the test extensions are statically linked, as we expect
|
||||
# all extensions to be.
|
||||
linkshared = True,
|
||||
non_transitive_dyn_linkopts = select({
|
||||
"@platforms//os:linux": [
|
||||
"-Wl,--version-script=$(location :test_extensions.version_script.lds)",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}) + select({
|
||||
"@platforms//os:macos": [
|
||||
"-Wl,-exported_symbols_list,$(location :test_extensions.exported_symbols_list.lds)",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
skip_global_deps = [
|
||||
# This is a globally injected dependency. We don't want a special allocator linked
|
||||
# here. Instead, the allocator should be overriden at load time.
|
||||
"allocator",
|
||||
"libunwind",
|
||||
],
|
||||
target_compatible_with = target_compatible_with + select({
|
||||
"//bazel/config:shared_archive_or_link_dynamic": [],
|
||||
"//conditions:default": ["@platforms//:incompatible"],
|
||||
}) + select({
|
||||
"@platforms//os:linux": [],
|
||||
"//conditions:default": ["@platforms//:incompatible"],
|
||||
}),
|
||||
)
|
||||
|
||||
@ -1,13 +1,23 @@
|
||||
/**
|
||||
* Tests error cases when using the --loadExtensions startup parameter on mongos and mongod.
|
||||
*
|
||||
* @tags: [featureFlagExtensionsAPI]
|
||||
* This includes testing cases where the host rejects the parsed options, file does not exist, and
|
||||
* two cases where the extension is rejected by the host during loading.
|
||||
*
|
||||
* @tags: [
|
||||
* featureFlagExtensionsAPI,
|
||||
* # TODO SERVER-109351 Re-enable aubsan coverage by resolving memory leak
|
||||
* incompatible_aubsan,
|
||||
* ]
|
||||
*/
|
||||
|
||||
import {isLinux} from "jstests/libs/os_helpers.js";
|
||||
import {ShardingTest} from "jstests/libs/shardingtest.js";
|
||||
|
||||
const pathToExtensionFoo = MongoRunner.getExtensionPath("libfoo_mongo_extension.so");
|
||||
const pathToMissingSymbolExtension = MongoRunner.getExtensionPath("libno_symbol_bad_extension.so");
|
||||
const pathToDuplicateStageExtension =
|
||||
MongoRunner.getExtensionPath("libduplicate_stage_descriptor_bad_extension.so");
|
||||
|
||||
// Create a ShardingTest so that we have a config DB for mongos to point to in our test. We don't
|
||||
// use ShardingTest directly because repeated failed ShardingTest startups causes issues in the test
|
||||
// environment. This also reduces the amount of times we have to start a whole sharded cluster in
|
||||
@ -52,6 +62,10 @@ if (isLinux()) {
|
||||
runTest({options: {loadExtensions: 12345}});
|
||||
// Path to extension does not exist.
|
||||
runTest({options: {loadExtensions: "path/does/not/exist.so"}});
|
||||
// Path to extension with an .so that is missing the get_mongodb_extension symbol.
|
||||
runTest({options: {loadExtensions: pathToMissingSymbolExtension}});
|
||||
// Path to extension that attempts to register duplicate stage descriptors.
|
||||
runTest({options: {loadExtensions: pathToDuplicateStageExtension}});
|
||||
} else {
|
||||
// Startup should fail because we are attempting to load an extension on a platform that is not
|
||||
// linux.
|
||||
@ -59,19 +59,19 @@ mongo_cc_unit_test(
|
||||
# TODO SERVER-109108: Remove this entry when the buzz extension is no longer needed.
|
||||
"//src/mongo/db/extension/test_examples:buzz_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:foo_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:hostVersionFails_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:host_version_fails_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:hostVersionSucceeds_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:initializeVersionFails_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:initialize_version_fails_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:loadTwoStages_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:malformed1_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:malformed2_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:malformed3_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:malformed4_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:malformed5_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:malformed6_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:malformed7_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:malformed8_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:nullStageDescriptor_mongo_extension",
|
||||
"//src/mongo/db/extension/test_examples:no_symbol_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:null_mongo_extension_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:major_version_too_high_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:major_version_too_low_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:minor_version_too_high_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:null_initialize_function_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:major_version_max_int_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:duplicate_stage_descriptor_bad_extension",
|
||||
"//src/mongo/db/extension/test_examples:null_stage_descriptor_bad_extension",
|
||||
],
|
||||
tags = ["mongo_unittest_seventh_group"],
|
||||
target_compatible_with = select({
|
||||
|
||||
@ -50,40 +50,6 @@
|
||||
#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kDefault
|
||||
|
||||
namespace mongo::extension::host {
|
||||
|
||||
stdx::unordered_map<std::string, std::unique_ptr<SharedLibrary>> ExtensionLoader::loadedExtensions;
|
||||
|
||||
bool loadExtensions(const std::vector<std::string>& extensionPaths) {
|
||||
if (extensionPaths.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!feature_flags::gFeatureFlagExtensionsAPI.isEnabled()) {
|
||||
LOGV2_ERROR(10668500,
|
||||
"Extensions are not allowed with the current configuration. You may need to "
|
||||
"enable featureFlagExtensionsAPI.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& extension : extensionPaths) {
|
||||
LOGV2(10668501, "Loading extension", "filePath"_attr = extension);
|
||||
|
||||
try {
|
||||
ExtensionLoader::load(extension);
|
||||
} catch (...) {
|
||||
LOGV2_ERROR(10668502,
|
||||
"Error loading extension",
|
||||
"filePath"_attr = extension,
|
||||
"status"_attr = exceptionToStatus());
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGV2(10668503, "Successfully loaded extension", "filePath"_attr = extension);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
void assertVersionCompatibility(const ::MongoExtensionAPIVersionVector* hostVersions,
|
||||
const ::MongoExtensionAPIVersion& extensionVersion) {
|
||||
@ -145,10 +111,43 @@ ExtensionHandle getMongoExtension(SharedLibrary& extensionLib, const std::string
|
||||
}
|
||||
} // namespace
|
||||
|
||||
stdx::unordered_map<std::string, std::unique_ptr<SharedLibrary>> ExtensionLoader::loadedExtensions;
|
||||
|
||||
bool loadExtensions(const std::vector<std::string>& extensionPaths) {
|
||||
if (extensionPaths.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!feature_flags::gFeatureFlagExtensionsAPI.isEnabled()) {
|
||||
LOGV2_ERROR(10668500,
|
||||
"Extensions are not allowed with the current configuration. You may need to "
|
||||
"enable featureFlagExtensionsAPI.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& extension : extensionPaths) {
|
||||
LOGV2(10668501, "Loading extension", "filePath"_attr = extension);
|
||||
|
||||
try {
|
||||
ExtensionLoader::load(extension);
|
||||
} catch (...) {
|
||||
LOGV2_ERROR(10668502,
|
||||
"Error loading extension",
|
||||
"filePath"_attr = extension,
|
||||
"status"_attr = exceptionToStatus());
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGV2(10668503, "Successfully loaded extension", "filePath"_attr = extension);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExtensionLoader::load(const std::string& extensionPath) {
|
||||
uassert(10845400,
|
||||
str::stream() << "Loading extension '" << extensionPath
|
||||
<< "' failed: " << "Extension has already been loaded",
|
||||
str::stream() << "Loading extension '" << extensionPath << "' failed: "
|
||||
<< "Extension has already been loaded",
|
||||
!loadedExtensions.contains(extensionPath));
|
||||
|
||||
StatusWith<std::unique_ptr<SharedLibrary>> swExtensionLib =
|
||||
|
||||
@ -76,45 +76,53 @@ TEST_F(LoadExtensionsTest, LoadExtensionErrorCases) {
|
||||
AssertionException,
|
||||
10615500);
|
||||
|
||||
// malformed1_extension is missing the get_mongodb_extension symbol definition.
|
||||
ASSERT_THROWS_CODE(ExtensionLoader::load(getExtensionPath("libmalformed1_mongo_extension.so")),
|
||||
// no_symbol_bad_extension is missing the get_mongodb_extension symbol definition.
|
||||
ASSERT_THROWS_CODE(ExtensionLoader::load(getExtensionPath("libno_symbol_bad_extension.so")),
|
||||
AssertionException,
|
||||
10615501);
|
||||
|
||||
// malformed2_extension returns null from get_mongodb_extension.
|
||||
ASSERT_THROWS_CODE(ExtensionLoader::load(getExtensionPath("libmalformed2_mongo_extension.so")),
|
||||
AssertionException,
|
||||
10615503);
|
||||
// null_mongo_extension_bad_extension returns null from get_mongodb_extension.
|
||||
ASSERT_THROWS_CODE(
|
||||
ExtensionLoader::load(getExtensionPath("libnull_mongo_extension_bad_extension.so")),
|
||||
AssertionException,
|
||||
10615503);
|
||||
|
||||
// malformed3_extension has an incompatible major version (plus 1).
|
||||
ASSERT_THROWS_CODE(ExtensionLoader::load(getExtensionPath("libmalformed3_mongo_extension.so")),
|
||||
AssertionException,
|
||||
10615504);
|
||||
// major_version_too_high_bad_extension has an incompatible major version (plus 1).
|
||||
ASSERT_THROWS_CODE(
|
||||
ExtensionLoader::load(getExtensionPath("libmajor_version_too_high_bad_extension.so")),
|
||||
AssertionException,
|
||||
10615504);
|
||||
|
||||
// malformed4_extension has an incompatible major version (minus 1).
|
||||
ASSERT_THROWS_CODE(ExtensionLoader::load(getExtensionPath("libmalformed4_mongo_extension.so")),
|
||||
AssertionException,
|
||||
10615504);
|
||||
// major_version_too_low_bad_extension has an incompatible major version (minus 1).
|
||||
ASSERT_THROWS_CODE(
|
||||
ExtensionLoader::load(getExtensionPath("libmajor_version_too_low_bad_extension.so")),
|
||||
AssertionException,
|
||||
10615504);
|
||||
|
||||
// malformed5_extension has an incompatible minor version.
|
||||
ASSERT_THROWS_CODE(ExtensionLoader::load(getExtensionPath("libmalformed5_mongo_extension.so")),
|
||||
AssertionException,
|
||||
10615505);
|
||||
// minor_version_too_high_bad_extension has an incompatible minor version.
|
||||
ASSERT_THROWS_CODE(
|
||||
ExtensionLoader::load(getExtensionPath("libminor_version_too_high_bad_extension.so")),
|
||||
AssertionException,
|
||||
10615505);
|
||||
|
||||
// malformed6_extension has a null initialization function.
|
||||
ASSERT_THROWS_CODE(ExtensionLoader::load(getExtensionPath("libmalformed6_mongo_extension.so")),
|
||||
AssertionException,
|
||||
10615506);
|
||||
// null_initialize_function_bad_extension has a null initialization function.
|
||||
ASSERT_THROWS_CODE(
|
||||
ExtensionLoader::load(getExtensionPath("libnull_initialize_function_bad_extension.so")),
|
||||
AssertionException,
|
||||
10615506);
|
||||
|
||||
// malformed7_extension has the maximum uint32_t value as its major version.
|
||||
ASSERT_THROWS_CODE(ExtensionLoader::load(getExtensionPath("libmalformed7_mongo_extension.so")),
|
||||
AssertionException,
|
||||
10615504);
|
||||
// major_version_max_int_bad_extension has the maximum uint32_t value as its major version.
|
||||
ASSERT_THROWS_CODE(
|
||||
ExtensionLoader::load(getExtensionPath("libmajor_version_max_int_bad_extension.so")),
|
||||
AssertionException,
|
||||
10615504);
|
||||
|
||||
// malformed8_extension attempts to register the same stage descriptor multiple times.
|
||||
ASSERT_THROWS_CODE(ExtensionLoader::load(getExtensionPath("libmalformed8_mongo_extension.so")),
|
||||
AssertionException,
|
||||
10696402);
|
||||
// duplicate_stage_descriptor_bad_extension attempts to register the same stage descriptor
|
||||
// multiple times.
|
||||
ASSERT_THROWS_CODE(
|
||||
ExtensionLoader::load(getExtensionPath("libduplicate_stage_descriptor_bad_extension.so")),
|
||||
AssertionException,
|
||||
10696402);
|
||||
}
|
||||
|
||||
// TODO SERVER-109108: Switch this to use the foo extension once we can reset state in between
|
||||
@ -189,20 +197,20 @@ TEST_F(LoadExtensionsTest, LoadExtensionHostVersionParameterSucceeds) {
|
||||
|
||||
TEST_F(LoadExtensionsTest, LoadExtensionHostVersionParameterFails) {
|
||||
ASSERT_THROWS_CODE(
|
||||
ExtensionLoader::load(getExtensionPath("libhostVersionFails_mongo_extension.so")),
|
||||
ExtensionLoader::load(getExtensionPath("libhost_version_fails_bad_extension.so")),
|
||||
AssertionException,
|
||||
10615503);
|
||||
}
|
||||
|
||||
TEST_F(LoadExtensionsTest, LoadExtensionInitializeVersionFails) {
|
||||
TEST_F(LoadExtensionsTest, LoadExtensioninitialize_version_fails) {
|
||||
ASSERT_THROWS_CODE(
|
||||
ExtensionLoader::load(getExtensionPath("libinitializeVersionFails_mongo_extension.so")),
|
||||
ExtensionLoader::load(getExtensionPath("libinitialize_version_fails_bad_extension.so")),
|
||||
AssertionException,
|
||||
10726600);
|
||||
}
|
||||
|
||||
DEATH_TEST_F(LoadExtensionsTest, LoadExtensionNullStageDescriptor, "10596400") {
|
||||
ExtensionLoader::load(getExtensionPath("libnullStageDescriptor_mongo_extension.so"));
|
||||
DEATH_TEST_F(LoadExtensionsTest, LoadExtensionnull_stage_descriptor, "10596400") {
|
||||
ExtensionLoader::load(getExtensionPath("libnull_stage_descriptor_bad_extension.so"));
|
||||
}
|
||||
|
||||
TEST(LoadExtensionTest, LoadExtensionTwoStagesSucceeds) {
|
||||
|
||||
@ -1,77 +1,51 @@
|
||||
load("//bazel:mongo_src_rules.bzl", "mongo_cc_library", "mongo_cc_unit_test")
|
||||
load("//bazel:mongo_src_rules.bzl", "mongo_cc_extension_shared_library", "mongo_cc_library", "mongo_cc_unit_test")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
# Extensions under test_examples/
|
||||
[
|
||||
# Note: For these extensions to load successfully in the server, they must be built with
|
||||
# --allocator=system. Otherwise, the extensions will get a local instance of tcmalloc which
|
||||
# fails to run properly because there isn't enough TLS space available for both the host and
|
||||
# extension's tcmalloc. When testing on evergreen, we should build the extensions with the
|
||||
# system allocator, and load the extensions into a host that was built with tcmalloc.
|
||||
mongo_cc_library(
|
||||
mongo_cc_extension_shared_library(
|
||||
name = extension_name + "_mongo_extension",
|
||||
srcs = [extension_name + ".cpp"],
|
||||
additional_linker_inputs = select({
|
||||
"@platforms//os:linux": [
|
||||
":test_extensions.version_script.lds",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}) + select({
|
||||
"@platforms//os:macos": [
|
||||
":test_extensions.exported_symbols_list.lds",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
# linkshared produces a shared library as the output.
|
||||
# TODO SERVER-109255 Make sure the test extensions are statically linked, as we expect
|
||||
# all extensions to be.
|
||||
linkshared = True,
|
||||
non_transitive_dyn_linkopts = select({
|
||||
"@platforms//os:linux": [
|
||||
"-Wl,--version-script=$(location :test_extensions.version_script.lds)",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}) + select({
|
||||
"@platforms//os:macos": [
|
||||
"-Wl,-exported_symbols_list,$(location :test_extensions.exported_symbols_list.lds)",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
skip_global_deps = [
|
||||
# This is a globally injected dependency. We don't want a special allocator linked
|
||||
# here. Instead, the allocator should be overriden at load time.
|
||||
"allocator",
|
||||
"libunwind",
|
||||
],
|
||||
target_compatible_with = select({
|
||||
"//bazel/config:shared_archive_or_link_dynamic": [],
|
||||
"//conditions:default": ["@platforms//:incompatible"],
|
||||
}) + select({
|
||||
"@platforms//os:linux": [],
|
||||
"//conditions:default": ["@platforms//:incompatible"],
|
||||
}),
|
||||
deps = [
|
||||
"//src/mongo/db/extension/public:api",
|
||||
"//src/mongo/db/extension/sdk:sdk_cpp",
|
||||
],
|
||||
)
|
||||
for extension_name in [
|
||||
"malformed1",
|
||||
"malformed2",
|
||||
"malformed3",
|
||||
"malformed4",
|
||||
"malformed5",
|
||||
"malformed6",
|
||||
"malformed7",
|
||||
"malformed8",
|
||||
"foo",
|
||||
"bar",
|
||||
# TODO SERVER-109108: Remove this entry when the buzz extension is no longer needed.
|
||||
"buzz",
|
||||
"hostVersionSucceeds",
|
||||
"hostVersionFails",
|
||||
"initializeVersionFails",
|
||||
"loadTwoStages",
|
||||
"nullStageDescriptor",
|
||||
]
|
||||
]
|
||||
|
||||
# Extensions under test_examples/loading/
|
||||
[
|
||||
mongo_cc_extension_shared_library(
|
||||
name = extension_name + "_mongo_extension",
|
||||
srcs = ["loading/" + extension_name + ".cpp"],
|
||||
)
|
||||
for extension_name in [
|
||||
"hostVersionSucceeds",
|
||||
"loadTwoStages",
|
||||
]
|
||||
]
|
||||
|
||||
# Extensions under test_examples/fail_to_load/
|
||||
# Each of these should fail startup.
|
||||
[
|
||||
mongo_cc_extension_shared_library(
|
||||
name = extension_name + "_bad_extension",
|
||||
srcs = ["fail_to_load/" + extension_name + ".cpp"],
|
||||
)
|
||||
for extension_name in [
|
||||
"no_symbol",
|
||||
"null_mongo_extension",
|
||||
"major_version_too_high",
|
||||
"major_version_too_low",
|
||||
"minor_version_too_high",
|
||||
"null_initialize_function",
|
||||
"major_version_max_int",
|
||||
"duplicate_stage_descriptor",
|
||||
"host_version_fails",
|
||||
"initialize_version_fails",
|
||||
"null_stage_descriptor",
|
||||
]
|
||||
]
|
||||
|
||||
@ -36,4 +36,4 @@ public:
|
||||
};
|
||||
|
||||
// No definition of get_mongodb_extension() here, which is intentional to simulate a malformed
|
||||
// extension.
|
||||
// extension missing the export of the get_mongodb_extension symbol.
|
||||
Loading…
Reference in New Issue
Block a user