Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 1 | //===- unittest/ProfileData/CoverageMappingTest.cpp -------------------------=// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
Easwaran Raman | a96d5370 | 2016-04-29 18:53:05 +0000 | [diff] [blame] | 10 | #include "llvm/ProfileData/Coverage/CoverageMapping.h" |
| 11 | #include "llvm/ProfileData/Coverage/CoverageMappingReader.h" |
| 12 | #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h" |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 13 | #include "llvm/ProfileData/InstrProfReader.h" |
| 14 | #include "llvm/ProfileData/InstrProfWriter.h" |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 15 | #include "llvm/Support/raw_ostream.h" |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 16 | #include "llvm/Testing/Support/Error.h" |
| 17 | #include "llvm/Testing/Support/SupportHelpers.h" |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 18 | #include "gtest/gtest.h" |
| 19 | |
Mehdi Amini | f6071e1 | 2016-04-18 09:17:29 +0000 | [diff] [blame] | 20 | #include <ostream> |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 21 | #include <utility> |
Justin Bogner | 341ed28 | 2015-02-04 11:19:16 +0000 | [diff] [blame] | 22 | |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 23 | using namespace llvm; |
| 24 | using namespace coverage; |
| 25 | |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 26 | LLVM_NODISCARD static ::testing::AssertionResult |
| 27 | ErrorEquals(coveragemap_error Expected, Error E) { |
Vedant Kumar | 9f0d281 | 2017-06-20 02:05:35 +0000 | [diff] [blame] | 28 | coveragemap_error Found; |
| 29 | std::string FoundMsg; |
| 30 | handleAllErrors(std::move(E), [&](const CoverageMapError &CME) { |
| 31 | Found = CME.get(); |
| 32 | FoundMsg = CME.message(); |
| 33 | }); |
| 34 | if (Expected == Found) |
| 35 | return ::testing::AssertionSuccess(); |
| 36 | return ::testing::AssertionFailure() << "error: " << FoundMsg << "\n"; |
| 37 | } |
| 38 | |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 39 | namespace llvm { |
| 40 | namespace coverage { |
| 41 | void PrintTo(const Counter &C, ::std::ostream *os) { |
| 42 | if (C.isZero()) |
| 43 | *os << "Zero"; |
| 44 | else if (C.isExpression()) |
| 45 | *os << "Expression " << C.getExpressionID(); |
| 46 | else |
| 47 | *os << "Counter " << C.getCounterID(); |
| 48 | } |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 49 | |
| 50 | void PrintTo(const CoverageSegment &S, ::std::ostream *os) { |
| 51 | *os << "CoverageSegment(" << S.Line << ", " << S.Col << ", "; |
| 52 | if (S.HasCount) |
| 53 | *os << S.Count << ", "; |
| 54 | *os << (S.IsRegionEntry ? "true" : "false") << ")"; |
| 55 | } |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 56 | } |
| 57 | } |
| 58 | |
| 59 | namespace { |
| 60 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 61 | struct OutputFunctionCoverageData { |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 62 | StringRef Name; |
| 63 | uint64_t Hash; |
| 64 | std::vector<StringRef> Filenames; |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 65 | std::vector<CounterMappingRegion> Regions; |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 66 | |
Vedant Kumar | f466ec4 | 2016-10-12 22:27:54 +0000 | [diff] [blame] | 67 | OutputFunctionCoverageData() : Hash(0) {} |
| 68 | |
| 69 | OutputFunctionCoverageData(OutputFunctionCoverageData &&OFCD) |
| 70 | : Name(OFCD.Name), Hash(OFCD.Hash), Filenames(std::move(OFCD.Filenames)), |
| 71 | Regions(std::move(OFCD.Regions)) {} |
| 72 | |
| 73 | OutputFunctionCoverageData(const OutputFunctionCoverageData &) = delete; |
| 74 | OutputFunctionCoverageData & |
| 75 | operator=(const OutputFunctionCoverageData &) = delete; |
| 76 | OutputFunctionCoverageData &operator=(OutputFunctionCoverageData &&) = delete; |
| 77 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 78 | void fillCoverageMappingRecord(CoverageMappingRecord &Record) const { |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 79 | Record.FunctionName = Name; |
| 80 | Record.FunctionHash = Hash; |
| 81 | Record.Filenames = Filenames; |
| 82 | Record.Expressions = {}; |
| 83 | Record.MappingRegions = Regions; |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 84 | } |
| 85 | }; |
| 86 | |
| 87 | struct CoverageMappingReaderMock : CoverageMappingReader { |
| 88 | ArrayRef<OutputFunctionCoverageData> Functions; |
| 89 | |
| 90 | CoverageMappingReaderMock(ArrayRef<OutputFunctionCoverageData> Functions) |
| 91 | : Functions(Functions) {} |
| 92 | |
Vedant Kumar | c77570e | 2016-05-19 03:54:45 +0000 | [diff] [blame] | 93 | Error readNextRecord(CoverageMappingRecord &Record) override { |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 94 | if (Functions.empty()) |
Vedant Kumar | c77570e | 2016-05-19 03:54:45 +0000 | [diff] [blame] | 95 | return make_error<CoverageMapError>(coveragemap_error::eof); |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 96 | |
| 97 | Functions.front().fillCoverageMappingRecord(Record); |
| 98 | Functions = Functions.slice(1); |
| 99 | |
Vedant Kumar | c77570e | 2016-05-19 03:54:45 +0000 | [diff] [blame] | 100 | return Error::success(); |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 101 | } |
| 102 | }; |
| 103 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 104 | struct InputFunctionCoverageData { |
| 105 | // Maps the global file index from CoverageMappingTest.Files |
| 106 | // to the index of that file within this function. We can't just use |
| 107 | // global file indexes here because local indexes have to be dense. |
| 108 | // This map is used during serialization to create the virtual file mapping |
| 109 | // (from local fileId to global Index) in the head of the per-function |
| 110 | // coverage mapping data. |
| 111 | SmallDenseMap<unsigned, unsigned> ReverseVirtualFileMapping; |
| 112 | std::string Name; |
| 113 | uint64_t Hash; |
| 114 | std::vector<CounterMappingRegion> Regions; |
| 115 | |
| 116 | InputFunctionCoverageData(std::string Name, uint64_t Hash) |
| 117 | : Name(std::move(Name)), Hash(Hash) {} |
Vedant Kumar | 7c9f5f9 | 2016-10-12 22:44:50 +0000 | [diff] [blame] | 118 | |
| 119 | InputFunctionCoverageData(InputFunctionCoverageData &&IFCD) |
| 120 | : ReverseVirtualFileMapping(std::move(IFCD.ReverseVirtualFileMapping)), |
| 121 | Name(std::move(IFCD.Name)), Hash(IFCD.Hash), |
| 122 | Regions(std::move(IFCD.Regions)) {} |
| 123 | |
| 124 | InputFunctionCoverageData(const InputFunctionCoverageData &) = delete; |
| 125 | InputFunctionCoverageData & |
| 126 | operator=(const InputFunctionCoverageData &) = delete; |
| 127 | InputFunctionCoverageData &operator=(InputFunctionCoverageData &&) = delete; |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 128 | }; |
| 129 | |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 130 | struct CoverageMappingTest : ::testing::TestWithParam<std::pair<bool, bool>> { |
| 131 | bool UseMultipleReaders; |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 132 | StringMap<unsigned> Files; |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 133 | std::vector<InputFunctionCoverageData> InputFunctions; |
| 134 | std::vector<OutputFunctionCoverageData> OutputFunctions; |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 135 | |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 136 | InstrProfWriter ProfileWriter; |
| 137 | std::unique_ptr<IndexedInstrProfReader> ProfileReader; |
| 138 | |
| 139 | std::unique_ptr<CoverageMapping> LoadedCoverage; |
| 140 | |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 141 | void SetUp() override { |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 142 | ProfileWriter.setOutputSparse(GetParam().first); |
| 143 | UseMultipleReaders = GetParam().second; |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 144 | } |
| 145 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 146 | unsigned getGlobalFileIndex(StringRef Name) { |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 147 | auto R = Files.find(Name); |
| 148 | if (R != Files.end()) |
| 149 | return R->second; |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 150 | unsigned Index = Files.size(); |
Benjamin Kramer | b11b352 | 2016-07-21 13:37:48 +0000 | [diff] [blame] | 151 | Files.try_emplace(Name, Index); |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 152 | return Index; |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 153 | } |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 154 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 155 | // Return the file index of file 'Name' for the current function. |
Simon Pilgrim | 84354d9 | 2016-11-20 13:31:13 +0000 | [diff] [blame] | 156 | // Add the file into the global map if necessary. |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 157 | // See also InputFunctionCoverageData::ReverseVirtualFileMapping |
| 158 | // for additional comments. |
| 159 | unsigned getFileIndexForFunction(StringRef Name) { |
| 160 | unsigned GlobalIndex = getGlobalFileIndex(Name); |
| 161 | auto &CurrentFunctionFileMapping = |
| 162 | InputFunctions.back().ReverseVirtualFileMapping; |
| 163 | auto R = CurrentFunctionFileMapping.find(GlobalIndex); |
| 164 | if (R != CurrentFunctionFileMapping.end()) |
| 165 | return R->second; |
| 166 | unsigned IndexInFunction = CurrentFunctionFileMapping.size(); |
| 167 | CurrentFunctionFileMapping.insert( |
| 168 | std::make_pair(GlobalIndex, IndexInFunction)); |
| 169 | return IndexInFunction; |
| 170 | } |
| 171 | |
| 172 | void startFunction(StringRef FuncName, uint64_t Hash) { |
| 173 | InputFunctions.emplace_back(FuncName.str(), Hash); |
| 174 | } |
| 175 | |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 176 | void addCMR(Counter C, StringRef File, unsigned LS, unsigned CS, unsigned LE, |
Vedant Kumar | 33671ba | 2017-09-08 18:44:50 +0000 | [diff] [blame] | 177 | unsigned CE, bool Skipped = false) { |
| 178 | auto &Regions = InputFunctions.back().Regions; |
| 179 | unsigned FileID = getFileIndexForFunction(File); |
| 180 | Regions.push_back( |
| 181 | Skipped ? CounterMappingRegion::makeSkipped(FileID, LS, CS, LE, CE) |
| 182 | : CounterMappingRegion::makeRegion(C, FileID, LS, CS, LE, CE)); |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 183 | } |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 184 | |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 185 | void addExpansionCMR(StringRef File, StringRef ExpandedFile, unsigned LS, |
| 186 | unsigned CS, unsigned LE, unsigned CE) { |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 187 | InputFunctions.back().Regions.push_back(CounterMappingRegion::makeExpansion( |
| 188 | getFileIndexForFunction(File), getFileIndexForFunction(ExpandedFile), |
| 189 | LS, CS, LE, CE)); |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 190 | } |
| 191 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 192 | std::string writeCoverageRegions(InputFunctionCoverageData &Data) { |
| 193 | SmallVector<unsigned, 8> FileIDs(Data.ReverseVirtualFileMapping.size()); |
| 194 | for (const auto &E : Data.ReverseVirtualFileMapping) |
| 195 | FileIDs[E.second] = E.first; |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 196 | std::string Coverage; |
| 197 | llvm::raw_string_ostream OS(Coverage); |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 198 | CoverageMappingWriter(FileIDs, None, Data.Regions).write(OS); |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 199 | return OS.str(); |
| 200 | } |
| 201 | |
Vedant Kumar | 3d62534 | 2016-10-12 22:27:52 +0000 | [diff] [blame] | 202 | void readCoverageRegions(const std::string &Coverage, |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 203 | OutputFunctionCoverageData &Data) { |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 204 | SmallVector<StringRef, 8> Filenames(Files.size()); |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 205 | for (const auto &E : Files) |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 206 | Filenames[E.getValue()] = E.getKey(); |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 207 | std::vector<CounterExpression> Expressions; |
| 208 | RawCoverageMappingReader Reader(Coverage, Filenames, Data.Filenames, |
| 209 | Expressions, Data.Regions); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 210 | EXPECT_THAT_ERROR(Reader.read(), Succeeded()); |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 211 | } |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 212 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 213 | void writeAndReadCoverageRegions(bool EmitFilenames = true) { |
| 214 | OutputFunctions.resize(InputFunctions.size()); |
| 215 | for (unsigned I = 0; I < InputFunctions.size(); ++I) { |
| 216 | std::string Regions = writeCoverageRegions(InputFunctions[I]); |
| 217 | readCoverageRegions(Regions, OutputFunctions[I]); |
| 218 | OutputFunctions[I].Name = InputFunctions[I].Name; |
| 219 | OutputFunctions[I].Hash = InputFunctions[I].Hash; |
| 220 | if (!EmitFilenames) |
| 221 | OutputFunctions[I].Filenames.clear(); |
| 222 | } |
| 223 | } |
| 224 | |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 225 | void readProfCounts() { |
| 226 | auto Profile = ProfileWriter.writeBuffer(); |
| 227 | auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile)); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 228 | EXPECT_THAT_ERROR(ReaderOrErr.takeError(), Succeeded()); |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 229 | ProfileReader = std::move(ReaderOrErr.get()); |
| 230 | } |
| 231 | |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 232 | Expected<std::unique_ptr<CoverageMapping>> readOutputFunctions() { |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 233 | std::vector<std::unique_ptr<CoverageMappingReader>> CoverageReaders; |
Vedant Kumar | 1626414 | 2017-06-30 00:45:26 +0000 | [diff] [blame] | 234 | if (UseMultipleReaders) { |
| 235 | for (const auto &OF : OutputFunctions) { |
| 236 | ArrayRef<OutputFunctionCoverageData> Funcs(OF); |
| 237 | CoverageReaders.push_back( |
| 238 | make_unique<CoverageMappingReaderMock>(Funcs)); |
| 239 | } |
| 240 | } else { |
Vedant Kumar | 461aeca | 2017-06-30 04:04:44 +0000 | [diff] [blame] | 241 | ArrayRef<OutputFunctionCoverageData> Funcs(OutputFunctions); |
Vedant Kumar | 1626414 | 2017-06-30 00:45:26 +0000 | [diff] [blame] | 242 | CoverageReaders.push_back( |
Vedant Kumar | 461aeca | 2017-06-30 04:04:44 +0000 | [diff] [blame] | 243 | make_unique<CoverageMappingReaderMock>(Funcs)); |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 244 | } |
| 245 | return CoverageMapping::load(CoverageReaders, *ProfileReader); |
| 246 | } |
| 247 | |
Vedant Kumar | 9f0d281 | 2017-06-20 02:05:35 +0000 | [diff] [blame] | 248 | Error loadCoverageMapping(bool EmitFilenames = true) { |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 249 | readProfCounts(); |
| 250 | writeAndReadCoverageRegions(EmitFilenames); |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 251 | auto CoverageOrErr = readOutputFunctions(); |
Vedant Kumar | 9f0d281 | 2017-06-20 02:05:35 +0000 | [diff] [blame] | 252 | if (!CoverageOrErr) |
| 253 | return CoverageOrErr.takeError(); |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 254 | LoadedCoverage = std::move(CoverageOrErr.get()); |
Vedant Kumar | 9f0d281 | 2017-06-20 02:05:35 +0000 | [diff] [blame] | 255 | return Error::success(); |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 256 | } |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 257 | }; |
| 258 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 259 | TEST_P(CoverageMappingTest, basic_write_read) { |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 260 | startFunction("func", 0x1234); |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 261 | addCMR(Counter::getCounter(0), "foo", 1, 1, 1, 1); |
| 262 | addCMR(Counter::getCounter(1), "foo", 2, 1, 2, 2); |
| 263 | addCMR(Counter::getZero(), "foo", 3, 1, 3, 4); |
| 264 | addCMR(Counter::getCounter(2), "foo", 4, 1, 4, 8); |
| 265 | addCMR(Counter::getCounter(3), "bar", 1, 2, 3, 4); |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 266 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 267 | writeAndReadCoverageRegions(); |
| 268 | ASSERT_EQ(1u, InputFunctions.size()); |
| 269 | ASSERT_EQ(1u, OutputFunctions.size()); |
| 270 | InputFunctionCoverageData &Input = InputFunctions.back(); |
| 271 | OutputFunctionCoverageData &Output = OutputFunctions.back(); |
| 272 | |
| 273 | size_t N = makeArrayRef(Input.Regions).size(); |
| 274 | ASSERT_EQ(N, Output.Regions.size()); |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 275 | for (size_t I = 0; I < N; ++I) { |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 276 | ASSERT_EQ(Input.Regions[I].Count, Output.Regions[I].Count); |
| 277 | ASSERT_EQ(Input.Regions[I].FileID, Output.Regions[I].FileID); |
| 278 | ASSERT_EQ(Input.Regions[I].startLoc(), Output.Regions[I].startLoc()); |
| 279 | ASSERT_EQ(Input.Regions[I].endLoc(), Output.Regions[I].endLoc()); |
| 280 | ASSERT_EQ(Input.Regions[I].Kind, Output.Regions[I].Kind); |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 281 | } |
| 282 | } |
| 283 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 284 | TEST_P(CoverageMappingTest, correct_deserialize_for_more_than_two_files) { |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 285 | const char *FileNames[] = {"bar", "baz", "foo"}; |
| 286 | static const unsigned N = array_lengthof(FileNames); |
| 287 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 288 | startFunction("func", 0x1234); |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 289 | for (unsigned I = 0; I < N; ++I) |
| 290 | // Use LineStart to hold the index of the file name |
| 291 | // in order to preserve that information during possible sorting of CMRs. |
| 292 | addCMR(Counter::getCounter(0), FileNames[I], I, 1, I, 1); |
| 293 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 294 | writeAndReadCoverageRegions(); |
| 295 | ASSERT_EQ(1u, OutputFunctions.size()); |
| 296 | OutputFunctionCoverageData &Output = OutputFunctions.back(); |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 297 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 298 | ASSERT_EQ(N, Output.Regions.size()); |
| 299 | ASSERT_EQ(N, Output.Filenames.size()); |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 300 | |
| 301 | for (unsigned I = 0; I < N; ++I) { |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 302 | ASSERT_GT(N, Output.Regions[I].FileID); |
| 303 | ASSERT_GT(N, Output.Regions[I].LineStart); |
| 304 | EXPECT_EQ(FileNames[Output.Regions[I].LineStart], |
| 305 | Output.Filenames[Output.Regions[I].FileID]); |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 306 | } |
| 307 | } |
| 308 | |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 309 | static const auto Err = [](Error E) { FAIL(); }; |
| 310 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 311 | TEST_P(CoverageMappingTest, load_coverage_for_more_than_two_files) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 312 | ProfileWriter.addRecord({"func", 0x1234, {0}}, Err); |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 313 | |
| 314 | const char *FileNames[] = {"bar", "baz", "foo"}; |
| 315 | static const unsigned N = array_lengthof(FileNames); |
| 316 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 317 | startFunction("func", 0x1234); |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 318 | for (unsigned I = 0; I < N; ++I) |
| 319 | // Use LineStart to hold the index of the file name |
| 320 | // in order to preserve that information during possible sorting of CMRs. |
| 321 | addCMR(Counter::getCounter(0), FileNames[I], I, 1, I, 1); |
| 322 | |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 323 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Igor Kudrin | 77eb420 | 2016-04-14 10:43:37 +0000 | [diff] [blame] | 324 | |
| 325 | for (unsigned I = 0; I < N; ++I) { |
| 326 | CoverageData Data = LoadedCoverage->getCoverageForFile(FileNames[I]); |
| 327 | ASSERT_TRUE(!Data.empty()); |
| 328 | EXPECT_EQ(I, Data.begin()->Line); |
| 329 | } |
| 330 | } |
| 331 | |
Vedant Kumar | 9f0d281 | 2017-06-20 02:05:35 +0000 | [diff] [blame] | 332 | TEST_P(CoverageMappingTest, load_coverage_with_bogus_function_name) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 333 | ProfileWriter.addRecord({"", 0x1234, {10}}, Err); |
Vedant Kumar | 9f0d281 | 2017-06-20 02:05:35 +0000 | [diff] [blame] | 334 | startFunction("", 0x1234); |
| 335 | addCMR(Counter::getCounter(0), "foo", 1, 1, 5, 5); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 336 | EXPECT_TRUE(ErrorEquals(coveragemap_error::malformed, loadCoverageMapping())); |
Vedant Kumar | 9f0d281 | 2017-06-20 02:05:35 +0000 | [diff] [blame] | 337 | } |
| 338 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 339 | TEST_P(CoverageMappingTest, load_coverage_for_several_functions) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 340 | ProfileWriter.addRecord({"func1", 0x1234, {10}}, Err); |
| 341 | ProfileWriter.addRecord({"func2", 0x2345, {20}}, Err); |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 342 | |
| 343 | startFunction("func1", 0x1234); |
| 344 | addCMR(Counter::getCounter(0), "foo", 1, 1, 5, 5); |
| 345 | |
| 346 | startFunction("func2", 0x2345); |
| 347 | addCMR(Counter::getCounter(0), "bar", 2, 2, 6, 6); |
| 348 | |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 349 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 350 | |
| 351 | const auto FunctionRecords = LoadedCoverage->getCoveredFunctions(); |
Simon Pilgrim | 892d11d | 2017-03-11 19:38:22 +0000 | [diff] [blame] | 352 | EXPECT_EQ(2, std::distance(FunctionRecords.begin(), FunctionRecords.end())); |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 353 | for (const auto &FunctionRecord : FunctionRecords) { |
| 354 | CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord); |
| 355 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 356 | ASSERT_EQ(2U, Segments.size()); |
| 357 | if (FunctionRecord.Name == "func1") { |
| 358 | EXPECT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]); |
| 359 | EXPECT_EQ(CoverageSegment(5, 5, false), Segments[1]); |
| 360 | } else { |
| 361 | ASSERT_EQ("func2", FunctionRecord.Name); |
| 362 | EXPECT_EQ(CoverageSegment(2, 2, 20, true), Segments[0]); |
| 363 | EXPECT_EQ(CoverageSegment(6, 6, false), Segments[1]); |
| 364 | } |
| 365 | } |
| 366 | } |
| 367 | |
Vedant Kumar | 33671ba | 2017-09-08 18:44:50 +0000 | [diff] [blame] | 368 | TEST_P(CoverageMappingTest, create_combined_regions) { |
| 369 | ProfileWriter.addRecord({"func1", 0x1234, {1, 2, 3}}, Err); |
| 370 | startFunction("func1", 0x1234); |
| 371 | |
| 372 | // Given regions which start at the same location, emit a segment for the |
| 373 | // last region. |
| 374 | addCMR(Counter::getCounter(0), "file1", 1, 1, 2, 2); |
| 375 | addCMR(Counter::getCounter(1), "file1", 1, 1, 2, 2); |
| 376 | addCMR(Counter::getCounter(2), "file1", 1, 1, 2, 2); |
| 377 | |
| 378 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
| 379 | const auto FunctionRecords = LoadedCoverage->getCoveredFunctions(); |
| 380 | const auto &FunctionRecord = *FunctionRecords.begin(); |
| 381 | CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord); |
| 382 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 383 | |
| 384 | ASSERT_EQ(2U, Segments.size()); |
| 385 | EXPECT_EQ(CoverageSegment(1, 1, 6, true), Segments[0]); |
| 386 | EXPECT_EQ(CoverageSegment(2, 2, false), Segments[1]); |
| 387 | } |
| 388 | |
| 389 | TEST_P(CoverageMappingTest, skipped_segments_have_no_count) { |
| 390 | ProfileWriter.addRecord({"func1", 0x1234, {1}}, Err); |
| 391 | startFunction("func1", 0x1234); |
| 392 | |
| 393 | addCMR(Counter::getCounter(0), "file1", 1, 1, 5, 5); |
| 394 | addCMR(Counter::getCounter(0), "file1", 5, 1, 5, 5, /*Skipped=*/true); |
| 395 | |
| 396 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
| 397 | const auto FunctionRecords = LoadedCoverage->getCoveredFunctions(); |
| 398 | const auto &FunctionRecord = *FunctionRecords.begin(); |
| 399 | CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord); |
| 400 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 401 | |
| 402 | ASSERT_EQ(3U, Segments.size()); |
| 403 | EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]); |
| 404 | EXPECT_EQ(CoverageSegment(5, 1, true), Segments[1]); |
| 405 | EXPECT_EQ(CoverageSegment(5, 5, false), Segments[2]); |
| 406 | } |
| 407 | |
| 408 | TEST_P(CoverageMappingTest, multiple_regions_end_after_parent_ends) { |
| 409 | ProfileWriter.addRecord({"func1", 0x1234, {1, 0}}, Err); |
| 410 | startFunction("func1", 0x1234); |
| 411 | |
| 412 | // 1| F{ a{ |
| 413 | // 2| |
| 414 | // 3| a} b{ c{ |
| 415 | // 4| |
| 416 | // 5| b} |
| 417 | // 6| |
| 418 | // 7| c} d{ e{ |
| 419 | // 8| |
| 420 | // 9| d} e} F} |
NAKAMURA Takumi | 23483f0 | 2017-09-09 06:19:53 +0000 | [diff] [blame] | 421 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); // < F |
| 422 | addCMR(Counter::getCounter(0), "file1", 1, 1, 3, 5); // < a |
| 423 | addCMR(Counter::getCounter(0), "file1", 3, 5, 5, 4); // < b |
| 424 | addCMR(Counter::getCounter(1), "file1", 3, 5, 7, 3); // < c |
| 425 | addCMR(Counter::getCounter(1), "file1", 7, 3, 9, 2); // < d |
| 426 | addCMR(Counter::getCounter(1), "file1", 7, 7, 9, 7); // < e |
Vedant Kumar | 33671ba | 2017-09-08 18:44:50 +0000 | [diff] [blame] | 427 | |
| 428 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
| 429 | const auto FunctionRecords = LoadedCoverage->getCoveredFunctions(); |
| 430 | const auto &FunctionRecord = *FunctionRecords.begin(); |
| 431 | CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord); |
| 432 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 433 | |
| 434 | // Old output (not sorted or unique): |
| 435 | // Segment at 1:1 with count 1 |
| 436 | // Segment at 1:1 with count 1 |
| 437 | // Segment at 3:5 with count 1 |
| 438 | // Segment at 3:5 with count 0 |
| 439 | // Segment at 3:5 with count 1 |
| 440 | // Segment at 5:4 with count 0 |
| 441 | // Segment at 7:3 with count 1 |
| 442 | // Segment at 7:3 with count 0 |
| 443 | // Segment at 7:7 with count 0 |
| 444 | // Segment at 9:7 with count 0 |
| 445 | // Segment at 9:2 with count 1 |
| 446 | // Top level segment at 9:9 |
| 447 | |
| 448 | // New output (sorted and unique): |
| 449 | // Segment at 1:1 (count = 1), RegionEntry |
| 450 | // Segment at 3:5 (count = 1), RegionEntry |
| 451 | // Segment at 5:4 (count = 0) |
| 452 | // Segment at 7:3 (count = 0), RegionEntry |
| 453 | // Segment at 7:7 (count = 0), RegionEntry |
| 454 | // Segment at 9:2 (count = 0) |
| 455 | // Segment at 9:7 (count = 1) |
| 456 | // Segment at 9:9 (count = 0), Skipped |
| 457 | |
| 458 | ASSERT_EQ(8U, Segments.size()); |
| 459 | EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]); |
| 460 | EXPECT_EQ(CoverageSegment(3, 5, 1, true), Segments[1]); |
| 461 | EXPECT_EQ(CoverageSegment(5, 4, 0, false), Segments[2]); |
| 462 | EXPECT_EQ(CoverageSegment(7, 3, 0, true), Segments[3]); |
| 463 | EXPECT_EQ(CoverageSegment(7, 7, 0, true), Segments[4]); |
| 464 | EXPECT_EQ(CoverageSegment(9, 2, 0, false), Segments[5]); |
| 465 | EXPECT_EQ(CoverageSegment(9, 7, 1, false), Segments[6]); |
| 466 | EXPECT_EQ(CoverageSegment(9, 9, false), Segments[7]); |
| 467 | } |
| 468 | |
Vedant Kumar | 310bfcc | 2017-11-30 00:28:23 +0000 | [diff] [blame] | 469 | TEST_P(CoverageMappingTest, multiple_completed_segments_at_same_loc) { |
| 470 | ProfileWriter.addRecord({"func1", 0x1234, {0, 1, 2}}, Err); |
| 471 | startFunction("func1", 0x1234); |
| 472 | |
Vedant Kumar | dea3d88 | 2017-12-07 00:01:15 +0000 | [diff] [blame] | 473 | // PR35495 |
Vedant Kumar | 310bfcc | 2017-11-30 00:28:23 +0000 | [diff] [blame] | 474 | addCMR(Counter::getCounter(1), "file1", 2, 1, 18, 2); |
Vedant Kumar | dea3d88 | 2017-12-07 00:01:15 +0000 | [diff] [blame] | 475 | addCMR(Counter::getCounter(0), "file1", 8, 10, 14, 6); |
Vedant Kumar | 310bfcc | 2017-11-30 00:28:23 +0000 | [diff] [blame] | 476 | addCMR(Counter::getCounter(0), "file1", 8, 12, 14, 6); |
| 477 | addCMR(Counter::getCounter(1), "file1", 9, 1, 14, 6); |
| 478 | addCMR(Counter::getCounter(2), "file1", 11, 13, 11, 14); |
| 479 | |
| 480 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
| 481 | const auto FunctionRecords = LoadedCoverage->getCoveredFunctions(); |
| 482 | const auto &FunctionRecord = *FunctionRecords.begin(); |
| 483 | CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord); |
| 484 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 485 | |
Vedant Kumar | dea3d88 | 2017-12-07 00:01:15 +0000 | [diff] [blame] | 486 | ASSERT_EQ(7U, Segments.size()); |
Vedant Kumar | 310bfcc | 2017-11-30 00:28:23 +0000 | [diff] [blame] | 487 | EXPECT_EQ(CoverageSegment(2, 1, 1, true), Segments[0]); |
Vedant Kumar | dea3d88 | 2017-12-07 00:01:15 +0000 | [diff] [blame] | 488 | EXPECT_EQ(CoverageSegment(8, 10, 0, true), Segments[1]); |
| 489 | EXPECT_EQ(CoverageSegment(8, 12, 0, true), Segments[2]); |
| 490 | EXPECT_EQ(CoverageSegment(9, 1, 1, true), Segments[3]); |
| 491 | EXPECT_EQ(CoverageSegment(11, 13, 2, true), Segments[4]); |
Vedant Kumar | 310bfcc | 2017-11-30 00:28:23 +0000 | [diff] [blame] | 492 | // Use count=1 (from 9:1 -> 14:6), not count=0 (from 8:12 -> 14:6). |
Vedant Kumar | dea3d88 | 2017-12-07 00:01:15 +0000 | [diff] [blame] | 493 | EXPECT_EQ(CoverageSegment(11, 14, 1, false), Segments[5]); |
| 494 | EXPECT_EQ(CoverageSegment(18, 2, false), Segments[6]); |
Vedant Kumar | 310bfcc | 2017-11-30 00:28:23 +0000 | [diff] [blame] | 495 | } |
| 496 | |
Vedant Kumar | 33671ba | 2017-09-08 18:44:50 +0000 | [diff] [blame] | 497 | TEST_P(CoverageMappingTest, dont_emit_redundant_segments) { |
| 498 | ProfileWriter.addRecord({"func1", 0x1234, {1, 1}}, Err); |
| 499 | startFunction("func1", 0x1234); |
| 500 | |
| 501 | addCMR(Counter::getCounter(0), "file1", 1, 1, 4, 4); |
| 502 | addCMR(Counter::getCounter(1), "file1", 2, 2, 5, 5); |
| 503 | addCMR(Counter::getCounter(0), "file1", 3, 3, 6, 6); |
| 504 | |
| 505 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
| 506 | const auto FunctionRecords = LoadedCoverage->getCoveredFunctions(); |
| 507 | const auto &FunctionRecord = *FunctionRecords.begin(); |
| 508 | CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord); |
| 509 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 510 | |
| 511 | ASSERT_EQ(5U, Segments.size()); |
| 512 | EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]); |
| 513 | EXPECT_EQ(CoverageSegment(2, 2, 1, true), Segments[1]); |
| 514 | EXPECT_EQ(CoverageSegment(3, 3, 1, true), Segments[2]); |
| 515 | EXPECT_EQ(CoverageSegment(4, 4, 1, false), Segments[3]); |
| 516 | // A closing segment starting at 5:5 would be redundant: it would have the |
| 517 | // same count as the segment starting at 4:4, and has all the same metadata. |
| 518 | EXPECT_EQ(CoverageSegment(6, 6, false), Segments[4]); |
| 519 | } |
| 520 | |
| 521 | TEST_P(CoverageMappingTest, dont_emit_closing_segment_at_new_region_start) { |
| 522 | ProfileWriter.addRecord({"func1", 0x1234, {1}}, Err); |
| 523 | startFunction("func1", 0x1234); |
| 524 | |
| 525 | addCMR(Counter::getCounter(0), "file1", 1, 1, 6, 5); |
| 526 | addCMR(Counter::getCounter(0), "file1", 2, 2, 6, 5); |
| 527 | addCMR(Counter::getCounter(0), "file1", 3, 3, 6, 5); |
| 528 | addCMR(Counter::getCounter(0), "file1", 6, 5, 7, 7); |
| 529 | |
| 530 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
| 531 | const auto FunctionRecords = LoadedCoverage->getCoveredFunctions(); |
| 532 | const auto &FunctionRecord = *FunctionRecords.begin(); |
| 533 | CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord); |
| 534 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 535 | |
| 536 | ASSERT_EQ(5U, Segments.size()); |
| 537 | EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]); |
| 538 | EXPECT_EQ(CoverageSegment(2, 2, 1, true), Segments[1]); |
| 539 | EXPECT_EQ(CoverageSegment(3, 3, 1, true), Segments[2]); |
| 540 | EXPECT_EQ(CoverageSegment(6, 5, 1, true), Segments[3]); |
| 541 | // The old segment builder would get this wrong by emitting multiple segments |
| 542 | // which start at 6:5 (a few of which were skipped segments). We should just |
| 543 | // get a segment for the region entry. |
| 544 | EXPECT_EQ(CoverageSegment(7, 7, false), Segments[4]); |
| 545 | } |
| 546 | |
| 547 | TEST_P(CoverageMappingTest, handle_consecutive_regions_with_zero_length) { |
| 548 | ProfileWriter.addRecord({"func1", 0x1234, {1, 2}}, Err); |
| 549 | startFunction("func1", 0x1234); |
| 550 | |
| 551 | addCMR(Counter::getCounter(0), "file1", 1, 1, 1, 1); |
| 552 | addCMR(Counter::getCounter(1), "file1", 1, 1, 1, 1); |
| 553 | addCMR(Counter::getCounter(0), "file1", 1, 1, 1, 1); |
| 554 | addCMR(Counter::getCounter(1), "file1", 1, 1, 1, 1); |
| 555 | addCMR(Counter::getCounter(0), "file1", 1, 1, 1, 1); |
| 556 | |
| 557 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
| 558 | const auto FunctionRecords = LoadedCoverage->getCoveredFunctions(); |
| 559 | const auto &FunctionRecord = *FunctionRecords.begin(); |
| 560 | CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord); |
| 561 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 562 | |
| 563 | ASSERT_EQ(1U, Segments.size()); |
| 564 | EXPECT_EQ(CoverageSegment(1, 1, true), Segments[0]); |
| 565 | // We need to get a skipped segment starting at 1:1. In this case there is |
| 566 | // also a region entry at 1:1. |
| 567 | } |
| 568 | |
| 569 | TEST_P(CoverageMappingTest, handle_sandwiched_zero_length_region) { |
| 570 | ProfileWriter.addRecord({"func1", 0x1234, {2, 1}}, Err); |
| 571 | startFunction("func1", 0x1234); |
| 572 | |
| 573 | addCMR(Counter::getCounter(0), "file1", 1, 5, 4, 4); |
| 574 | addCMR(Counter::getCounter(1), "file1", 1, 9, 1, 50); |
| 575 | addCMR(Counter::getCounter(1), "file1", 2, 7, 2, 34); |
| 576 | addCMR(Counter::getCounter(1), "file1", 3, 5, 3, 21); |
| 577 | addCMR(Counter::getCounter(1), "file1", 3, 21, 3, 21); |
| 578 | addCMR(Counter::getCounter(1), "file1", 4, 12, 4, 17); |
| 579 | |
| 580 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
| 581 | const auto FunctionRecords = LoadedCoverage->getCoveredFunctions(); |
| 582 | const auto &FunctionRecord = *FunctionRecords.begin(); |
| 583 | CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord); |
| 584 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 585 | |
| 586 | ASSERT_EQ(10U, Segments.size()); |
| 587 | EXPECT_EQ(CoverageSegment(1, 5, 2, true), Segments[0]); |
| 588 | EXPECT_EQ(CoverageSegment(1, 9, 1, true), Segments[1]); |
| 589 | EXPECT_EQ(CoverageSegment(1, 50, 2, false), Segments[2]); |
| 590 | EXPECT_EQ(CoverageSegment(2, 7, 1, true), Segments[3]); |
| 591 | EXPECT_EQ(CoverageSegment(2, 34, 2, false), Segments[4]); |
| 592 | EXPECT_EQ(CoverageSegment(3, 5, 1, true), Segments[5]); |
| 593 | EXPECT_EQ(CoverageSegment(3, 21, 2, true), Segments[6]); |
| 594 | // Handle the zero-length region by creating a segment with its predecessor's |
| 595 | // count (i.e the count from 1:5 -> 4:4). |
| 596 | EXPECT_EQ(CoverageSegment(4, 4, false), Segments[7]); |
| 597 | // The area between 4:4 and 4:12 is skipped. |
| 598 | EXPECT_EQ(CoverageSegment(4, 12, 1, true), Segments[8]); |
| 599 | EXPECT_EQ(CoverageSegment(4, 17, false), Segments[9]); |
| 600 | } |
| 601 | |
| 602 | TEST_P(CoverageMappingTest, handle_last_completed_region) { |
| 603 | ProfileWriter.addRecord({"func1", 0x1234, {1, 2, 3, 4}}, Err); |
| 604 | startFunction("func1", 0x1234); |
| 605 | |
| 606 | addCMR(Counter::getCounter(0), "file1", 1, 1, 8, 8); |
| 607 | addCMR(Counter::getCounter(1), "file1", 2, 2, 5, 5); |
| 608 | addCMR(Counter::getCounter(2), "file1", 3, 3, 4, 4); |
| 609 | addCMR(Counter::getCounter(3), "file1", 6, 6, 7, 7); |
| 610 | |
| 611 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
| 612 | const auto FunctionRecords = LoadedCoverage->getCoveredFunctions(); |
| 613 | const auto &FunctionRecord = *FunctionRecords.begin(); |
| 614 | CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord); |
| 615 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 616 | |
| 617 | ASSERT_EQ(8U, Segments.size()); |
| 618 | EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]); |
| 619 | EXPECT_EQ(CoverageSegment(2, 2, 2, true), Segments[1]); |
| 620 | EXPECT_EQ(CoverageSegment(3, 3, 3, true), Segments[2]); |
| 621 | EXPECT_EQ(CoverageSegment(4, 4, 2, false), Segments[3]); |
| 622 | EXPECT_EQ(CoverageSegment(5, 5, 1, false), Segments[4]); |
| 623 | EXPECT_EQ(CoverageSegment(6, 6, 4, true), Segments[5]); |
| 624 | EXPECT_EQ(CoverageSegment(7, 7, 1, false), Segments[6]); |
| 625 | EXPECT_EQ(CoverageSegment(8, 8, false), Segments[7]); |
| 626 | } |
| 627 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 628 | TEST_P(CoverageMappingTest, expansion_gets_first_counter) { |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 629 | startFunction("func", 0x1234); |
Justin Bogner | ad295b5 | 2015-02-17 21:33:43 +0000 | [diff] [blame] | 630 | addCMR(Counter::getCounter(1), "foo", 10, 1, 10, 2); |
| 631 | // This starts earlier in "foo", so the expansion should get its counter. |
| 632 | addCMR(Counter::getCounter(2), "foo", 1, 1, 20, 1); |
| 633 | addExpansionCMR("bar", "foo", 3, 3, 3, 3); |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 634 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 635 | writeAndReadCoverageRegions(); |
| 636 | ASSERT_EQ(1u, OutputFunctions.size()); |
| 637 | OutputFunctionCoverageData &Output = OutputFunctions.back(); |
| 638 | |
| 639 | ASSERT_EQ(CounterMappingRegion::ExpansionRegion, Output.Regions[2].Kind); |
| 640 | ASSERT_EQ(Counter::getCounter(2), Output.Regions[2].Count); |
| 641 | ASSERT_EQ(3U, Output.Regions[2].LineStart); |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 642 | } |
| 643 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 644 | TEST_P(CoverageMappingTest, basic_coverage_iteration) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 645 | ProfileWriter.addRecord({"func", 0x1234, {30, 20, 10, 0}}, Err); |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 646 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 647 | startFunction("func", 0x1234); |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 648 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
| 649 | addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7); |
| 650 | addCMR(Counter::getCounter(2), "file1", 5, 8, 9, 1); |
| 651 | addCMR(Counter::getCounter(3), "file1", 10, 10, 11, 11); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 652 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Justin Bogner | 94da968 | 2015-02-18 18:01:14 +0000 | [diff] [blame] | 653 | |
| 654 | CoverageData Data = LoadedCoverage->getCoverageForFile("file1"); |
| 655 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 656 | ASSERT_EQ(7U, Segments.size()); |
| 657 | ASSERT_EQ(CoverageSegment(1, 1, 20, true), Segments[0]); |
| 658 | ASSERT_EQ(CoverageSegment(4, 7, 30, false), Segments[1]); |
| 659 | ASSERT_EQ(CoverageSegment(5, 8, 10, true), Segments[2]); |
| 660 | ASSERT_EQ(CoverageSegment(9, 1, 30, false), Segments[3]); |
| 661 | ASSERT_EQ(CoverageSegment(9, 9, false), Segments[4]); |
| 662 | ASSERT_EQ(CoverageSegment(10, 10, 0, true), Segments[5]); |
| 663 | ASSERT_EQ(CoverageSegment(11, 11, false), Segments[6]); |
| 664 | } |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 665 | |
Vedant Kumar | 2ce33a5 | 2017-10-18 23:58:28 +0000 | [diff] [blame] | 666 | TEST_P(CoverageMappingTest, test_line_coverage_iterator) { |
| 667 | ProfileWriter.addRecord({"func", 0x1234, {30, 20, 10, 0}}, Err); |
| 668 | |
| 669 | startFunction("func", 0x1234); |
| 670 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
| 671 | addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7); |
| 672 | addCMR(Counter::getCounter(2), "file1", 5, 8, 9, 1); |
| 673 | addCMR(Counter::getCounter(3), "file1", 10, 10, 11, 11); |
| 674 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
| 675 | |
| 676 | CoverageData Data = LoadedCoverage->getCoverageForFile("file1"); |
| 677 | |
Vedant Kumar | 120c3be | 2017-10-19 06:16:23 +0000 | [diff] [blame] | 678 | unsigned Line = 0; |
Vedant Kumar | f361756 | 2017-11-09 02:33:43 +0000 | [diff] [blame] | 679 | unsigned LineCounts[] = {20, 20, 20, 20, 30, 10, 10, 10, 10, 0, 0}; |
Vedant Kumar | 2ce33a5 | 2017-10-18 23:58:28 +0000 | [diff] [blame] | 680 | for (const auto &LCS : getLineCoverageStats(Data)) { |
Vedant Kumar | 120c3be | 2017-10-19 06:16:23 +0000 | [diff] [blame] | 681 | ASSERT_EQ(Line + 1, LCS.getLine()); |
Vedant Kumar | f361756 | 2017-11-09 02:33:43 +0000 | [diff] [blame] | 682 | errs() << "Line: " << Line + 1 << ", count = " << LCS.getExecutionCount() << "\n"; |
Vedant Kumar | 120c3be | 2017-10-19 06:16:23 +0000 | [diff] [blame] | 683 | ASSERT_EQ(LineCounts[Line], LCS.getExecutionCount()); |
| 684 | ++Line; |
Vedant Kumar | 2ce33a5 | 2017-10-18 23:58:28 +0000 | [diff] [blame] | 685 | } |
Vedant Kumar | 120c3be | 2017-10-19 06:16:23 +0000 | [diff] [blame] | 686 | ASSERT_EQ(11U, Line); |
Vedant Kumar | 2ce33a5 | 2017-10-18 23:58:28 +0000 | [diff] [blame] | 687 | } |
| 688 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 689 | TEST_P(CoverageMappingTest, uncovered_function) { |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 690 | startFunction("func", 0x1234); |
Justin Bogner | e0eae15 | 2015-02-18 18:40:46 +0000 | [diff] [blame] | 691 | addCMR(Counter::getZero(), "file1", 1, 2, 3, 4); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 692 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Justin Bogner | e0eae15 | 2015-02-18 18:40:46 +0000 | [diff] [blame] | 693 | |
| 694 | CoverageData Data = LoadedCoverage->getCoverageForFile("file1"); |
| 695 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 696 | ASSERT_EQ(2U, Segments.size()); |
| 697 | ASSERT_EQ(CoverageSegment(1, 2, 0, true), Segments[0]); |
| 698 | ASSERT_EQ(CoverageSegment(3, 4, false), Segments[1]); |
| 699 | } |
| 700 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 701 | TEST_P(CoverageMappingTest, uncovered_function_with_mapping) { |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 702 | startFunction("func", 0x1234); |
Justin Bogner | 42ab8c0 | 2015-05-13 22:03:04 +0000 | [diff] [blame] | 703 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
| 704 | addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 705 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Justin Bogner | 42ab8c0 | 2015-05-13 22:03:04 +0000 | [diff] [blame] | 706 | |
| 707 | CoverageData Data = LoadedCoverage->getCoverageForFile("file1"); |
| 708 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 709 | ASSERT_EQ(3U, Segments.size()); |
| 710 | ASSERT_EQ(CoverageSegment(1, 1, 0, true), Segments[0]); |
| 711 | ASSERT_EQ(CoverageSegment(4, 7, 0, false), Segments[1]); |
| 712 | ASSERT_EQ(CoverageSegment(9, 9, false), Segments[2]); |
| 713 | } |
| 714 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 715 | TEST_P(CoverageMappingTest, combine_regions) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 716 | ProfileWriter.addRecord({"func", 0x1234, {10, 20, 30}}, Err); |
Justin Bogner | 798787c | 2015-02-18 19:01:06 +0000 | [diff] [blame] | 717 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 718 | startFunction("func", 0x1234); |
Justin Bogner | 798787c | 2015-02-18 19:01:06 +0000 | [diff] [blame] | 719 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
| 720 | addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4); |
| 721 | addCMR(Counter::getCounter(2), "file1", 3, 3, 4, 4); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 722 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Justin Bogner | 798787c | 2015-02-18 19:01:06 +0000 | [diff] [blame] | 723 | |
| 724 | CoverageData Data = LoadedCoverage->getCoverageForFile("file1"); |
| 725 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 726 | ASSERT_EQ(4U, Segments.size()); |
| 727 | ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]); |
| 728 | ASSERT_EQ(CoverageSegment(3, 3, 50, true), Segments[1]); |
| 729 | ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]); |
| 730 | ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]); |
| 731 | } |
| 732 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 733 | TEST_P(CoverageMappingTest, restore_combined_counter_after_nested_region) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 734 | ProfileWriter.addRecord({"func", 0x1234, {10, 20, 40}}, Err); |
Igor Kudrin | 3c7ad33 | 2016-04-25 09:43:37 +0000 | [diff] [blame] | 735 | |
| 736 | startFunction("func", 0x1234); |
| 737 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
| 738 | addCMR(Counter::getCounter(1), "file1", 1, 1, 9, 9); |
| 739 | addCMR(Counter::getCounter(2), "file1", 3, 3, 5, 5); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 740 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Igor Kudrin | 3c7ad33 | 2016-04-25 09:43:37 +0000 | [diff] [blame] | 741 | |
| 742 | CoverageData Data = LoadedCoverage->getCoverageForFile("file1"); |
| 743 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 744 | ASSERT_EQ(4U, Segments.size()); |
| 745 | EXPECT_EQ(CoverageSegment(1, 1, 30, true), Segments[0]); |
| 746 | EXPECT_EQ(CoverageSegment(3, 3, 40, true), Segments[1]); |
| 747 | EXPECT_EQ(CoverageSegment(5, 5, 30, false), Segments[2]); |
| 748 | EXPECT_EQ(CoverageSegment(9, 9, false), Segments[3]); |
| 749 | } |
| 750 | |
Igor Kudrin | 68065ba | 2016-05-05 09:39:45 +0000 | [diff] [blame] | 751 | // If CodeRegions and ExpansionRegions cover the same area, |
| 752 | // only counts of CodeRegions should be used. |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 753 | TEST_P(CoverageMappingTest, dont_combine_expansions) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 754 | ProfileWriter.addRecord({"func", 0x1234, {10, 20}}, Err); |
| 755 | ProfileWriter.addRecord({"func", 0x1234, {0, 0}}, Err); |
Justin Bogner | 798787c | 2015-02-18 19:01:06 +0000 | [diff] [blame] | 756 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 757 | startFunction("func", 0x1234); |
Justin Bogner | 798787c | 2015-02-18 19:01:06 +0000 | [diff] [blame] | 758 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
| 759 | addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4); |
| 760 | addCMR(Counter::getCounter(1), "include1", 6, 6, 7, 7); |
| 761 | addExpansionCMR("file1", "include1", 3, 3, 4, 4); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 762 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Justin Bogner | 798787c | 2015-02-18 19:01:06 +0000 | [diff] [blame] | 763 | |
| 764 | CoverageData Data = LoadedCoverage->getCoverageForFile("file1"); |
| 765 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 766 | ASSERT_EQ(4U, Segments.size()); |
| 767 | ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]); |
| 768 | ASSERT_EQ(CoverageSegment(3, 3, 20, true), Segments[1]); |
| 769 | ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]); |
| 770 | ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]); |
| 771 | } |
| 772 | |
Igor Kudrin | 68065ba | 2016-05-05 09:39:45 +0000 | [diff] [blame] | 773 | // If an area is covered only by ExpansionRegions, they should be combinated. |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 774 | TEST_P(CoverageMappingTest, combine_expansions) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 775 | ProfileWriter.addRecord({"func", 0x1234, {2, 3, 7}}, Err); |
Igor Kudrin | 68065ba | 2016-05-05 09:39:45 +0000 | [diff] [blame] | 776 | |
| 777 | startFunction("func", 0x1234); |
| 778 | addCMR(Counter::getCounter(1), "include1", 1, 1, 1, 10); |
| 779 | addCMR(Counter::getCounter(2), "include2", 1, 1, 1, 10); |
| 780 | addCMR(Counter::getCounter(0), "file", 1, 1, 5, 5); |
| 781 | addExpansionCMR("file", "include1", 3, 1, 3, 5); |
| 782 | addExpansionCMR("file", "include2", 3, 1, 3, 5); |
| 783 | |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 784 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Igor Kudrin | 68065ba | 2016-05-05 09:39:45 +0000 | [diff] [blame] | 785 | |
| 786 | CoverageData Data = LoadedCoverage->getCoverageForFile("file"); |
| 787 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 788 | ASSERT_EQ(4U, Segments.size()); |
| 789 | EXPECT_EQ(CoverageSegment(1, 1, 2, true), Segments[0]); |
| 790 | EXPECT_EQ(CoverageSegment(3, 1, 10, true), Segments[1]); |
| 791 | EXPECT_EQ(CoverageSegment(3, 5, 2, false), Segments[2]); |
| 792 | EXPECT_EQ(CoverageSegment(5, 5, false), Segments[3]); |
| 793 | } |
| 794 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 795 | TEST_P(CoverageMappingTest, strip_filename_prefix) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 796 | ProfileWriter.addRecord({"file1:func", 0x1234, {0}}, Err); |
Justin Bogner | 730ddb6 | 2015-05-05 23:44:48 +0000 | [diff] [blame] | 797 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 798 | startFunction("file1:func", 0x1234); |
Justin Bogner | 730ddb6 | 2015-05-05 23:44:48 +0000 | [diff] [blame] | 799 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 800 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Justin Bogner | 730ddb6 | 2015-05-05 23:44:48 +0000 | [diff] [blame] | 801 | |
| 802 | std::vector<std::string> Names; |
| 803 | for (const auto &Func : LoadedCoverage->getCoveredFunctions()) |
| 804 | Names.push_back(Func.Name); |
| 805 | ASSERT_EQ(1U, Names.size()); |
| 806 | ASSERT_EQ("func", Names[0]); |
| 807 | } |
| 808 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 809 | TEST_P(CoverageMappingTest, strip_unknown_filename_prefix) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 810 | ProfileWriter.addRecord({"<unknown>:func", 0x1234, {0}}, Err); |
Vedant Kumar | 9c51ac3 | 2016-03-28 01:16:12 +0000 | [diff] [blame] | 811 | |
Igor Kudrin | e5d4119 | 2016-04-15 14:46:31 +0000 | [diff] [blame] | 812 | startFunction("<unknown>:func", 0x1234); |
Vedant Kumar | 9c51ac3 | 2016-03-28 01:16:12 +0000 | [diff] [blame] | 813 | addCMR(Counter::getCounter(0), "", 1, 1, 9, 9); |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 814 | EXPECT_THAT_ERROR(loadCoverageMapping(/*EmitFilenames=*/false), Succeeded()); |
Vedant Kumar | 9c51ac3 | 2016-03-28 01:16:12 +0000 | [diff] [blame] | 815 | |
| 816 | std::vector<std::string> Names; |
| 817 | for (const auto &Func : LoadedCoverage->getCoveredFunctions()) |
| 818 | Names.push_back(Func.Name); |
| 819 | ASSERT_EQ(1U, Names.size()); |
| 820 | ASSERT_EQ("func", Names[0]); |
| 821 | } |
| 822 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 823 | TEST_P(CoverageMappingTest, dont_detect_false_instantiations) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 824 | ProfileWriter.addRecord({"foo", 0x1234, {10}}, Err); |
| 825 | ProfileWriter.addRecord({"bar", 0x2345, {20}}, Err); |
Igor Kudrin | 66a92f3 | 2016-04-18 15:36:30 +0000 | [diff] [blame] | 826 | |
| 827 | startFunction("foo", 0x1234); |
| 828 | addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10); |
| 829 | addExpansionCMR("main", "expanded", 4, 1, 4, 5); |
| 830 | |
| 831 | startFunction("bar", 0x2345); |
| 832 | addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10); |
| 833 | addExpansionCMR("main", "expanded", 9, 1, 9, 5); |
| 834 | |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 835 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Igor Kudrin | 66a92f3 | 2016-04-18 15:36:30 +0000 | [diff] [blame] | 836 | |
Vedant Kumar | a8dfa81 | 2017-08-02 23:35:25 +0000 | [diff] [blame] | 837 | std::vector<InstantiationGroup> InstantiationGroups = |
| 838 | LoadedCoverage->getInstantiationGroups("expanded"); |
| 839 | for (const auto &Group : InstantiationGroups) |
| 840 | ASSERT_EQ(Group.size(), 1U); |
Igor Kudrin | 66a92f3 | 2016-04-18 15:36:30 +0000 | [diff] [blame] | 841 | } |
| 842 | |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 843 | TEST_P(CoverageMappingTest, load_coverage_for_expanded_file) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 844 | ProfileWriter.addRecord({"func", 0x1234, {10}}, Err); |
Igor Kudrin | 66a92f3 | 2016-04-18 15:36:30 +0000 | [diff] [blame] | 845 | |
| 846 | startFunction("func", 0x1234); |
| 847 | addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10); |
| 848 | addExpansionCMR("main", "expanded", 4, 1, 4, 5); |
| 849 | |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 850 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Igor Kudrin | 66a92f3 | 2016-04-18 15:36:30 +0000 | [diff] [blame] | 851 | |
| 852 | CoverageData Data = LoadedCoverage->getCoverageForFile("expanded"); |
| 853 | std::vector<CoverageSegment> Segments(Data.begin(), Data.end()); |
| 854 | ASSERT_EQ(2U, Segments.size()); |
| 855 | EXPECT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]); |
| 856 | EXPECT_EQ(CoverageSegment(1, 10, false), Segments[1]); |
| 857 | } |
| 858 | |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 859 | TEST_P(CoverageMappingTest, skip_duplicate_function_record) { |
David Blaikie | cb16061 | 2017-07-10 03:04:59 +0000 | [diff] [blame] | 860 | ProfileWriter.addRecord({"func", 0x1234, {1}}, Err); |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 861 | |
Max Moroz | c97ab8f | 2018-05-08 19:26:51 +0000 | [diff] [blame] | 862 | // This record should be loaded. |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 863 | startFunction("func", 0x1234); |
| 864 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
| 865 | |
Max Moroz | c97ab8f | 2018-05-08 19:26:51 +0000 | [diff] [blame] | 866 | // This record should be loaded. |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 867 | startFunction("func", 0x1234); |
| 868 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
Max Moroz | c97ab8f | 2018-05-08 19:26:51 +0000 | [diff] [blame] | 869 | addCMR(Counter::getCounter(0), "file2", 1, 1, 9, 9); |
| 870 | |
| 871 | // This record should be skipped. |
| 872 | startFunction("func", 0x1234); |
| 873 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
| 874 | |
| 875 | // This record should be loaded. |
| 876 | startFunction("func", 0x1234); |
| 877 | addCMR(Counter::getCounter(0), "file2", 1, 1, 9, 9); |
| 878 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
| 879 | |
| 880 | // This record should be skipped. |
| 881 | startFunction("func", 0x1234); |
| 882 | addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); |
| 883 | addCMR(Counter::getCounter(0), "file2", 1, 1, 9, 9); |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 884 | |
David Blaikie | 8c2dc92 | 2017-07-07 21:02:59 +0000 | [diff] [blame] | 885 | EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded()); |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 886 | |
| 887 | auto Funcs = LoadedCoverage->getCoveredFunctions(); |
| 888 | unsigned NumFuncs = std::distance(Funcs.begin(), Funcs.end()); |
Max Moroz | c97ab8f | 2018-05-08 19:26:51 +0000 | [diff] [blame] | 889 | ASSERT_EQ(3U, NumFuncs); |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 890 | } |
| 891 | |
| 892 | // FIXME: Use ::testing::Combine() when llvm updates its copy of googletest. |
Vedant Kumar | 87963ed | 2016-10-13 17:22:44 +0000 | [diff] [blame] | 893 | INSTANTIATE_TEST_CASE_P(ParameterizedCovMapTest, CoverageMappingTest, |
Vedant Kumar | 20bdbbe | 2016-10-14 17:16:53 +0000 | [diff] [blame] | 894 | ::testing::Values(std::pair<bool, bool>({false, false}), |
| 895 | std::pair<bool, bool>({false, true}), |
| 896 | std::pair<bool, bool>({true, false}), |
Galina Kistanova | 34d05a5 | 2017-06-04 05:30:26 +0000 | [diff] [blame] | 897 | std::pair<bool, bool>({true, true})),); |
Vedant Kumar | 0c94d7d | 2016-01-29 22:54:45 +0000 | [diff] [blame] | 898 | |
Justin Bogner | ff96630 | 2015-02-04 00:15:12 +0000 | [diff] [blame] | 899 | } // end anonymous namespace |