blob: ae352c81ec2bf07b8bb2175ad4f9c565cabb1237 [file] [log] [blame]
Christopher Wiley5781aa42012-07-30 14:42:23 -07001// Copyright (c) 2012 The Chromium OS 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 <deque>
6#include <string>
7
8#include <base/file_util.h>
Christopher Wiley5781aa42012-07-30 14:42:23 -07009#include <base/scoped_temp_dir.h>
10#include <gmock/gmock.h>
11#include <gtest/gtest.h>
12
Christopher Wileyb691efd2012-08-09 13:51:51 -070013#include "shill/logging.h"
Christopher Wiley5781aa42012-07-30 14:42:23 -070014#include "shill/mock_log.h"
Christopher Wiley5781aa42012-07-30 14:42:23 -070015
16using testing::_;
17
18namespace {
Christopher Wiley5781aa42012-07-30 14:42:23 -070019
Christopher Wileyf11cebb2012-08-08 12:22:20 -070020const char kTestStr1[] = "What does Mr Wallace look like?";
21const char kTestStr2[] = "And now little man, I give the watch to you.";
22const char kTestStr3[] = "This is a tasty burger!";
23const char kTestStr1WithPrefix[] = "memlog: What does Mr Wallace look like?";
24const char kTestStr2WithPrefix[] =
25 "memlog: And now little man, I give the watch to you.";
26const char kTestStr3WithPrefix[] = "memlog: This is a tasty burger!";
27
28} // namespace
Christopher Wiley5781aa42012-07-30 14:42:23 -070029
30namespace shill {
31
32class MemoryLogTest : public testing::Test {
33 protected:
34 void TearDown() {
35 // Restore everything to defaults once more.
36 MemoryLog::GetInstance()->Clear();
37 MemoryLog::GetInstance()->SetMaximumSize(
38 MemoryLog::kDefaultMaximumMemoryLogSizeInBytes);
39 ScopeLogger::GetInstance()->set_verbose_level(0);
40 ScopeLogger::GetInstance()->EnableScopesByName("");
41 ::logging::SetMinLogLevel(logging::LOG_INFO);
42 }
43};
44
45TEST_F(MemoryLogTest, ScopedLoggerStillWorks) {
46 ScopedMockLog log;
Christopher Wileyf11cebb2012-08-08 12:22:20 -070047 EXPECT_CALL(log, Log(_, _, kTestStr1WithPrefix));
48 EXPECT_CALL(log, Log(_, _, kTestStr2WithPrefix));
Christopher Wileyb691efd2012-08-09 13:51:51 -070049 SLOG(WiFi, 2) << "does not get through";
Christopher Wiley5781aa42012-07-30 14:42:23 -070050 ScopeLogger::GetInstance()->EnableScopesByName("+wifi");
51 // Verbose levels are inverted.
52 ScopeLogger::GetInstance()->set_verbose_level(3);
Christopher Wileyb691efd2012-08-09 13:51:51 -070053 SLOG(WiFi, 2) << kTestStr1;
Christopher Wiley5781aa42012-07-30 14:42:23 -070054 // It would be nice if the compiler didn't optimize out my conditional check.
Christopher Wileyb691efd2012-08-09 13:51:51 -070055 SLOG_IF(WiFi, 3, strlen("two") == 3) << kTestStr2;
56 SLOG_IF(WiFi, 3, strlen("one") == 2) << "does not get through again";
57 SLOG(WiFi, 4) << "spanish inquisition";
Christopher Wiley5781aa42012-07-30 14:42:23 -070058}
59
60TEST_F(MemoryLogTest, NormalLoggingStillWorks) {
61 ::logging::SetMinLogLevel(logging::LOG_WARNING);
62 ScopedMockLog log;
Christopher Wileyf11cebb2012-08-08 12:22:20 -070063 EXPECT_CALL(log, Log(_, _, kTestStr1WithPrefix));
64 EXPECT_CALL(log, Log(_, _, kTestStr2WithPrefix));
Christopher Wiley5781aa42012-07-30 14:42:23 -070065 MLOG(ERROR) << kTestStr1;
66 MLOG(INFO) << "does not propagate down";
67 // It would be nice if the compiler didn't optimize out my conditional check.
68 MLOG_IF(WARNING, strlen("two") == 3) << kTestStr2;
69}
70
71TEST_F(MemoryLogTest, MemoryLogIsLogging) {
72 ScopedMockLog log;
Christopher Wileyf11cebb2012-08-08 12:22:20 -070073 EXPECT_CALL(log, Log(_, _, kTestStr1WithPrefix));
74 EXPECT_CALL(log, Log(_, _, kTestStr2WithPrefix));
Christopher Wiley5781aa42012-07-30 14:42:23 -070075 ::logging::SetMinLogLevel(logging::LOG_WARNING);
76 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
77 MLOG(WARNING) << kTestStr1;
78 MLOG(WARNING) << kTestStr2;
79 // LT because of the prefixes prepended by the logger
Christopher Wileyf11cebb2012-08-08 12:22:20 -070080 ASSERT_LT(strlen(kTestStr1WithPrefix) + strlen(kTestStr2WithPrefix),
Christopher Wiley5781aa42012-07-30 14:42:23 -070081 MemoryLog::GetInstance()->current_size_bytes());
82 ASSERT_EQ(2, MemoryLog::GetInstance()->TestGetNumberMessages());
83 MemoryLog::GetInstance()->Clear();
84 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
85 ASSERT_EQ(0, MemoryLog::GetInstance()->TestGetNumberMessages());
86}
87
88TEST_F(MemoryLogTest, MemoryLogLimitingWorks) {
89 ScopedMockLog log;
90 ::logging::SetMinLogLevel(logging::LOG_WARNING);
91 MLOG(INFO) << kTestStr1;
92 size_t old_size = MemoryLog::GetInstance()->current_size_bytes();
93 MLOG(INFO) << kTestStr2;
94 size_t new_size = MemoryLog::GetInstance()->current_size_bytes();
95 // Setting the size just above the current size shouldn't affect anything.
96 MemoryLog::GetInstance()->SetMaximumSize(new_size + 1);
97 ASSERT_EQ(new_size, MemoryLog::GetInstance()->current_size_bytes());
98 // Force MemoryLog to discard the earliest message
99 MemoryLog::GetInstance()->SetMaximumSize(new_size - 1);
100 // Should be just last message in the buffer.
101 ASSERT_EQ(new_size - old_size,
102 MemoryLog::GetInstance()->current_size_bytes());
103 // Now force it to discard the most recent message.
104 MemoryLog::GetInstance()->SetMaximumSize(0);
105 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
106 // Can't log if we don't have room, but the messages should still get to LOG
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700107 EXPECT_CALL(log, Log(_, _, kTestStr3WithPrefix));
Christopher Wiley5781aa42012-07-30 14:42:23 -0700108 MLOG(WARNING) << kTestStr3;
109 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
110 ASSERT_EQ(0, MemoryLog::GetInstance()->TestGetNumberMessages());
111}
112
113TEST_F(MemoryLogTest, MemoryLogFlushToDiskWorks) {
114 ScopedTempDir temp_dir;
115 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
116 FilePath test_path = temp_dir.path().Append("somelogfile");
117 ::logging::SetMinLogLevel(logging::LOG_WARNING);
118 MLOG(INFO) << kTestStr1;
119 MLOG(INFO) << kTestStr2;
120 MLOG(INFO) << kTestStr3;
121 ASSERT_EQ(3, MemoryLog::GetInstance()->TestGetNumberMessages());
122 // Because of all the prefixed metadata on each log message, the stuff sent to
123 // disk should be bigger than the original strings put together.
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700124 size_t minimal_message_length = strlen(kTestStr1WithPrefix) +
125 strlen(kTestStr2WithPrefix) + strlen(kTestStr3WithPrefix);
126 ASSERT_LT(minimal_message_length,
Christopher Wiley5781aa42012-07-30 14:42:23 -0700127 MemoryLog::GetInstance()->FlushToDisk(test_path.value().c_str()));
128 std::string file_contents;
129 ASSERT_TRUE(file_util::ReadFileToString(test_path, &file_contents));
130 // Log should contain all three messages
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700131 ASSERT_NE(file_contents.find(kTestStr1WithPrefix), std::string::npos);
132 ASSERT_NE(file_contents.find(kTestStr2WithPrefix), std::string::npos);
133 ASSERT_NE(file_contents.find(kTestStr3WithPrefix), std::string::npos);
Christopher Wiley5781aa42012-07-30 14:42:23 -0700134 // Preserve message order
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700135 ASSERT_LT(file_contents.find(kTestStr1WithPrefix),
136 file_contents.find(kTestStr2WithPrefix));
137 ASSERT_LT(file_contents.find(kTestStr2WithPrefix),
138 file_contents.find(kTestStr3WithPrefix));
Christopher Wiley5781aa42012-07-30 14:42:23 -0700139 ASSERT_TRUE(temp_dir.Delete());
140}
141
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700142TEST_F(MemoryLogTest, MemoryLogMessageInterceptorWorks) {
143 ASSERT_EQ(0, MemoryLog::GetInstance()->TestGetNumberMessages());
144 NOTIMPLEMENTED();
145 ASSERT_EQ(0, MemoryLog::GetInstance()->TestGetNumberMessages());
146 MemoryLog::InstallLogInterceptor();
147 NOTIMPLEMENTED();
148 ASSERT_EQ(1, MemoryLog::GetInstance()->TestGetNumberMessages());
149 // Make sure we're not double logging.
150 MLOG(ERROR) << kTestStr1;
151 ASSERT_EQ(2, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyb691efd2012-08-09 13:51:51 -0700152 // SLOG_IF works with the intercepting handler.
153 SLOG_IF(WiFi, 3, strlen("two") == 3) << kTestStr2;
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700154 ASSERT_EQ(3, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyb691efd2012-08-09 13:51:51 -0700155 SLOG_IF(WiFi, 3, strlen("one") == 2) << "does not get through again";
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700156 ASSERT_EQ(3, MemoryLog::GetInstance()->TestGetNumberMessages());
157 // Similarly, MLOG_IF works with the handler.
158 MLOG_IF(ERROR, strlen("two") == 3) << kTestStr2;
159 ASSERT_EQ(4, MemoryLog::GetInstance()->TestGetNumberMessages());
160 MLOG_IF(ERROR, strlen("one") == 2) << "does not get through again";
161 ASSERT_EQ(4, MemoryLog::GetInstance()->TestGetNumberMessages());
162 MemoryLog::UninstallLogInterceptor();
163 NOTIMPLEMENTED();
164 ASSERT_EQ(4, MemoryLog::GetInstance()->TestGetNumberMessages());
165 // Normal log messages still get through.
166 MLOG(ERROR) << kTestStr2;
167 ASSERT_EQ(5, MemoryLog::GetInstance()->TestGetNumberMessages());
168}
169
Christopher Wiley5781aa42012-07-30 14:42:23 -0700170} // namespace shill