c0a1568e35712a222abb2c9139910e7cca75ea27
[platform/framework/web/crosswalk.git] / src / base / debug / trace_event_memory_unittest.cc
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.
4
5 #include "base/debug/trace_event_memory.h"
6
7 #include <sstream>
8 #include <string>
9
10 #include "base/debug/trace_event_impl.h"
11 #include "base/message_loop/message_loop.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
15 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
16 #endif
17
18 namespace base {
19 namespace debug {
20
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() {}
27
28  private:
29   DISALLOW_COPY_AND_ASSIGN(TraceMemoryTest);
30 };
31
32 //////////////////////////////////////////////////////////////////////////////
33
34 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
35
36 TEST_F(TraceMemoryTest, TraceMemoryController) {
37   MessageLoop message_loop;
38
39   // Start with no observers of the TraceLog.
40   EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest());
41
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()));
52
53   // By default the observer isn't dumping memory profiles.
54   EXPECT_FALSE(controller->IsTimerRunningForTest());
55
56   // Simulate enabling tracing.
57   controller->StartProfiling();
58   message_loop.RunUntilIdle();
59   EXPECT_TRUE(controller->IsTimerRunningForTest());
60
61   // Simulate disabling tracing.
62   controller->StopProfiling();
63   message_loop.RunUntilIdle();
64   EXPECT_FALSE(controller->IsTimerRunningForTest());
65
66   // Deleting the observer removes it from the TraceLog observer list.
67   controller.reset();
68   EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest());
69 }
70
71 TEST_F(TraceMemoryTest, ScopedTraceMemory) {
72   ScopedTraceMemory::InitForTest();
73
74   // Start with an empty stack.
75   EXPECT_EQ(0, ScopedTraceMemory::GetStackDepthForTest());
76
77   {
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);
83
84     {
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);
90     }
91
92     // Ended scope 2.
93     EXPECT_EQ(1, ScopedTraceMemory::GetStackDepthForTest());
94   }
95
96   // Ended scope 1.
97   EXPECT_EQ(0, ScopedTraceMemory::GetStackDepthForTest());
98
99   ScopedTraceMemory::CleanupForTest();
100 }
101
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());
108 }
109
110 TEST_F(TraceMemoryTest, DeepScopeNesting) {
111   ScopedTraceMemory::InitForTest();
112
113   // Ensure really deep scopes don't crash.
114   TestDeepScopeNesting(0, 100);
115
116   ScopedTraceMemory::CleanupForTest();
117 }
118
119 #endif  // defined(TRACE_MEMORY_SUPPORTED)
120
121 /////////////////////////////////////////////////////////////////////////////
122
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);
128
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);
137 }
138
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);
144
145   // Invalid input returns false.
146   std::string junk_output;
147   EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("junk", &junk_output));
148
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"
157       "{"
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);
166
167   // Input with with the category "task".
168   // TODO(jamescook): Eliminate this special case and move the logic to the
169   // trace viewer code.
170   const char kTaskCategory[] = "task";
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"
177       "{"
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);
186
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);
195 }
196
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);
202
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);
228 }
229
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()));
237 }
238
239 }  // namespace debug
240 }  // namespace base