Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / base / trace_event / trace_event_memory_unittest.cc
blob781a0544c457c7f6049a822ced65e9b091c82123
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/trace_event/trace_event_memory.h"
7 #include <sstream>
8 #include <string>
10 #include "base/trace_event/trace_event_impl.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
14 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
15 #endif
17 namespace base {
18 namespace trace_event {
20 // Tests for the trace event memory tracking system. Exists as a class so it
21 // can be a friend of TraceMemoryController.
22 class TraceMemoryTest : public testing::Test {
23 public:
24 TraceMemoryTest() {}
25 ~TraceMemoryTest() override {}
27 private:
28 DISALLOW_COPY_AND_ASSIGN(TraceMemoryTest);
31 //////////////////////////////////////////////////////////////////////////////
33 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
35 TEST_F(TraceMemoryTest, TraceMemoryController) {
36 MessageLoop message_loop;
38 // Start with no observers of the TraceLog.
39 EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest());
41 // Creating a controller adds it to the TraceLog observer list.
42 scoped_ptr<TraceMemoryController> controller(new TraceMemoryController(
43 message_loop.task_runner(), ::HeapProfilerWithPseudoStackStart,
44 ::HeapProfilerStop, ::GetHeapProfile));
45 EXPECT_EQ(1u, TraceLog::GetInstance()->GetObserverCountForTest());
46 EXPECT_TRUE(
47 TraceLog::GetInstance()->HasEnabledStateObserver(controller.get()));
49 // By default the observer isn't dumping memory profiles.
50 EXPECT_FALSE(controller->IsTimerRunningForTest());
52 // Simulate enabling tracing.
53 controller->StartProfiling();
54 message_loop.RunUntilIdle();
55 EXPECT_TRUE(controller->IsTimerRunningForTest());
57 // Simulate disabling tracing.
58 controller->StopProfiling();
59 message_loop.RunUntilIdle();
60 EXPECT_FALSE(controller->IsTimerRunningForTest());
62 // Deleting the observer removes it from the TraceLog observer list.
63 controller.reset();
64 EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest());
67 TEST_F(TraceMemoryTest, ScopedTraceMemory) {
68 ScopedTraceMemory::InitForTest();
70 // Start with an empty stack.
71 EXPECT_EQ(0, ScopedTraceMemory::GetStackDepthForTest());
74 // Push an item.
75 ScopedTraceMemory scope1("cat1", "name1");
76 EXPECT_EQ(1, ScopedTraceMemory::GetStackDepthForTest());
77 EXPECT_EQ("cat1", ScopedTraceMemory::GetScopeDataForTest(0).category);
78 EXPECT_EQ("name1", ScopedTraceMemory::GetScopeDataForTest(0).name);
81 // One more item.
82 ScopedTraceMemory scope2("cat2", "name2");
83 EXPECT_EQ(2, ScopedTraceMemory::GetStackDepthForTest());
84 EXPECT_EQ("cat2", ScopedTraceMemory::GetScopeDataForTest(1).category);
85 EXPECT_EQ("name2", ScopedTraceMemory::GetScopeDataForTest(1).name);
88 // Ended scope 2.
89 EXPECT_EQ(1, ScopedTraceMemory::GetStackDepthForTest());
92 // Ended scope 1.
93 EXPECT_EQ(0, ScopedTraceMemory::GetStackDepthForTest());
95 ScopedTraceMemory::CleanupForTest();
98 void TestDeepScopeNesting(int current, int depth) {
99 EXPECT_EQ(current, ScopedTraceMemory::GetStackDepthForTest());
100 ScopedTraceMemory scope("category", "name");
101 if (current < depth)
102 TestDeepScopeNesting(current + 1, depth);
103 EXPECT_EQ(current + 1, ScopedTraceMemory::GetStackDepthForTest());
106 TEST_F(TraceMemoryTest, DeepScopeNesting) {
107 ScopedTraceMemory::InitForTest();
109 // Ensure really deep scopes don't crash.
110 TestDeepScopeNesting(0, 100);
112 ScopedTraceMemory::CleanupForTest();
115 #endif // defined(TRACE_MEMORY_SUPPORTED)
117 /////////////////////////////////////////////////////////////////////////////
119 TEST_F(TraceMemoryTest, AppendHeapProfileTotalsAsTraceFormat) {
120 // Empty input gives empty output.
121 std::string empty_output;
122 AppendHeapProfileTotalsAsTraceFormat("", &empty_output);
123 EXPECT_EQ("", empty_output);
125 // Typical case.
126 const char input[] =
127 "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile";
128 const std::string kExpectedOutput =
129 "{\"current_allocs\": 357, \"current_bytes\": 55227, \"trace\": \"\"}";
130 std::string output;
131 AppendHeapProfileTotalsAsTraceFormat(input, &output);
132 EXPECT_EQ(kExpectedOutput, output);
135 TEST_F(TraceMemoryTest, AppendHeapProfileLineAsTraceFormat) {
136 // Empty input gives empty output.
137 std::string empty_output;
138 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("", &empty_output));
139 EXPECT_EQ("", empty_output);
141 // Invalid input returns false.
142 std::string junk_output;
143 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("junk", &junk_output));
145 // Input with normal category and name entries.
146 const char kCategory[] = "category";
147 const char kName[] = "name";
148 std::ostringstream input;
149 input << " 68: 4195 [ 1087: 98009] @ " << &kCategory << " "
150 << &kName;
151 const std::string kExpectedOutput =
152 ",\n"
154 "\"current_allocs\": 68, "
155 "\"current_bytes\": 4195, "
156 "\"trace\": \"name \""
157 "}";
158 std::string output;
159 EXPECT_TRUE(
160 AppendHeapProfileLineAsTraceFormat(input.str().c_str(), &output));
161 EXPECT_EQ(kExpectedOutput, output);
163 // Input with with the category "toplevel".
164 // TODO(jamescook): Eliminate this special case and move the logic to the
165 // trace viewer code.
166 const char kTaskCategory[] = "toplevel";
167 const char kTaskName[] = "TaskName";
168 std::ostringstream input2;
169 input2 << " 68: 4195 [ 1087: 98009] @ " << &kTaskCategory << " "
170 << &kTaskName;
171 const std::string kExpectedOutput2 =
172 ",\n"
174 "\"current_allocs\": 68, "
175 "\"current_bytes\": 4195, "
176 "\"trace\": \"TaskName->PostTask \""
177 "}";
178 std::string output2;
179 EXPECT_TRUE(
180 AppendHeapProfileLineAsTraceFormat(input2.str().c_str(), &output2));
181 EXPECT_EQ(kExpectedOutput2, output2);
183 // Zero current allocations is skipped.
184 std::ostringstream zero_input;
185 zero_input << " 0: 0 [ 1087: 98009] @ " << &kCategory << " "
186 << &kName;
187 std::string zero_output;
188 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat(zero_input.str().c_str(),
189 &zero_output));
190 EXPECT_EQ("", zero_output);
193 TEST_F(TraceMemoryTest, AppendHeapProfileAsTraceFormat) {
194 // Empty input gives empty output.
195 std::string empty_output;
196 AppendHeapProfileAsTraceFormat("", &empty_output);
197 EXPECT_EQ("", empty_output);
199 // Typical case.
200 const char input[] =
201 "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile\n"
202 " 95: 40940 [ 649: 114260] @\n"
203 " 77: 32546 [ 742: 106234] @ 0x0 0x0\n"
204 " 0: 0 [ 132: 4236] @ 0x0\n"
205 "\n"
206 "MAPPED_LIBRARIES:\n"
207 "1be411fc1000-1be4139e4000 rw-p 00000000 00:00 0\n"
208 "1be4139e4000-1be4139e5000 ---p 00000000 00:00 0\n";
209 const std::string kExpectedOutput =
210 "[{"
211 "\"current_allocs\": 357, "
212 "\"current_bytes\": 55227, "
213 "\"trace\": \"\"},\n"
214 "{\"current_allocs\": 95, "
215 "\"current_bytes\": 40940, "
216 "\"trace\": \"\"},\n"
217 "{\"current_allocs\": 77, "
218 "\"current_bytes\": 32546, "
219 "\"trace\": \"null \""
220 "}]\n";
221 std::string output;
222 AppendHeapProfileAsTraceFormat(input, &output);
223 EXPECT_EQ(kExpectedOutput, output);
226 TEST_F(TraceMemoryTest, StringFromHexAddress) {
227 EXPECT_STREQ("null", StringFromHexAddress("0x0"));
228 EXPECT_STREQ("error", StringFromHexAddress("not an address"));
229 const char kHello[] = "hello";
230 std::ostringstream hex_address;
231 hex_address << &kHello;
232 EXPECT_STREQ(kHello, StringFromHexAddress(hex_address.str()));
235 } // namespace trace_event
236 } // namespace base