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

Side by Side 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: relax MojoLogger.SetMinimumLogLevel thread-safety & related comments. 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <set>
6 #include <thread>
7 #include <vector>
8
9 #include "mojo/public/cpp/application/application_test_base.h"
10 #include "mojo/public/cpp/bindings/strong_binding.h"
11 #include "mojo/public/cpp/system/macros.h"
12 #include "mojo/public/cpp/utility/run_loop.h"
13 #include "mojo/services/log/cpp/log_client.h"
14 #include "mojo/services/log/interfaces/entry.mojom.h"
15 #include "mojo/services/log/interfaces/log.mojom.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using LogClientTest = mojo::test::ApplicationTestBase;
19 using mojo::Environment;
20 using mojo::internal::ValidationError;
21
22 namespace mojo {
23 namespace {
24
25 // A Log implementation that remembers the set of all incoming messages.
26 class TestLogServiceImpl : public log::Log {
27 public:
28 explicit TestLogServiceImpl(InterfaceRequest<log::Log> log_req)
29 : binding_(this, std::move(log_req)) {
30 EXPECT_TRUE(binding_.is_bound());
31 binding_.set_connection_error_handler([this]() {
32 FAIL() << "Log service lost connection to the log client.";
33 });
34 validation_observer_.set_last_error(ValidationError::NONE);
35 }
36 void AddEntry(mojo::log::EntryPtr entry) override {
37 entry_msgs_.insert(entry->message.To<std::string>());
38 }
39 const std::set<std::string>& entries() { return entry_msgs_; }
40 mojo::internal::ValidationError previous_validation_error() {
41 return validation_observer_.last_error();
42 }
43
44 private:
45 mojo::StrongBinding<log::Log> binding_;
46 std::set<std::string> entry_msgs_;
47 mojo::internal::ValidationErrorObserverForTesting validation_observer_;
48 };
49
50 MojoLogLevel g_fallback_logger_level = MOJO_LOG_LEVEL_INFO;
viettrungluu 2015/12/18 00:32:56 You should set |g_fallback_logger_level| and |g_fa
vardhan 2015/12/18 03:56:29 Good point! Done.
51 bool g_fallback_logger_invoked = false;
viettrungluu 2015/12/18 00:32:56 nit: add a blank line below
vardhan 2015/12/18 03:56:29 Done.
52 // This tests that multiple threads can use the MojoLogger that
53 // mojo::log::LogClient produces, by spawning off |kNumLogEntries| threads, each
54 // issuing one unique log message.
55 TEST_F(LogClientTest, ConcurrentAddEntry) {
56 log::LogPtr log_ptr;
57 std::unique_ptr<mojo::TestLogServiceImpl> log_impl(
58 new mojo::TestLogServiceImpl(mojo::GetProxy(&log_ptr)));
59
60 // This is our test fallback logger + state. We simply records whether it's
61 // been called.
62 MojoLogger fallback_logger = {
63 // LogMessage
64 [](MojoLogLevel log_level, const char* source_file, uint32_t source_line,
65 const char* message) { g_fallback_logger_invoked = true; },
66 // SetMinimumLogLevel
67 []() -> MojoLogLevel { return g_fallback_logger_level; },
68 // GetMinimumLogLevel
69 [](MojoLogLevel lvl) { g_fallback_logger_level = lvl; }};
70 log::InitializeLogger(std::move(log_ptr), &fallback_logger);
71 Environment::SetDefaultLogger(log::GetLogger());
72
73 // Spawn off numerous threads, each of them issuing a unique log message.
74 std::vector<std::thread> threads;
75 std::set<std::string> expected_entries;
76
77 // The number of log entries to issue.
78 const int kNumLogEntries = 1000;
79 for (int i = 0; i < kNumLogEntries; i++) {
80 std::stringstream msg;
81 msg << "Test message: " << i;
82 EXPECT_TRUE(expected_entries.insert(msg.str()).second);
83
84 std::thread t([](std::string msg) { MOJO_LOG(INFO) << msg; }, msg.str());
85
86 threads.push_back(std::move(t));
87 }
88 for (auto& t : threads) {
89 t.join();
90 }
91
92 // The log message calls should now be processed by TestLogServiceImpl.
93 mojo::RunLoop::current()->RunUntilIdle();
94
95 EXPECT_EQ(expected_entries, log_impl->entries());
96 EXPECT_EQ(ValidationError::NONE, log_impl->previous_validation_error());
97
98 // We kill our binding, closing the connection to the log client and
99 // causing the log client to revert to using its fallback logger.
100 log_impl.reset();
101
102 EXPECT_FALSE(mojo::g_fallback_logger_invoked);
103 MOJO_LOG(INFO) << "Ignore this log message.";
104 EXPECT_TRUE(mojo::g_fallback_logger_invoked);
105
106 // Check that this logger propogates get/set min level calls to the fallback
107 // logger.
108 auto* logger = log::GetLogger();
109 EXPECT_EQ(MOJO_LOG_LEVEL_INFO, logger->GetMinimumLogLevel());
110 logger->SetMinimumLogLevel(MOJO_LOG_LEVEL_FATAL);
111 EXPECT_EQ(MOJO_LOG_LEVEL_FATAL, logger->GetMinimumLogLevel());
112 EXPECT_EQ(MOJO_LOG_LEVEL_FATAL, fallback_logger.GetMinimumLogLevel());
113
114 log::DestroyLogger();
115 }
116
117 } // namespace
118 } // namespace mojo
OLDNEW
« 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