// Copyright 2017 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/graph_processor.h"

#include "base/memory/shared_memory_tracker.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace memory_instrumentation {

using base::ProcessId;
using base::trace_event::MemoryAllocatorDump;
using base::trace_event::MemoryAllocatorDumpGuid;
using base::trace_event::MemoryDumpArgs;
using base::trace_event::MemoryDumpLevelOfDetail;
using base::trace_event::ProcessMemoryDump;
using Edge = GlobalDumpGraph::Edge;
using Node = GlobalDumpGraph::Node;
using Process = GlobalDumpGraph::Process;

namespace {

const MemoryAllocatorDumpGuid kEmptyGuid;

}  // namespace

class GraphProcessorTest : public testing::Test {
 public:
  GraphProcessorTest() {}

  void MarkImplicitWeakParentsRecursively(Node* node) {
    GraphProcessor::MarkImplicitWeakParentsRecursively(node);
  }

  void MarkWeakOwnersAndChildrenRecursively(Node* node) {
    std::set<const Node*> visited;
    GraphProcessor::MarkWeakOwnersAndChildrenRecursively(node, &visited);
  }

  void RemoveWeakNodesRecursively(Node* node) {
    GraphProcessor::RemoveWeakNodesRecursively(node);
  }

  void AssignTracingOverhead(base::StringPiece allocator,
                             GlobalDumpGraph* global_graph,
                             Process* process) {
    GraphProcessor::AssignTracingOverhead(allocator, global_graph, process);
  }

  GlobalDumpGraph::Node::Entry AggregateNumericWithNameForNode(
      Node* node,
      base::StringPiece name) {
    return GraphProcessor::AggregateNumericWithNameForNode(node, name);
  }

  void AggregateNumericsRecursively(Node* node) {
    GraphProcessor::AggregateNumericsRecursively(node);
  }

  void PropagateNumericsAndDiagnosticsRecursively(Node* node) {
    GraphProcessor::PropagateNumericsAndDiagnosticsRecursively(node);
  }

  base::Optional<uint64_t> AggregateSizeForDescendantNode(Node* root,
                                                          Node* descendant) {
    return GraphProcessor::AggregateSizeForDescendantNode(root, descendant);
  }

  void CalculateSizeForNode(Node* node) {
    GraphProcessor::CalculateSizeForNode(node);
  }

  void CalculateDumpSubSizes(Node* node) {
    GraphProcessor::CalculateDumpSubSizes(node);
  }

  void CalculateDumpOwnershipCoefficient(Node* node) {
    GraphProcessor::CalculateDumpOwnershipCoefficient(node);
  }

  void CalculateDumpCumulativeOwnershipCoefficient(Node* node) {
    GraphProcessor::CalculateDumpCumulativeOwnershipCoefficient(node);
  }

  void CalculateDumpEffectiveSize(Node* node) {
    GraphProcessor::CalculateDumpEffectiveSize(node);
  }

 protected:
  GlobalDumpGraph graph;
};

