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
3 // found in the LICENSE file.
5 #include "content/child/web_process_memory_dump_impl.h"
7 #include "base/trace_event/memory_allocator_dump.h"
8 #include "base/trace_event/process_memory_dump.h"
9 #include "base/trace_event/trace_event_argument.h"
10 #include "base/values.h"
11 #include "content/child/web_memory_allocator_dump_impl.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 // Tests that the Chromium<>Blink plumbing that exposes the MemoryInfra classes
17 // behaves correctly, performs the right transfers of memory ownerships and
18 // doesn't leak objects.
19 TEST(WebProcessMemoryDumpImplTest
, IntegrationTest
) {
20 scoped_refptr
<base::trace_event::TracedValue
> traced_value(
21 new base::trace_event::TracedValue());
23 scoped_ptr
<WebProcessMemoryDumpImpl
> pmd1(new WebProcessMemoryDumpImpl());
24 pmd1
->createMemoryAllocatorDump("pmd1/1");
25 pmd1
->createMemoryAllocatorDump("pmd1/2");
27 scoped_ptr
<WebProcessMemoryDumpImpl
> pmd2(new WebProcessMemoryDumpImpl());
28 pmd2
->createMemoryAllocatorDump("pmd2/1");
29 pmd2
->createMemoryAllocatorDump("pmd2/2");
31 pmd1
->takeAllDumpsFrom(pmd2
.get());
33 // Make sure that pmd2 still owns its own PMD, even if empty.
34 ASSERT_NE(static_cast<base::trace_event::ProcessMemoryDump
*>(nullptr),
35 pmd2
->process_memory_dump_
);
36 ASSERT_EQ(pmd2
->owned_process_memory_dump_
.get(),
37 pmd2
->process_memory_dump());
38 ASSERT_TRUE(pmd2
->process_memory_dump()->allocator_dumps().empty());
40 // Make sure that pmd2 is still usable after it has been emptied.
41 auto wmad
= pmd2
->createMemoryAllocatorDump("pmd2/new");
42 wmad
->AddScalar("attr_name", "bytes", 42);
43 ASSERT_EQ(1u, pmd2
->process_memory_dump()->allocator_dumps().size());
44 auto mad
= pmd2
->process_memory_dump()->GetAllocatorDump("pmd2/new");
45 ASSERT_NE(static_cast<base::trace_event::MemoryAllocatorDump
*>(nullptr), mad
);
46 const char* attr_type
= nullptr;
47 const char* attr_units
= nullptr;
48 const base::Value
* attr_value
= nullptr;
49 bool has_attr
= mad
->Get("attr_name", &attr_type
, &attr_units
, &attr_value
);
50 ASSERT_TRUE(has_attr
);
51 ASSERT_STREQ(base::trace_event::MemoryAllocatorDump::kTypeScalar
, attr_type
);
52 ASSERT_STREQ("bytes", attr_units
);
53 ASSERT_NE(static_cast<base::Value
*>(nullptr), attr_value
);
55 // Check that AsValueInto() doesn't cause a crash.
56 pmd2
->process_memory_dump()->AsValueInto(traced_value
.get());
58 // Free the |pmd2| to check that the memory ownership of the two MAD(s)
59 // has been transferred to |pmd1|.
62 // Now check that |pmd1| has been effectively merged.
63 ASSERT_EQ(4u, pmd1
->process_memory_dump()->allocator_dumps().size());
64 ASSERT_EQ(1u, pmd1
->process_memory_dump()->allocator_dumps().count("pmd1/1"));
65 ASSERT_EQ(1u, pmd1
->process_memory_dump()->allocator_dumps().count("pmd1/2"));
66 ASSERT_EQ(1u, pmd1
->process_memory_dump()->allocator_dumps().count("pmd2/1"));
67 ASSERT_EQ(1u, pmd1
->process_memory_dump()->allocator_dumps().count("pmd1/2"));
69 // Check that AsValueInto() doesn't cause a crash.
70 traced_value
= new base::trace_event::TracedValue();
71 pmd1
->process_memory_dump()->AsValueInto(traced_value
.get());
73 // Check that clear() actually works.
75 ASSERT_TRUE(pmd1
->process_memory_dump()->allocator_dumps().empty());
76 ASSERT_EQ(nullptr, pmd1
->process_memory_dump()->GetAllocatorDump("pmd1/1"));
77 ASSERT_EQ(nullptr, pmd1
->process_memory_dump()->GetAllocatorDump("pmd2/1"));
79 // Check that AsValueInto() doesn't cause a crash.
80 traced_value
= new base::trace_event::TracedValue();
81 pmd1
->process_memory_dump()->AsValueInto(traced_value
.get());
86 } // namespace content