1 //===- llvm/unittest/XRay/FDRBlockVerifierTest.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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 #include "llvm/Testing/Support/Error.h" 9 #include "llvm/XRay/BlockIndexer.h" 10 #include "llvm/XRay/BlockVerifier.h" 11 #include "llvm/XRay/FDRLogBuilder.h" 12 #include "llvm/XRay/FDRRecords.h" 13 #include "gmock/gmock.h" 14 #include "gtest/gtest.h" 15 16 namespace llvm { 17 namespace xray { 18 namespace { 19 20 using ::testing::ElementsAre; 21 using ::testing::Not; 22 using ::testing::SizeIs; 23 24 TEST(FDRBlockVerifierTest, ValidBlocksV3) { 25 auto Block0 = LogBuilder() 26 .add<BufferExtents>(80) 27 .add<NewBufferRecord>(1) 28 .add<WallclockRecord>(1, 2) 29 .add<PIDRecord>(1) 30 .add<NewCPUIDRecord>(1, 2) 31 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) 32 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) 33 .consume(); 34 auto Block1 = LogBuilder() 35 .add<BufferExtents>(80) 36 .add<NewBufferRecord>(1) 37 .add<WallclockRecord>(1, 2) 38 .add<PIDRecord>(1) 39 .add<NewCPUIDRecord>(1, 2) 40 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) 41 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) 42 .consume(); 43 auto Block2 = LogBuilder() 44 .add<BufferExtents>(80) 45 .add<NewBufferRecord>(2) 46 .add<WallclockRecord>(1, 2) 47 .add<PIDRecord>(1) 48 .add<NewCPUIDRecord>(2, 2) 49 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) 50 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) 51 .consume(); 52 BlockIndexer::Index Index; 53 BlockIndexer Indexer(Index); 54 for (auto B : {std::ref(Block0), std::ref(Block1), std::ref(Block2)}) { 55 for (auto &R : B.get()) 56 ASSERT_FALSE(errorToBool(R->apply(Indexer))); 57 ASSERT_FALSE(errorToBool(Indexer.flush())); 58 } 59 60 BlockVerifier Verifier; 61 for (auto &ProcessThreadBlocks : Index) { 62 auto &Blocks = ProcessThreadBlocks.second; 63 for (auto &B : Blocks) { 64 for (auto *R : B.Records) 65 ASSERT_FALSE(errorToBool(R->apply(Verifier))); 66 ASSERT_FALSE(errorToBool(Verifier.verify())); 67 Verifier.reset(); 68 } 69 } 70 } 71 72 TEST(FDRBlockVerifierTest, MissingPIDRecord) { 73 auto Block = LogBuilder() 74 .add<BufferExtents>(20) 75 .add<NewBufferRecord>(1) 76 .add<WallclockRecord>(1, 2) 77 .add<NewCPUIDRecord>(1, 2) 78 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) 79 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) 80 .consume(); 81 BlockVerifier Verifier; 82 for (auto &R : Block) 83 ASSERT_FALSE(errorToBool(R->apply(Verifier))); 84 ASSERT_FALSE(errorToBool(Verifier.verify())); 85 } 86 87 TEST(FDRBlockVerifierTest, MissingBufferExtents) { 88 auto Block = LogBuilder() 89 .add<NewBufferRecord>(1) 90 .add<WallclockRecord>(1, 2) 91 .add<NewCPUIDRecord>(1, 2) 92 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) 93 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) 94 .consume(); 95 BlockVerifier Verifier; 96 for (auto &R : Block) 97 ASSERT_FALSE(errorToBool(R->apply(Verifier))); 98 ASSERT_FALSE(errorToBool(Verifier.verify())); 99 } 100 101 TEST(FDRBlockVerifierTest, IgnoreRecordsAfterEOB) { 102 auto Block = LogBuilder() 103 .add<NewBufferRecord>(1) 104 .add<WallclockRecord>(1, 2) 105 .add<NewCPUIDRecord>(1, 2) 106 .add<EndBufferRecord>() 107 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) 108 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) 109 .consume(); 110 BlockVerifier Verifier; 111 for (auto &R : Block) 112 ASSERT_FALSE(errorToBool(R->apply(Verifier))); 113 ASSERT_FALSE(errorToBool(Verifier.verify())); 114 } 115 116 TEST(FDRBlockVerifierTest, MalformedV2) { 117 auto Block = LogBuilder() 118 .add<NewBufferRecord>(1) 119 .add<WallclockRecord>(1, 2) 120 .add<NewCPUIDRecord>(1, 2) 121 .add<FunctionRecord>(RecordTypes::ENTER, 1, 1) 122 .add<FunctionRecord>(RecordTypes::EXIT, 1, 100) 123 .add<NewBufferRecord>(2) 124 .consume(); 125 BlockVerifier Verifier; 126 127 ASSERT_THAT(Block, SizeIs(6u)); 128 EXPECT_THAT_ERROR(Block[0]->apply(Verifier), Succeeded()); 129 EXPECT_THAT_ERROR(Block[1]->apply(Verifier), Succeeded()); 130 EXPECT_THAT_ERROR(Block[2]->apply(Verifier), Succeeded()); 131 EXPECT_THAT_ERROR(Block[3]->apply(Verifier), Succeeded()); 132 EXPECT_THAT_ERROR(Block[4]->apply(Verifier), Succeeded()); 133 EXPECT_THAT_ERROR(Block[5]->apply(Verifier), Failed()); 134 } 135 136 } // namespace 137 } // namespace xray 138 } // namespace llvm 139