TEST_F(GraphProcessorTest, SmokeComputeMemoryGraph) {
  std::map<ProcessId, const ProcessMemoryDump*> process_dumps;

  MemoryDumpArgs dump_args = {MemoryDumpLevelOfDetail::DETAILED};
  ProcessMemoryDump pmd(dump_args);

  auto* source = pmd.CreateAllocatorDump("test1/test2/test3");
  source->AddScalar(MemoryAllocatorDump::kNameSize,
                    MemoryAllocatorDump::kUnitsBytes, 10);

  auto* target = pmd.CreateAllocatorDump("target");
  pmd.AddOwnershipEdge(source->guid(), target->guid(), 10);

  auto* weak =
      pmd.CreateWeakSharedGlobalAllocatorDump(MemoryAllocatorDumpGuid(1));

  process_dumps.emplace(1, &pmd);

  auto global_dump = GraphProcessor::CreateMemoryGraph(process_dumps);

  ASSERT_EQ(1u, global_dump->process_dump_graphs().size());

  auto id_to_dump_it = global_dump->process_dump_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(MemoryAllocatorDump::kNameSize);
  ASSERT_EQ(10ul, size->second.value_uint64);

  ASSERT_TRUE(weak->flags() & MemoryAllocatorDump::Flags::WEAK);

  auto& edges = global_dump->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_F(GraphProcessorTest, SmokeComputeSharedFootprint) {
  std::map<ProcessId, const ProcessMemoryDump*> process_dumps;

  MemoryDumpArgs dump_args = {MemoryDumpLevelOfDetail::DETAILED};
  ProcessMemoryDump pmd1(dump_args);
  ProcessMemoryDump pmd2(dump_args);

  auto* p1_d1 = pmd1.CreateAllocatorDump("process1/dump1");
  auto* p1_d2 = pmd1.CreateAllocatorDump("process1/dump2");
  auto* p2_d1 = pmd2.CreateAllocatorDump("process2/dump1");

  base::UnguessableToken token = base::UnguessableToken::Create();

  // Done by SharedMemoryTracker.
  size_t size = 256;
  auto global_dump_guid =
      base::SharedMemoryTracker::GetGlobalDumpIdForTracing(token);
  auto local_dump_name =
      base::SharedMemoryTracker::GetDumpNameForTracing(token);

  MemoryAllocatorDump* local_dump_1 =
      pmd1.CreateAllocatorDump(local_dump_name, MemoryAllocatorDumpGuid(1));
  local_dump_1->AddScalar("virtual_size", MemoryAllocatorDump::kUnitsBytes,
                          size);
  local_dump_1->AddScalar(MemoryAllocatorDump::kNameSize,
                          MemoryAllocatorDump::kUnitsBytes, size);

  MemoryAllocatorDump* global_dump_1 =
      pmd1.CreateSharedGlobalAllocatorDump(global_dump_guid);
  global_dump_1->AddScalar(MemoryAllocatorDump::kNameSize,
                           MemoryAllocatorDump::kUnitsBytes, size);

  pmd1.AddOverridableOwnershipEdge(local_dump_1->guid(), global_dump_1->guid(),
                                   0 /* importance */);

  MemoryAllocatorDump* local_dump_2 =
      pmd2.CreateAllocatorDump(local_dump_name, MemoryAllocatorDumpGuid(2));
  local_dump_2->AddScalar("virtual_size", MemoryAllocatorDump::kUnitsBytes,
                          size);
  local_dump_2->AddScalar(MemoryAllocatorDump::kNameSize,
                          MemoryAllocatorDump::kUnitsBytes, size);

  MemoryAllocatorDump* global_dump_2 =
      pmd2.CreateSharedGlobalAllocatorDump(global_dump_guid);
  pmd2.AddOverridableOwnershipEdge(local_dump_2->guid(), global_dump_2->guid(),
                                   0 /* importance */);

  // Done by each consumer of the shared memory.
  pmd1.CreateSharedMemoryOwnershipEdge(p1_d1->guid(), token, 2);
  pmd1.CreateSharedMemoryOwnershipEdge(p1_d2->guid(), token, 1);
  pmd2.CreateSharedMemoryOwnershipEdge(p2_d1->guid(), token, 2);

  process_dumps.emplace(1, &pmd1);
  process_dumps.emplace(2, &pmd2);

  auto graph = GraphProcessor::CreateMemoryGraph(process_dumps);
  auto pid_to_sizes = GraphProcessor::ComputeSharedFootprintFromGraph(*graph);
  ASSERT_EQ(pid_to_sizes[1], 128ul);
  ASSERT_EQ(pid_to_sizes[2], 128ul);
}

TEST_F(GraphProcessorTest, ComputeSharedFootprintFromGraphSameImportance) {
  Process* global_process = graph.shared_memory_graph();
  Node* global_node = global_process->CreateNode(kEmptyGuid, "global/1", false);
  global_node->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 100);

  Process* first = graph.CreateGraphForProcess(1);
  Node* shared_1 = first->CreateNode(kEmptyGuid, "shared_memory/1", false);

  Process* second = graph.CreateGraphForProcess(2);
  Node* shared_2 = second->CreateNode(kEmptyGuid, "shared_memory/2", false);

  graph.AddNodeOwnershipEdge(shared_1, global_node, 1);
  graph.AddNodeOwnershipEdge(shared_2, global_node, 1);

  auto pid_to_sizes = GraphProcessor::ComputeSharedFootprintFromGraph(graph);
  ASSERT_EQ(pid_to_sizes[1], 50ul);
  ASSERT_EQ(pid_to_sizes[2], 50ul);
}

