OLD | NEW |
---|---|
(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 | |
OLD | NEW |