blob: 53cab666cc9dc31f3596d6581aff09c8d2bdacaf [file] [log] [blame]
henrike@webrtc.org0e118e72013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2004--2011, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "talk/base/fileutils.h"
29#include "talk/base/gunit.h"
30#include "talk/base/logging.h"
31#include "talk/base/pathutils.h"
32#include "talk/base/stream.h"
33#include "talk/base/thread.h"
34
35namespace talk_base {
36
37// Test basic logging operation. We should get the INFO log but not the VERBOSE.
38// We should restore the correct global state at the end.
39TEST(LogTest, SingleStream) {
40 int sev = LogMessage::GetLogToStream(NULL);
41
42 std::string str;
43 StringStream stream(str);
44 LogMessage::AddLogToStream(&stream, LS_INFO);
45 EXPECT_EQ(LS_INFO, LogMessage::GetLogToStream(&stream));
46
47 LOG(LS_INFO) << "INFO";
48 LOG(LS_VERBOSE) << "VERBOSE";
49 EXPECT_NE(std::string::npos, str.find("INFO"));
50 EXPECT_EQ(std::string::npos, str.find("VERBOSE"));
51
52 LogMessage::RemoveLogToStream(&stream);
53 EXPECT_EQ(LogMessage::NO_LOGGING, LogMessage::GetLogToStream(&stream));
54
55 EXPECT_EQ(sev, LogMessage::GetLogToStream(NULL));
56}
57
58// Test using multiple log streams. The INFO stream should get the INFO message,
59// the VERBOSE stream should get the INFO and the VERBOSE.
60// We should restore the correct global state at the end.
61TEST(LogTest, MultipleStreams) {
62 int sev = LogMessage::GetLogToStream(NULL);
63
64 std::string str1, str2;
65 StringStream stream1(str1), stream2(str2);
66 LogMessage::AddLogToStream(&stream1, LS_INFO);
67 LogMessage::AddLogToStream(&stream2, LS_VERBOSE);
68 EXPECT_EQ(LS_INFO, LogMessage::GetLogToStream(&stream1));
69 EXPECT_EQ(LS_VERBOSE, LogMessage::GetLogToStream(&stream2));
70
71 LOG(LS_INFO) << "INFO";
72 LOG(LS_VERBOSE) << "VERBOSE";
73
74 EXPECT_NE(std::string::npos, str1.find("INFO"));
75 EXPECT_EQ(std::string::npos, str1.find("VERBOSE"));
76 EXPECT_NE(std::string::npos, str2.find("INFO"));
77 EXPECT_NE(std::string::npos, str2.find("VERBOSE"));
78
79 LogMessage::RemoveLogToStream(&stream2);
80 LogMessage::RemoveLogToStream(&stream1);
81 EXPECT_EQ(LogMessage::NO_LOGGING, LogMessage::GetLogToStream(&stream2));
82 EXPECT_EQ(LogMessage::NO_LOGGING, LogMessage::GetLogToStream(&stream1));
83
84 EXPECT_EQ(sev, LogMessage::GetLogToStream(NULL));
85}
86
87// Ensure we don't crash when adding/removing streams while threads are going.
88// We should restore the correct global state at the end.
89class LogThread : public Thread {
wu@webrtc.orge5b49102013-10-18 16:27:26 +000090 public:
91 virtual ~LogThread() {
92 Stop();
93 }
94
95 private:
henrike@webrtc.org0e118e72013-07-10 00:45:36 +000096 void Run() {
97 // LS_SENSITIVE to avoid cluttering up any real logging going on
98 LOG(LS_SENSITIVE) << "LOG";
99 }
100};
101
102TEST(LogTest, MultipleThreads) {
103 int sev = LogMessage::GetLogToStream(NULL);
104
105 LogThread thread1, thread2, thread3;
106 thread1.Start();
107 thread2.Start();
108 thread3.Start();
109
110 NullStream stream1, stream2, stream3;
111 for (int i = 0; i < 1000; ++i) {
112 LogMessage::AddLogToStream(&stream1, LS_INFO);
113 LogMessage::AddLogToStream(&stream2, LS_VERBOSE);
114 LogMessage::AddLogToStream(&stream3, LS_SENSITIVE);
115 LogMessage::RemoveLogToStream(&stream1);
116 LogMessage::RemoveLogToStream(&stream2);
117 LogMessage::RemoveLogToStream(&stream3);
118 }
119
120 EXPECT_EQ(sev, LogMessage::GetLogToStream(NULL));
121}
122
123
124TEST(LogTest, WallClockStartTime) {
125 uint32 time = LogMessage::WallClockStartTime();
126 // Expect the time to be in a sensible range, e.g. > 2012-01-01.
127 EXPECT_GT(time, 1325376000u);
128}
129
130// Test the time required to write 1000 80-character logs to an unbuffered file.
131TEST(LogTest, Perf) {
132 Pathname path;
133 EXPECT_TRUE(Filesystem::GetTemporaryFolder(path, true, NULL));
134 path.SetPathname(Filesystem::TempFilename(path, "ut"));
135
136 FileStream stream;
137 EXPECT_TRUE(stream.Open(path.pathname(), "wb", NULL));
138 stream.DisableBuffering();
139 LogMessage::AddLogToStream(&stream, LS_SENSITIVE);
140
141 uint32 start = Time(), finish;
142 std::string message('X', 80);
143 for (int i = 0; i < 1000; ++i) {
144 LOG(LS_SENSITIVE) << message;
145 }
146 finish = Time();
147
148 LogMessage::RemoveLogToStream(&stream);
149 stream.Close();
150 Filesystem::DeleteFile(path);
151
152 LOG(LS_INFO) << "Average log time: " << TimeDiff(finish, start) << " us";
153}
154
155} // namespace talk_base