summaryrefslogtreecommitdiff
path: root/src/mongo/client/embedded
diff options
context:
space:
mode:
authorHenrik Edin <henrik.edin@mongodb.com>2018-04-10 16:20:53 -0400
committerHenrik Edin <henrik.edin@mongodb.com>2018-04-18 08:34:36 -0400
commitda019f4197df2abfec336c5063e674980307ff93 (patch)
tree70d5504a95ea51710a92fe3cb210f6866fe4ae04 /src/mongo/client/embedded
parent980e650068c23c762c3662216277fad576a7e7f4 (diff)
downloadmongo-da019f4197df2abfec336c5063e674980307ff93.tar.gz
SERVER-29725 mongoe application
Embedded MongoDB in a standalone application. To be able to connect with the shell and perform testing on embedded.
Diffstat (limited to 'src/mongo/client/embedded')
-rw-r--r--src/mongo/client/embedded/SConscript28
-rw-r--r--src/mongo/client/embedded/embedded.cpp5
-rw-r--r--src/mongo/client/embedded/mongoe_main.cpp136
-rw-r--r--src/mongo/client/embedded/replication_coordinator_embedded.cpp2
4 files changed, 170 insertions, 1 deletions
diff --git a/src/mongo/client/embedded/SConscript b/src/mongo/client/embedded/SConscript
index 1130e37cdc6..3025372251d 100644
--- a/src/mongo/client/embedded/SConscript
+++ b/src/mongo/client/embedded/SConscript
@@ -109,8 +109,10 @@ env.Library(
'$BUILD_DIR/mongo/db/commands/mongod_fcv',
'$BUILD_DIR/mongo/db/op_observer_d',
'$BUILD_DIR/mongo/db/repair_database_and_check_version',
+ '$BUILD_DIR/mongo/db/repl/repl_set_status_commands',
'$BUILD_DIR/mongo/db/repl/storage_interface_impl',
'$BUILD_DIR/mongo/db/storage/mobile/storage_mobile',
+ '$BUILD_DIR/mongo/db/storage/storage_init_d',
'$BUILD_DIR/mongo/util/version_impl',
'embedded_commands',
'embedded_options',
@@ -171,6 +173,32 @@ capiTest = capiTestEnv.Program(
env.RegisterUnitTest(capiTest[0])
env.Alias('embedded_capi', capiTest)
+mongoe_env = env.Clone()
+mongoe_env.InjectThirdPartyIncludePaths(libraries=['yaml'])
+mongoe = mongoe_env.Program(
+ target='mongoe',
+ source=[
+ 'mongoe_main.cpp',
+ ],
+ LIBDEPS=[
+ '$BUILD_DIR/mongo/db/commands/shell_protocol',
+ '$BUILD_DIR/mongo/db/mongod_options',
+ '$BUILD_DIR/mongo/db/server_options',
+ '$BUILD_DIR/mongo/transport/transport_layer_manager',
+ '$BUILD_DIR/mongo/util/signal_handlers',
+ 'embedded',
+ ],
+ INSTALL_ALIAS=[
+ 'mobile-test',
+ ],
+)
+
+hygienic = get_option('install-mode') == 'hygienic'
+
+if not hygienic:
+ env.Install('#/', mongoe)
+
+
if not env['MONGO_HAVE_LIBMONGOC']:
Return()
diff --git a/src/mongo/client/embedded/embedded.cpp b/src/mongo/client/embedded/embedded.cpp
index 328217bd157..9f99b33d253 100644
--- a/src/mongo/client/embedded/embedded.cpp
+++ b/src/mongo/client/embedded/embedded.cpp
@@ -49,6 +49,7 @@
#include "mongo/db/global_settings.h"
#include "mongo/db/index_rebuilder.h"
#include "mongo/db/kill_sessions_local.h"
+#include "mongo/db/logical_clock.h"
#include "mongo/db/op_observer_impl.h"
#include "mongo/db/op_observer_registry.h"
#include "mongo/db/repair_database_and_check_version.h"
@@ -104,6 +105,9 @@ GlobalInitializerRegisterer replicationManagerInitializer(
auto serviceContext = context->serviceContext();
repl::StorageInterface::set(serviceContext, std::make_unique<repl::StorageInterfaceImpl>());
+ auto logicalClock = stdx::make_unique<LogicalClock>(serviceContext);
+ LogicalClock::set(serviceContext, std::move(logicalClock));
+
auto replCoord = std::make_unique<ReplicationCoordinatorEmbedded>(serviceContext);
repl::ReplicationCoordinator::set(serviceContext, std::move(replCoord));
repl::setOplogCollectionName(serviceContext);
@@ -113,6 +117,7 @@ GlobalInitializerRegisterer replicationManagerInitializer(
auto serviceContext = context->serviceContext();
repl::ReplicationCoordinator::set(serviceContext, nullptr);
+ LogicalClock::set(serviceContext, nullptr);
repl::StorageInterface::set(serviceContext, nullptr);
return Status::OK();
diff --git a/src/mongo/client/embedded/mongoe_main.cpp b/src/mongo/client/embedded/mongoe_main.cpp
new file mode 100644
index 00000000000..3a7bcd9ec38
--- /dev/null
+++ b/src/mongo/client/embedded/mongoe_main.cpp
@@ -0,0 +1,136 @@
+/**
+* Copyright (C) 2018 MongoDB Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* As a special exception, the copyright holders give permission to link the
+* code of portions of this program with the OpenSSL library under certain
+* conditions as described in each individual source file and distribute
+* linked combinations including the program with the OpenSSL library. You
+* must comply with the GNU Affero General Public License in all respects
+* for all of the code used other than as permitted herein. If you modify
+* file(s) with this exception, you may extend this exception to your
+* version of the file(s), but you are not obligated to do so. If you do not
+* wish to do so, delete this exception statement from your version. If you
+* delete this exception statement from all source files in the program,
+* then also delete it in the license file.
+*/
+
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/base/init.h"
+#include "mongo/client/embedded/embedded.h"
+#include "mongo/db/mongod_options.h"
+#include "mongo/db/service_context.h"
+#include "mongo/transport/transport_layer.h"
+#include "mongo/transport/transport_layer_manager.h"
+#include "mongo/util/exit.h"
+#include "mongo/util/log.h"
+#include "mongo/util/options_parser/options_parser.h"
+#include "mongo/util/options_parser/startup_options.h"
+#include "mongo/util/signal_handlers.h"
+#include "mongo/util/text.h"
+
+#include <yaml-cpp/yaml.h>
+
+namespace mongo {
+namespace {
+
+MONGO_INITIALIZER_WITH_PREREQUISITES(SignalProcessingStartup, ("ThreadNameInitializer"))
+(InitializerContext*) {
+ // Make sure we call this as soon as possible but before any other threads are started. Before
+ // embedded::initialize is too early and after is too late. So instead we hook in during the
+ // global initialization at the right place.
+ startSignalProcessingThread();
+ return Status::OK();
+}
+
+int mongoeMain(int argc, char* argv[], char** envp) {
+ ServiceContext* serviceContext = nullptr;
+
+ registerShutdownTask([&]() {
+ if (!serviceContext)
+ return;
+
+ if (auto tl = serviceContext->getTransportLayer()) {
+ log(logger::LogComponent::kNetwork) << "shutdown: going to close listening sockets...";
+ tl->shutdown();
+ }
+
+ embedded::shutdown(serviceContext);
+ });
+
+ setupSignalHandlers();
+
+ log() << "MongoDB embedded standalone application, for testing purposes only";
+
+ try {
+ optionenvironment::OptionSection startupOptions("Options");
+ uassertStatusOK(addMongodOptions(&startupOptions));
+
+ // Manually run the code that's equivalent to the MONGO_INITIALIZERs for mongod. We can't do
+ // this in initializers because embedded uses a different options format. However as long as
+ // we store the options in the same place it will be valid for embedded too. Adding all
+ // options mongod we don't have to maintain a separate set for this executable, some will be
+ // unused but that's fine as this is just an executable for testing purposes anyway.
+ std::vector<std::string> args;
+ std::map<std::string, std::string> env;
+
+ args.reserve(argc);
+ std::copy(argv, argv + argc, std::back_inserter(args));
+
+ optionenvironment::OptionsParser parser;
+ uassertStatusOK(
+ parser.run(startupOptions, args, env, &optionenvironment::startupOptionsParsed));
+ uassertStatusOK(storeMongodOptions(optionenvironment::startupOptionsParsed));
+
+ // Add embedded specific options that's not available in mongod here.
+ YAML::Emitter yaml;
+ serviceContext = embedded::initialize(yaml.c_str());
+
+ auto tl =
+ transport::TransportLayerManager::createWithConfig(&serverGlobalParams, serviceContext);
+ uassertStatusOK(tl->setup());
+
+ serviceContext->setTransportLayer(std::move(tl));
+
+ uassertStatusOK(serviceContext->getServiceExecutor()->start());
+ uassertStatusOK(serviceContext->getTransportLayer()->start());
+ } catch (const std::exception& ex) {
+ error() << ex.what();
+ return EXIT_BADOPTIONS;
+ }
+
+ return waitForShutdown();
+}
+
+} // namespace
+} // namespace mongo
+
+#if defined(_WIN32)
+// In Windows, wmain() is an alternate entry point for main(), and receives the same parameters
+// as main() but encoded in Windows Unicode (UTF-16); "wide" 16-bit wchar_t characters. The
+// WindowsCommandLine object converts these wide character strings to a UTF-8 coded equivalent
+// and makes them available through the argv() and envp() members. This enables mongoDbMain()
+// to process UTF-8 encoded arguments and environment variables without regard to platform.
+int wmain(int argc, wchar_t* argvW[], wchar_t* envpW[]) {
+ mongo::WindowsCommandLine wcl(argc, argvW, envpW);
+ return mongo::mongoeMain(argc, wcl.argv(), wcl.envp());
+}
+#else
+int main(int argc, char* argv[], char** envp) {
+ return mongo::mongoeMain(argc, argv, envp);
+}
+#endif
diff --git a/src/mongo/client/embedded/replication_coordinator_embedded.cpp b/src/mongo/client/embedded/replication_coordinator_embedded.cpp
index e0dfc14ce22..85d272a6bb7 100644
--- a/src/mongo/client/embedded/replication_coordinator_embedded.cpp
+++ b/src/mongo/client/embedded/replication_coordinator_embedded.cpp
@@ -346,7 +346,7 @@ Status ReplicationCoordinatorEmbedded::checkIfWriteConcernCanBeSatisfied(
}
Status ReplicationCoordinatorEmbedded::checkReplEnabledForCommand(BSONObjBuilder*) {
- UASSERT_NOT_IMPLEMENTED;
+ return Status(ErrorCodes::NoReplicationEnabled, "no replication on embedded");
}
HostAndPort ReplicationCoordinatorEmbedded::chooseNewSyncSource(const OpTime&) {