diff options
Diffstat (limited to 'llvm/unittests/XRay/FDRRecordsTest.cpp')
| -rw-r--r-- | llvm/unittests/XRay/FDRRecordsTest.cpp | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/llvm/unittests/XRay/FDRRecordsTest.cpp b/llvm/unittests/XRay/FDRRecordsTest.cpp new file mode 100644 index 00000000000..24ff7a5ad51 --- /dev/null +++ b/llvm/unittests/XRay/FDRRecordsTest.cpp @@ -0,0 +1,156 @@ +//===- FDRRecords.cpp - Unit Tests for XRay FDR Record Loading ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#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<BufferExtents>(100) + .add<NewBufferRecord>(1) + .add<WallclockRecord>(1, 1) + .add<PIDRecord>(1) + .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) + .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) + .consume(); + auto Block1 = LogBuilder() + .add<BufferExtents>(100) + .add<NewBufferRecord>(1) + .add<WallclockRecord>(1, 2) + .add<PIDRecord>(1) + .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) + .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) + .consume(); + auto Block2 = LogBuilder() + .add<BufferExtents>(100) + .add<NewBufferRecord>(2) + .add<WallclockRecord>(1, 3) + .add<PIDRecord>(1) + .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) + .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) + .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<BufferExtents>(48) + .add<NewBufferRecord>(1) + .add<WallclockRecord>(1, 1) + .add<PIDRecord>(1) + .add<NewCPUIDRecord>(1) + .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<BufferExtents>(64) + .add<NewBufferRecord>(1) + .add<WallclockRecord>(1, 1) + .add<PIDRecord>(1) + .add<NewCPUIDRecord>(1) + .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) + .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) + .consume(); + auto Block1 = LogBuilder() + .add<BufferExtents>(64) + .add<NewBufferRecord>(1) + .add<WallclockRecord>(1, 1) + .add<PIDRecord>(1) + .add<NewCPUIDRecord>(1) + .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) + .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) + .consume(); + auto Block2 = LogBuilder() + .add<BufferExtents>(64) + .add<NewBufferRecord>(1) + .add<WallclockRecord>(1, 1) + .add<PIDRecord>(1) + .add<NewCPUIDRecord>(1) + .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) + .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) + .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 |

