blob: 3fc225a4c482f1dd983ea68a05bd84d863988926 [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>
Christopher Wiley5781aa42012-07-30 14:42:23 -070010#include <base/scoped_temp_dir.h>
11#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) {
Christopher Wiley5781aa42012-07-30 14:42:23 -0700119 ScopedTempDir temp_dir;
120 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;
147 EXPECT_CALL(log, Log(_,
148 _,
149 "Failed to open file for dumping memory log to disk."));
150 EXPECT_CALL(log, Log(_, _, "Failed to flush memory log to disk"));
151 FilePath tmp_path;
152 file_util::CreateTemporaryFile(&tmp_path);
153 // Flushing fails because a directory already exists with the same name as
154 // our log file.
155 MemoryLog::GetInstance()->FlushToDiskImpl(
156 tmp_path.Append("cannot_be_created"));
157}
158
159TEST_F(MemoryLogTest, MemoryLogFlushToDiskRotateWorks) {
160 FilePath tmp_dir;
161 file_util::CreateNewTempDirectory(std::string("/"), &tmp_dir);
162 FilePath log_path = tmp_dir.Append("connectivity.log");
163 FilePath log_path_backup = tmp_dir.Append("connectivity.bak");
164 LOG(INFO) << kTestStr1;
165 LOG(INFO) << kTestStr2;
166 // Populate a dump file with some messages.
167 MemoryLog::GetInstance()->FlushToDiskImpl(log_path);
168 // There should be no rotated file at this point, we've only done one dump.
169 EXPECT_FALSE(file_util::PathExists(log_path_backup));
170 // Tell MemoryLog it should rotate at a really small size threshhold.
171 MemoryLog::GetInstance()->TestSetMaxDiskLogSize(1);
172 LOG(INFO) << kTestStr3;
173 // Flush to disk, which should cause a log rotate, since the old log file had
174 // more than a byte in it.
175 MemoryLog::GetInstance()->FlushToDiskImpl(log_path);
176 MemoryLog::GetInstance()->TestSetMaxDiskLogSize(
177 MemoryLog::kDefaultMaxDiskLogSizeInBytes);
178 std::string file_contents;
179 EXPECT_TRUE(file_util::ReadFileToString(log_path_backup, &file_contents));
180 // Rotated log should contain the first two messages.
181 EXPECT_NE(file_contents.find(kTestStr1), std::string::npos);
182 EXPECT_NE(file_contents.find(kTestStr2), std::string::npos);
183 EXPECT_TRUE(file_util::Delete(tmp_dir, true));
184}
185
186TEST_F(MemoryLogTest, MemoryLogFlushToDiskWorks) {
187 FilePath tmp_path;
188 file_util::CreateTemporaryFile(&tmp_path);
189 LOG(INFO) << kTestStr1;
190 LOG(INFO) << kTestStr2;
191 LOG(INFO) << kTestStr3;
192 MemoryLog::GetInstance()->FlushToDiskImpl(tmp_path);
193 // No rotation should have happened.
194 EXPECT_FALSE(file_util::PathExists(tmp_path.Append(".bak")));
195 // But we should have a dump file now.
196 std::string file_contents;
197 EXPECT_TRUE(file_util::ReadFileToString(tmp_path, &file_contents));
198 // Dump file should contain everything we logged.
199 EXPECT_NE(file_contents.find(kTestStr1), std::string::npos);
200 EXPECT_NE(file_contents.find(kTestStr2), std::string::npos);
201 EXPECT_NE(file_contents.find(kTestStr3), std::string::npos);
202 EXPECT_TRUE(file_util::Delete(tmp_path, false));
203}
204
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700205// Test that most messages go through MemoryLog
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700206TEST_F(MemoryLogTest, MemoryLogMessageInterceptorWorks) {
207 ASSERT_EQ(0, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700208 // Make sure we're not double logging.
Christopher Wileyd7783522012-08-10 14:21:47 -0700209 LOG(ERROR) << kTestStr1;
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700210 ASSERT_EQ(1, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyb691efd2012-08-09 13:51:51 -0700211 SLOG_IF(WiFi, 3, strlen("two") == 3) << kTestStr2;
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700212 ASSERT_EQ(2, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyb691efd2012-08-09 13:51:51 -0700213 SLOG_IF(WiFi, 3, strlen("one") == 2) << "does not get through again";
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700214 ASSERT_EQ(2, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyd7783522012-08-10 14:21:47 -0700215 LOG_IF(ERROR, strlen("two") == 3) << kTestStr2;
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700216 ASSERT_EQ(3, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wileyd7783522012-08-10 14:21:47 -0700217 LOG_IF(ERROR, strlen("one") == 2) << "does not get through again";
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700218 ASSERT_EQ(3, MemoryLog::GetInstance()->TestGetNumberMessages());
219 NOTIMPLEMENTED();
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700220 ASSERT_EQ(4, MemoryLog::GetInstance()->TestGetNumberMessages());
Christopher Wiley6e8c54b2012-08-15 16:12:30 -0700221
Christopher Wileyf11cebb2012-08-08 12:22:20 -0700222}
223
Christopher Wiley5781aa42012-07-30 14:42:23 -0700224} // namespace shill