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 ScopedTraceMemory::InitForTest(); |
| 62 |
| 63 // Start with an empty stack. |
| 64 EXPECT_EQ(0, ScopedTraceMemory::GetStackIndexForTest()); |
| 65 |
| 66 { |
| 67 // Push an item. |
| 68 const char kScope1[] = "scope1"; |
| 69 ScopedTraceMemory scope1(kScope1); |
| 70 EXPECT_EQ(1, ScopedTraceMemory::GetStackIndexForTest()); |
| 71 EXPECT_EQ(kScope1, ScopedTraceMemory::GetItemForTest(0)); |
| 72 |
| 73 { |
| 74 // One more item. |
| 75 const char kScope2[] = "scope2"; |
| 76 ScopedTraceMemory scope2(kScope2); |
| 77 EXPECT_EQ(2, ScopedTraceMemory::GetStackIndexForTest()); |
| 78 EXPECT_EQ(kScope2, ScopedTraceMemory::GetItemForTest(1)); |
| 79 } |
| 80 |
| 81 // Ended scope 2. |
| 82 EXPECT_EQ(1, ScopedTraceMemory::GetStackIndexForTest()); |
| 83 } |
| 84 |
| 85 // Ended scope 1. |
| 86 EXPECT_EQ(0, ScopedTraceMemory::GetStackIndexForTest()); |
| 87 |
| 88 ScopedTraceMemory::CleanupForTest(); |
| 89 } |
| 90 |
| 91 void TestDeepScopeNesting(int current, int depth) { |
| 92 EXPECT_EQ(current, ScopedTraceMemory::GetStackIndexForTest()); |
| 93 const char kCategory[] = "foo"; |
| 94 ScopedTraceMemory scope(kCategory); |
| 95 if (current < depth) |
| 96 TestDeepScopeNesting(current + 1, depth); |
| 97 EXPECT_EQ(current + 1, ScopedTraceMemory::GetStackIndexForTest()); |
| 98 } |
| 99 |
| 100 TEST_F(TraceMemoryTest, DeepScopeNesting) { |
| 101 ScopedTraceMemory::InitForTest(); |
| 102 |
| 103 // Ensure really deep scopes don't crash. |
| 104 TestDeepScopeNesting(0, 100); |
| 105 |
| 106 ScopedTraceMemory::CleanupForTest(); |
| 107 } |
| 108 |
| 109 TEST_F(TraceMemoryTest, AppendHeapProfileTotalsAsTraceFormat) { |
| 110 // Empty input gives empty output. |
| 111 std::string empty_output; |
| 112 AppendHeapProfileTotalsAsTraceFormat("", &empty_output); |
| 113 EXPECT_EQ("", empty_output); |
| 114 |
| 115 // Typical case. |
| 116 const char input[] = |
| 117 "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile"; |
| 118 const std::string kExpectedOutput = |
| 119 "{\"current_allocs\": 357, \"current_bytes\": 55227, \"trace\": \"\"}"; |
| 120 std::string output; |
| 121 AppendHeapProfileTotalsAsTraceFormat(input, &output); |
| 122 EXPECT_EQ(kExpectedOutput, output); |
| 123 } |
| 124 |
| 125 TEST_F(TraceMemoryTest, AppendHeapProfileLineAsTraceFormat) { |
| 126 // Empty input gives empty output. |
| 127 std::string empty_output; |
| 128 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("", &empty_output)); |
| 129 EXPECT_EQ("", empty_output); |
| 130 |
| 131 // Invalid input returns false. |
| 132 std::string junk_output; |
| 133 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("junk", &junk_output)); |
| 134 |
| 135 // Input with the addresses of name1 and name2. |
| 136 const char kName1[] = "name1"; |
| 137 const char kName2[] = "name2"; |
| 138 std::ostringstream input; |
| 139 input << " 68: 4195 [ 1087: 98009] @ " << &kName1 << " " << &kName2; |
| 140 const std::string kExpectedOutput = |
| 141 "{" |
| 142 "\"current_allocs\": 68, " |
| 143 "\"current_bytes\": 4195, " |
| 144 "\"trace\": \"name1 name2 \"" |
| 145 "}"; |
| 146 std::string output; |
| 147 EXPECT_TRUE( |
| 148 AppendHeapProfileLineAsTraceFormat(input.str().c_str(), &output)); |
| 149 EXPECT_EQ(kExpectedOutput, output); |
| 150 |
| 151 // Zero current allocations is skipped. |
| 152 std::ostringstream zero_input; |
| 153 zero_input << " 0: 0 [ 1087: 98009] @ " << &kName1 << " " |
| 154 << &kName2; |
| 155 std::string zero_output; |
| 156 EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat(zero_input.str().c_str(), |
| 157 &zero_output)); |
| 158 EXPECT_EQ("", zero_output); |
| 159 } |
| 160 |
| 161 TEST_F(TraceMemoryTest, AppendHeapProfileAsTraceFormat) { |
| 162 // Empty input gives empty output. |
| 163 std::string empty_output; |
| 164 AppendHeapProfileAsTraceFormat("", &empty_output); |
| 165 EXPECT_EQ("", empty_output); |
| 166 |
| 167 // Typical case. |
| 168 const char input[] = |
| 169 "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile\n" |
| 170 " 95: 40940 [ 649: 114260] @\n" |
| 171 " 77: 32546 [ 742: 106234] @ 0x0 0x0\n" |
| 172 " 0: 0 [ 132: 4236] @ 0x0\n" |
| 173 "\n" |
| 174 "MAPPED_LIBRARIES:\n" |
| 175 "1be411fc1000-1be4139e4000 rw-p 00000000 00:00 0\n" |
| 176 "1be4139e4000-1be4139e5000 ---p 00000000 00:00 0\n"; |
| 177 const std::string kExpectedOutput = |
| 178 "[{" |
| 179 "\"current_allocs\": 357, " |
| 180 "\"current_bytes\": 55227, " |
| 181 "\"trace\": \"\"},\n" |
| 182 "{\"current_allocs\": 95, " |
| 183 "\"current_bytes\": 40940, " |
| 184 "\"trace\": \"\"},\n" |
| 185 "{\"current_allocs\": 77, " |
| 186 "\"current_bytes\": 32546, " |
| 187 "\"trace\": \"null null \"" |
| 188 "}]\n"; |
| 189 std::string output; |
| 190 AppendHeapProfileAsTraceFormat(input, &output); |
| 191 EXPECT_EQ(kExpectedOutput, output); |
| 192 } |
| 193 |
| 194 } // namespace debug |
| 195 } // namespace base |
OLD | NEW |