Ensure that mouse lock works correctly on Chrome ASH in Windows 8.
[chromium-blink-merge.git] / base / debug / trace_event_memory_unittest.cc
blob3f5cad3ede213cb8b59e63577b942dbe72d26519
1 // Copyright 2013 The Chromium 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.
5 #include "base/debug/trace_event_memory.h"
7 #include <sstream>
8 #include <string>
10 #include "base/debug/trace_event_impl.h"
11 #include "base/message_loop/message_loop.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
15 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
16 #endif
18 namespace base {
19 namespace debug {
21 // Tests for the trace event memory tracking system. Exists as a class so it
22 // can be a friend of TraceMemoryController.
23 class TraceMemoryTest : public testing::Test {
24 public:
25 TraceMemoryTest() {}
26 virtual ~TraceMemoryTest() {}
28 private:
29 DISALLOW_COPY_AND_ASSIGN(TraceMemoryTest);
32 //////////////////////////////////////////////////////////////////////////////
34 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
36 TEST_F(TraceMemoryTest, TraceMemoryController) {
37 MessageLoop message_loop;
39 // Start with no observers of the TraceLog.
40 EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest());
42 // Creating a controller adds it to the TraceLog observer list.
43 scoped_ptr<TraceMemoryController> controller(
44 new TraceMemoryController(
45 message_loop.message_loop_proxy(),
46 ::HeapProfilerWithPseudoStackStart,
47 ::HeapProfilerStop,
48 ::GetHeapProfile));
49 EXPECT_EQ(1u, TraceLog::GetInstance()->GetObserverCountForTest());
50 EXPECT_TRUE(
51 TraceLog::GetInstance()->HasEnabledStateObserver(controller.get()));
53 // By default the observer isn't dumping memory profiles.
54 EXPECT_FALSE(controller->IsTimerRunningForTest());
56 // Simulate enabling tracing.
57 controller->StartProfiling();
58 message_loop.RunUntilIdle();
59 EXPECT_TRUE(controller->IsTimerRunningForTest());
61 // Simulate disabling tracing.
62 controller->StopProfiling();
63 message_loop.RunUntilIdle();
64 EXPECT_FALSE(controller->IsTimerRunningForTest());
66 // Deleting the observer removes it from the TraceLog observer list.
67 controller.reset();
68 EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest());
71 TEST_F(TraceMemoryTest, ScopedTraceMemory) {
72 ScopedTraceMemory::InitForTest();
74 // Start with an empty stack.
75 EXPECT_EQ(0, ScopedTraceMemory::GetStackDepthForTest());
78 // Push an item.
79 ScopedTraceMemory scope1("cat1", "name1");
80 EXPECT_EQ(1, ScopedTraceMemory::GetStackDepthForTest());
81 EXPECT_EQ("cat1", ScopedTraceMemory::GetScopeDataForTest(0).category);
82 EXPECT_EQ("name1", ScopedTraceMemory::GetScopeDataForTest(0).name);
85 // One more item.
86 ScopedTraceMemory scope2("cat2", "name2");
87 EXPECT_EQ(2, ScopedTraceMemory::GetStackDepthForTest());
88 EXPECT_EQ("cat2", ScopedTraceMemory::GetScopeDataForTest(1).category);
89 EXPECT_EQ("name2", ScopedTraceMemory::GetScopeDataForTest(1).name);
92 // Ended scope 2.
93 EXPECT_EQ(1, ScopedTraceMemory::GetStackDepthForTest());
96 // Ended scope 1.
97 EXPECT_EQ(0, ScopedTraceMemory::GetStackDepthForTest());
99 ScopedTraceMemory::CleanupForTest();
102 void TestDeepScopeNesting(int current, int depth) {
103 EXPECT_EQ(current, ScopedTraceMemory::GetStackDepthForTest());
104 ScopedTraceMemory scope("category", "name");
105 if (current < depth)
106 TestDeepScopeNesting(current + 1, depth);
107 EXPECT_EQ(current + 1, ScopedTraceMemory::GetStackDepthForTest());
110 TEST_F(TraceMemoryTest, DeepScopeNesting) {
111 ScopedTraceMemory::InitForTest();
113 // Ensure really deep scopes don't crash.
114 TestDeepScopeNesting(0, 100);
116 ScopedTraceMemory::CleanupForTest();
119 #endif // defined(TRACE_MEMORY_SUPPORTED)
121 /////////////////////////////////////////////////////////////////////////////
123 TEST_F(TraceMemoryTest, AppendHeapProfileTotalsAsTraceFormat) {
124 // Empty input gives empty output.
125 std::string empty_output;
126 AppendHeapProfileTotalsAsTraceFormat("", &empty_output);
127 EXPECT_EQ("", empty_output);
129 // Typical case.
130 const char input[] =
131 "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile";
132 const std::string kExpectedOutput =
133 "{\"current_allocs\": 357, \"current_bytes\": 55227, \"trace\": \"\"}";
134 std::string output;
135 AppendHeapProfileTotalsAsTraceFormat(input, &output);
136 EXPECT_EQ(kExpectedOutput, output);
139 TEST_F(TraceMemoryTest, AppendHeapProfileLineAsTraceFormat) {
140 // Empty input gives empty output.
141 std::string empty_output;
142 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("", &empty_output));
143 EXPECT_EQ("", empty_output);
145 // Invalid input returns false.
146 std::string junk_output;
147 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("junk", &junk_output));
149 // Input with normal category and name entries.
150 const char kCategory[] = "category";
151 const char kName[] = "name";
152 std::ostringstream input;
153 input << " 68: 4195 [ 1087: 98009] @ " << &kCategory << " "
154 << &kName;
155 const std::string kExpectedOutput =
156 ",\n"
158 "\"current_allocs\": 68, "
159 "\"current_bytes\": 4195, "
160 "\"trace\": \"name \""
161 "}";
162 std::string output;
163 EXPECT_TRUE(
164 AppendHeapProfileLineAsTraceFormat(input.str().c_str(), &output));
165 EXPECT_EQ(kExpectedOutput, output);
167 // Input with with the category "toplevel".
168 // TODO(jamescook): Eliminate this special case and move the logic to the
169 // trace viewer code.
170 const char kTaskCategory[] = "toplevel";
171 const char kTaskName[] = "TaskName";
172 std::ostringstream input2;
173 input2 << " 68: 4195 [ 1087: 98009] @ " << &kTaskCategory << " "
174 << &kTaskName;
175 const std::string kExpectedOutput2 =
176 ",\n"
178 "\"current_allocs\": 68, "
179 "\"current_bytes\": 4195, "
180 "\"trace\": \"TaskName->PostTask \""
181 "}";
182 std::string output2;
183 EXPECT_TRUE(
184 AppendHeapProfileLineAsTraceFormat(input2.str().c_str(), &output2));
185 EXPECT_EQ(kExpectedOutput2, output2);
187 // Zero current allocations is skipped.
188 std::ostringstream zero_input;
189 zero_input << " 0: 0 [ 1087: 98009] @ " << &kCategory << " "
190 << &kName;
191 std::string zero_output;
192 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat(zero_input.str().c_str(),
193 &zero_output));
194 EXPECT_EQ("", zero_output);
197 TEST_F(TraceMemoryTest, AppendHeapProfileAsTraceFormat) {
198 // Empty input gives empty output.
199 std::string empty_output;
200 AppendHeapProfileAsTraceFormat("", &empty_output);
201 EXPECT_EQ("", empty_output);
203 // Typical case.
204 const char input[] =
205 "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile\n"
206 " 95: 40940 [ 649: 114260] @\n"
207 " 77: 32546 [ 742: 106234] @ 0x0 0x0\n"
208 " 0: 0 [ 132: 4236] @ 0x0\n"
209 "\n"
210 "MAPPED_LIBRARIES:\n"
211 "1be411fc1000-1be4139e4000 rw-p 00000000 00:00 0\n"
212 "1be4139e4000-1be4139e5000 ---p 00000000 00:00 0\n";
213 const std::string kExpectedOutput =
214 "[{"
215 "\"current_allocs\": 357, "
216 "\"current_bytes\": 55227, "
217 "\"trace\": \"\"},\n"
218 "{\"current_allocs\": 95, "
219 "\"current_bytes\": 40940, "
220 "\"trace\": \"\"},\n"
221 "{\"current_allocs\": 77, "
222 "\"current_bytes\": 32546, "
223 "\"trace\": \"null \""
224 "}]\n";
225 std::string output;
226 AppendHeapProfileAsTraceFormat(input, &output);
227 EXPECT_EQ(kExpectedOutput, output);
230 TEST_F(TraceMemoryTest, StringFromHexAddress) {
231 EXPECT_STREQ("null", StringFromHexAddress("0x0"));
232 EXPECT_STREQ("error", StringFromHexAddress("not an address"));
233 const char kHello[] = "hello";
234 std::ostringstream hex_address;
235 hex_address << &kHello;
236 EXPECT_STREQ(kHello, StringFromHexAddress(hex_address.str()));
239 } // namespace debug
240 } // namespace base