1 //===-- MemoryTreeTests.cpp -------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "support/MemoryTree.h"
10 #include "support/TestTracer.h"
11 #include "support/Trace.h"
12 #include "llvm/Support/Allocator.h"
13 #include "gmock/gmock.h"
14 #include "gtest/gtest.h"
20 using testing::Contains
;
21 using testing::ElementsAre
;
22 using testing::IsEmpty
;
23 using testing::UnorderedElementsAre
;
25 MATCHER_P2(WithNameAndSize
, Name
, Size
, "") {
26 return arg
.first
== Name
&&
27 arg
.getSecond().total() == static_cast<size_t>(Size
);
30 TEST(MemoryTree
, Basics
) {
32 EXPECT_EQ(MT
.total(), 0U);
33 EXPECT_THAT(MT
.children(), IsEmpty());
36 EXPECT_EQ(MT
.total(), 42U);
37 EXPECT_THAT(MT
.children(), IsEmpty());
39 MT
.child("leaf").addUsage(1);
40 EXPECT_EQ(MT
.total(), 43U);
41 EXPECT_THAT(MT
.children(), UnorderedElementsAre(WithNameAndSize("leaf", 1)));
43 // child should be idempotent.
44 MT
.child("leaf").addUsage(1);
45 EXPECT_EQ(MT
.total(), 44U);
46 EXPECT_THAT(MT
.children(), UnorderedElementsAre(WithNameAndSize("leaf", 2)));
49 TEST(MemoryTree
, DetailedNodesWithoutDetails
) {
51 MT
.detail("should_be_ignored").addUsage(2);
52 EXPECT_THAT(MT
.children(), IsEmpty());
53 EXPECT_EQ(MT
.total(), 2U);
55 // Make sure children from details are merged.
56 MT
.detail("first_detail").child("leaf").addUsage(1);
57 MT
.detail("second_detail").child("leaf").addUsage(1);
58 EXPECT_THAT(MT
.children(), Contains(WithNameAndSize("leaf", 2)));
61 TEST(MemoryTree
, DetailedNodesWithDetails
) {
62 llvm::BumpPtrAllocator Alloc
;
63 MemoryTree
MT(&Alloc
);
66 auto &Detail
= MT
.detail("first_detail");
67 Detail
.child("leaf").addUsage(1);
68 EXPECT_THAT(MT
.children(), Contains(WithNameAndSize("first_detail", 1)));
69 EXPECT_THAT(Detail
.children(), Contains(WithNameAndSize("leaf", 1)));
73 auto &Detail
= MT
.detail("second_detail");
74 Detail
.child("leaf").addUsage(1);
75 EXPECT_THAT(MT
.children(), Contains(WithNameAndSize("second_detail", 1)));
76 EXPECT_THAT(Detail
.children(), Contains(WithNameAndSize("leaf", 1)));
80 TEST(MemoryTree
, Record
) {
81 trace::TestTracer Tracer
;
82 static constexpr llvm::StringLiteral MetricName
= "memory_usage";
83 static constexpr trace::Metric
OutMetric(MetricName
, trace::Metric::Value
,
85 auto AddNodes
= [](MemoryTree Root
) {
86 Root
.child("leaf").addUsage(1);
89 auto &Detail
= Root
.detail("detail");
91 Detail
.child("leaf").addUsage(1);
92 auto &Child
= Detail
.child("child");
94 Child
.child("leaf").addUsage(1);
98 auto &Child
= Root
.child("child");
100 Child
.child("leaf").addUsage(1);
105 llvm::BumpPtrAllocator Alloc
;
106 record(AddNodes(MemoryTree(&Alloc
)), "root", OutMetric
);
107 EXPECT_THAT(Tracer
.takeMetric(MetricName
, "root"), ElementsAre(7));
108 EXPECT_THAT(Tracer
.takeMetric(MetricName
, "root.leaf"), ElementsAre(1));
109 EXPECT_THAT(Tracer
.takeMetric(MetricName
, "root.detail"), ElementsAre(4));
110 EXPECT_THAT(Tracer
.takeMetric(MetricName
, "root.detail.leaf"),
112 EXPECT_THAT(Tracer
.takeMetric(MetricName
, "root.detail.child"),
114 EXPECT_THAT(Tracer
.takeMetric(MetricName
, "root.detail.child.leaf"),
116 EXPECT_THAT(Tracer
.takeMetric(MetricName
, "root.child"), ElementsAre(2));
117 EXPECT_THAT(Tracer
.takeMetric(MetricName
, "root.child.leaf"), ElementsAre(1));
120 } // namespace clangd