167 lines · cpp
1//===- FDRRecords.cpp - Unit Tests for XRay FDR Record Loading ------------===//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#include "gmock/gmock.h"9#include "gtest/gtest.h"10 11#include "llvm/XRay/BlockIndexer.h"12#include "llvm/XRay/BlockPrinter.h"13#include "llvm/XRay/BlockVerifier.h"14#include "llvm/XRay/FDRLogBuilder.h"15#include "llvm/XRay/FDRRecords.h"16#include "llvm/XRay/RecordPrinter.h"17 18namespace llvm {19namespace xray {20namespace {21 22using ::testing::Eq;23using ::testing::Not;24 25TEST(XRayFDRTest, BuilderAndBlockIndexer) {26 // We recreate a single block of valid records, then ensure that we find all27 // of them belonging in the same index. We do this for three blocks, and28 // ensure we find the same records in the blocks we deduce.29 auto Block0 = LogBuilder()30 .add<BufferExtents>(100)31 .add<NewBufferRecord>(1)32 .add<WallclockRecord>(1, 1)33 .add<PIDRecord>(1)34 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)35 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)36 .add<CustomEventRecordV5>(1, 4, "XRAY")37 .add<TypedEventRecord>(1, 4, 2, "XRAY")38 .consume();39 auto Block1 = LogBuilder()40 .add<BufferExtents>(100)41 .add<NewBufferRecord>(1)42 .add<WallclockRecord>(1, 2)43 .add<PIDRecord>(1)44 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)45 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)46 .add<CustomEventRecordV5>(1, 4, "XRAY")47 .add<TypedEventRecord>(1, 4, 2, "XRAY")48 .consume();49 auto Block2 = LogBuilder()50 .add<BufferExtents>(100)51 .add<NewBufferRecord>(2)52 .add<WallclockRecord>(1, 3)53 .add<PIDRecord>(1)54 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)55 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)56 .add<CustomEventRecordV5>(1, 4, "XRAY")57 .add<TypedEventRecord>(1, 4, 2, "XRAY")58 .consume();59 BlockIndexer::Index Index;60 BlockIndexer Indexer(Index);61 for (auto B : {std::ref(Block0), std::ref(Block1), std::ref(Block2)}) {62 for (auto &R : B.get())63 ASSERT_FALSE(errorToBool(R->apply(Indexer)));64 ASSERT_FALSE(errorToBool(Indexer.flush()));65 }66 67 // We have two threads worth of blocks.68 ASSERT_THAT(Index.size(), Eq(2u));69 auto T1Blocks = Index.find({1, 1});70 ASSERT_THAT(T1Blocks, Not(Eq(Index.end())));71 ASSERT_THAT(T1Blocks->second.size(), Eq(2u));72 auto T2Blocks = Index.find({1, 2});73 ASSERT_THAT(T2Blocks, Not(Eq(Index.end())));74 ASSERT_THAT(T2Blocks->second.size(), Eq(1u));75}76 77TEST(XRayFDRTest, BuilderAndBlockVerifier) {78 auto Block = LogBuilder()79 .add<BufferExtents>(48)80 .add<NewBufferRecord>(1)81 .add<WallclockRecord>(1, 1)82 .add<PIDRecord>(1)83 .add<NewCPUIDRecord>(1, 2)84 .consume();85 BlockVerifier Verifier;86 for (auto &R : Block)87 ASSERT_FALSE(errorToBool(R->apply(Verifier)));88 ASSERT_FALSE(errorToBool(Verifier.verify()));89}90 91TEST(XRayFDRTest, IndexAndVerifyBlocks) {92 auto Block0 = LogBuilder()93 .add<BufferExtents>(64)94 .add<NewBufferRecord>(1)95 .add<WallclockRecord>(1, 1)96 .add<PIDRecord>(1)97 .add<NewCPUIDRecord>(1, 2)98 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)99 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)100 .add<CustomEventRecordV5>(1, 4, "XRAY")101 .add<TypedEventRecord>(1, 4, 2, "XRAY")102 .consume();103 auto Block1 = LogBuilder()104 .add<BufferExtents>(64)105 .add<NewBufferRecord>(1)106 .add<WallclockRecord>(1, 1)107 .add<PIDRecord>(1)108 .add<NewCPUIDRecord>(1, 2)109 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)110 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)111 .add<CustomEventRecordV5>(1, 4, "XRAY")112 .add<TypedEventRecord>(1, 4, 2, "XRAY")113 .consume();114 auto Block2 = LogBuilder()115 .add<BufferExtents>(64)116 .add<NewBufferRecord>(1)117 .add<WallclockRecord>(1, 1)118 .add<PIDRecord>(1)119 .add<NewCPUIDRecord>(1, 2)120 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)121 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)122 .add<CustomEventRecordV5>(1, 4, "XRAY")123 .add<TypedEventRecord>(1, 4, 2, "XRAY")124 .consume();125 126 // First, index the records in different blocks.127 BlockIndexer::Index Index;128 BlockIndexer Indexer(Index);129 for (auto B : {std::ref(Block0), std::ref(Block1), std::ref(Block2)}) {130 for (auto &R : B.get())131 ASSERT_FALSE(errorToBool(R->apply(Indexer)));132 ASSERT_FALSE(errorToBool(Indexer.flush()));133 }134 135 // Next, verify that each block is consistently defined.136 BlockVerifier Verifier;137 for (auto &ProcessThreadBlocks : Index) {138 auto &Blocks = ProcessThreadBlocks.second;139 for (auto &B : Blocks) {140 for (auto *R : B.Records)141 ASSERT_FALSE(errorToBool(R->apply(Verifier)));142 ASSERT_FALSE(errorToBool(Verifier.verify()));143 Verifier.reset();144 }145 }146 147 // Then set up the printing mechanisms.148 std::string Output;149 raw_string_ostream OS(Output);150 RecordPrinter RP(OS);151 BlockPrinter BP(OS, RP);152 for (auto &ProcessThreadBlocks : Index) {153 auto &Blocks = ProcessThreadBlocks.second;154 for (auto &B : Blocks) {155 for (auto *R : B.Records)156 ASSERT_FALSE(errorToBool(R->apply(BP)));157 BP.reset();158 }159 }160 161 EXPECT_THAT(Output, Not(Eq("")));162}163 164} // namespace165} // namespace xray166} // namespace llvm167