[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / unittests / ProfileData / CoverageMappingTest.cpp
blobe04265eb0813a7e825a666a9a7b5b5498ba78cba
1 //===- unittest/ProfileData/CoverageMappingTest.cpp -------------------------=//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
10 #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
11 #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
12 #include "llvm/ProfileData/InstrProfReader.h"
13 #include "llvm/ProfileData/InstrProfWriter.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include "llvm/Testing/Support/Error.h"
16 #include "llvm/Testing/Support/SupportHelpers.h"
17 #include "gtest/gtest.h"
19 #include <ostream>
20 #include <utility>
22 using namespace llvm;
23 using namespace coverage;
25 [[nodiscard]] static ::testing::AssertionResult
26 ErrorEquals(coveragemap_error Expected, Error E) {
27 coveragemap_error Found;
28 std::string FoundMsg;
29 handleAllErrors(std::move(E), [&](const CoverageMapError &CME) {
30 Found = CME.get();
31 FoundMsg = CME.message();
32 });
33 if (Expected == Found)
34 return ::testing::AssertionSuccess();
35 return ::testing::AssertionFailure() << "error: " << FoundMsg << "\n";
38 namespace llvm {
39 namespace coverage {
40 void PrintTo(const Counter &C, ::std::ostream *os) {
41 if (C.isZero())
42 *os << "Zero";
43 else if (C.isExpression())
44 *os << "Expression " << C.getExpressionID();
45 else
46 *os << "Counter " << C.getCounterID();
49 void PrintTo(const CoverageSegment &S, ::std::ostream *os) {
50 *os << "CoverageSegment(" << S.Line << ", " << S.Col << ", ";
51 if (S.HasCount)
52 *os << S.Count << ", ";
53 *os << (S.IsRegionEntry ? "true" : "false") << ")";
58 namespace {
60 struct OutputFunctionCoverageData {
61 StringRef Name;
62 uint64_t Hash;
63 std::vector<StringRef> Filenames;
64 std::vector<CounterMappingRegion> Regions;
65 std::vector<CounterExpression> Expressions;
67 OutputFunctionCoverageData() : Hash(0) {}
69 OutputFunctionCoverageData(OutputFunctionCoverageData &&OFCD)
70 : Name(OFCD.Name), Hash(OFCD.Hash), Filenames(std::move(OFCD.Filenames)),
71 Regions(std::move(OFCD.Regions)) {}
73 OutputFunctionCoverageData(const OutputFunctionCoverageData &) = delete;
74 OutputFunctionCoverageData &
75 operator=(const OutputFunctionCoverageData &) = delete;
76 OutputFunctionCoverageData &operator=(OutputFunctionCoverageData &&) = delete;
78 void fillCoverageMappingRecord(CoverageMappingRecord &Record) const {
79 Record.FunctionName = Name;
80 Record.FunctionHash = Hash;
81 Record.Filenames = Filenames;
82 Record.Expressions = Expressions;
83 Record.MappingRegions = Regions;
87 struct CoverageMappingReaderMock : CoverageMappingReader {
88 ArrayRef<OutputFunctionCoverageData> Functions;
90 CoverageMappingReaderMock(ArrayRef<OutputFunctionCoverageData> Functions)
91 : Functions(Functions) {}
93 Error readNextRecord(CoverageMappingRecord &Record) override {
94 if (Functions.empty())
95 return make_error<CoverageMapError>(coveragemap_error::eof);
97 Functions.front().fillCoverageMappingRecord(Record);
98 Functions = Functions.slice(1);
100 return Error::success();
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 std::vector<CounterExpression> Expressions;
117 InputFunctionCoverageData(std::string Name, uint64_t Hash)
118 : Name(std::move(Name)), Hash(Hash) {}
120 InputFunctionCoverageData(InputFunctionCoverageData &&IFCD)
121 : ReverseVirtualFileMapping(std::move(IFCD.ReverseVirtualFileMapping)),
122 Name(std::move(IFCD.Name)), Hash(IFCD.Hash),
123 Regions(std::move(IFCD.Regions)) {}
125 InputFunctionCoverageData(const InputFunctionCoverageData &) = delete;
126 InputFunctionCoverageData &
127 operator=(const InputFunctionCoverageData &) = delete;
128 InputFunctionCoverageData &operator=(InputFunctionCoverageData &&) = delete;
131 struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
132 bool UseMultipleReaders;
133 StringMap<unsigned> Files;
134 std::vector<std::string> Filenames;
135 std::vector<InputFunctionCoverageData> InputFunctions;
136 std::vector<OutputFunctionCoverageData> OutputFunctions;
138 InstrProfWriter ProfileWriter;
139 std::unique_ptr<IndexedInstrProfReader> ProfileReader;
141 std::unique_ptr<CoverageMapping> LoadedCoverage;
143 void SetUp() override {
144 ProfileWriter.setOutputSparse(std::get<0>(GetParam()));
145 UseMultipleReaders = std::get<1>(GetParam());
148 unsigned getGlobalFileIndex(StringRef Name) {
149 auto R = Files.find(Name);
150 if (R != Files.end())
151 return R->second;
152 unsigned Index = Files.size() + 1;
153 Files.try_emplace(Name, Index);
154 return Index;
157 // Return the file index of file 'Name' for the current function.
158 // Add the file into the global map if necessary.
159 // See also InputFunctionCoverageData::ReverseVirtualFileMapping
160 // for additional comments.
161 unsigned getFileIndexForFunction(StringRef Name) {
162 unsigned GlobalIndex = getGlobalFileIndex(Name);
163 auto &CurrentFunctionFileMapping =
164 InputFunctions.back().ReverseVirtualFileMapping;
165 auto R = CurrentFunctionFileMapping.find(GlobalIndex);
166 if (R != CurrentFunctionFileMapping.end())
167 return R->second;
168 unsigned IndexInFunction = CurrentFunctionFileMapping.size();
169 CurrentFunctionFileMapping.insert(
170 std::make_pair(GlobalIndex, IndexInFunction));
171 return IndexInFunction;
174 void startFunction(StringRef FuncName, uint64_t Hash) {
175 InputFunctions.emplace_back(FuncName.str(), Hash);
178 void addCMR(Counter C, StringRef File, unsigned LS, unsigned CS, unsigned LE,
179 unsigned CE, bool Skipped = false) {
180 auto &Regions = InputFunctions.back().Regions;
181 unsigned FileID = getFileIndexForFunction(File);
182 Regions.push_back(
183 Skipped ? CounterMappingRegion::makeSkipped(FileID, LS, CS, LE, CE)
184 : CounterMappingRegion::makeRegion(C, FileID, LS, CS, LE, CE));
187 void addExpansionCMR(StringRef File, StringRef ExpandedFile, unsigned LS,
188 unsigned CS, unsigned LE, unsigned CE) {
189 InputFunctions.back().Regions.push_back(CounterMappingRegion::makeExpansion(
190 getFileIndexForFunction(File), getFileIndexForFunction(ExpandedFile),
191 LS, CS, LE, CE));
194 void addExpression(CounterExpression CE) {
195 InputFunctions.back().Expressions.push_back(CE);
198 std::string writeCoverageRegions(InputFunctionCoverageData &Data) {
199 SmallVector<unsigned, 8> FileIDs(Data.ReverseVirtualFileMapping.size());
200 for (const auto &E : Data.ReverseVirtualFileMapping)
201 FileIDs[E.second] = E.first;
202 std::string Coverage;
203 llvm::raw_string_ostream OS(Coverage);
204 CoverageMappingWriter(FileIDs, Data.Expressions, Data.Regions).write(OS);
205 return OS.str();
208 void readCoverageRegions(const std::string &Coverage,
209 OutputFunctionCoverageData &Data) {
210 // We will re-use the StringRef in duplicate tests, clear it to avoid
211 // clobber previous ones.
212 Filenames.clear();
213 Filenames.resize(Files.size() + 1);
214 for (const auto &E : Files)
215 Filenames[E.getValue()] = E.getKey().str();
216 ArrayRef<std::string> FilenameRefs = llvm::makeArrayRef(Filenames);
217 RawCoverageMappingReader Reader(Coverage, FilenameRefs, Data.Filenames,
218 Data.Expressions, Data.Regions);
219 EXPECT_THAT_ERROR(Reader.read(), Succeeded());
222 void writeAndReadCoverageRegions(bool EmitFilenames = true) {
223 OutputFunctions.resize(InputFunctions.size());
224 for (unsigned I = 0; I < InputFunctions.size(); ++I) {
225 std::string Regions = writeCoverageRegions(InputFunctions[I]);
226 readCoverageRegions(Regions, OutputFunctions[I]);
227 OutputFunctions[I].Name = InputFunctions[I].Name;
228 OutputFunctions[I].Hash = InputFunctions[I].Hash;
229 if (!EmitFilenames)
230 OutputFunctions[I].Filenames.clear();
234 void readProfCounts() {
235 auto Profile = ProfileWriter.writeBuffer();
236 auto ReaderOrErr = IndexedInstrProfReader::create(std::move(Profile));
237 EXPECT_THAT_ERROR(ReaderOrErr.takeError(), Succeeded());
238 ProfileReader = std::move(ReaderOrErr.get());
241 Expected<std::unique_ptr<CoverageMapping>> readOutputFunctions() {
242 std::vector<std::unique_ptr<CoverageMappingReader>> CoverageReaders;
243 if (UseMultipleReaders) {
244 for (const auto &OF : OutputFunctions) {
245 ArrayRef<OutputFunctionCoverageData> Funcs(OF);
246 CoverageReaders.push_back(
247 std::make_unique<CoverageMappingReaderMock>(Funcs));
249 } else {
250 ArrayRef<OutputFunctionCoverageData> Funcs(OutputFunctions);
251 CoverageReaders.push_back(
252 std::make_unique<CoverageMappingReaderMock>(Funcs));
254 return CoverageMapping::load(CoverageReaders, *ProfileReader);
257 Error loadCoverageMapping(bool EmitFilenames = true) {
258 readProfCounts();
259 writeAndReadCoverageRegions(EmitFilenames);
260 auto CoverageOrErr = readOutputFunctions();
261 if (!CoverageOrErr)
262 return CoverageOrErr.takeError();
263 LoadedCoverage = std::move(CoverageOrErr.get());
264 return Error::success();
268 TEST_P(CoverageMappingTest, basic_write_read) {
269 startFunction("func", 0x1234);
270 addCMR(Counter::getCounter(0), "foo", 1, 1, 1, 1);
271 addCMR(Counter::getCounter(1), "foo", 2, 1, 2, 2);
272 addCMR(Counter::getZero(), "foo", 3, 1, 3, 4);
273 addCMR(Counter::getCounter(2), "foo", 4, 1, 4, 8);
274 addCMR(Counter::getCounter(3), "bar", 1, 2, 3, 4);
276 writeAndReadCoverageRegions();
277 ASSERT_EQ(1u, InputFunctions.size());
278 ASSERT_EQ(1u, OutputFunctions.size());
279 InputFunctionCoverageData &Input = InputFunctions.back();
280 OutputFunctionCoverageData &Output = OutputFunctions.back();
282 size_t N = makeArrayRef(Input.Regions).size();
283 ASSERT_EQ(N, Output.Regions.size());
284 for (size_t I = 0; I < N; ++I) {
285 ASSERT_EQ(Input.Regions[I].Count, Output.Regions[I].Count);
286 ASSERT_EQ(Input.Regions[I].FileID, Output.Regions[I].FileID);
287 ASSERT_EQ(Input.Regions[I].startLoc(), Output.Regions[I].startLoc());
288 ASSERT_EQ(Input.Regions[I].endLoc(), Output.Regions[I].endLoc());
289 ASSERT_EQ(Input.Regions[I].Kind, Output.Regions[I].Kind);
293 TEST_P(CoverageMappingTest, correct_deserialize_for_more_than_two_files) {
294 const char *FileNames[] = {"bar", "baz", "foo"};
295 static const unsigned N = array_lengthof(FileNames);
297 startFunction("func", 0x1234);
298 for (unsigned I = 0; I < N; ++I)
299 // Use LineStart to hold the index of the file name
300 // in order to preserve that information during possible sorting of CMRs.
301 addCMR(Counter::getCounter(0), FileNames[I], I, 1, I, 1);
303 writeAndReadCoverageRegions();
304 ASSERT_EQ(1u, OutputFunctions.size());
305 OutputFunctionCoverageData &Output = OutputFunctions.back();
307 ASSERT_EQ(N, Output.Regions.size());
308 ASSERT_EQ(N, Output.Filenames.size());
310 for (unsigned I = 0; I < N; ++I) {
311 ASSERT_GT(N, Output.Regions[I].FileID);
312 ASSERT_GT(N, Output.Regions[I].LineStart);
313 EXPECT_EQ(FileNames[Output.Regions[I].LineStart],
314 Output.Filenames[Output.Regions[I].FileID]);
318 static const auto Err = [](Error E) { FAIL(); };
320 TEST_P(CoverageMappingTest, load_coverage_for_more_than_two_files) {
321 ProfileWriter.addRecord({"func", 0x1234, {0}}, Err);
323 const char *FileNames[] = {"bar", "baz", "foo"};
324 static const unsigned N = array_lengthof(FileNames);
326 startFunction("func", 0x1234);
327 for (unsigned I = 0; I < N; ++I)
328 // Use LineStart to hold the index of the file name
329 // in order to preserve that information during possible sorting of CMRs.
330 addCMR(Counter::getCounter(0), FileNames[I], I, 1, I, 1);
332 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
334 for (unsigned I = 0; I < N; ++I) {
335 CoverageData Data = LoadedCoverage->getCoverageForFile(FileNames[I]);
336 ASSERT_TRUE(!Data.empty());
337 EXPECT_EQ(I, Data.begin()->Line);
341 TEST_P(CoverageMappingTest, load_coverage_with_bogus_function_name) {
342 ProfileWriter.addRecord({"", 0x1234, {10}}, Err);
343 startFunction("", 0x1234);
344 addCMR(Counter::getCounter(0), "foo", 1, 1, 5, 5);
345 EXPECT_TRUE(ErrorEquals(coveragemap_error::malformed, loadCoverageMapping()));
348 TEST_P(CoverageMappingTest, load_coverage_for_several_functions) {
349 ProfileWriter.addRecord({"func1", 0x1234, {10}}, Err);
350 ProfileWriter.addRecord({"func2", 0x2345, {20}}, Err);
352 startFunction("func1", 0x1234);
353 addCMR(Counter::getCounter(0), "foo", 1, 1, 5, 5);
355 startFunction("func2", 0x2345);
356 addCMR(Counter::getCounter(0), "bar", 2, 2, 6, 6);
358 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
360 const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
361 EXPECT_EQ(2, std::distance(FunctionRecords.begin(), FunctionRecords.end()));
362 for (const auto &FunctionRecord : FunctionRecords) {
363 CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
364 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
365 ASSERT_EQ(2U, Segments.size());
366 if (FunctionRecord.Name == "func1") {
367 EXPECT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
368 EXPECT_EQ(CoverageSegment(5, 5, false), Segments[1]);
369 } else {
370 ASSERT_EQ("func2", FunctionRecord.Name);
371 EXPECT_EQ(CoverageSegment(2, 2, 20, true), Segments[0]);
372 EXPECT_EQ(CoverageSegment(6, 6, false), Segments[1]);
377 TEST_P(CoverageMappingTest, create_combined_regions) {
378 ProfileWriter.addRecord({"func1", 0x1234, {1, 2, 3}}, Err);
379 startFunction("func1", 0x1234);
381 // Given regions which start at the same location, emit a segment for the
382 // last region.
383 addCMR(Counter::getCounter(0), "file1", 1, 1, 2, 2);
384 addCMR(Counter::getCounter(1), "file1", 1, 1, 2, 2);
385 addCMR(Counter::getCounter(2), "file1", 1, 1, 2, 2);
387 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
388 const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
389 const auto &FunctionRecord = *FunctionRecords.begin();
390 CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
391 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
393 ASSERT_EQ(2U, Segments.size());
394 EXPECT_EQ(CoverageSegment(1, 1, 6, true), Segments[0]);
395 EXPECT_EQ(CoverageSegment(2, 2, false), Segments[1]);
398 TEST_P(CoverageMappingTest, skipped_segments_have_no_count) {
399 ProfileWriter.addRecord({"func1", 0x1234, {1}}, Err);
400 startFunction("func1", 0x1234);
402 addCMR(Counter::getCounter(0), "file1", 1, 1, 5, 5);
403 addCMR(Counter::getCounter(0), "file1", 5, 1, 5, 5, /*Skipped=*/true);
405 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
406 const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
407 const auto &FunctionRecord = *FunctionRecords.begin();
408 CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
409 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
411 ASSERT_EQ(3U, Segments.size());
412 EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]);
413 EXPECT_EQ(CoverageSegment(5, 1, true), Segments[1]);
414 EXPECT_EQ(CoverageSegment(5, 5, false), Segments[2]);
417 TEST_P(CoverageMappingTest, multiple_regions_end_after_parent_ends) {
418 ProfileWriter.addRecord({"func1", 0x1234, {1, 0}}, Err);
419 startFunction("func1", 0x1234);
421 // 1| F{ a{
422 // 2|
423 // 3| a} b{ c{
424 // 4|
425 // 5| b}
426 // 6|
427 // 7| c} d{ e{
428 // 8|
429 // 9| d} e} F}
430 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9); // < F
431 addCMR(Counter::getCounter(0), "file1", 1, 1, 3, 5); // < a
432 addCMR(Counter::getCounter(0), "file1", 3, 5, 5, 4); // < b
433 addCMR(Counter::getCounter(1), "file1", 3, 5, 7, 3); // < c
434 addCMR(Counter::getCounter(1), "file1", 7, 3, 9, 2); // < d
435 addCMR(Counter::getCounter(1), "file1", 7, 7, 9, 7); // < e
437 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
438 const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
439 const auto &FunctionRecord = *FunctionRecords.begin();
440 CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
441 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
443 // Old output (not sorted or unique):
444 // Segment at 1:1 with count 1
445 // Segment at 1:1 with count 1
446 // Segment at 3:5 with count 1
447 // Segment at 3:5 with count 0
448 // Segment at 3:5 with count 1
449 // Segment at 5:4 with count 0
450 // Segment at 7:3 with count 1
451 // Segment at 7:3 with count 0
452 // Segment at 7:7 with count 0
453 // Segment at 9:7 with count 0
454 // Segment at 9:2 with count 1
455 // Top level segment at 9:9
457 // New output (sorted and unique):
458 // Segment at 1:1 (count = 1), RegionEntry
459 // Segment at 3:5 (count = 1), RegionEntry
460 // Segment at 5:4 (count = 0)
461 // Segment at 7:3 (count = 0), RegionEntry
462 // Segment at 7:7 (count = 0), RegionEntry
463 // Segment at 9:2 (count = 0)
464 // Segment at 9:7 (count = 1)
465 // Segment at 9:9 (count = 0), Skipped
467 ASSERT_EQ(8U, Segments.size());
468 EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]);
469 EXPECT_EQ(CoverageSegment(3, 5, 1, true), Segments[1]);
470 EXPECT_EQ(CoverageSegment(5, 4, 0, false), Segments[2]);
471 EXPECT_EQ(CoverageSegment(7, 3, 0, true), Segments[3]);
472 EXPECT_EQ(CoverageSegment(7, 7, 0, true), Segments[4]);
473 EXPECT_EQ(CoverageSegment(9, 2, 0, false), Segments[5]);
474 EXPECT_EQ(CoverageSegment(9, 7, 1, false), Segments[6]);
475 EXPECT_EQ(CoverageSegment(9, 9, false), Segments[7]);
478 TEST_P(CoverageMappingTest, multiple_completed_segments_at_same_loc) {
479 ProfileWriter.addRecord({"func1", 0x1234, {0, 1, 2}}, Err);
480 startFunction("func1", 0x1234);
482 // PR35495
483 addCMR(Counter::getCounter(1), "file1", 2, 1, 18, 2);
484 addCMR(Counter::getCounter(0), "file1", 8, 10, 14, 6);
485 addCMR(Counter::getCounter(0), "file1", 8, 12, 14, 6);
486 addCMR(Counter::getCounter(1), "file1", 9, 1, 14, 6);
487 addCMR(Counter::getCounter(2), "file1", 11, 13, 11, 14);
489 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
490 const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
491 const auto &FunctionRecord = *FunctionRecords.begin();
492 CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
493 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
495 ASSERT_EQ(7U, Segments.size());
496 EXPECT_EQ(CoverageSegment(2, 1, 1, true), Segments[0]);
497 EXPECT_EQ(CoverageSegment(8, 10, 0, true), Segments[1]);
498 EXPECT_EQ(CoverageSegment(8, 12, 0, true), Segments[2]);
499 EXPECT_EQ(CoverageSegment(9, 1, 1, true), Segments[3]);
500 EXPECT_EQ(CoverageSegment(11, 13, 2, true), Segments[4]);
501 // Use count=1 (from 9:1 -> 14:6), not count=0 (from 8:12 -> 14:6).
502 EXPECT_EQ(CoverageSegment(11, 14, 1, false), Segments[5]);
503 EXPECT_EQ(CoverageSegment(18, 2, false), Segments[6]);
506 TEST_P(CoverageMappingTest, dont_emit_redundant_segments) {
507 ProfileWriter.addRecord({"func1", 0x1234, {1, 1}}, Err);
508 startFunction("func1", 0x1234);
510 addCMR(Counter::getCounter(0), "file1", 1, 1, 4, 4);
511 addCMR(Counter::getCounter(1), "file1", 2, 2, 5, 5);
512 addCMR(Counter::getCounter(0), "file1", 3, 3, 6, 6);
514 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
515 const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
516 const auto &FunctionRecord = *FunctionRecords.begin();
517 CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
518 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
520 ASSERT_EQ(5U, Segments.size());
521 EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]);
522 EXPECT_EQ(CoverageSegment(2, 2, 1, true), Segments[1]);
523 EXPECT_EQ(CoverageSegment(3, 3, 1, true), Segments[2]);
524 EXPECT_EQ(CoverageSegment(4, 4, 1, false), Segments[3]);
525 // A closing segment starting at 5:5 would be redundant: it would have the
526 // same count as the segment starting at 4:4, and has all the same metadata.
527 EXPECT_EQ(CoverageSegment(6, 6, false), Segments[4]);
530 TEST_P(CoverageMappingTest, dont_emit_closing_segment_at_new_region_start) {
531 ProfileWriter.addRecord({"func1", 0x1234, {1}}, Err);
532 startFunction("func1", 0x1234);
534 addCMR(Counter::getCounter(0), "file1", 1, 1, 6, 5);
535 addCMR(Counter::getCounter(0), "file1", 2, 2, 6, 5);
536 addCMR(Counter::getCounter(0), "file1", 3, 3, 6, 5);
537 addCMR(Counter::getCounter(0), "file1", 6, 5, 7, 7);
539 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
540 const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
541 const auto &FunctionRecord = *FunctionRecords.begin();
542 CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
543 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
545 ASSERT_EQ(5U, Segments.size());
546 EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]);
547 EXPECT_EQ(CoverageSegment(2, 2, 1, true), Segments[1]);
548 EXPECT_EQ(CoverageSegment(3, 3, 1, true), Segments[2]);
549 EXPECT_EQ(CoverageSegment(6, 5, 1, true), Segments[3]);
550 // The old segment builder would get this wrong by emitting multiple segments
551 // which start at 6:5 (a few of which were skipped segments). We should just
552 // get a segment for the region entry.
553 EXPECT_EQ(CoverageSegment(7, 7, false), Segments[4]);
556 TEST_P(CoverageMappingTest, handle_consecutive_regions_with_zero_length) {
557 ProfileWriter.addRecord({"func1", 0x1234, {1, 2}}, Err);
558 startFunction("func1", 0x1234);
560 addCMR(Counter::getCounter(0), "file1", 1, 1, 1, 1);
561 addCMR(Counter::getCounter(1), "file1", 1, 1, 1, 1);
562 addCMR(Counter::getCounter(0), "file1", 1, 1, 1, 1);
563 addCMR(Counter::getCounter(1), "file1", 1, 1, 1, 1);
564 addCMR(Counter::getCounter(0), "file1", 1, 1, 1, 1);
566 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
567 const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
568 const auto &FunctionRecord = *FunctionRecords.begin();
569 CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
570 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
572 ASSERT_EQ(1U, Segments.size());
573 EXPECT_EQ(CoverageSegment(1, 1, true), Segments[0]);
574 // We need to get a skipped segment starting at 1:1. In this case there is
575 // also a region entry at 1:1.
578 TEST_P(CoverageMappingTest, handle_sandwiched_zero_length_region) {
579 ProfileWriter.addRecord({"func1", 0x1234, {2, 1}}, Err);
580 startFunction("func1", 0x1234);
582 addCMR(Counter::getCounter(0), "file1", 1, 5, 4, 4);
583 addCMR(Counter::getCounter(1), "file1", 1, 9, 1, 50);
584 addCMR(Counter::getCounter(1), "file1", 2, 7, 2, 34);
585 addCMR(Counter::getCounter(1), "file1", 3, 5, 3, 21);
586 addCMR(Counter::getCounter(1), "file1", 3, 21, 3, 21);
587 addCMR(Counter::getCounter(1), "file1", 4, 12, 4, 17);
589 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
590 const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
591 const auto &FunctionRecord = *FunctionRecords.begin();
592 CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
593 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
595 ASSERT_EQ(10U, Segments.size());
596 EXPECT_EQ(CoverageSegment(1, 5, 2, true), Segments[0]);
597 EXPECT_EQ(CoverageSegment(1, 9, 1, true), Segments[1]);
598 EXPECT_EQ(CoverageSegment(1, 50, 2, false), Segments[2]);
599 EXPECT_EQ(CoverageSegment(2, 7, 1, true), Segments[3]);
600 EXPECT_EQ(CoverageSegment(2, 34, 2, false), Segments[4]);
601 EXPECT_EQ(CoverageSegment(3, 5, 1, true), Segments[5]);
602 EXPECT_EQ(CoverageSegment(3, 21, 2, true), Segments[6]);
603 // Handle the zero-length region by creating a segment with its predecessor's
604 // count (i.e the count from 1:5 -> 4:4).
605 EXPECT_EQ(CoverageSegment(4, 4, false), Segments[7]);
606 // The area between 4:4 and 4:12 is skipped.
607 EXPECT_EQ(CoverageSegment(4, 12, 1, true), Segments[8]);
608 EXPECT_EQ(CoverageSegment(4, 17, false), Segments[9]);
611 TEST_P(CoverageMappingTest, handle_last_completed_region) {
612 ProfileWriter.addRecord({"func1", 0x1234, {1, 2, 3, 4}}, Err);
613 startFunction("func1", 0x1234);
615 addCMR(Counter::getCounter(0), "file1", 1, 1, 8, 8);
616 addCMR(Counter::getCounter(1), "file1", 2, 2, 5, 5);
617 addCMR(Counter::getCounter(2), "file1", 3, 3, 4, 4);
618 addCMR(Counter::getCounter(3), "file1", 6, 6, 7, 7);
620 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
621 const auto FunctionRecords = LoadedCoverage->getCoveredFunctions();
622 const auto &FunctionRecord = *FunctionRecords.begin();
623 CoverageData Data = LoadedCoverage->getCoverageForFunction(FunctionRecord);
624 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
626 ASSERT_EQ(8U, Segments.size());
627 EXPECT_EQ(CoverageSegment(1, 1, 1, true), Segments[0]);
628 EXPECT_EQ(CoverageSegment(2, 2, 2, true), Segments[1]);
629 EXPECT_EQ(CoverageSegment(3, 3, 3, true), Segments[2]);
630 EXPECT_EQ(CoverageSegment(4, 4, 2, false), Segments[3]);
631 EXPECT_EQ(CoverageSegment(5, 5, 1, false), Segments[4]);
632 EXPECT_EQ(CoverageSegment(6, 6, 4, true), Segments[5]);
633 EXPECT_EQ(CoverageSegment(7, 7, 1, false), Segments[6]);
634 EXPECT_EQ(CoverageSegment(8, 8, false), Segments[7]);
637 TEST_P(CoverageMappingTest, expansion_gets_first_counter) {
638 startFunction("func", 0x1234);
639 addCMR(Counter::getCounter(1), "foo", 10, 1, 10, 2);
640 // This starts earlier in "foo", so the expansion should get its counter.
641 addCMR(Counter::getCounter(2), "foo", 1, 1, 20, 1);
642 addExpansionCMR("bar", "foo", 3, 3, 3, 3);
644 writeAndReadCoverageRegions();
645 ASSERT_EQ(1u, OutputFunctions.size());
646 OutputFunctionCoverageData &Output = OutputFunctions.back();
648 ASSERT_EQ(CounterMappingRegion::ExpansionRegion, Output.Regions[2].Kind);
649 ASSERT_EQ(Counter::getCounter(2), Output.Regions[2].Count);
650 ASSERT_EQ(3U, Output.Regions[2].LineStart);
653 TEST_P(CoverageMappingTest, basic_coverage_iteration) {
654 ProfileWriter.addRecord({"func", 0x1234, {30, 20, 10, 0}}, Err);
656 startFunction("func", 0x1234);
657 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
658 addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
659 addCMR(Counter::getCounter(2), "file1", 5, 8, 9, 1);
660 addCMR(Counter::getCounter(3), "file1", 10, 10, 11, 11);
661 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
663 CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
664 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
665 ASSERT_EQ(7U, Segments.size());
666 ASSERT_EQ(CoverageSegment(1, 1, 20, true), Segments[0]);
667 ASSERT_EQ(CoverageSegment(4, 7, 30, false), Segments[1]);
668 ASSERT_EQ(CoverageSegment(5, 8, 10, true), Segments[2]);
669 ASSERT_EQ(CoverageSegment(9, 1, 30, false), Segments[3]);
670 ASSERT_EQ(CoverageSegment(9, 9, false), Segments[4]);
671 ASSERT_EQ(CoverageSegment(10, 10, 0, true), Segments[5]);
672 ASSERT_EQ(CoverageSegment(11, 11, false), Segments[6]);
675 TEST_P(CoverageMappingTest, test_line_coverage_iterator) {
676 ProfileWriter.addRecord({"func", 0x1234, {30, 20, 10, 0}}, Err);
678 startFunction("func", 0x1234);
679 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
680 addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
681 addCMR(Counter::getCounter(2), "file1", 5, 8, 9, 1);
682 addCMR(Counter::getCounter(3), "file1", 10, 10, 11, 11);
683 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
685 CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
687 unsigned Line = 0;
688 unsigned LineCounts[] = {20, 20, 20, 20, 30, 10, 10, 10, 10, 0, 0};
689 for (const auto &LCS : getLineCoverageStats(Data)) {
690 ASSERT_EQ(Line + 1, LCS.getLine());
691 errs() << "Line: " << Line + 1 << ", count = " << LCS.getExecutionCount() << "\n";
692 ASSERT_EQ(LineCounts[Line], LCS.getExecutionCount());
693 ++Line;
695 ASSERT_EQ(11U, Line);
697 // Check that operator->() works / compiles.
698 ASSERT_EQ(1U, LineCoverageIterator(Data)->getLine());
701 TEST_P(CoverageMappingTest, uncovered_function) {
702 startFunction("func", 0x1234);
703 addCMR(Counter::getZero(), "file1", 1, 2, 3, 4);
704 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
706 CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
707 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
708 ASSERT_EQ(2U, Segments.size());
709 ASSERT_EQ(CoverageSegment(1, 2, 0, true), Segments[0]);
710 ASSERT_EQ(CoverageSegment(3, 4, false), Segments[1]);
713 TEST_P(CoverageMappingTest, uncovered_function_with_mapping) {
714 startFunction("func", 0x1234);
715 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
716 addCMR(Counter::getCounter(1), "file1", 1, 1, 4, 7);
717 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
719 CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
720 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
721 ASSERT_EQ(3U, Segments.size());
722 ASSERT_EQ(CoverageSegment(1, 1, 0, true), Segments[0]);
723 ASSERT_EQ(CoverageSegment(4, 7, 0, false), Segments[1]);
724 ASSERT_EQ(CoverageSegment(9, 9, false), Segments[2]);
727 TEST_P(CoverageMappingTest, combine_regions) {
728 ProfileWriter.addRecord({"func", 0x1234, {10, 20, 30}}, Err);
730 startFunction("func", 0x1234);
731 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
732 addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
733 addCMR(Counter::getCounter(2), "file1", 3, 3, 4, 4);
734 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
736 CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
737 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
738 ASSERT_EQ(4U, Segments.size());
739 ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
740 ASSERT_EQ(CoverageSegment(3, 3, 50, true), Segments[1]);
741 ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]);
742 ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]);
745 TEST_P(CoverageMappingTest, restore_combined_counter_after_nested_region) {
746 ProfileWriter.addRecord({"func", 0x1234, {10, 20, 40}}, Err);
748 startFunction("func", 0x1234);
749 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
750 addCMR(Counter::getCounter(1), "file1", 1, 1, 9, 9);
751 addCMR(Counter::getCounter(2), "file1", 3, 3, 5, 5);
752 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
754 CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
755 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
756 ASSERT_EQ(4U, Segments.size());
757 EXPECT_EQ(CoverageSegment(1, 1, 30, true), Segments[0]);
758 EXPECT_EQ(CoverageSegment(3, 3, 40, true), Segments[1]);
759 EXPECT_EQ(CoverageSegment(5, 5, 30, false), Segments[2]);
760 EXPECT_EQ(CoverageSegment(9, 9, false), Segments[3]);
763 // If CodeRegions and ExpansionRegions cover the same area,
764 // only counts of CodeRegions should be used.
765 TEST_P(CoverageMappingTest, dont_combine_expansions) {
766 ProfileWriter.addRecord({"func", 0x1234, {10, 20}}, Err);
767 ProfileWriter.addRecord({"func", 0x1234, {0, 0}}, Err);
769 startFunction("func", 0x1234);
770 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
771 addCMR(Counter::getCounter(1), "file1", 3, 3, 4, 4);
772 addCMR(Counter::getCounter(1), "include1", 6, 6, 7, 7);
773 addExpansionCMR("file1", "include1", 3, 3, 4, 4);
774 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
776 CoverageData Data = LoadedCoverage->getCoverageForFile("file1");
777 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
778 ASSERT_EQ(4U, Segments.size());
779 ASSERT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
780 ASSERT_EQ(CoverageSegment(3, 3, 20, true), Segments[1]);
781 ASSERT_EQ(CoverageSegment(4, 4, 10, false), Segments[2]);
782 ASSERT_EQ(CoverageSegment(9, 9, false), Segments[3]);
785 // If an area is covered only by ExpansionRegions, they should be combinated.
786 TEST_P(CoverageMappingTest, combine_expansions) {
787 ProfileWriter.addRecord({"func", 0x1234, {2, 3, 7}}, Err);
789 startFunction("func", 0x1234);
790 addCMR(Counter::getCounter(1), "include1", 1, 1, 1, 10);
791 addCMR(Counter::getCounter(2), "include2", 1, 1, 1, 10);
792 addCMR(Counter::getCounter(0), "file", 1, 1, 5, 5);
793 addExpansionCMR("file", "include1", 3, 1, 3, 5);
794 addExpansionCMR("file", "include2", 3, 1, 3, 5);
796 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
798 CoverageData Data = LoadedCoverage->getCoverageForFile("file");
799 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
800 ASSERT_EQ(4U, Segments.size());
801 EXPECT_EQ(CoverageSegment(1, 1, 2, true), Segments[0]);
802 EXPECT_EQ(CoverageSegment(3, 1, 10, true), Segments[1]);
803 EXPECT_EQ(CoverageSegment(3, 5, 2, false), Segments[2]);
804 EXPECT_EQ(CoverageSegment(5, 5, false), Segments[3]);
807 // Test that counters not associated with any code regions are allowed.
808 TEST_P(CoverageMappingTest, non_code_region_counters) {
809 // No records in profdata
811 startFunction("func", 0x1234);
812 addCMR(Counter::getCounter(0), "file", 1, 1, 5, 5);
813 addCMR(Counter::getExpression(0), "file", 6, 1, 6, 5);
814 addExpression(CounterExpression(
815 CounterExpression::Add, Counter::getCounter(1), Counter::getCounter(2)));
817 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
819 std::vector<std::string> Names;
820 for (const auto &Func : LoadedCoverage->getCoveredFunctions()) {
821 Names.push_back(Func.Name);
822 ASSERT_EQ(2U, Func.CountedRegions.size());
824 ASSERT_EQ(1U, Names.size());
827 TEST_P(CoverageMappingTest, strip_filename_prefix) {
828 ProfileWriter.addRecord({"file1:func", 0x1234, {0}}, Err);
830 startFunction("file1:func", 0x1234);
831 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
832 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
834 std::vector<std::string> Names;
835 for (const auto &Func : LoadedCoverage->getCoveredFunctions())
836 Names.push_back(Func.Name);
837 ASSERT_EQ(1U, Names.size());
838 ASSERT_EQ("func", Names[0]);
841 TEST_P(CoverageMappingTest, strip_unknown_filename_prefix) {
842 ProfileWriter.addRecord({"<unknown>:func", 0x1234, {0}}, Err);
844 startFunction("<unknown>:func", 0x1234);
845 addCMR(Counter::getCounter(0), "", 1, 1, 9, 9);
846 EXPECT_THAT_ERROR(loadCoverageMapping(/*EmitFilenames=*/false), Succeeded());
848 std::vector<std::string> Names;
849 for (const auto &Func : LoadedCoverage->getCoveredFunctions())
850 Names.push_back(Func.Name);
851 ASSERT_EQ(1U, Names.size());
852 ASSERT_EQ("func", Names[0]);
855 TEST_P(CoverageMappingTest, dont_detect_false_instantiations) {
856 ProfileWriter.addRecord({"foo", 0x1234, {10}}, Err);
857 ProfileWriter.addRecord({"bar", 0x2345, {20}}, Err);
859 startFunction("foo", 0x1234);
860 addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10);
861 addExpansionCMR("main", "expanded", 4, 1, 4, 5);
863 startFunction("bar", 0x2345);
864 addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10);
865 addExpansionCMR("main", "expanded", 9, 1, 9, 5);
867 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
869 std::vector<InstantiationGroup> InstantiationGroups =
870 LoadedCoverage->getInstantiationGroups("expanded");
871 ASSERT_TRUE(InstantiationGroups.empty());
874 TEST_P(CoverageMappingTest, load_coverage_for_expanded_file) {
875 ProfileWriter.addRecord({"func", 0x1234, {10}}, Err);
877 startFunction("func", 0x1234);
878 addCMR(Counter::getCounter(0), "expanded", 1, 1, 1, 10);
879 addExpansionCMR("main", "expanded", 4, 1, 4, 5);
881 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
883 CoverageData Data = LoadedCoverage->getCoverageForFile("expanded");
884 std::vector<CoverageSegment> Segments(Data.begin(), Data.end());
885 ASSERT_EQ(2U, Segments.size());
886 EXPECT_EQ(CoverageSegment(1, 1, 10, true), Segments[0]);
887 EXPECT_EQ(CoverageSegment(1, 10, false), Segments[1]);
890 TEST_P(CoverageMappingTest, skip_duplicate_function_record) {
891 ProfileWriter.addRecord({"func", 0x1234, {1}}, Err);
893 // This record should be loaded.
894 startFunction("func", 0x1234);
895 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
897 // This record should be loaded.
898 startFunction("func", 0x1234);
899 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
900 addCMR(Counter::getCounter(0), "file2", 1, 1, 9, 9);
902 // This record should be skipped.
903 startFunction("func", 0x1234);
904 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
906 // This record should be loaded.
907 startFunction("func", 0x1234);
908 addCMR(Counter::getCounter(0), "file2", 1, 1, 9, 9);
909 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
911 // This record should be skipped.
912 startFunction("func", 0x1234);
913 addCMR(Counter::getCounter(0), "file1", 1, 1, 9, 9);
914 addCMR(Counter::getCounter(0), "file2", 1, 1, 9, 9);
916 EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
918 auto Funcs = LoadedCoverage->getCoveredFunctions();
919 unsigned NumFuncs = std::distance(Funcs.begin(), Funcs.end());
920 ASSERT_EQ(3U, NumFuncs);
923 INSTANTIATE_TEST_SUITE_P(ParameterizedCovMapTest, CoverageMappingTest,
924 ::testing::Combine(::testing::Bool(),
925 ::testing::Bool()));
927 TEST(CoverageMappingTest, filename_roundtrip) {
928 std::vector<std::string> Paths({"dir", "a", "b", "c", "d", "e"});
930 for (bool Compress : {false, true}) {
931 std::string EncodedFilenames;
933 raw_string_ostream OS(EncodedFilenames);
934 CoverageFilenamesSectionWriter Writer(Paths);
935 Writer.write(OS, Compress);
938 std::vector<std::string> ReadFilenames;
939 RawCoverageFilenamesReader Reader(EncodedFilenames, ReadFilenames);
940 EXPECT_THAT_ERROR(Reader.read(CovMapVersion::CurrentVersion), Succeeded());
942 ASSERT_EQ(ReadFilenames.size(), Paths.size());
943 for (unsigned I = 1; I < Paths.size(); ++I) {
944 SmallString<256> P(Paths[0]);
945 llvm::sys::path::append(P, Paths[I]);
946 ASSERT_EQ(ReadFilenames[I], P);
951 TEST(CoverageMappingTest, filename_compilation_dir) {
952 std::vector<std::string> Paths({"dir", "a", "b", "c", "d", "e"});
954 for (bool Compress : {false, true}) {
955 std::string EncodedFilenames;
957 raw_string_ostream OS(EncodedFilenames);
958 CoverageFilenamesSectionWriter Writer(Paths);
959 Writer.write(OS, Compress);
962 StringRef CompilationDir = "out";
963 std::vector<std::string> ReadFilenames;
964 RawCoverageFilenamesReader Reader(EncodedFilenames, ReadFilenames,
965 CompilationDir);
966 EXPECT_THAT_ERROR(Reader.read(CovMapVersion::CurrentVersion), Succeeded());
968 ASSERT_EQ(ReadFilenames.size(), Paths.size());
969 for (unsigned I = 1; I < Paths.size(); ++I) {
970 SmallString<256> P(CompilationDir);
971 llvm::sys::path::append(P, Paths[I]);
972 ASSERT_EQ(ReadFilenames[I], P);
977 } // end anonymous namespace