Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Unified Diff: mojo/services/log/cpp/tests/log_client_unittest.cc

Issue 1447273002: Mojo Log service and a thread-safe client library. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: initialize global variables at start of the test Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/services/log/cpp/log_client.h ('k') | mojo/services/log/interfaces/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/services/log/cpp/tests/log_client_unittest.cc
diff --git a/mojo/services/log/cpp/tests/log_client_unittest.cc b/mojo/services/log/cpp/tests/log_client_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5d3c4dbc361f3822c31b147103aa1a021162c539
--- /dev/null
+++ b/mojo/services/log/cpp/tests/log_client_unittest.cc
@@ -0,0 +1,122 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <set>
+#include <thread>
+#include <vector>
+
+#include "mojo/public/cpp/application/application_test_base.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/system/macros.h"
+#include "mojo/public/cpp/utility/run_loop.h"
+#include "mojo/services/log/cpp/log_client.h"
+#include "mojo/services/log/interfaces/entry.mojom.h"
+#include "mojo/services/log/interfaces/log.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using LogClientTest = mojo::test::ApplicationTestBase;
+using mojo::Environment;
+using mojo::internal::ValidationError;
+
+namespace mojo {
+namespace {
+
+// A Log implementation that remembers the set of all incoming messages.
+class TestLogServiceImpl : public log::Log {
+ public:
+ explicit TestLogServiceImpl(InterfaceRequest<log::Log> log_req)
+ : binding_(this, std::move(log_req)) {
+ EXPECT_TRUE(binding_.is_bound());
+ binding_.set_connection_error_handler([this]() {
+ FAIL() << "Log service lost connection to the log client.";
+ });
+ validation_observer_.set_last_error(ValidationError::NONE);
+ }
+ void AddEntry(mojo::log::EntryPtr entry) override {
+ entry_msgs_.insert(entry->message.To<std::string>());
+ }
+ const std::set<std::string>& entries() { return entry_msgs_; }
+ mojo::internal::ValidationError previous_validation_error() {
+ return validation_observer_.last_error();
+ }
+
+ private:
+ mojo::StrongBinding<log::Log> binding_;
+ std::set<std::string> entry_msgs_;
+ mojo::internal::ValidationErrorObserverForTesting validation_observer_;
+};
+
+MojoLogLevel g_fallback_logger_level;
+bool g_fallback_logger_invoked;
+
+// This tests that multiple threads can use the MojoLogger that
+// mojo::log::LogClient produces, by spawning off |kNumLogEntries| threads, each
+// issuing one unique log message.
+TEST_F(LogClientTest, ConcurrentAddEntry) {
+ g_fallback_logger_level = MOJO_LOG_LEVEL_INFO;
+ g_fallback_logger_invoked = false;
+
+ log::LogPtr log_ptr;
+ std::unique_ptr<mojo::TestLogServiceImpl> log_impl(
+ new mojo::TestLogServiceImpl(mojo::GetProxy(&log_ptr)));
+
+ // This is our test fallback logger + state. We simply records whether it's
+ // been called.
+ MojoLogger fallback_logger = {
+ // LogMessage
+ [](MojoLogLevel log_level, const char* source_file, uint32_t source_line,
+ const char* message) { g_fallback_logger_invoked = true; },
+ // SetMinimumLogLevel
+ []() -> MojoLogLevel { return g_fallback_logger_level; },
+ // GetMinimumLogLevel
+ [](MojoLogLevel lvl) { g_fallback_logger_level = lvl; }};
+ log::InitializeLogger(std::move(log_ptr), &fallback_logger);
+ Environment::SetDefaultLogger(log::GetLogger());
+
+ // Spawn off numerous threads, each of them issuing a unique log message.
+ std::vector<std::thread> threads;
+ std::set<std::string> expected_entries;
+
+ // The number of log entries to issue.
+ const int kNumLogEntries = 1000;
+ for (int i = 0; i < kNumLogEntries; i++) {
+ std::stringstream msg;
+ msg << "Test message: " << i;
+ EXPECT_TRUE(expected_entries.insert(msg.str()).second);
+
+ std::thread t([](std::string msg) { MOJO_LOG(INFO) << msg; }, msg.str());
+
+ threads.push_back(std::move(t));
+ }
+ for (auto& t : threads) {
+ t.join();
+ }
+
+ // The log message calls should now be processed by TestLogServiceImpl.
+ mojo::RunLoop::current()->RunUntilIdle();
+
+ EXPECT_EQ(expected_entries, log_impl->entries());
+ EXPECT_EQ(ValidationError::NONE, log_impl->previous_validation_error());
+
+ // We kill our binding, closing the connection to the log client and
+ // causing the log client to revert to using its fallback logger.
+ log_impl.reset();
+
+ EXPECT_FALSE(mojo::g_fallback_logger_invoked);
+ MOJO_LOG(INFO) << "Ignore this log message.";
+ EXPECT_TRUE(mojo::g_fallback_logger_invoked);
+
+ // Check that this logger propogates get/set min level calls to the fallback
+ // logger.
+ auto* logger = log::GetLogger();
+ EXPECT_EQ(MOJO_LOG_LEVEL_INFO, logger->GetMinimumLogLevel());
+ logger->SetMinimumLogLevel(MOJO_LOG_LEVEL_FATAL);
+ EXPECT_EQ(MOJO_LOG_LEVEL_FATAL, logger->GetMinimumLogLevel());
+ EXPECT_EQ(MOJO_LOG_LEVEL_FATAL, fallback_logger.GetMinimumLogLevel());
+
+ log::DestroyLogger();
+}
+
+} // namespace
+} // namespace mojo
« no previous file with comments | « mojo/services/log/cpp/log_client.h ('k') | mojo/services/log/interfaces/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698