TEST_F(GraphProcessorTest, ComputeSharedFootprintFromGraphSomeDiffImportance) {
  Process* global_process = graph.shared_memory_graph();

  Node* global_node = global_process->CreateNode(kEmptyGuid, "global/1", false);
  global_node->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 100);

  Process* first = graph.CreateGraphForProcess(1);
  Node* shared_1 = first->CreateNode(kEmptyGuid, "shared_memory/1", false);

  Process* second = graph.CreateGraphForProcess(2);
  Node* shared_2 = second->CreateNode(kEmptyGuid, "shared_memory/2", false);

  Process* third = graph.CreateGraphForProcess(3);
  Node* shared_3 = third->CreateNode(kEmptyGuid, "shared_memory/3", false);

  Process* fourth = graph.CreateGraphForProcess(4);
  Node* shared_4 = fourth->CreateNode(kEmptyGuid, "shared_memory/4", false);

  Process* fifth = graph.CreateGraphForProcess(5);
  Node* shared_5 = fifth->CreateNode(kEmptyGuid, "shared_memory/5", false);

  graph.AddNodeOwnershipEdge(shared_1, global_node, 1);
  graph.AddNodeOwnershipEdge(shared_2, global_node, 2);
  graph.AddNodeOwnershipEdge(shared_3, global_node, 3);
  graph.AddNodeOwnershipEdge(shared_4, global_node, 3);
  graph.AddNodeOwnershipEdge(shared_5, global_node, 3);

  auto pid_to_sizes = GraphProcessor::ComputeSharedFootprintFromGraph(graph);
  ASSERT_EQ(pid_to_sizes[1], 0ul);
  ASSERT_EQ(pid_to_sizes[2], 0ul);
  ASSERT_EQ(pid_to_sizes[3], 33ul);
  ASSERT_EQ(pid_to_sizes[4], 33ul);
  ASSERT_EQ(pid_to_sizes[5], 33ul);
}

TEST_F(GraphProcessorTest, MarkWeakParentsSimple) {
  Process* process = graph.CreateGraphForProcess(1);
  Node* parent = process->CreateNode(kEmptyGuid, "parent", false);
  Node* first = process->CreateNode(kEmptyGuid, "parent/first", true);
  Node* second = process->CreateNode(kEmptyGuid, "parent/second", false);

  // Case where one child is not weak.
  parent->set_explicit(false);
  first->set_explicit(true);
  second->set_explicit(true);

  // The function should be a no-op.
  MarkImplicitWeakParentsRecursively(parent);
  ASSERT_FALSE(parent->is_weak());
  ASSERT_TRUE(first->is_weak());
  ASSERT_FALSE(second->is_weak());

  // Case where all children is weak.
  second->set_weak(true);

  // The function should mark parent as weak.
  MarkImplicitWeakParentsRecursively(parent);
  ASSERT_TRUE(parent->is_weak());
  ASSERT_TRUE(first->is_weak());
  ASSERT_TRUE(second->is_weak());
}

TEST_F(GraphProcessorTest, MarkWeakParentsComplex) {
  Process* process = graph.CreateGraphForProcess(1);

  // |first| is explicitly strong but |first_child| is implicitly so.
  Node* parent = process->CreateNode(kEmptyGuid, "parent", false);
  Node* first = process->CreateNode(kEmptyGuid, "parent/f", false);
  Node* first_child = process->CreateNode(kEmptyGuid, "parent/f/c", false);
  Node* first_gchild = process->CreateNode(kEmptyGuid, "parent/f/c/c", true);

  parent->set_explicit(false);
  first->set_explicit(true);
  first_child->set_explicit(false);
  first_gchild->set_explicit(true);

  // That should lead to |first_child| marked implicitly weak.
  MarkImplicitWeakParentsRecursively(parent);
  ASSERT_FALSE(parent->is_weak());
  ASSERT_FALSE(first->is_weak());
  ASSERT_TRUE(first_child->is_weak());
  ASSERT_TRUE(first_gchild->is_weak());

  // Reset and change so that first is now only implicitly strong.
  first->set_explicit(false);
  first_child->set_weak(false);

  // The whole chain should now be weak.
  MarkImplicitWeakParentsRecursively(parent);
  ASSERT_TRUE(parent->is_weak());
  ASSERT_TRUE(first->is_weak());
  ASSERT_TRUE(first_child->is_weak());
  ASSERT_TRUE(first_gchild->is_weak());
}

