OLD | NEW |
(Empty) | |
| 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.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 |
| 14 namespace base { |
| 15 namespace debug { |
| 16 |
| 17 // Tests for the trace event memory tracking system. Exists as a class so it |
| 18 // can be a friend of TraceMemoryTraceLogObserver. |
| 19 class TraceMemoryTest : public testing::Test { |
| 20 public: |
| 21 TraceMemoryTest() {} |
| 22 virtual ~TraceMemoryTest() {} |
| 23 |
| 24 private: |
| 25 DISALLOW_COPY_AND_ASSIGN(TraceMemoryTest); |
| 26 }; |
| 27 |
| 28 TEST_F(TraceMemoryTest, TraceMemoryController) { |
| 29 MessageLoop message_loop; |
| 30 |
| 31 // Start with no observers of the TraceLog. |
| 32 EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest()); |
| 33 |
| 34 // Creating a controller adds it to the TraceLog observer list. |
| 35 scoped_ptr<TraceMemoryController> controller( |
| 36 new TraceMemoryController( |
| 37 message_loop.message_loop_proxy())); |
| 38 EXPECT_EQ(1u, TraceLog::GetInstance()->GetObserverCountForTest()); |
| 39 EXPECT_TRUE( |
| 40 TraceLog::GetInstance()->HasEnabledStateObserver(controller.get())); |
| 41 |
| 42 // By default the observer isn't dumping memory profiles. |
| 43 EXPECT_FALSE(controller->IsTimerRunningForTest()); |
| 44 |
| 45 // Simulate enabling tracing. |
| 46 controller->OnTraceLogEnabled(); |
| 47 message_loop.RunUntilIdle(); |
| 48 EXPECT_TRUE(controller->IsTimerRunningForTest()); |
| 49 |
| 50 // Simulate disabling tracing. |
| 51 controller->OnTraceLogDisabled(); |
| 52 message_loop.RunUntilIdle(); |
| 53 EXPECT_FALSE(controller->IsTimerRunningForTest()); |
| 54 |
| 55 // Deleting the observer removes it from the TraceLog observer list. |
| 56 controller.reset(); |
| 57 EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest()); |
| 58 } |
| 59 |
| 60 TEST_F(TraceMemoryTest, ScopedTraceMemory) { |
| 61 // Start with an empty stack. |
| 62 EXPECT_EQ(0, ScopedTraceMemory::GetStackIndexForTest()); |
| 63 |
| 64 { |
| 65 // Push an item. |
| 66 const char kScope1[] = "scope1"; |
| 67 ScopedTraceMemory scope1(kScope1); |
| 68 EXPECT_EQ(1, ScopedTraceMemory::GetStackIndexForTest()); |
| 69 EXPECT_EQ(kScope1, ScopedTraceMemory::GetItemForTest(0)); |
| 70 |
| 71 { |
| 72 // One more item. |
| 73 const char kScope2[] = "scope2"; |
| 74 ScopedTraceMemory scope2(kScope2); |
| 75 EXPECT_EQ(2, ScopedTraceMemory::GetStackIndexForTest()); |
| 76 EXPECT_EQ(kScope2, ScopedTraceMemory::GetItemForTest(1)); |
| 77 } |
| 78 |
| 79 // Ended scope 2. |
| 80 EXPECT_EQ(1, ScopedTraceMemory::GetStackIndexForTest()); |
| 81 } |
| 82 |
| 83 // Ended scope 1. |
| 84 EXPECT_EQ(0, ScopedTraceMemory::GetStackIndexForTest()); |
| 85 } |
| 86 |
| 87 void TestDeepScopeNesting(int current, int depth) { |
| 88 EXPECT_EQ(current, ScopedTraceMemory::GetStackIndexForTest()); |
| 89 const char kCategory[] = "foo"; |
| 90 ScopedTraceMemory scope(kCategory); |
| 91 if (current < depth) |
| 92 TestDeepScopeNesting(current + 1, depth); |
| 93 EXPECT_EQ(current + 1, ScopedTraceMemory::GetStackIndexForTest()); |
| 94 } |
| 95 |
| 96 TEST_F(TraceMemoryTest, DeepScopeNesting) { |
| 97 // Ensure really deep scopes don't crash. |
| 98 TestDeepScopeNesting(0, 100); |
| 99 } |
| 100 |
| 101 TEST_F(TraceMemoryTest, AppendHeapProfileTotalsAsTraceFormat) { |
| 102 // Empty input gives empty output. |
| 103 std::string empty_output; |
| 104 AppendHeapProfileTotalsAsTraceFormat("", &empty_output); |
| 105 EXPECT_EQ("", empty_output); |
| 106 |
| 107 // Typical case. |
| 108 const char input[] = |
| 109 "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile"; |
| 110 const std::string kExpectedOutput = |
| 111 "{\"current_allocs\": 357, \"current_bytes\": 55227, \"trace\": \"\"}"; |
| 112 std::string output; |
| 113 AppendHeapProfileTotalsAsTraceFormat(input, &output); |
| 114 EXPECT_EQ(kExpectedOutput, output); |
| 115 } |
| 116 |
| 117 TEST_F(TraceMemoryTest, AppendHeapProfileLineAsTraceFormat) { |
| 118 // Empty input gives empty output. |
| 119 std::string empty_output; |
| 120 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("", &empty_output)); |
| 121 EXPECT_EQ("", empty_output); |
| 122 |
| 123 // Invalid input returns false. |
| 124 std::string junk_output; |
| 125 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("junk", &junk_output)); |
| 126 |
| 127 // Input with the addresses of name1 and name2. |
| 128 const char kName1[] = "name1"; |
| 129 const char kName2[] = "name2"; |
| 130 std::ostringstream input; |
| 131 input << " 68: 4195 [ 1087: 98009] @ " << &kName1 << " " << &kName2; |
| 132 const std::string kExpectedOutput = |
| 133 "{" |
| 134 "\"current_allocs\": 68, " |
| 135 "\"current_bytes\": 4195, " |
| 136 "\"trace\": \"name1 name2 \"" |
| 137 "}"; |
| 138 std::string output; |
| 139 EXPECT_TRUE( |
| 140 AppendHeapProfileLineAsTraceFormat(input.str().c_str(), &output)); |
| 141 EXPECT_EQ(kExpectedOutput, output); |
| 142 |
| 143 // Zero current allocations is skipped. |
| 144 std::ostringstream zero_input; |
| 145 zero_input << " 0: 0 [ 1087: 98009] @ " << &kName1 << " " |
| 146 << &kName2; |
| 147 std::string zero_output; |
| 148 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat(zero_input.str().c_str(), |
| 149 &zero_output)); |
| 150 EXPECT_EQ("", zero_output); |
| 151 } |
| 152 |
| 153 TEST_F(TraceMemoryTest, AppendHeapProfileAsTraceFormat) { |
| 154 // Empty input gives empty output. |
| 155 std::string empty_output; |
| 156 AppendHeapProfileAsTraceFormat("", &empty_output); |
| 157 EXPECT_EQ("", empty_output); |
| 158 |
| 159 // Typical case. |
| 160 const char input[] = |
| 161 "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile\n" |
| 162 " 95: 40940 [ 649: 114260] @\n" |
| 163 " 77: 32546 [ 742: 106234] @ 0x0 0x0\n" |
| 164 " 0: 0 [ 132: 4236] @ 0x0\n" |
| 165 "\n" |
| 166 "MAPPED_LIBRARIES:\n" |
| 167 "1be411fc1000-1be4139e4000 rw-p 00000000 00:00 0\n" |
| 168 "1be4139e4000-1be4139e5000 ---p 00000000 00:00 0\n"; |
| 169 const std::string kExpectedOutput = |
| 170 "[{" |
| 171 "\"current_allocs\": 357, " |
| 172 "\"current_bytes\": 55227, " |
| 173 "\"trace\": \"\"},\n" |
| 174 "{\"current_allocs\": 95, " |
| 175 "\"current_bytes\": 40940, " |
| 176 "\"trace\": \"\"},\n" |
| 177 "{\"current_allocs\": 77, " |
| 178 "\"current_bytes\": 32546, " |
| 179 "\"trace\": \"null null \"" |
| 180 "}]\n"; |
| 181 std::string output; |
| 182 AppendHeapProfileAsTraceFormat(input, &output); |
| 183 EXPECT_EQ(kExpectedOutput, output); |
| 184 } |
| 185 |
| 186 } // namespace debug |
| 187 } // namespace base |
OLD | NEW |