blob: 00cd7cab353649eee6ceb548f7e4a59acc47fe0c [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>
9#include <base/logging.h>
10#include <base/scoped_temp_dir.h>
11#include <gmock/gmock.h>
12#include <gtest/gtest.h>
13
14#include "shill/memory_log.h"
15#include "shill/mock_log.h"
16#include "shill/scope_logger.h"
17
18using testing::_;
19
20namespace {
21 const char kTestStr1[] = "What does Mr Wallace look like?";
22 const char kTestStr2[] = "And now little man, I give the watch to you.";
23 const char kTestStr3[] = "This is a tasty burger!";
24
25} // namespace
26
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
42TEST_F(MemoryLogTest, ScopedLoggerStillWorks) {
43 ScopedMockLog log;
44 EXPECT_CALL(log, Log(_, _, kTestStr1));
45 EXPECT_CALL(log, Log(_, _, kTestStr2));
46 SMLOG(WiFi, 2) << "does not get through";
47 ScopeLogger::GetInstance()->EnableScopesByName("+wifi");
48 // Verbose levels are inverted.
49 ScopeLogger::GetInstance()->set_verbose_level(3);
50 SMLOG(WiFi, 2) << kTestStr1;
51 // It would be nice if the compiler didn't optimize out my conditional check.
52 SMLOG_IF(WiFi, 3, strlen("two") == 3) << kTestStr2;
53 SMLOG_IF(WiFi, 3, strlen("one") == 2) << "does not get through again";
54 SMLOG(WiFi, 4) << "spanish inquisition";
55}
56
57TEST_F(MemoryLogTest, NormalLoggingStillWorks) {
58 ::logging::SetMinLogLevel(logging::LOG_WARNING);
59 ScopedMockLog log;
60 EXPECT_CALL(log, Log(_, _, kTestStr1));
61 EXPECT_CALL(log, Log(_, _, kTestStr2));
62 MLOG(ERROR) << kTestStr1;
63 MLOG(INFO) << "does not propagate down";
64 // It would be nice if the compiler didn't optimize out my conditional check.
65 MLOG_IF(WARNING, strlen("two") == 3) << kTestStr2;
66}
67
68TEST_F(MemoryLogTest, MemoryLogIsLogging) {
69 ScopedMockLog log;
70 EXPECT_CALL(log, Log(_, _, kTestStr1));
71 EXPECT_CALL(log, Log(_, _, kTestStr2));
72 ::logging::SetMinLogLevel(logging::LOG_WARNING);
73 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
74 MLOG(WARNING) << kTestStr1;
75 MLOG(WARNING) << kTestStr2;
76 // LT because of the prefixes prepended by the logger
77 ASSERT_LT(strlen(kTestStr1) + strlen(kTestStr2),
78 MemoryLog::GetInstance()->current_size_bytes());
79 ASSERT_EQ(2, MemoryLog::GetInstance()->TestGetNumberMessages());
80 MemoryLog::GetInstance()->Clear();
81 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
82 ASSERT_EQ(0, MemoryLog::GetInstance()->TestGetNumberMessages());
83}
84
85TEST_F(MemoryLogTest, MemoryLogLimitingWorks) {
86 ScopedMockLog log;
87 ::logging::SetMinLogLevel(logging::LOG_WARNING);
88 MLOG(INFO) << kTestStr1;
89 size_t old_size = MemoryLog::GetInstance()->current_size_bytes();
90 MLOG(INFO) << kTestStr2;
91 size_t new_size = MemoryLog::GetInstance()->current_size_bytes();
92 // Setting the size just above the current size shouldn't affect anything.
93 MemoryLog::GetInstance()->SetMaximumSize(new_size + 1);
94 ASSERT_EQ(new_size, MemoryLog::GetInstance()->current_size_bytes());
95 // Force MemoryLog to discard the earliest message
96 MemoryLog::GetInstance()->SetMaximumSize(new_size - 1);
97 // Should be just last message in the buffer.
98 ASSERT_EQ(new_size - old_size,
99 MemoryLog::GetInstance()->current_size_bytes());
100 // Now force it to discard the most recent message.
101 MemoryLog::GetInstance()->SetMaximumSize(0);
102 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
103 // Can't log if we don't have room, but the messages should still get to LOG
104 EXPECT_CALL(log, Log(_, _, kTestStr3));
105 MLOG(WARNING) << kTestStr3;
106 ASSERT_EQ(0, MemoryLog::GetInstance()->current_size_bytes());
107 ASSERT_EQ(0, MemoryLog::GetInstance()->TestGetNumberMessages());
108}
109
110TEST_F(MemoryLogTest, MemoryLogFlushToDiskWorks) {
111 ScopedTempDir temp_dir;
112 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
113 FilePath test_path = temp_dir.path().Append("somelogfile");
114 ::logging::SetMinLogLevel(logging::LOG_WARNING);
115 MLOG(INFO) << kTestStr1;
116 MLOG(INFO) << kTestStr2;
117 MLOG(INFO) << kTestStr3;
118 ASSERT_EQ(3, MemoryLog::GetInstance()->TestGetNumberMessages());
119 // Because of all the prefixed metadata on each log message, the stuff sent to
120 // disk should be bigger than the original strings put together.
121 ASSERT_LT(strlen(kTestStr1) + strlen(kTestStr2) + strlen(kTestStr3),
122 MemoryLog::GetInstance()->FlushToDisk(test_path.value().c_str()));
123 std::string file_contents;
124 ASSERT_TRUE(file_util::ReadFileToString(test_path, &file_contents));
125 // Log should contain all three messages
126 ASSERT_NE(file_contents.find(kTestStr1), std::string::npos);
127 ASSERT_NE(file_contents.find(kTestStr2), std::string::npos);
128 ASSERT_NE(file_contents.find(kTestStr3), std::string::npos);
129 // Preserve message order
130 ASSERT_LT(file_contents.find(kTestStr1), file_contents.find(kTestStr2));
131 ASSERT_LT(file_contents.find(kTestStr2), file_contents.find(kTestStr3));
132 ASSERT_TRUE(temp_dir.Delete());
133}
134
135} // namespace shill