TEST_F(GraphProcessorTest, MarkWeakOwners) {
  Process* process = graph.CreateGraphForProcess(1);

  // Make only the ultimate owned node weak.
  Node* owner = process->CreateNode(kEmptyGuid, "owner", false);
  Node* owned = process->CreateNode(kEmptyGuid, "owned", false);
  Node* owned_2 = process->CreateNode(kEmptyGuid, "owned2", true);

  graph.AddNodeOwnershipEdge(owner, owned, 0);
  graph.AddNodeOwnershipEdge(owned, owned_2, 0);

  // Starting from leaf node should lead to everything being weak.
  MarkWeakOwnersAndChildrenRecursively(process->root());
  ASSERT_TRUE(owner->is_weak());
  ASSERT_TRUE(owned->is_weak());
  ASSERT_TRUE(owned_2->is_weak());
}

TEST_F(GraphProcessorTest, MarkWeakParent) {
  Process* process = graph.CreateGraphForProcess(1);
  Node* parent = process->CreateNode(kEmptyGuid, "parent", true);
  Node* child = process->CreateNode(kEmptyGuid, "parent/c", false);
  Node* child_2 = process->CreateNode(kEmptyGuid, "parent/c/c", false);

  // Starting from parent node should lead to everything being weak.
  MarkWeakOwnersAndChildrenRecursively(process->root());
  ASSERT_TRUE(parent->is_weak());
  ASSERT_TRUE(child->is_weak());
  ASSERT_TRUE(child_2->is_weak());
}

TEST_F(GraphProcessorTest, MarkWeakParentOwner) {
  Process* process = graph.CreateGraphForProcess(1);

  // Make only the parent node weak.
  Node* parent = process->CreateNode(kEmptyGuid, "parent", true);
  Node* child = process->CreateNode(kEmptyGuid, "parent/c", false);
  Node* child_2 = process->CreateNode(kEmptyGuid, "parent/c/c", false);
  Node* owner = process->CreateNode(kEmptyGuid, "owner", false);

  graph.AddNodeOwnershipEdge(owner, parent, 0);

  // Starting from parent node should lead to everything being weak.
  MarkWeakOwnersAndChildrenRecursively(process->root());
  ASSERT_TRUE(parent->is_weak());
  ASSERT_TRUE(child->is_weak());
  ASSERT_TRUE(child_2->is_weak());
  ASSERT_TRUE(owner->is_weak());
}

TEST_F(GraphProcessorTest, RemoveWeakNodesRecursively) {
  Process* process = graph.CreateGraphForProcess(1);

  // Make only the child node weak.
  Node* parent = process->CreateNode(kEmptyGuid, "parent", false);
  Node* child = process->CreateNode(kEmptyGuid, "parent/c", true);
  process->CreateNode(kEmptyGuid, "parent/c/c", false);
  Node* owned = process->CreateNode(kEmptyGuid, "parent/owned", false);

  graph.AddNodeOwnershipEdge(child, owned, 0);

  // Starting from parent node should lead child and child_2 being
  // removed and owned to have the edge from it removed.
  RemoveWeakNodesRecursively(parent);

  ASSERT_EQ(parent->children()->size(), 1ul);
  ASSERT_EQ(parent->children()->begin()->second, owned);

  ASSERT_TRUE(owned->owned_by_edges()->empty());
}

TEST_F(GraphProcessorTest, RemoveWeakNodesRecursivelyBetweenGraphs) {
  Process* f_process = graph.CreateGraphForProcess(1);
  Process* s_process = graph.CreateGraphForProcess(2);

  // Make only the child node weak.
  Node* child = f_process->CreateNode(kEmptyGuid, "c", true);
  f_process->CreateNode(kEmptyGuid, "c/c", false);
  Node* owned = s_process->CreateNode(kEmptyGuid, "owned", false);

  graph.AddNodeOwnershipEdge(child, owned, 0);

  // Starting from root node should lead child and child_2 being
  // removed.
  RemoveWeakNodesRecursively(f_process->root());

  ASSERT_EQ(f_process->root()->children()->size(), 0ul);
  ASSERT_EQ(s_process->root()->children()->size(), 1ul);

  // This should be false until our next pass.
  ASSERT_FALSE(owned->owned_by_edges()->empty());

  RemoveWeakNodesRecursively(s_process->root());

  // We should now have cleaned up the owned node's edges.
  ASSERT_TRUE(owned->owned_by_edges()->empty());
}

