blob: dde98d89432f4b33116c137f6f562fdb1d0c8af9 [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
Christopher Wiley3e7635e2012-08-15 09:46:17 -07008#include <base/file_path.h>
Christopher Wiley5781aa42012-07-30 14:42:23 -07009#include <base/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -080010#include <base/files/scoped_temp_dir.h>
Christopher Wiley5781aa42012-07-30 14:42:23 -070011#include <gmock/gmock.h>
12#include <gtest/gtest.h>
13
Christopher Wileyb691efd2012-08-09 13:51:51 -070014#include "shill/logging.h"
Christopher Wiley5781aa42012-07-30 14:42:23 -070015#include "shill/mock_log.h"
Christopher Wiley5781aa42012-07-30 14:42:23 -070016
17using testing::_;
18
19namespace {
Christopher Wiley5781aa42012-07-30 14:42:23 -070020
Christopher Wileyf11cebb2012-08-08 12:22:20 -070021const char kTestStr1[] = "What does Mr Wallace look like?";
22const char kTestStr2[] = "And now little man, I give the watch to you.";
23const char kTestStr3[] = "This is a tasty burger!";
Christopher Wileyf11cebb2012-08-08 12:22:20 -070024
25} // namespace
Christopher Wiley5781aa42012-07-30 14:42:23 -070026
27namespace shill {
28
29class MemoryLogTest : public testing::Test {
30 protected:
31 void TearDown() {
32 // Restore everything to defaults once more.
33 MemoryLog::GetInstance()->Clear();
34 MemoryLog::GetInstance()->SetMaximumSize(
35 MemoryLog::kDefaultMaximumMemoryLogSizeInBytes);
36 ScopeLogger::GetInstance()->set_verbose_level(0);
37 ScopeLogger::GetInstance()->EnableScopesByName("");
38 ::logging::SetMinLogLevel(logging::LOG_INFO);
39 }
40};
41
Christopher Wiley6e8c54b2012-08-15 16:12:30 -070042class MemoryLogDeathTest : public testing::Test { };
43
Christopher Wiley5781aa42012-07-30 14:42:23 -070044TEST_F(MemoryLogTest, ScopedLoggerStillWorks) {
45 ScopedMockLog log;
Christopher Wileyd7783522012-08-10 14:21:47 -070046 EXPECT_CALL(log, Log(_, _, kTestStr1));
47 EXPECT_CALL(log, Log(_, _, kTestStr2));
Christopher Wileyb691efd2012-08-09 13:51:51 -070048 SLOG(WiFi, 2) << "does not get through";
Christopher Wiley5781aa42012-07-30 14:42:23 -070049 ScopeLogger::GetInstance()->EnableScopesByName("+wifi");
50 // Verbose levels are inverted.
51 ScopeLogger::GetInstance()->set_verbose_level(3);
Christopher Wileyb691efd2012-08-09 13:51:51 -070052 SLOG(WiFi, 2) << kTestStr1;
Christopher Wiley5781aa42012-07-30 14:42:23 -070053 // It would be nice if the compiler didn't optimize out my conditional check.
Christopher Wileyb691efd2012-08-09 13:51:51 -070054 SLOG_IF(WiFi, 3, strlen("two") == 3) << kTestStr2;
55 SLOG_IF(WiFi, 3, strlen("one") == 2) << "does not get through again";
56 SLOG(WiFi, 4) << "spanish inquisition";
Christopher Wiley5781aa42012-07-30 14:42:23 -070057}
58
59TEST_F(MemoryLogTest, NormalLoggingStillWorks) {
60 ::logging::SetMinLogLevel(logging::LOG_WARNING);
61 ScopedMockLog log;
Christopher Wileyd7783522012-08-10 14:21:47 -070062 EXPECT_CALL(log, Log(_, _, kTestStr1));
63 EXPECT_CALL(log, Log(_, _, kTestStr2));
64 LOG(ERROR) << kTestStr1;
65 LOG(INFO) << "does not propagate down";
Christopher Wiley5781aa42012-07-30 14:42:23 -070066 // It would be nice if the compiler didn't optimize out my conditional check.
Christopher Wileyd7783522012-08-10 14:21:47 -070067 LOG_IF(WARNING, strlen("two") == 3) << kTestStr2;
Christopher Wiley5781aa42012-07-30 14:42:23 -070068}
69
Christopher Wiley6e8c54b2012-08-15 16:12:30 -070070// Test that no matter what we did, CHECK still kills the process.
71TEST_F(MemoryLogDeathTest, CheckLogsStillWork) {
72 EXPECT_DEATH( { CHECK(false) << "diediedie"; },
73 "Check failed: false. diediedie");
74}
75
Christopher Wiley5781aa42012-07-30 14:42:23 -070076TEST_F(MemoryLogTest, MemoryLogIsLogging) {
77 ScopedMockLog log;
Christopher Wileyd7783522012-08-10 14:21:47 -070078 EXPECT_CALL(log, Log(_, _, kTestStr1));
79 EXPECT_CALL(log, Log(_, _, kTestStr2));
Christopher Wiley5781aa42012-07-30 14:42:23 -070080 ::logging::SetMinLogLevel(logging::LOG_WARNING);
81 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
Christopher Wileyd7783522012-08-10 14:21:47 -070082 LOG(WARNING) << kTestStr1;
83 LOG(WARNING) << kTestStr2;
Christopher Wiley5781aa42012-07-30 14:42:23 -070084 // LT because of the prefixes prepended by the logger
Christopher Wileyd7783522012-08-10 14:21:47 -070085 EXPECT_LT(strlen(kTestStr1) + strlen(kTestStr2),
Christopher Wiley5781aa42012-07-30 14:42:23 -070086 MemoryLog::GetInstance()->current_size_bytes());
Christopher Wileyd7783522012-08-10 14:21:47 -070087 EXPECT_EQ(2, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wiley5781aa42012-07-30 14:42:23 -070088 MemoryLog::GetInstance()->Clear();
Christopher Wileyd7783522012-08-10 14:21:47 -070089 EXPECT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
90 EXPECT_EQ(0, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wiley5781aa42012-07-30 14:42:23 -070091}
92
93TEST_F(MemoryLogTest, MemoryLogLimitingWorks) {
94 ScopedMockLog log;
95 ::logging::SetMinLogLevel(logging::LOG_WARNING);
Christopher Wileyd7783522012-08-10 14:21:47 -070096 LOG(INFO) << kTestStr1;
Christopher Wiley5781aa42012-07-30 14:42:23 -070097 size_t old_size = MemoryLog::GetInstance()->current_size_bytes();
Christopher Wileyd7783522012-08-10 14:21:47 -070098 LOG(INFO) << kTestStr2;
Christopher Wiley5781aa42012-07-30 14:42:23 -070099 size_t new_size = MemoryLog::GetInstance()->current_size_bytes();
100 // Setting the size just above the current size shouldn't affect anything.
101 MemoryLog::GetInstance()->SetMaximumSize(new_size + 1);
102 ASSERT_EQ(new_size, MemoryLog::GetInstance()->current_size_bytes());
103 // Force MemoryLog to discard the earliest message
104 MemoryLog::GetInstance()->SetMaximumSize(new_size - 1);
105 // Should be just last message in the buffer.
106 ASSERT_EQ(new_size - old_size,
107 MemoryLog::GetInstance()->current_size_bytes());
108 // Now force it to discard the most recent message.
109 MemoryLog::GetInstance()->SetMaximumSize(0);
110 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
111 // Can't log if we don't have room, but the messages should still get to LOG
Christopher Wileyd7783522012-08-10 14:21:47 -0700112 EXPECT_CALL(log, Log(_, _, kTestStr3));
113 LOG(WARNING) << kTestStr3;
Christopher Wiley5781aa42012-07-30 14:42:23 -0700114 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
115 ASSERT_EQ(0, MemoryLog::GetInstance()->TestGetNumberMessages());
116}
117
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700118TEST_F(MemoryLogTest, MemoryLogFlushToFileWorks) {
Paul Stewart5ad16062013-02-21 18:10:48 -0800119 base::ScopedTempDir temp_dir;
Christopher Wiley5781aa42012-07-30 14:42:23 -0700120 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
121 FilePath test_path = temp_dir.path().Append("somelogfile");
122 ::logging::SetMinLogLevel(logging::LOG_WARNING);
Christopher Wileyd7783522012-08-10 14:21:47 -0700123 LOG(INFO) << kTestStr1;
124 LOG(INFO) << kTestStr2;
125 LOG(INFO) << kTestStr3;
126 EXPECT_EQ(3, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wiley5781aa42012-07-30 14:42:23 -0700127 // Because of all the prefixed metadata on each log message, the stuff sent to
128 // disk should be bigger than the original strings put together.
Christopher Wileyd7783522012-08-10 14:21:47 -0700129 size_t minimal_message_length = strlen(kTestStr1) + strlen(kTestStr2) +
130 strlen(kTestStr3);
131 EXPECT_LT(minimal_message_length,
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700132 MemoryLog::GetInstance()->FlushToFile(test_path));
Christopher Wiley5781aa42012-07-30 14:42:23 -0700133 std::string file_contents;
Christopher Wileyd7783522012-08-10 14:21:47 -0700134 EXPECT_TRUE(file_util::ReadFileToString(test_path, &file_contents));
Christopher Wiley5781aa42012-07-30 14:42:23 -0700135 // Log should contain all three messages
Christopher Wileyd7783522012-08-10 14:21:47 -0700136 EXPECT_NE(file_contents.find(kTestStr1), std::string::npos);
137 EXPECT_NE(file_contents.find(kTestStr2), std::string::npos);
138 EXPECT_NE(file_contents.find(kTestStr3), std::string::npos);
Christopher Wiley5781aa42012-07-30 14:42:23 -0700139 // Preserve message order
Christopher Wileyd7783522012-08-10 14:21:47 -0700140 EXPECT_LT(file_contents.find(kTestStr1), file_contents.find(kTestStr2));
141 EXPECT_LT(file_contents.find(kTestStr2), file_contents.find(kTestStr3));
142 EXPECT_TRUE(temp_dir.Delete());
Christopher Wiley5781aa42012-07-30 14:42:23 -0700143}
144
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700145TEST_F(MemoryLogTest, MemoryLogFlushToDiskCannotCreateFile) {
146 ScopedMockLog log;
mukesh agrawal910d0d62012-12-06 14:35:40 -0800147 FilePath tmp_path;
148 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith(tmp_path.AsUTF8Unsafe())));
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700149 EXPECT_CALL(log, Log(_,
150 _,
151 "Failed to open file for dumping memory log to disk."));
152 EXPECT_CALL(log, Log(_, _, "Failed to flush memory log to disk"));
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700153 file_util::CreateTemporaryFile(&tmp_path);
154 // Flushing fails because a directory already exists with the same name as
155 // our log file.
156 MemoryLog::GetInstance()->FlushToDiskImpl(
157 tmp_path.Append("cannot_be_created"));
158}
159
160TEST_F(MemoryLogTest, MemoryLogFlushToDiskRotateWorks) {
161 FilePath tmp_dir;
162 file_util::CreateNewTempDirectory(std::string("/"), &tmp_dir);
163 FilePath log_path = tmp_dir.Append("connectivity.log");
164 FilePath log_path_backup = tmp_dir.Append("connectivity.bak");
165 LOG(INFO) << kTestStr1;
166 LOG(INFO) << kTestStr2;
167 // Populate a dump file with some messages.
168 MemoryLog::GetInstance()->FlushToDiskImpl(log_path);
169 // There should be no rotated file at this point, we've only done one dump.
170 EXPECT_FALSE(file_util::PathExists(log_path_backup));
171 // Tell MemoryLog it should rotate at a really small size threshhold.
172 MemoryLog::GetInstance()->TestSetMaxDiskLogSize(1);
173 LOG(INFO) << kTestStr3;
174 // Flush to disk, which should cause a log rotate, since the old log file had
175 // more than a byte in it.
176 MemoryLog::GetInstance()->FlushToDiskImpl(log_path);
177 MemoryLog::GetInstance()->TestSetMaxDiskLogSize(
178 MemoryLog::kDefaultMaxDiskLogSizeInBytes);
179 std::string file_contents;
180 EXPECT_TRUE(file_util::ReadFileToString(log_path_backup, &file_contents));
181 // Rotated log should contain the first two messages.
182 EXPECT_NE(file_contents.find(kTestStr1), std::string::npos);
183 EXPECT_NE(file_contents.find(kTestStr2), std::string::npos);
184 EXPECT_TRUE(file_util::Delete(tmp_dir, true));
185}
186
187TEST_F(MemoryLogTest, MemoryLogFlushToDiskWorks) {
mukesh agrawal910d0d62012-12-06 14:35:40 -0800188 ScopedMockLog log;
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700189 FilePath tmp_path;
190 file_util::CreateTemporaryFile(&tmp_path);
191 LOG(INFO) << kTestStr1;
192 LOG(INFO) << kTestStr2;
193 LOG(INFO) << kTestStr3;
mukesh agrawal910d0d62012-12-06 14:35:40 -0800194 EXPECT_CALL(log, Log(_, _, _));
195 EXPECT_CALL(log, Log(_, _, ::testing::EndsWith(tmp_path.AsUTF8Unsafe())));
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700196 MemoryLog::GetInstance()->FlushToDiskImpl(tmp_path);
197 // No rotation should have happened.
198 EXPECT_FALSE(file_util::PathExists(tmp_path.Append(".bak")));
199 // But we should have a dump file now.
200 std::string file_contents;
201 EXPECT_TRUE(file_util::ReadFileToString(tmp_path, &file_contents));
202 // Dump file should contain everything we logged.
203 EXPECT_NE(file_contents.find(kTestStr1), std::string::npos);
204 EXPECT_NE(file_contents.find(kTestStr2), std::string::npos);
205 EXPECT_NE(file_contents.find(kTestStr3), std::string::npos);
206 EXPECT_TRUE(file_util::Delete(tmp_path, false));
207}
208
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700209// Test that most messages go through MemoryLog
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700210TEST_F(MemoryLogTest, MemoryLogMessageInterceptorWorks) {
211 ASSERT_EQ(0, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700212 // Make sure we're not double logging.
Christopher Wileyd7783522012-08-10 14:21:47 -0700213 LOG(ERROR) << kTestStr1;
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700214 ASSERT_EQ(1, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyb691efd2012-08-09 13:51:51 -0700215 SLOG_IF(WiFi, 3, strlen("two") == 3) << kTestStr2;
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700216 ASSERT_EQ(2, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyb691efd2012-08-09 13:51:51 -0700217 SLOG_IF(WiFi, 3, strlen("one") == 2) << "does not get through again";
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700218 ASSERT_EQ(2, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyd7783522012-08-10 14:21:47 -0700219 LOG_IF(ERROR, strlen("two") == 3) << kTestStr2;
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700220 ASSERT_EQ(3, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyd7783522012-08-10 14:21:47 -0700221 LOG_IF(ERROR, strlen("one") == 2) << "does not get through again";
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700222 ASSERT_EQ(3, MemoryLog::GetInstance()->TestGetNumberMessages());
223 NOTIMPLEMENTED();
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700224 ASSERT_EQ(4, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700225
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700226}
227
Christopher Wiley5781aa42012-07-30 14:42:23 -0700228} // namespace shill