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

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

Powered by Google App Engine
This is Rietveld 408576698