TEST_F(GraphProcessorTest, AssignTracingOverhead) {
  Process* process = graph.CreateGraphForProcess(1);

  // Now add an allocator node.
  process->CreateNode(kEmptyGuid, "malloc", false);

  // If the tracing node does not exist, this should do nothing.
  AssignTracingOverhead("malloc", &graph, process);
  ASSERT_TRUE(process->root()->GetChild("malloc")->children()->empty());

  // Now add a tracing node.
  process->CreateNode(kEmptyGuid, "tracing", false);

  // This should now add a node with the allocator.
  AssignTracingOverhead("malloc", &graph, process);
  ASSERT_NE(process->FindNode("malloc/allocated_objects/tracing_overhead"),
            nullptr);
}

TEST_F(GraphProcessorTest, AggregateNumericWithNameForNode) {
  Process* process = graph.CreateGraphForProcess(1);

  Node* c1 = process->CreateNode(kEmptyGuid, "c1", false);
  Node* c2 = process->CreateNode(kEmptyGuid, "c2", false);
  Node* c3 = process->CreateNode(kEmptyGuid, "c3", false);

  c1->AddEntry("random_numeric", Node::Entry::ScalarUnits::kBytes, 100);
  c2->AddEntry("random_numeric", Node::Entry::ScalarUnits::kBytes, 256);
  c3->AddEntry("other_numeric", Node::Entry::ScalarUnits::kBytes, 1000);

  Node* root = process->root();
  Node::Entry entry = AggregateNumericWithNameForNode(root, "random_numeric");
  ASSERT_EQ(entry.value_uint64, 356ul);
  ASSERT_EQ(entry.units, Node::Entry::ScalarUnits::kBytes);
}

TEST_F(GraphProcessorTest, AggregateNumericsRecursively) {
  Process* process = graph.CreateGraphForProcess(1);

  Node* c1 = process->CreateNode(kEmptyGuid, "c1", false);
  Node* c2 = process->CreateNode(kEmptyGuid, "c2", false);
  Node* c2_c1 = process->CreateNode(kEmptyGuid, "c2/c1", false);
  Node* c2_c2 = process->CreateNode(kEmptyGuid, "c2/c2", false);
  Node* c3_c1 = process->CreateNode(kEmptyGuid, "c3/c1", false);
  Node* c3_c2 = process->CreateNode(kEmptyGuid, "c3/c2", false);

  // If an entry already exists in the parent, the child should not
  // ovewrite it. If nothing exists, then the child can aggregrate.
  c1->AddEntry("random_numeric", Node::Entry::ScalarUnits::kBytes, 100);
  c2->AddEntry("random_numeric", Node::Entry::ScalarUnits::kBytes, 256);
  c2_c1->AddEntry("random_numeric", Node::Entry::ScalarUnits::kBytes, 256);
  c2_c2->AddEntry("random_numeric", Node::Entry::ScalarUnits::kBytes, 256);
  c3_c1->AddEntry("random_numeric", Node::Entry::ScalarUnits::kBytes, 10);
  c3_c2->AddEntry("random_numeric", Node::Entry::ScalarUnits::kBytes, 10);

  Node* root = process->root();
  AggregateNumericsRecursively(root);
  ASSERT_EQ(root->entries()->size(), 1ul);

  auto entry = root->entries()->begin()->second;
  ASSERT_EQ(entry.value_uint64, 376ul);
  ASSERT_EQ(entry.units, Node::Entry::ScalarUnits::kBytes);
}

