//===- FDRRecords.cpp - Unit Tests for XRay FDR Record Loading ------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "gmock/gmock.h" #include "gtest/gtest.h" #include "llvm/XRay/BlockIndexer.h" #include "llvm/XRay/BlockPrinter.h" #include "llvm/XRay/BlockVerifier.h" #include "llvm/XRay/FDRLogBuilder.h" #include "llvm/XRay/FDRRecords.h" #include "llvm/XRay/RecordPrinter.h" namespace llvm { namespace xray { namespace { using ::testing::Eq; using ::testing::Not; TEST(XRayFDRTest, BuilderAndBlockIndexer) { // We recreate a single block of valid records, then ensure that we find all // of them belonging in the same index. We do this for three blocks, and // ensure we find the same records in the blocks we deduce. auto Block0 = LogBuilder() .add(100) .add(1) .add(1, 1) .add(1) .add(RecordTypes::ENTER, 1, 1) .add(RecordTypes::EXIT, 1, 100) .add(1, 4, "XRAY") .add(1, 4, 2, "XRAY") .consume(); auto Block1 = LogBuilder() .add(100) .add(1) .add(1, 2) .add(1) .add(RecordTypes::ENTER, 1, 1) .add(RecordTypes::EXIT, 1, 100) .add(1, 4, "XRAY") .add(1, 4, 2, "XRAY") .consume(); auto Block2 = LogBuilder() .add(100) .add(2) .add(1, 3) .add(1) .add(RecordTypes::ENTER, 1, 1) .add(RecordTypes::EXIT, 1, 100) .add(1, 4, "XRAY") .add(1, 4, 2, "XRAY") .consume(); BlockIndexer::Index Index; BlockIndexer Indexer(Index); for (auto B : {std::ref(Block0), std::ref(Block1), std::ref(Block2)}) { for (auto &R : B.get()) ASSERT_FALSE(errorToBool(R->apply(Indexer))); ASSERT_FALSE(errorToBool(Indexer.flush())); } // We have two threads worth of blocks. ASSERT_THAT(Index.size(), Eq(2u)); auto T1Blocks = Index.find({1, 1}); ASSERT_THAT(T1Blocks, Not(Eq(Index.end()))); ASSERT_THAT(T1Blocks->second.size(), Eq(2u)); auto T2Blocks = Index.find({1, 2}); ASSERT_THAT(T2Blocks, Not(Eq(Index.end()))); ASSERT_THAT(T2Blocks->second.size(), Eq(1u)); } TEST(XRayFDRTest, BuilderAndBlockVerifier) { auto Block = LogBuilder() .add(48) .add(1) .add(1, 1) .add(1) .add(1, 2) .consume(); BlockVerifier Verifier; for (auto &R : Block) ASSERT_FALSE(errorToBool(R->apply(Verifier))); ASSERT_FALSE(errorToBool(Verifier.verify())); } TEST(XRayFDRTest, IndexAndVerifyBlocks) { auto Block0 = LogBuilder() .add(64) .add(1) .add(1, 1) .add(1) .add(1, 2) .add(RecordTypes::ENTER, 1, 1) .add(RecordTypes::EXIT, 1, 100) .add(1, 4, "XRAY") .add(1, 4, 2, "XRAY") .consume(); auto Block1 = LogBuilder() .add(64) .add(1) .add(1, 1) .add(1) .add(1, 2) .add(RecordTypes::ENTER, 1, 1) .add(RecordTypes::EXIT, 1, 100) .add(1, 4, "XRAY") .add(1, 4, 2, "XRAY") .consume(); auto Block2 = LogBuilder() .add(64) .add(1) .add(1, 1) .add(1) .add(1, 2) .add(RecordTypes::ENTER, 1, 1) .add(RecordTypes::EXIT, 1, 100) .add(1, 4, "XRAY") .add(1, 4, 2, "XRAY") .consume(); // First, index the records in different blocks. BlockIndexer::Index Index; BlockIndexer Indexer(Index); for (auto B : {std::ref(Block0), std::ref(Block1), std::ref(Block2)}) { for (auto &R : B.get()) ASSERT_FALSE(errorToBool(R->apply(Indexer))); ASSERT_FALSE(errorToBool(Indexer.flush())); } // Next, verify that each block is consistently defined. BlockVerifier Verifier; for (auto &ProcessThreadBlocks : Index) { auto &Blocks = ProcessThreadBlocks.second; for (auto &B : Blocks) { for (auto *R : B.Records) ASSERT_FALSE(errorToBool(R->apply(Verifier))); ASSERT_FALSE(errorToBool(Verifier.verify())); Verifier.reset(); } } // Then set up the printing mechanisms. std::string Output; raw_string_ostream OS(Output); RecordPrinter RP(OS); BlockPrinter BP(OS, RP); for (auto &ProcessThreadBlocks : Index) { auto &Blocks = ProcessThreadBlocks.second; for (auto &B : Blocks) { for (auto *R : B.Records) ASSERT_FALSE(errorToBool(R->apply(BP))); BP.reset(); } } OS.flush(); EXPECT_THAT(Output, Not(Eq(""))); } } // namespace } // namespace xray } // namespace llvm