summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Edin <henrik.edin@mongodb.com>2019-03-26 13:25:41 -0400
committerHenrik Edin <henrik.edin@mongodb.com>2019-04-04 15:26:53 -0400
commit1b75c7b9b1295fa8a94552da7f2c63cbc2cc2105 (patch)
tree51e0271c86e045e76c15bd96ac1e204b3112c04f
parentf16366d55edae0bf02cd3d0a532e31c7c938e8db (diff)
downloadmongo-1b75c7b9b1295fa8a94552da7f2c63cbc2cc2105.tar.gz
SERVER-39102 Fix embedded and stitch unittests so logging and time reporting works correctly.
Also fixed so embedded::initialize leaves a cleaner state in case of failure so initialize with correct parameters can be done afterwards.
-rw-r--r--src/mongo/embedded/embedded.cpp18
-rw-r--r--src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp28
-rw-r--r--src/mongo/embedded/mongoc_embedded/mongoc_embedded_test.cpp16
-rw-r--r--src/mongo/embedded/stitch_support/stitch_support_test.cpp15
4 files changed, 68 insertions, 9 deletions
diff --git a/src/mongo/embedded/embedded.cpp b/src/mongo/embedded/embedded.cpp
index 7d2b82d19ec..4bd214b7532 100644
--- a/src/mongo/embedded/embedded.cpp
+++ b/src/mongo/embedded/embedded.cpp
@@ -194,9 +194,12 @@ ServiceContext* initialize(const char* yaml_config) {
Status status = mongo::runGlobalInitializers(yaml_config ? 1 : 0, argv, nullptr);
uassertStatusOKWithContext(status, "Global initilization failed");
+ auto giGuard = makeGuard([] { mongo::runGlobalDeinitializers().ignore(); });
setGlobalServiceContext(ServiceContext::make());
Client::initThread("initandlisten");
+ // Make sure current thread have no client set in thread_local when we leave this function
+ auto clientGuard = makeGuard([] { Client::releaseCurrent(); });
initWireSpec();
@@ -285,10 +288,11 @@ ServiceContext* initialize(const char* yaml_config) {
quickExit(EXIT_NEED_DOWNGRADE);
}
- // Assert that the in-memory featureCompatibilityVersion parameter has been explicitly set. If
- // we are part of a replica set and are started up with no data files, we do not set the
- // featureCompatibilityVersion until a primary is chosen. For this case, we expect the in-memory
- // featureCompatibilityVersion parameter to still be uninitialized until after startup.
+ // Assert that the in-memory featureCompatibilityVersion parameter has been explicitly set.
+ // If we are part of a replica set and are started up with no data files, we do not set the
+ // featureCompatibilityVersion until a primary is chosen. For this case, we expect the
+ // in-memory featureCompatibilityVersion parameter to still be uninitialized until after
+ // startup.
if (canCallFCVSetIfCleanStartup) {
invariant(serverGlobalParams.featureCompatibility.isVersionInitialized());
}
@@ -309,11 +313,11 @@ ServiceContext* initialize(const char* yaml_config) {
// operation context anymore
startupOpCtx.reset();
- // Make sure current thread have no client set in thread_local
- Client::releaseCurrent();
-
serviceContext->notifyStartupComplete();
+ // Init succeeded, no need for global deinit.
+ giGuard.dismiss();
+
return serviceContext;
}
} // namespace embedded
diff --git a/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp b/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp
index d1c48cc4cf9..510b467733d 100644
--- a/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp
+++ b/src/mongo/embedded/mongo_embedded/mongo_embedded_test.cpp
@@ -34,6 +34,7 @@
#include <set>
#include <yaml-cpp/yaml.h>
+#include "mongo/base/initializer.h"
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/db/commands/test_commands_enabled.h"
#include "mongo/db/json.h"
@@ -695,13 +696,30 @@ int main(const int argc, const char* const* const argv) {
::mongo::clearSignalMask();
::mongo::setupSynchronousSignalHandlers();
::mongo::serverGlobalParams.noUnixSocket = true;
- ::mongo::unittest::setupTestLogger();
// Allocate an error descriptor for use in non-configured tests
const auto status = makeStatusPtr();
mongo::setTestCommandsEnabled(true);
+ // Perform one cycle of global initialization/deinitialization before running test. This will
+ // make sure everything that is needed is setup for the unittest infrastructure.
+ // The reason this works is that the unittest system relies on other systems being initialized
+ // through global init and deinitialize just deinitializes systems that explicitly supports
+ // deinit leaving the systems unittest needs initialized.
+ const char* null_argv[1] = {nullptr};
+ ret = mongo::runGlobalInitializers(0, null_argv, nullptr);
+ if (!ret.isOK()) {
+ std::cerr << "Global initilization failed";
+ return EXIT_FAILURE;
+ }
+
+ ret = mongo::runGlobalDeinitializers();
+ if (!ret.isOK()) {
+ std::cerr << "Global deinitilization failed";
+ return EXIT_FAILURE;
+ }
+
// Check so we can initialize the library without providing init params
mongo_embedded_v1_lib* lib = mongo_embedded_v1_lib_init(nullptr, status.get());
if (lib == nullptr) {
@@ -742,6 +760,13 @@ int main(const int argc, const char* const* const argv) {
<< mongo_embedded_v1_status_get_explanation(status.get()) << std::endl;
}
+ // Attempt to create an embedded instance to make sure something gets logged. This will probably
+ // fail but that's fine.
+ mongo_embedded_v1_instance* instance = mongo_embedded_v1_instance_create(lib, nullptr, nullptr);
+ if (instance) {
+ mongo_embedded_v1_instance_destroy(instance, nullptr);
+ }
+
if (mongo_embedded_v1_lib_fini(lib, nullptr) != MONGO_EMBEDDED_V1_SUCCESS) {
std::cerr << "mongo_embedded_v1_fini() failed with "
<< mongo_embedded_v1_status_get_error(status.get()) << ": "
@@ -750,6 +775,7 @@ int main(const int argc, const char* const* const argv) {
if (!receivedCallback) {
std::cerr << "Did not get a log callback." << std::endl;
+ return EXIT_FAILURE;
}
const auto result = ::mongo::unittest::Suite::run(std::vector<std::string>(), "", 1);
diff --git a/src/mongo/embedded/mongoc_embedded/mongoc_embedded_test.cpp b/src/mongo/embedded/mongoc_embedded/mongoc_embedded_test.cpp
index 7f16c2220c6..c6c5c65c8a8 100644
--- a/src/mongo/embedded/mongoc_embedded/mongoc_embedded_test.cpp
+++ b/src/mongo/embedded/mongoc_embedded/mongoc_embedded_test.cpp
@@ -38,6 +38,7 @@
#include <mongoc/mongoc.h>
#include <yaml-cpp/yaml.h>
+#include "mongo/base/initializer.h"
#include "mongo/db/server_options.h"
#include "mongo/embedded/mongo_embedded/mongo_embedded.h"
#include "mongo/embedded/mongoc_embedded/mongoc_embedded_test_gen.h"
@@ -282,7 +283,20 @@ int main(int argc, char** argv, char** envp) {
::mongo::clearSignalMask();
::mongo::setupSynchronousSignalHandlers();
::mongo::serverGlobalParams.noUnixSocket = true;
- ::mongo::unittest::setupTestLogger();
+
+ // See comment by the same code block in mongo_embedded_test.cpp
+ const char* null_argv[1] = {nullptr};
+ ret = mongo::runGlobalInitializers(0, null_argv, nullptr);
+ if (!ret.isOK()) {
+ std::cerr << "Global initilization failed";
+ return EXIT_FAILURE;
+ }
+
+ ret = mongo::runGlobalDeinitializers();
+ if (!ret.isOK()) {
+ std::cerr << "Global deinitilization failed";
+ return EXIT_FAILURE;
+ }
StatusPtr status(mongo_embedded_v1_status_create());
mongoc_init();
diff --git a/src/mongo/embedded/stitch_support/stitch_support_test.cpp b/src/mongo/embedded/stitch_support/stitch_support_test.cpp
index dcafc52ef3d..4192b11219c 100644
--- a/src/mongo/embedded/stitch_support/stitch_support_test.cpp
+++ b/src/mongo/embedded/stitch_support/stitch_support_test.cpp
@@ -33,6 +33,7 @@
#include "stitch_support/stitch_support.h"
+#include "mongo/base/initializer.h"
#include "mongo/bson/json.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/quick_exit.h"
@@ -589,6 +590,20 @@ TEST_F(StitchSupportTest, TestUpsertProducesProperStatus) {
// calling runGlobalInitializers(), which is called both from the regular unit test main() and from
// the Stitch Support Library intializer function that gets tested here.
int main(const int argc, const char* const* const argv) {
+ // See comment by the same code block in mongo_embedded_test.cpp
+ const char* null_argv[1] = {nullptr};
+ auto ret = mongo::runGlobalInitializers(0, null_argv, nullptr);
+ if (!ret.isOK()) {
+ std::cerr << "Global initilization failed";
+ return EXIT_FAILURE;
+ }
+
+ ret = mongo::runGlobalDeinitializers();
+ if (!ret.isOK()) {
+ std::cerr << "Global deinitilization failed";
+ return EXIT_FAILURE;
+ }
+
const auto result = ::mongo::unittest::Suite::run(std::vector<std::string>(), "", 1);
// This is the standard exit path for Mongo processes. See the mongo::quickExit() declaration