TEST_F(GraphProcessorTest, AggregateSizeForDescendantNode) {
  Process* process = graph.CreateGraphForProcess(1);

  Node* c1 = process->CreateNode(kEmptyGuid, "c1", false);
  Node* c2 = process->CreateNode(kEmptyGuid, "c2", false);
  Node* c2_c1 = process->CreateNode(kEmptyGuid, "c2/c1", false);
  Node* c2_c2 = process->CreateNode(kEmptyGuid, "c2/c2", false);
  Node* c3_c1 = process->CreateNode(kEmptyGuid, "c3/c1", false);
  Node* c3_c2 = process->CreateNode(kEmptyGuid, "c3/c2", false);

  c1->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 100);
  c2_c1->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 256);
  c2_c2->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 256);
  c3_c1->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 10);
  c3_c2->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 10);

  graph.AddNodeOwnershipEdge(c2_c2, c3_c2, 0);

  // Aggregating root should give size of (100 + 256 + 10 * 2) = 376.
  // |c2_c2| is not counted because it is owns by |c3_c2|.
  Node* root = process->root();
  ASSERT_EQ(376ul, *AggregateSizeForDescendantNode(root, root));

  // Aggregating c2 should give size of (256 * 2) = 512. |c2_c2| is counted
  // because |c3_c2| is not a child of |c2|.
  ASSERT_EQ(512ul, *AggregateSizeForDescendantNode(c2, c2));
}

TEST_F(GraphProcessorTest, CalculateSizeForNode) {
  Process* process = graph.CreateGraphForProcess(1);

  Node* c1 = process->CreateNode(kEmptyGuid, "c1", false);
  Node* c2 = process->CreateNode(kEmptyGuid, "c2", false);
  Node* c2_c1 = process->CreateNode(kEmptyGuid, "c2/c1", false);
  Node* c2_c2 = process->CreateNode(kEmptyGuid, "c2/c2", false);
  Node* c3 = process->CreateNode(kEmptyGuid, "c3", false);
  Node* c3_c1 = process->CreateNode(kEmptyGuid, "c3/c1", false);
  Node* c3_c2 = process->CreateNode(kEmptyGuid, "c3/c2", false);

  c1->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 600);
  c2_c1->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 10);
  c2_c2->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 10);
  c3->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 600);
  c3_c1->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 256);
  c3_c2->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 256);

  graph.AddNodeOwnershipEdge(c2_c2, c3_c2, 0);

  // Compute size entry for |c2| since computations for |c2_c1| and |c2_c2|
  // are already complete.
  CalculateSizeForNode(c2);

  // Check that |c2| now has a size entry of 20 (sum of children).
  auto c2_entry = c2->entries()->begin()->second;
  ASSERT_EQ(c2_entry.value_uint64, 20ul);
  ASSERT_EQ(c2_entry.units, Node::Entry::ScalarUnits::kBytes);

  // Compute size entry for |c3_c2| which should not change in size.
  CalculateSizeForNode(c3_c2);

  // Check that |c3_c2| now has unchanged size.
  auto c3_c2_entry = c3_c2->entries()->begin()->second;
  ASSERT_EQ(c3_c2_entry.value_uint64, 256ul);
  ASSERT_EQ(c3_c2_entry.units, Node::Entry::ScalarUnits::kBytes);

  // Compute size entry for |c3| which should add an unspecified node.
  CalculateSizeForNode(c3);

  // Check that |c3| has unchanged size.
  auto c3_entry = c3->entries()->begin()->second;
  ASSERT_EQ(c3_entry.value_uint64, 600ul);
  ASSERT_EQ(c3_entry.units, Node::Entry::ScalarUnits::kBytes);

  // Check that the unspecified node is a child of |c3| and has size
  // 600 - 512 = 88.
  Node* c3_child = c3->children()->find("<unspecified>")->second;
  auto c3_child_entry = c3_child->entries()->begin()->second;
  ASSERT_EQ(c3_child_entry.value_uint64, 88ul);
  ASSERT_EQ(c3_child_entry.units, Node::Entry::ScalarUnits::kBytes);

  // Compute size entry for |root| which should aggregate children sizes.
  CalculateSizeForNode(process->root());

  // Check that |root| has been assigned a size of 600 + 10 + 600 = 1210.
  // Note that |c2_c2| is not counted because it ows |c3_c2| which is a
  // descendant of |root|.
  auto root_entry = process->root()->entries()->begin()->second;
  ASSERT_EQ(root_entry.value_uint64, 1210ul);
  ASSERT_EQ(root_entry.units, Node::Entry::ScalarUnits::kBytes);
}

