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

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: 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 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;
51 bool g_fallback_logger_invoked;
52
53 // This tests that multiple threads can use the MojoLogger that
54 // mojo::log::LogClient produces, by spawning off |kNumLogEntries| threads, each
55 // issuing one unique log message.
56 TEST_F(LogClientTest, ConcurrentAddEntry) {
57 g_fallback_logger_level = MOJO_LOG_LEVEL_INFO;
58 g_fallback_logger_invoked = false;
59
60 log::LogPtr log_ptr;
61 std::unique_ptr<mojo::TestLogServiceImpl> log_impl(
62 new mojo::TestLogServiceImpl(mojo::GetProxy(&log_ptr)));
63
64 // This is our test fallback logger + state. We simply records whether it's
65 // been called.
66 MojoLogger fallback_logger = {
67 // LogMessage
68 [](MojoLogLevel log_level, const char* source_file, uint32_t source_line,
69 const char* message) { g_fallback_logger_invoked = true; },
70 // SetMinimumLogLevel
71 []() -> MojoLogLevel { return g_fallback_logger_level; },
72 // GetMinimumLogLevel
73 [](MojoLogLevel lvl) { g_fallback_logger_level = lvl; }};
74 log::InitializeLogger(std::move(log_ptr), &fallback_logger);
75 Environment::SetDefaultLogger(log::GetLogger());
76
77 // Spawn off numerous threads, each of them issuing a unique log message.
78 std::vector<std::thread> threads;
79 std::set<std::string> expected_entries;
80
81 // The number of log entries to issue.
82 const int kNumLogEntries = 1000;
83 for (int i = 0; i < kNumLogEntries; i++) {
84 std::stringstream msg;
85 msg << "Test message: " << i;
86 EXPECT_TRUE(expected_entries.insert(msg.str()).second);
87
88 std::thread t([](std::string msg) { MOJO_LOG(INFO) << msg; }, msg.str());
89
90 threads.push_back(std::move(t));
91 }
92 for (auto& t : threads) {
93 t.join();
94 }
95
96 // The log message calls should now be processed by TestLogServiceImpl.
97 mojo::RunLoop::current()->RunUntilIdle();
98
99 EXPECT_EQ(expected_entries, log_impl->entries());
100 EXPECT_EQ(ValidationError::NONE, log_impl->previous_validation_error());
101
102 // We kill our binding, closing the connection to the log client and
103 // causing the log client to revert to using its fallback logger.
104 log_impl.reset();
105
106 EXPECT_FALSE(mojo::g_fallback_logger_invoked);
107 MOJO_LOG(INFO) << "Ignore this log message.";
108 EXPECT_TRUE(mojo::g_fallback_logger_invoked);
109
110 // Check that this logger propogates get/set min level calls to the fallback
111 // logger.
112 auto* logger = log::GetLogger();
113 EXPECT_EQ(MOJO_LOG_LEVEL_INFO, logger->GetMinimumLogLevel());
114 logger->SetMinimumLogLevel(MOJO_LOG_LEVEL_FATAL);
115 EXPECT_EQ(MOJO_LOG_LEVEL_FATAL, logger->GetMinimumLogLevel());
116 EXPECT_EQ(MOJO_LOG_LEVEL_FATAL, fallback_logger.GetMinimumLogLevel());
117
118 log::DestroyLogger();
119 }
120
121 } // namespace
122 } // 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