122 lines · cpp
1//===-- MemoryTreeTests.cpp -------------------------------------*- C++ -*-===//2//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-exception6//7//===----------------------------------------------------------------------===//8 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"15#include <ostream>16 17namespace clang {18namespace clangd {19namespace {20using testing::Contains;21using testing::ElementsAre;22using testing::IsEmpty;23using testing::UnorderedElementsAre;24 25MATCHER_P2(WithNameAndSize, Name, Size, "") {26 return arg.first == Name &&27 arg.getSecond().total() == static_cast<size_t>(Size);28}29 30TEST(MemoryTree, Basics) {31 MemoryTree MT;32 EXPECT_EQ(MT.total(), 0U);33 EXPECT_THAT(MT.children(), IsEmpty());34 35 MT.addUsage(42);36 EXPECT_EQ(MT.total(), 42U);37 EXPECT_THAT(MT.children(), IsEmpty());38 39 MT.child("leaf").addUsage(1);40 EXPECT_EQ(MT.total(), 43U);41 EXPECT_THAT(MT.children(), UnorderedElementsAre(WithNameAndSize("leaf", 1)));42 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)));47}48 49TEST(MemoryTree, DetailedNodesWithoutDetails) {50 MemoryTree MT;51 MT.detail("should_be_ignored").addUsage(2);52 EXPECT_THAT(MT.children(), IsEmpty());53 EXPECT_EQ(MT.total(), 2U);54 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)));59}60 61TEST(MemoryTree, DetailedNodesWithDetails) {62 llvm::BumpPtrAllocator Alloc;63 MemoryTree MT(&Alloc);64 65 {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)));70 }71 72 {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)));77 }78}79 80TEST(MemoryTree, Record) {81 trace::TestTracer Tracer;82 static constexpr llvm::StringLiteral MetricName = "memory_usage";83 static constexpr trace::Metric OutMetric(MetricName, trace::Metric::Value,84 "component_name");85 auto AddNodes = [](MemoryTree Root) {86 Root.child("leaf").addUsage(1);87 88 {89 auto &Detail = Root.detail("detail");90 Detail.addUsage(1);91 Detail.child("leaf").addUsage(1);92 auto &Child = Detail.child("child");93 Child.addUsage(1);94 Child.child("leaf").addUsage(1);95 }96 97 {98 auto &Child = Root.child("child");99 Child.addUsage(1);100 Child.child("leaf").addUsage(1);101 }102 return Root;103 };104 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"),111 ElementsAre(1));112 EXPECT_THAT(Tracer.takeMetric(MetricName, "root.detail.child"),113 ElementsAre(2));114 EXPECT_THAT(Tracer.takeMetric(MetricName, "root.detail.child.leaf"),115 ElementsAre(1));116 EXPECT_THAT(Tracer.takeMetric(MetricName, "root.child"), ElementsAre(2));117 EXPECT_THAT(Tracer.takeMetric(MetricName, "root.child.leaf"), ElementsAre(1));118}119} // namespace120} // namespace clangd121} // namespace clang122