TEST_F(GraphProcessorTest, CalculateDumpSubSizes) {
  Process* process_1 = graph.CreateGraphForProcess(1);
  Process* process_2 = graph.CreateGraphForProcess(2);

  Node* parent_1 = process_1->CreateNode(kEmptyGuid, "parent", false);
  Node* child_1 = process_1->CreateNode(kEmptyGuid, "parent/child", false);

  Node* parent_2 = process_2->CreateNode(kEmptyGuid, "parent", false);
  Node* child_2 = process_2->CreateNode(kEmptyGuid, "parent/child", false);

  graph.AddNodeOwnershipEdge(parent_1, parent_2, 0);

  process_1->root()->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 4);
  parent_1->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 4);
  child_1->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 4);
  process_2->root()->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 5);
  parent_2->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 5);
  child_2->AddEntry("size", Node::Entry::ScalarUnits::kBytes, 5);

  // Each of these nodes should have owner/owned same as size itself.
  CalculateDumpSubSizes(child_1);
  ASSERT_EQ(child_1->not_owned_sub_size(), 4ul);
  ASSERT_EQ(child_1->not_owning_sub_size(), 4ul);
  CalculateDumpSubSizes(child_2);
  ASSERT_EQ(child_2->not_owned_sub_size(), 5ul);
  ASSERT_EQ(child_2->not_owning_sub_size(), 5ul);

  // These nodes should also have size of children.
  CalculateDumpSubSizes(parent_1);
  ASSERT_EQ(parent_1->not_owned_sub_size(), 4ul);
  ASSERT_EQ(parent_1->not_owning_sub_size(), 4ul);
  CalculateDumpSubSizes(parent_2);
  ASSERT_EQ(parent_2->not_owned_sub_size(), 5ul);
  ASSERT_EQ(parent_2->not_owning_sub_size(), 5ul);

  // These nodes should account for edge between parents.
  CalculateDumpSubSizes(process_1->root());
  ASSERT_EQ(process_1->root()->not_owned_sub_size(), 4ul);
  ASSERT_EQ(process_1->root()->not_owning_sub_size(), 0ul);
  CalculateDumpSubSizes(process_2->root());
  ASSERT_EQ(process_2->root()->not_owned_sub_size(), 1ul);
  ASSERT_EQ(process_2->root()->not_owning_sub_size(), 5ul);
}

TEST_F(GraphProcessorTest, CalculateDumpOwnershipCoefficient) {
  Process* process = graph.CreateGraphForProcess(1);

  Node* owned = process->CreateNode(kEmptyGuid, "owned", false);
  Node* owner_1 = process->CreateNode(kEmptyGuid, "owner1", false);
  Node* owner_2 = process->CreateNode(kEmptyGuid, "owner2", false);
  Node* owner_3 = process->CreateNode(kEmptyGuid, "owner3", false);
  Node* owner_4 = process->CreateNode(kEmptyGuid, "owner4", false);

  graph.AddNodeOwnershipEdge(owner_1, owned, 2);
  graph.AddNodeOwnershipEdge(owner_2, owned, 2);
  graph.AddNodeOwnershipEdge(owner_3, owned, 1);
  graph.AddNodeOwnershipEdge(owner_4, owned, 0);

  // Ensure the owned node has a size otherwise calculations will not happen.
  owned->AddEntry("size", Node::Entry::kBytes, 10);

  // Setup the owned/owning sub sizes.
  owned->add_not_owned_sub_size(10);
  owner_1->add_not_owning_sub_size(6);
  owner_2->add_not_owning_sub_size(7);
  owner_3->add_not_owning_sub_size(5);
  owner_4->add_not_owning_sub_size(8);

  // Perform the computation.
  CalculateDumpOwnershipCoefficient(owned);

  // Ensure that the coefficients are correct.
  ASSERT_DOUBLE_EQ(owned->owned_coefficient(), 2.0 / 10.0);
  ASSERT_DOUBLE_EQ(owner_1->owning_coefficient(), 3.0 / 6.0);
  ASSERT_DOUBLE_EQ(owner_2->owning_coefficient(), 4.0 / 7.0);
  ASSERT_DOUBLE_EQ(owner_3->owning_coefficient(), 0.0 / 5.0);
  ASSERT_DOUBLE_EQ(owner_4->owning_coefficient(), 1.0 / 8.0);
}

