1bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// found in the LICENSE file. 4bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 5bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/debug/trace_event_memory.h" 6bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 7bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include <sstream> 8bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include <string> 9bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 10bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/debug/trace_event_impl.h" 11bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/message_loop/message_loop.h" 12bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "testing/gtest/include/gtest/gtest.h" 13bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 14bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED) 15bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h" 16bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#endif 17bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 18bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochnamespace base { 19bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochnamespace debug { 20bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 21bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// Tests for the trace event memory tracking system. Exists as a class so it 22bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch// can be a friend of TraceMemoryController. 23bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochclass TraceMemoryTest : public testing::Test { 24bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch public: 25bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch TraceMemoryTest() {} 26bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch virtual ~TraceMemoryTest() {} 27bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 28bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch private: 29bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch DISALLOW_COPY_AND_ASSIGN(TraceMemoryTest); 30bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}; 31bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 32bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch////////////////////////////////////////////////////////////////////////////// 33bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 34bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED) 35bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 36bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(TraceMemoryTest, TraceMemoryController) { 37bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MessageLoop message_loop; 38bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 39bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Start with no observers of the TraceLog. 40bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest()); 41bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 42bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Creating a controller adds it to the TraceLog observer list. 43bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch scoped_ptr<TraceMemoryController> controller( 44bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch new TraceMemoryController( 45bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop.message_loop_proxy(), 46bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ::HeapProfilerWithPseudoStackStart, 47bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ::HeapProfilerStop, 48bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ::GetHeapProfile)); 49bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(1u, TraceLog::GetInstance()->GetObserverCountForTest()); 50bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE( 51bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch TraceLog::GetInstance()->HasEnabledStateObserver(controller.get())); 52bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 53bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // By default the observer isn't dumping memory profiles. 54bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_FALSE(controller->IsTimerRunningForTest()); 55bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 56bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Simulate enabling tracing. 57bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch controller->StartProfiling(); 58bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop.RunUntilIdle(); 59bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE(controller->IsTimerRunningForTest()); 60bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 61bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Simulate disabling tracing. 62bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch controller->StopProfiling(); 63bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch message_loop.RunUntilIdle(); 64bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_FALSE(controller->IsTimerRunningForTest()); 65bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 66bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Deleting the observer removes it from the TraceLog observer list. 67bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch controller.reset(); 68bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest()); 69bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 70bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 71bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(TraceMemoryTest, ScopedTraceMemory) { 72bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ScopedTraceMemory::InitForTest(); 73bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 74bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Start with an empty stack. 75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(0, ScopedTraceMemory::GetStackDepthForTest()); 76bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 77bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch { 78bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Push an item. 79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ScopedTraceMemory scope1("cat1", "name1"); 80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(1, ScopedTraceMemory::GetStackDepthForTest()); 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ("cat1", ScopedTraceMemory::GetScopeDataForTest(0).category); 82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ("name1", ScopedTraceMemory::GetScopeDataForTest(0).name); 83bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 84bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch { 85bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // One more item. 86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ScopedTraceMemory scope2("cat2", "name2"); 87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(2, ScopedTraceMemory::GetStackDepthForTest()); 88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ("cat2", ScopedTraceMemory::GetScopeDataForTest(1).category); 89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ("name2", ScopedTraceMemory::GetScopeDataForTest(1).name); 90bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 91bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 92bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Ended scope 2. 93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(1, ScopedTraceMemory::GetStackDepthForTest()); 94bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch } 95bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 96bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Ended scope 1. 97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(0, ScopedTraceMemory::GetStackDepthForTest()); 98bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 99bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ScopedTraceMemory::CleanupForTest(); 100bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 101bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 102bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid TestDeepScopeNesting(int current, int depth) { 103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(current, ScopedTraceMemory::GetStackDepthForTest()); 104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ScopedTraceMemory scope("category", "name"); 105bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch if (current < depth) 106bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch TestDeepScopeNesting(current + 1, depth); 107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(current + 1, ScopedTraceMemory::GetStackDepthForTest()); 108bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 109bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 110bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(TraceMemoryTest, DeepScopeNesting) { 111bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ScopedTraceMemory::InitForTest(); 112bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 113bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Ensure really deep scopes don't crash. 114bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch TestDeepScopeNesting(0, 100); 115bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 116bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ScopedTraceMemory::CleanupForTest(); 117bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 118bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 119bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#endif // defined(TRACE_MEMORY_SUPPORTED) 120bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 121bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch///////////////////////////////////////////////////////////////////////////// 122bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 123bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(TraceMemoryTest, AppendHeapProfileTotalsAsTraceFormat) { 124bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Empty input gives empty output. 125bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::string empty_output; 126bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch AppendHeapProfileTotalsAsTraceFormat("", &empty_output); 127bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ("", empty_output); 128bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 129bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Typical case. 130bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const char input[] = 131bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile"; 132bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const std::string kExpectedOutput = 133bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "{\"current_allocs\": 357, \"current_bytes\": 55227, \"trace\": \"\"}"; 134bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::string output; 135bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch AppendHeapProfileTotalsAsTraceFormat(input, &output); 136bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(kExpectedOutput, output); 137bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 138bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 139bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(TraceMemoryTest, AppendHeapProfileLineAsTraceFormat) { 140bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Empty input gives empty output. 141bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::string empty_output; 142bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("", &empty_output)); 143bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ("", empty_output); 144bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 145bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Invalid input returns false. 146bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::string junk_output; 147bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("junk", &junk_output)); 148bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Input with normal category and name entries. 150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char kCategory[] = "category"; 151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char kName[] = "name"; 152bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::ostringstream input; 153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) input << " 68: 4195 [ 1087: 98009] @ " << &kCategory << " " 154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) << &kName; 155bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const std::string kExpectedOutput = 156bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ",\n" 157bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "{" 158bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "\"current_allocs\": 68, " 159bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "\"current_bytes\": 4195, " 160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "\"trace\": \"name \"" 161bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "}"; 162bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::string output; 163bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_TRUE( 164bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch AppendHeapProfileLineAsTraceFormat(input.str().c_str(), &output)); 165bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(kExpectedOutput, output); 166bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Input with with the category "toplevel". 168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(jamescook): Eliminate this special case and move the logic to the 169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // trace viewer code. 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char kTaskCategory[] = "toplevel"; 171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char kTaskName[] = "TaskName"; 172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::ostringstream input2; 173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) input2 << " 68: 4195 [ 1087: 98009] @ " << &kTaskCategory << " " 174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) << &kTaskName; 175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string kExpectedOutput2 = 176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ",\n" 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "{" 178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "\"current_allocs\": 68, " 179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "\"current_bytes\": 4195, " 180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "\"trace\": \"TaskName->PostTask \"" 181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "}"; 182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string output2; 183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_TRUE( 184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) AppendHeapProfileLineAsTraceFormat(input2.str().c_str(), &output2)); 185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(kExpectedOutput2, output2); 186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 187bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Zero current allocations is skipped. 188bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::ostringstream zero_input; 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) zero_input << " 0: 0 [ 1087: 98009] @ " << &kCategory << " " 190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) << &kName; 191bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::string zero_output; 192bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat(zero_input.str().c_str(), 193bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch &zero_output)); 194bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ("", zero_output); 195bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 196bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 197bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(TraceMemoryTest, AppendHeapProfileAsTraceFormat) { 198bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Empty input gives empty output. 199bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::string empty_output; 200bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch AppendHeapProfileAsTraceFormat("", &empty_output); 201bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ("", empty_output); 202bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 203bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // Typical case. 204bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const char input[] = 205bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile\n" 206bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch " 95: 40940 [ 649: 114260] @\n" 207bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch " 77: 32546 [ 742: 106234] @ 0x0 0x0\n" 208bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch " 0: 0 [ 132: 4236] @ 0x0\n" 209bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "\n" 210bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "MAPPED_LIBRARIES:\n" 211bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "1be411fc1000-1be4139e4000 rw-p 00000000 00:00 0\n" 212bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "1be4139e4000-1be4139e5000 ---p 00000000 00:00 0\n"; 213bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch const std::string kExpectedOutput = 214bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "[{" 215bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "\"current_allocs\": 357, " 216bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "\"current_bytes\": 55227, " 217bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "\"trace\": \"\"},\n" 218bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "{\"current_allocs\": 95, " 219bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "\"current_bytes\": 40940, " 220bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "\"trace\": \"\"},\n" 221bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "{\"current_allocs\": 77, " 222bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "\"current_bytes\": 32546, " 223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "\"trace\": \"null \"" 224bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch "}]\n"; 225bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::string output; 226bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch AppendHeapProfileAsTraceFormat(input, &output); 227bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch EXPECT_EQ(kExpectedOutput, output); 228bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 229bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(TraceMemoryTest, StringFromHexAddress) { 231424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_STREQ("null", StringFromHexAddress("0x0")); 232424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_STREQ("error", StringFromHexAddress("not an address")); 233424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char kHello[] = "hello"; 234424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::ostringstream hex_address; 235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) hex_address << &kHello; 236424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_STREQ(kHello, StringFromHexAddress(hex_address.str())); 237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 239bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} // namespace debug 240bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} // namespace base 241