blob: 3a6b0c18d83c29c9c9aba263ab2ea9be00b46973 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/resource_coordinator/memory_instrumentation/chrome_graph_processor.h"
#include <iostream>
#include "base/memory/shared_memory_tracker.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/perfetto/include/perfetto/ext/trace_processor/importers/memory_tracker/raw_memory_graph_node.h"
namespace memory_instrumentation {
TEST(ChromeGraphProcessorTest, CreateMemoryGraphWithNoneOperation) {
ChromeGraphProcessor::MemoryDumpMap process_dumps;
base::trace_event::MemoryDumpArgs dump_args = {
.level_of_detail = base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
base::trace_event::ProcessMemoryDump pmd(dump_args);
auto* source = pmd.CreateAllocatorDump("test1/test2/test3");
source->AddScalar(perfetto::trace_processor::RawMemoryGraphNode::kNameSize,
perfetto::trace_processor::RawMemoryGraphNode::kUnitsBytes,
10);
auto* target = pmd.CreateAllocatorDump("target");
pmd.AddOwnershipEdge(source->guid(), target->guid(), 10);
auto* weak = pmd.CreateWeakSharedGlobalAllocatorDump(
base::trace_event::MemoryAllocatorDumpGuid(1));
process_dumps.emplace(1, &pmd);
auto global_node = ChromeGraphProcessor::CreateMemoryGraph(
process_dumps, ChromeGraphProcessor::Operations::kNoneOperation);
ASSERT_EQ(1u, global_node->process_node_graphs().size());
auto id_to_dump_it = global_node->process_node_graphs().find(1);
auto* first_child = id_to_dump_it->second->FindNode("test1");
ASSERT_NE(first_child, nullptr);
ASSERT_EQ(first_child->parent(), id_to_dump_it->second->root());
auto* second_child = first_child->GetChild("test2");
ASSERT_NE(second_child, nullptr);
ASSERT_EQ(second_child->parent(), first_child);
auto* third_child = second_child->GetChild("test3");
ASSERT_NE(third_child, nullptr);
ASSERT_EQ(third_child->parent(), second_child);
auto* direct = id_to_dump_it->second->FindNode("test1/test2/test3");
ASSERT_EQ(third_child, direct);
ASSERT_EQ(third_child->entries()->size(), 1ul);
auto size = third_child->entries()->find(
perfetto::trace_processor::RawMemoryGraphNode::kNameSize);
ASSERT_EQ(10ul, size->second.value_uint64);
ASSERT_TRUE(weak->flags() &
perfetto::trace_processor::RawMemoryGraphNode::Flags::kWeak);
auto& edges = global_node->edges();
auto edge_it = edges.begin();
ASSERT_EQ(std::distance(edges.begin(), edges.end()), 1l);
ASSERT_EQ(edge_it->source(), direct);
ASSERT_EQ(edge_it->target(), id_to_dump_it->second->FindNode("target"));
ASSERT_EQ(edge_it->priority(), 10);
}
TEST(ChromeGraphProcessorTest, CreateMemoryGraphWithAllOperations) {
ChromeGraphProcessor::MemoryDumpMap process_dumps;
base::trace_event::MemoryDumpArgs dump_args = {
.level_of_detail = base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
base::trace_event::ProcessMemoryDump pmd(dump_args);
auto* source = pmd.CreateAllocatorDump("test1/test2/test3");
source->AddScalar(perfetto::trace_processor::RawMemoryGraphNode::kNameSize,
perfetto::trace_processor::RawMemoryGraphNode::kUnitsBytes,
10);
auto* target = pmd.CreateAllocatorDump("target");
pmd.AddOwnershipEdge(source->guid(), target->guid(), 10);
auto* weak = pmd.CreateWeakSharedGlobalAllocatorDump(
base::trace_event::MemoryAllocatorDumpGuid(1));
process_dumps.emplace(1, &pmd);
std::map<base::ProcessId, uint64_t> shared_footprints;
auto global_node = ChromeGraphProcessor::CreateMemoryGraph(
process_dumps, ChromeGraphProcessor::Operations::kAllOperations,
&shared_footprints);
ASSERT_EQ(1u, global_node->process_node_graphs().size());
auto id_to_dump_it = global_node->process_node_graphs().find(1);
auto* first_child = id_to_dump_it->second->FindNode("test1");
ASSERT_NE(first_child, nullptr);
ASSERT_EQ(first_child->parent(), id_to_dump_it->second->root());
auto* second_child = first_child->GetChild("test2");
ASSERT_NE(second_child, nullptr);
ASSERT_EQ(second_child->parent(), first_child);
auto* third_child = second_child->GetChild("test3");
ASSERT_NE(third_child, nullptr);
ASSERT_EQ(third_child->parent(), second_child);
auto* direct = id_to_dump_it->second->FindNode("test1/test2/test3");
ASSERT_EQ(third_child, direct);
ASSERT_EQ(third_child->entries()->size(), 2ul);
auto size = third_child->entries()->find(
perfetto::trace_processor::RawMemoryGraphNode::kNameSize);
ASSERT_EQ(10ul, size->second.value_uint64);
ASSERT_TRUE(weak->flags() &
perfetto::trace_processor::RawMemoryGraphNode::Flags::kWeak);
auto& edges = global_node->edges();
auto edge_it = edges.begin();
ASSERT_EQ(std::distance(edges.begin(), edges.end()), 1l);
ASSERT_EQ(edge_it->source(), direct);
ASSERT_EQ(edge_it->target(), id_to_dump_it->second->FindNode("target"));
ASSERT_EQ(edge_it->priority(), 10);
}
} // namespace memory_instrumentation