TEST_F(GraphProcessorTest, CalculateDumpCumulativeOwnershipCoefficient) {
  Process* process = graph.CreateGraphForProcess(1);

  Node* c1 = process->CreateNode(kEmptyGuid, "c1", false);
  Node* c1_c1 = process->CreateNode(kEmptyGuid, "c1/c1", false);
  Node* c1_c2 = process->CreateNode(kEmptyGuid, "c1/c2", false);
  Node* owned = process->CreateNode(kEmptyGuid, "owned", false);

  graph.AddNodeOwnershipEdge(c1_c2, owned, 2);

  // Ensure all nodes have sizes otherwise calculations will not happen.
  c1_c1->AddEntry("size", Node::Entry::kBytes, 10);
  c1_c2->AddEntry("size", Node::Entry::kBytes, 10);
  owned->AddEntry("size", Node::Entry::kBytes, 10);

  // Setup the owned/owning cummulative coefficients.
  c1->set_cumulative_owning_coefficient(0.123);
  c1->set_cumulative_owned_coefficient(0.456);
  owned->set_cumulative_owning_coefficient(0.789);
  owned->set_cumulative_owned_coefficient(0.987);

  // Set owning and owned for the children.
  c1_c1->set_owning_coefficient(0.654);
  c1_c1->set_owned_coefficient(0.321);
  c1_c2->set_owning_coefficient(0.135);
  c1_c2->set_owned_coefficient(0.246);

  // Perform the computation and check our answers.
  CalculateDumpCumulativeOwnershipCoefficient(c1_c1);
  ASSERT_DOUBLE_EQ(c1_c1->cumulative_owning_coefficient(), 0.123);
  ASSERT_DOUBLE_EQ(c1_c1->cumulative_owned_coefficient(), 0.456 * 0.321);

  CalculateDumpCumulativeOwnershipCoefficient(c1_c2);
  ASSERT_DOUBLE_EQ(c1_c2->cumulative_owning_coefficient(), 0.135 * 0.789);
  ASSERT_DOUBLE_EQ(c1_c2->cumulative_owned_coefficient(), 0.456 * 0.246);
}

TEST_F(GraphProcessorTest, CalculateDumpEffectiveSize) {
  Process* process = graph.CreateGraphForProcess(1);

  Node* c1 = process->CreateNode(kEmptyGuid, "c1", false);
  Node* c1_c1 = process->CreateNode(kEmptyGuid, "c1/c1", false);
  Node* c1_c2 = process->CreateNode(kEmptyGuid, "c1/c2", false);

  // Ensure all nodes have sizes otherwise calculations will not happen.
  c1->AddEntry("size", Node::Entry::kBytes, 200);
  c1_c1->AddEntry("size", Node::Entry::kBytes, 32);
  c1_c2->AddEntry("size", Node::Entry::kBytes, 20);

  // Setup the owned/owning cummulative coefficients.
  c1_c1->set_cumulative_owning_coefficient(0.123);
  c1_c1->set_cumulative_owned_coefficient(0.456);
  c1_c2->set_cumulative_owning_coefficient(0.789);
  c1_c2->set_cumulative_owned_coefficient(0.987);

  // Perform the computation and check our answers.
  CalculateDumpEffectiveSize(c1_c1);
  const Node::Entry& entry_c1_c1 =
      c1_c1->entries()->find("effective_size")->second;
  uint64_t expected_c1_c1 = static_cast<int>(0.123 * 0.456 * 32);
  ASSERT_EQ(entry_c1_c1.value_uint64, expected_c1_c1);

  CalculateDumpEffectiveSize(c1_c2);
  const Node::Entry& entry_c1_c2 =
      c1_c2->entries()->find("effective_size")->second;
  uint64_t expected_c1_c2 = static_cast<int>(0.789 * 0.987 * 20);
  ASSERT_EQ(entry_c1_c2.value_uint64, expected_c1_c2);

  CalculateDumpEffectiveSize(c1);
  const Node::Entry& entry_c1 = c1->entries()->find("effective_size")->second;
  ASSERT_EQ(entry_c1.value_uint64, expected_c1_c1 + expected_c1_c2);
}

}  // namespace memory_instrumentation
