1f9317f7bSKadir Cetinkaya //===-- MemoryTreeTests.cpp -------------------------------------*- C++ -*-===//
2f9317f7bSKadir Cetinkaya //
3f9317f7bSKadir Cetinkaya // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f9317f7bSKadir Cetinkaya // See https://llvm.org/LICENSE.txt for license information.
5f9317f7bSKadir Cetinkaya // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f9317f7bSKadir Cetinkaya //
7f9317f7bSKadir Cetinkaya //===----------------------------------------------------------------------===//
8f9317f7bSKadir Cetinkaya
9f9317f7bSKadir Cetinkaya #include "support/MemoryTree.h"
10*c9d2876dSKadir Cetinkaya #include "support/TestTracer.h"
11*c9d2876dSKadir Cetinkaya #include "support/Trace.h"
12f9317f7bSKadir Cetinkaya #include "llvm/Support/Allocator.h"
13f9317f7bSKadir Cetinkaya #include "gmock/gmock.h"
14f9317f7bSKadir Cetinkaya #include "gtest/gtest.h"
15f9317f7bSKadir Cetinkaya #include <ostream>
16f9317f7bSKadir Cetinkaya
17f9317f7bSKadir Cetinkaya namespace clang {
18f9317f7bSKadir Cetinkaya namespace clangd {
19f9317f7bSKadir Cetinkaya namespace {
20f9317f7bSKadir Cetinkaya using testing::Contains;
21*c9d2876dSKadir Cetinkaya using testing::ElementsAre;
22f9317f7bSKadir Cetinkaya using testing::IsEmpty;
23f9317f7bSKadir Cetinkaya using testing::UnorderedElementsAre;
24f9317f7bSKadir Cetinkaya
25f9317f7bSKadir Cetinkaya MATCHER_P2(WithNameAndSize, Name, Size, "") {
26f9317f7bSKadir Cetinkaya return arg.first == Name &&
27f9317f7bSKadir Cetinkaya arg.getSecond().total() == static_cast<size_t>(Size);
28f9317f7bSKadir Cetinkaya }
29f9317f7bSKadir Cetinkaya
TEST(MemoryTree,Basics)30f9317f7bSKadir Cetinkaya TEST(MemoryTree, Basics) {
31f9317f7bSKadir Cetinkaya MemoryTree MT;
32f9317f7bSKadir Cetinkaya EXPECT_EQ(MT.total(), 0U);
33f9317f7bSKadir Cetinkaya EXPECT_THAT(MT.children(), IsEmpty());
34f9317f7bSKadir Cetinkaya
35f9317f7bSKadir Cetinkaya MT.addUsage(42);
36f9317f7bSKadir Cetinkaya EXPECT_EQ(MT.total(), 42U);
37f9317f7bSKadir Cetinkaya EXPECT_THAT(MT.children(), IsEmpty());
38f9317f7bSKadir Cetinkaya
39f9317f7bSKadir Cetinkaya MT.child("leaf").addUsage(1);
40f9317f7bSKadir Cetinkaya EXPECT_EQ(MT.total(), 43U);
41f9317f7bSKadir Cetinkaya EXPECT_THAT(MT.children(), UnorderedElementsAre(WithNameAndSize("leaf", 1)));
42f9317f7bSKadir Cetinkaya
43f9317f7bSKadir Cetinkaya // child should be idempotent.
44f9317f7bSKadir Cetinkaya MT.child("leaf").addUsage(1);
45f9317f7bSKadir Cetinkaya EXPECT_EQ(MT.total(), 44U);
46f9317f7bSKadir Cetinkaya EXPECT_THAT(MT.children(), UnorderedElementsAre(WithNameAndSize("leaf", 2)));
47f9317f7bSKadir Cetinkaya }
48f9317f7bSKadir Cetinkaya
TEST(MemoryTree,DetailedNodesWithoutDetails)49f9317f7bSKadir Cetinkaya TEST(MemoryTree, DetailedNodesWithoutDetails) {
50f9317f7bSKadir Cetinkaya MemoryTree MT;
51f9317f7bSKadir Cetinkaya MT.detail("should_be_ignored").addUsage(2);
52f9317f7bSKadir Cetinkaya EXPECT_THAT(MT.children(), IsEmpty());
53f9317f7bSKadir Cetinkaya EXPECT_EQ(MT.total(), 2U);
54f9317f7bSKadir Cetinkaya
55f9317f7bSKadir Cetinkaya // Make sure children from details are merged.
56f9317f7bSKadir Cetinkaya MT.detail("first_detail").child("leaf").addUsage(1);
57f9317f7bSKadir Cetinkaya MT.detail("second_detail").child("leaf").addUsage(1);
58f9317f7bSKadir Cetinkaya EXPECT_THAT(MT.children(), Contains(WithNameAndSize("leaf", 2)));
59f9317f7bSKadir Cetinkaya }
60f9317f7bSKadir Cetinkaya
TEST(MemoryTree,DetailedNodesWithDetails)61f9317f7bSKadir Cetinkaya TEST(MemoryTree, DetailedNodesWithDetails) {
62f9317f7bSKadir Cetinkaya llvm::BumpPtrAllocator Alloc;
63f9317f7bSKadir Cetinkaya MemoryTree MT(&Alloc);
64f9317f7bSKadir Cetinkaya
65f9317f7bSKadir Cetinkaya {
66f9317f7bSKadir Cetinkaya auto &Detail = MT.detail("first_detail");
67f9317f7bSKadir Cetinkaya Detail.child("leaf").addUsage(1);
68f9317f7bSKadir Cetinkaya EXPECT_THAT(MT.children(), Contains(WithNameAndSize("first_detail", 1)));
69f9317f7bSKadir Cetinkaya EXPECT_THAT(Detail.children(), Contains(WithNameAndSize("leaf", 1)));
70f9317f7bSKadir Cetinkaya }
71f9317f7bSKadir Cetinkaya
72f9317f7bSKadir Cetinkaya {
73f9317f7bSKadir Cetinkaya auto &Detail = MT.detail("second_detail");
74f9317f7bSKadir Cetinkaya Detail.child("leaf").addUsage(1);
75f9317f7bSKadir Cetinkaya EXPECT_THAT(MT.children(), Contains(WithNameAndSize("second_detail", 1)));
76f9317f7bSKadir Cetinkaya EXPECT_THAT(Detail.children(), Contains(WithNameAndSize("leaf", 1)));
77f9317f7bSKadir Cetinkaya }
78f9317f7bSKadir Cetinkaya }
79*c9d2876dSKadir Cetinkaya
TEST(MemoryTree,Record)80*c9d2876dSKadir Cetinkaya TEST(MemoryTree, Record) {
81*c9d2876dSKadir Cetinkaya trace::TestTracer Tracer;
82*c9d2876dSKadir Cetinkaya static constexpr llvm::StringLiteral MetricName = "memory_usage";
83*c9d2876dSKadir Cetinkaya static constexpr trace::Metric OutMetric(MetricName, trace::Metric::Value,
84*c9d2876dSKadir Cetinkaya "component_name");
85*c9d2876dSKadir Cetinkaya auto AddNodes = [](MemoryTree Root) {
86*c9d2876dSKadir Cetinkaya Root.child("leaf").addUsage(1);
87*c9d2876dSKadir Cetinkaya
88*c9d2876dSKadir Cetinkaya {
89*c9d2876dSKadir Cetinkaya auto &Detail = Root.detail("detail");
90*c9d2876dSKadir Cetinkaya Detail.addUsage(1);
91*c9d2876dSKadir Cetinkaya Detail.child("leaf").addUsage(1);
92*c9d2876dSKadir Cetinkaya auto &Child = Detail.child("child");
93*c9d2876dSKadir Cetinkaya Child.addUsage(1);
94*c9d2876dSKadir Cetinkaya Child.child("leaf").addUsage(1);
95*c9d2876dSKadir Cetinkaya }
96*c9d2876dSKadir Cetinkaya
97*c9d2876dSKadir Cetinkaya {
98*c9d2876dSKadir Cetinkaya auto &Child = Root.child("child");
99*c9d2876dSKadir Cetinkaya Child.addUsage(1);
100*c9d2876dSKadir Cetinkaya Child.child("leaf").addUsage(1);
101*c9d2876dSKadir Cetinkaya }
102*c9d2876dSKadir Cetinkaya return Root;
103*c9d2876dSKadir Cetinkaya };
104*c9d2876dSKadir Cetinkaya
105*c9d2876dSKadir Cetinkaya llvm::BumpPtrAllocator Alloc;
106*c9d2876dSKadir Cetinkaya record(AddNodes(MemoryTree(&Alloc)), "root", OutMetric);
107*c9d2876dSKadir Cetinkaya EXPECT_THAT(Tracer.takeMetric(MetricName, "root"), ElementsAre(7));
108*c9d2876dSKadir Cetinkaya EXPECT_THAT(Tracer.takeMetric(MetricName, "root.leaf"), ElementsAre(1));
109*c9d2876dSKadir Cetinkaya EXPECT_THAT(Tracer.takeMetric(MetricName, "root.detail"), ElementsAre(4));
110*c9d2876dSKadir Cetinkaya EXPECT_THAT(Tracer.takeMetric(MetricName, "root.detail.leaf"),
111*c9d2876dSKadir Cetinkaya ElementsAre(1));
112*c9d2876dSKadir Cetinkaya EXPECT_THAT(Tracer.takeMetric(MetricName, "root.detail.child"),
113*c9d2876dSKadir Cetinkaya ElementsAre(2));
114*c9d2876dSKadir Cetinkaya EXPECT_THAT(Tracer.takeMetric(MetricName, "root.detail.child.leaf"),
115*c9d2876dSKadir Cetinkaya ElementsAre(1));
116*c9d2876dSKadir Cetinkaya EXPECT_THAT(Tracer.takeMetric(MetricName, "root.child"), ElementsAre(2));
117*c9d2876dSKadir Cetinkaya EXPECT_THAT(Tracer.takeMetric(MetricName, "root.child.leaf"), ElementsAre(1));
118*c9d2876dSKadir Cetinkaya }
119f9317f7bSKadir Cetinkaya } // namespace
120f9317f7bSKadir Cetinkaya } // namespace clangd
121f9317f7bSKadir Cetinkaya } // namespace clang
122