| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/trace_event/memory_allocator_dump.h" | 5 #include "base/trace_event/memory_allocator_dump.h" |
| 6 | 6 |
| 7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
| 8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
| 9 #include "base/trace_event/memory_allocator_dump_guid.h" | 9 #include "base/trace_event/memory_allocator_dump_guid.h" |
| 10 #include "base/trace_event/memory_dump_provider.h" | 10 #include "base/trace_event/memory_dump_provider.h" |
| 11 #include "base/trace_event/memory_dump_session_state.h" | 11 #include "base/trace_event/memory_dump_session_state.h" |
| 12 #include "base/trace_event/process_memory_dump.h" | 12 #include "base/trace_event/process_memory_dump.h" |
| 13 #include "base/trace_event/trace_event_argument.h" | 13 #include "base/trace_event/trace_event_argument.h" |
| 14 #include "base/values.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 16 |
| 16 namespace base { | 17 namespace base { |
| 17 namespace trace_event { | 18 namespace trace_event { |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 class FakeMemoryAllocatorDumpProvider : public MemoryDumpProvider { | 22 class FakeMemoryAllocatorDumpProvider : public MemoryDumpProvider { |
| 22 public: | 23 public: |
| 23 bool OnMemoryDump(ProcessMemoryDump* pmd) override { | 24 bool OnMemoryDump(ProcessMemoryDump* pmd) override { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 40 MemoryAllocatorDump::kUnitsObjects, 3); | 41 MemoryAllocatorDump::kUnitsObjects, 3); |
| 41 | 42 |
| 42 pmd->CreateAllocatorDump("foobar_allocator/sub_heap/empty"); | 43 pmd->CreateAllocatorDump("foobar_allocator/sub_heap/empty"); |
| 43 // Leave the rest of sub heap deliberately uninitialized, to check that | 44 // Leave the rest of sub heap deliberately uninitialized, to check that |
| 44 // CreateAllocatorDump returns a properly zero-initialized object. | 45 // CreateAllocatorDump returns a properly zero-initialized object. |
| 45 | 46 |
| 46 return true; | 47 return true; |
| 47 } | 48 } |
| 48 }; | 49 }; |
| 49 | 50 |
| 50 bool CheckAttribute(const MemoryAllocatorDump* dump, | 51 scoped_ptr<Value> CheckAttribute(const MemoryAllocatorDump* dump, |
| 51 const std::string& name, | 52 const std::string& name, |
| 52 const char* expected_type, | 53 const char* expected_type, |
| 53 const char* expected_units, | 54 const char* expected_units) { |
| 54 const Value** out_value) { | 55 scoped_ptr<Value> raw_attrs = dump->attributes_for_testing()->ToBaseValue(); |
| 55 const char* attr_type; | 56 DictionaryValue* args = nullptr; |
| 56 const char* attr_units; | 57 DictionaryValue* arg = nullptr; |
| 57 bool res = dump->Get(name, &attr_type, &attr_units, out_value); | 58 std::string arg_value; |
| 58 EXPECT_TRUE(res); | 59 const Value* out_value = nullptr; |
| 59 if (!res) | 60 EXPECT_TRUE(raw_attrs->GetAsDictionary(&args)); |
| 60 return false; | 61 EXPECT_TRUE(args->GetDictionary(name, &arg)); |
| 61 EXPECT_EQ(expected_type, std::string(attr_type)); | 62 EXPECT_TRUE(arg->GetString("type", &arg_value)); |
| 62 EXPECT_EQ(expected_units, std::string(attr_units)); | 63 EXPECT_EQ(expected_type, arg_value); |
| 63 return true; | 64 EXPECT_TRUE(arg->GetString("units", &arg_value)); |
| 65 EXPECT_EQ(expected_units, arg_value); |
| 66 EXPECT_TRUE(arg->Get("value", &out_value)); |
| 67 return out_value ? out_value->CreateDeepCopy() : scoped_ptr<Value>(); |
| 64 } | 68 } |
| 65 | 69 |
| 66 void CheckString(const MemoryAllocatorDump* dump, | 70 void CheckString(const MemoryAllocatorDump* dump, |
| 67 const std::string& name, | 71 const std::string& name, |
| 68 const char* expected_type, | 72 const char* expected_type, |
| 69 const char* expected_units, | 73 const char* expected_units, |
| 70 const std::string& expected_value) { | 74 const std::string& expected_value) { |
| 71 const Value* attr_value = nullptr; | |
| 72 std::string attr_str_value; | 75 std::string attr_str_value; |
| 73 bool res = | 76 auto attr_value = CheckAttribute(dump, name, expected_type, expected_units); |
| 74 CheckAttribute(dump, name, expected_type, expected_units, &attr_value); | |
| 75 if (!res) | |
| 76 return; | |
| 77 EXPECT_TRUE(attr_value->GetAsString(&attr_str_value)); | 77 EXPECT_TRUE(attr_value->GetAsString(&attr_str_value)); |
| 78 EXPECT_EQ(expected_value, attr_str_value); | 78 EXPECT_EQ(expected_value, attr_str_value); |
| 79 } | 79 } |
| 80 | 80 |
| 81 void CheckScalar(const MemoryAllocatorDump* dump, | 81 void CheckScalar(const MemoryAllocatorDump* dump, |
| 82 const std::string& name, | 82 const std::string& name, |
| 83 const char* expected_units, | 83 const char* expected_units, |
| 84 uint64 expected_value) { | 84 uint64 expected_value) { |
| 85 CheckString(dump, name, MemoryAllocatorDump::kTypeScalar, expected_units, | 85 CheckString(dump, name, MemoryAllocatorDump::kTypeScalar, expected_units, |
| 86 StringPrintf("%" PRIx64, expected_value)); | 86 StringPrintf("%" PRIx64, expected_value)); |
| 87 } | 87 } |
| 88 | 88 |
| 89 void CheckScalarF(const MemoryAllocatorDump* dump, | 89 void CheckScalarF(const MemoryAllocatorDump* dump, |
| 90 const std::string& name, | 90 const std::string& name, |
| 91 const char* expected_units, | 91 const char* expected_units, |
| 92 double expected_value) { | 92 double expected_value) { |
| 93 const Value* attr_value = nullptr; | 93 auto attr_value = CheckAttribute(dump, name, MemoryAllocatorDump::kTypeScalar, |
| 94 expected_units); |
| 94 double attr_double_value; | 95 double attr_double_value; |
| 95 bool res = CheckAttribute(dump, name, MemoryAllocatorDump::kTypeScalar, | |
| 96 expected_units, &attr_value); | |
| 97 if (!res) | |
| 98 return; | |
| 99 EXPECT_TRUE(attr_value->GetAsDouble(&attr_double_value)); | 96 EXPECT_TRUE(attr_value->GetAsDouble(&attr_double_value)); |
| 100 EXPECT_EQ(expected_value, attr_double_value); | 97 EXPECT_EQ(expected_value, attr_double_value); |
| 101 } | 98 } |
| 102 | 99 |
| 103 } // namespace | 100 } // namespace |
| 104 | 101 |
| 105 TEST(MemoryAllocatorDumpTest, GuidGeneration) { | 102 TEST(MemoryAllocatorDumpTest, GuidGeneration) { |
| 106 scoped_ptr<MemoryAllocatorDump> mad( | 103 scoped_ptr<MemoryAllocatorDump> mad( |
| 107 new MemoryAllocatorDump("foo", nullptr, MemoryAllocatorDumpGuid(0x42u))); | 104 new MemoryAllocatorDump("foo", nullptr, MemoryAllocatorDumpGuid(0x42u))); |
| 108 ASSERT_EQ("42", mad->guid().ToString()); | 105 ASSERT_EQ("42", mad->guid().ToString()); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 CheckScalarF(root_heap, "attr3", "units3", 42.5f); | 144 CheckScalarF(root_heap, "attr3", "units3", 42.5f); |
| 148 | 145 |
| 149 const MemoryAllocatorDump* sub_heap = | 146 const MemoryAllocatorDump* sub_heap = |
| 150 pmd.GetAllocatorDump("foobar_allocator/sub_heap"); | 147 pmd.GetAllocatorDump("foobar_allocator/sub_heap"); |
| 151 ASSERT_NE(nullptr, sub_heap); | 148 ASSERT_NE(nullptr, sub_heap); |
| 152 EXPECT_EQ("foobar_allocator/sub_heap", sub_heap->absolute_name()); | 149 EXPECT_EQ("foobar_allocator/sub_heap", sub_heap->absolute_name()); |
| 153 CheckScalar(sub_heap, MemoryAllocatorDump::kNameSize, | 150 CheckScalar(sub_heap, MemoryAllocatorDump::kNameSize, |
| 154 MemoryAllocatorDump::kUnitsBytes, 1); | 151 MemoryAllocatorDump::kUnitsBytes, 1); |
| 155 CheckScalar(sub_heap, MemoryAllocatorDump::kNameObjectsCount, | 152 CheckScalar(sub_heap, MemoryAllocatorDump::kNameObjectsCount, |
| 156 MemoryAllocatorDump::kUnitsObjects, 3); | 153 MemoryAllocatorDump::kUnitsObjects, 3); |
| 157 | |
| 158 const MemoryAllocatorDump* empty_sub_heap = | 154 const MemoryAllocatorDump* empty_sub_heap = |
| 159 pmd.GetAllocatorDump("foobar_allocator/sub_heap/empty"); | 155 pmd.GetAllocatorDump("foobar_allocator/sub_heap/empty"); |
| 160 ASSERT_NE(nullptr, empty_sub_heap); | 156 ASSERT_NE(nullptr, empty_sub_heap); |
| 161 EXPECT_EQ("foobar_allocator/sub_heap/empty", empty_sub_heap->absolute_name()); | 157 EXPECT_EQ("foobar_allocator/sub_heap/empty", empty_sub_heap->absolute_name()); |
| 162 ASSERT_FALSE(empty_sub_heap->Get(MemoryAllocatorDump::kNameSize, nullptr, | 158 auto raw_attrs = empty_sub_heap->attributes_for_testing()->ToBaseValue(); |
| 163 nullptr, nullptr)); | 159 DictionaryValue* attrs = nullptr; |
| 164 ASSERT_FALSE(empty_sub_heap->Get(MemoryAllocatorDump::kNameObjectsCount, | 160 ASSERT_TRUE(raw_attrs->GetAsDictionary(&attrs)); |
| 165 nullptr, nullptr, nullptr)); | 161 ASSERT_FALSE(attrs->HasKey(MemoryAllocatorDump::kNameSize)); |
| 162 ASSERT_FALSE(attrs->HasKey(MemoryAllocatorDump::kNameObjectsCount)); |
| 166 | 163 |
| 167 // Check that the AsValueInfo doesn't hit any DCHECK. | 164 // Check that the AsValueInfo doesn't hit any DCHECK. |
| 168 scoped_refptr<TracedValue> traced_value(new TracedValue()); | 165 scoped_refptr<TracedValue> traced_value(new TracedValue()); |
| 169 pmd.AsValueInto(traced_value.get()); | 166 pmd.AsValueInto(traced_value.get()); |
| 170 } | 167 } |
| 171 | 168 |
| 172 // DEATH tests are not supported in Android / iOS. | 169 // DEATH tests are not supported in Android / iOS. |
| 173 #if !defined(NDEBUG) && !defined(OS_ANDROID) && !defined(OS_IOS) | 170 #if !defined(NDEBUG) && !defined(OS_ANDROID) && !defined(OS_IOS) |
| 174 TEST(MemoryAllocatorDumpTest, ForbidDuplicatesDeathTest) { | 171 TEST(MemoryAllocatorDumpTest, ForbidDuplicatesDeathTest) { |
| 175 FakeMemoryAllocatorDumpProvider fmadp; | 172 FakeMemoryAllocatorDumpProvider fmadp; |
| 176 ProcessMemoryDump pmd(make_scoped_refptr(new MemoryDumpSessionState())); | 173 ProcessMemoryDump pmd(make_scoped_refptr(new MemoryDumpSessionState())); |
| 177 pmd.CreateAllocatorDump("foo_allocator"); | 174 pmd.CreateAllocatorDump("foo_allocator"); |
| 178 pmd.CreateAllocatorDump("bar_allocator/heap"); | 175 pmd.CreateAllocatorDump("bar_allocator/heap"); |
| 179 ASSERT_DEATH(pmd.CreateAllocatorDump("foo_allocator"), ""); | 176 ASSERT_DEATH(pmd.CreateAllocatorDump("foo_allocator"), ""); |
| 180 ASSERT_DEATH(pmd.CreateAllocatorDump("bar_allocator/heap"), ""); | 177 ASSERT_DEATH(pmd.CreateAllocatorDump("bar_allocator/heap"), ""); |
| 181 ASSERT_DEATH(pmd.CreateAllocatorDump(""), ""); | 178 ASSERT_DEATH(pmd.CreateAllocatorDump(""), ""); |
| 182 } | 179 } |
| 183 #endif | 180 #endif |
| 184 | 181 |
| 185 } // namespace trace_event | 182 } // namespace trace_event |
| 186 } // namespace base | 183 } // namespace base |
| OLD | NEW |