Use new FailedWithMessage matcher in DWARFDebugLineTest.cpp

Summary:
This should produce slightly better error messages in case of failures.
Only slightly, because this code was pretty careful about that to begin
with -- I've seen code which does much worse.

Reviewers: jhenderson, dblaikie

Subscribers: llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D74899
This commit is contained in:
Pavel Labath 2020-02-20 15:24:09 +01:00
parent c3f36acc92
commit 9b23024c8b
1 changed files with 109 additions and 117 deletions

View File

@ -96,42 +96,12 @@ struct CommonFixture {
Unrecoverable = joinErrors(std::move(Unrecoverable), std::move(Err)); Unrecoverable = joinErrors(std::move(Unrecoverable), std::move(Err));
} }
void checkError(ArrayRef<StringRef> ExpectedMsgs, Error Err) { Expected<const DWARFDebugLine::LineTable *>
ASSERT_TRUE(Err.operator bool()); getOrParseLineTableFatalErrors(uint64_t Offset = 0) {
size_t WhichMsg = 0;
Error Remaining =
handleErrors(std::move(Err), [&](const ErrorInfoBase &Actual) {
ASSERT_LT(WhichMsg, ExpectedMsgs.size());
// Use .str(), because googletest doesn't visualise a StringRef
// properly.
EXPECT_EQ(Actual.message(), ExpectedMsgs[WhichMsg++].str());
});
EXPECT_EQ(WhichMsg, ExpectedMsgs.size());
EXPECT_FALSE(Remaining);
}
void checkError(StringRef ExpectedMsg, Error Err) {
checkError(ArrayRef<StringRef>{ExpectedMsg}, std::move(Err));
}
void checkGetOrParseLineTableEmitsFatalError(StringRef ExpectedMsg,
uint64_t Offset = 0) {
auto ExpectedLineTable = Line.getOrParseLineTable( auto ExpectedLineTable = Line.getOrParseLineTable(
LineData, Offset, *Context, nullptr, RecordRecoverable); LineData, Offset, *Context, nullptr, RecordRecoverable);
EXPECT_FALSE(ExpectedLineTable); EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded());
EXPECT_FALSE(Recoverable); return ExpectedLineTable;
checkError(ExpectedMsg, ExpectedLineTable.takeError());
}
void checkGetOrParseLineTableEmitsFatalError(ArrayRef<StringRef> ExpectedMsgs,
uint64_t Offset = 0) {
auto ExpectedLineTable = Line.getOrParseLineTable(
LineData, Offset, *Context, nullptr, RecordRecoverable);
EXPECT_FALSE(ExpectedLineTable);
EXPECT_FALSE(Recoverable);
checkError(ExpectedMsgs, ExpectedLineTable.takeError());
} }
uint8_t AddressSize; uint8_t AddressSize;
@ -213,14 +183,21 @@ TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffset) {
return; return;
generate(); generate();
checkGetOrParseLineTableEmitsFatalError( EXPECT_THAT_EXPECTED(
"offset 0x00000000 is not a valid debug line section offset", 0); getOrParseLineTableFatalErrors(0),
FailedWithMessage(
"offset 0x00000000 is not a valid debug line section offset"));
// Repeat to show that an error is reported each time. // Repeat to show that an error is reported each time.
checkGetOrParseLineTableEmitsFatalError( EXPECT_THAT_EXPECTED(
"offset 0x00000000 is not a valid debug line section offset", 0); getOrParseLineTableFatalErrors(0),
FailedWithMessage(
"offset 0x00000000 is not a valid debug line section offset"));
// Show that an error is reported for later offsets too. // Show that an error is reported for later offsets too.
checkGetOrParseLineTableEmitsFatalError( EXPECT_THAT_EXPECTED(
"offset 0x00000001 is not a valid debug line section offset", 1); getOrParseLineTableFatalErrors(1),
FailedWithMessage(
"offset 0x00000001 is not a valid debug line section offset"));
} }
TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffsetAfterData) { TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffsetAfterData) {
@ -232,8 +209,10 @@ TEST_F(DebugLineBasicFixture, GetOrParseLineTableAtInvalidOffsetAfterData) {
generate(); generate();
checkGetOrParseLineTableEmitsFatalError( EXPECT_THAT_EXPECTED(
"offset 0x00000001 is not a valid debug line section offset", 1); getOrParseLineTableFatalErrors(1),
FailedWithMessage(
"offset 0x00000001 is not a valid debug line section offset"));
} }
TEST_P(DebugLineParameterisedFixture, PrologueGetLength) { TEST_P(DebugLineParameterisedFixture, PrologueGetLength) {
@ -334,9 +313,11 @@ TEST_F(DebugLineBasicFixture, ErrorForReservedLength) {
generate(); generate();
checkGetOrParseLineTableEmitsFatalError( EXPECT_THAT_EXPECTED(
"parsing line table prologue at offset 0x00000000 unsupported reserved " getOrParseLineTableFatalErrors(),
"unit length found of value 0xfffffff0"); FailedWithMessage(
"parsing line table prologue at offset 0x00000000 unsupported "
"reserved unit length found of value 0xfffffff0"));
} }
struct DebugLineUnsupportedVersionFixture : public TestWithParam<uint16_t>, struct DebugLineUnsupportedVersionFixture : public TestWithParam<uint16_t>,
@ -356,10 +337,11 @@ TEST_P(DebugLineUnsupportedVersionFixture, ErrorForUnsupportedVersion) {
generate(); generate();
checkGetOrParseLineTableEmitsFatalError( EXPECT_THAT_EXPECTED(
"parsing line table prologue at offset 0x00000000 found unsupported " getOrParseLineTableFatalErrors(),
"version " + FailedWithMessage("parsing line table prologue at offset 0x00000000 "
std::to_string(Version)); "found unsupported version " +
std::to_string(Version)));
} }
INSTANTIATE_TEST_CASE_P(UnsupportedVersionTestParams, INSTANTIATE_TEST_CASE_P(UnsupportedVersionTestParams,
@ -399,11 +381,13 @@ TEST_F(DebugLineBasicFixture, ErrorForInvalidV5IncludeDirTable) {
nullptr, RecordRecoverable); nullptr, RecordRecoverable);
EXPECT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); EXPECT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
checkError( EXPECT_THAT_ERROR(
{"parsing line table prologue at 0x00000000 found an invalid directory " std::move(Recoverable),
"or file table description at 0x00000014", FailedWithMessage(
"failed to parse entry content descriptions because no path was found"}, "parsing line table prologue at 0x00000000 found an invalid "
std::move(Recoverable)); "directory or file table description at 0x00000014",
"failed to parse entry content descriptions because no path was "
"found"));
} }
TEST_P(DebugLineParameterisedFixture, ErrorForTooLargePrologueLength) { TEST_P(DebugLineParameterisedFixture, ErrorForTooLargePrologueLength) {
@ -431,13 +415,14 @@ TEST_P(DebugLineParameterisedFixture, ErrorForTooLargePrologueLength) {
uint64_t ExpectedEnd = uint64_t ExpectedEnd =
Prologue.TotalLength + 1 + Prologue.sizeofTotalLength(); Prologue.TotalLength + 1 + Prologue.sizeofTotalLength();
checkError( EXPECT_THAT_ERROR(
(Twine("parsing line table prologue at 0x00000000 should have ended at " std::move(Recoverable),
"0x000000") + FailedWithMessage(("parsing line table prologue at 0x00000000 should "
Twine::utohexstr(ExpectedEnd) + " but it ended at 0x000000" + "have ended at 0x000000" +
Twine::utohexstr(ExpectedEnd - 1)) Twine::utohexstr(ExpectedEnd) +
.str(), " but it ended at 0x000000" +
std::move(Recoverable)); Twine::utohexstr(ExpectedEnd - 1))
.str()));
} }
TEST_P(DebugLineParameterisedFixture, ErrorForTooShortPrologueLength) { TEST_P(DebugLineParameterisedFixture, ErrorForTooShortPrologueLength) {
@ -486,8 +471,8 @@ TEST_P(DebugLineParameterisedFixture, ErrorForTooShortPrologueLength) {
Twine::utohexstr(ExpectedEnd) + " but it ended at 0x000000" + Twine::utohexstr(ExpectedEnd) + " but it ended at 0x000000" +
Twine::utohexstr(ActualEnd)) Twine::utohexstr(ActualEnd))
.str()); .str());
std::vector<StringRef> ErrRefs(Errs.begin(), Errs.end()); EXPECT_THAT_ERROR(std::move(Recoverable),
checkError(ErrRefs, std::move(Recoverable)); FailedWithMessageArray(testing::ElementsAreArray(Errs)));
} }
INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P(
@ -517,9 +502,9 @@ TEST_F(DebugLineBasicFixture, ErrorForExtendedOpcodeLengthSmallerThanExpected) {
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
nullptr, RecordRecoverable); nullptr, RecordRecoverable);
checkError( EXPECT_THAT_ERROR(std::move(Recoverable),
"unexpected line op length at offset 0x00000031 expected 0x01 found 0x02", FailedWithMessage("unexpected line op length at offset "
std::move(Recoverable)); "0x00000031 expected 0x01 found 0x02"));
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u); ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u);
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
@ -546,9 +531,9 @@ TEST_F(DebugLineBasicFixture, ErrorForExtendedOpcodeLengthLargerThanExpected) {
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
nullptr, RecordRecoverable); nullptr, RecordRecoverable);
checkError( EXPECT_THAT_ERROR(std::move(Recoverable),
"unexpected line op length at offset 0x00000032 expected 0x02 found 0x01", FailedWithMessage("unexpected line op length at offset "
std::move(Recoverable)); "0x00000032 expected 0x02 found 0x01"));
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 4u); ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 4u);
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 2u); EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 2u);
@ -576,9 +561,10 @@ TEST_F(DebugLineBasicFixture, ErrorForUnitLengthTooLarge) {
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 1, *Context, auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 1, *Context,
nullptr, RecordRecoverable); nullptr, RecordRecoverable);
checkError("line table program with offset 0x00000001 has length 0x00000034 " EXPECT_THAT_ERROR(
"but only 0x00000033 bytes are available", std::move(Recoverable),
std::move(Recoverable)); FailedWithMessage("line table program with offset 0x00000001 has length "
"0x00000034 but only 0x00000033 bytes are available"));
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
EXPECT_EQ((*ExpectedLineTable)->Rows.size(), 2u); EXPECT_EQ((*ExpectedLineTable)->Rows.size(), 2u);
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
@ -603,9 +589,9 @@ TEST_F(DebugLineBasicFixture, ErrorForMismatchedAddressSize) {
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
nullptr, RecordRecoverable); nullptr, RecordRecoverable);
checkError( EXPECT_THAT_ERROR(std::move(Recoverable),
"mismatching address size at offset 0x00000030 expected 0x08 found 0x04", FailedWithMessage("mismatching address size at offset "
std::move(Recoverable)); "0x00000030 expected 0x08 found 0x04"));
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u); ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u);
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
@ -630,9 +616,9 @@ TEST_F(DebugLineBasicFixture,
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
nullptr, RecordRecoverable); nullptr, RecordRecoverable);
checkError( EXPECT_THAT_ERROR(std::move(Recoverable),
"mismatching address size at offset 0x00000038 expected 0x04 found 0x08", FailedWithMessage("mismatching address size at offset "
std::move(Recoverable)); "0x00000038 expected 0x04 found 0x08"));
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u); ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 2u);
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
@ -662,10 +648,10 @@ TEST_F(DebugLineBasicFixture,
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
nullptr, RecordRecoverable); nullptr, RecordRecoverable);
checkError( EXPECT_THAT_ERROR(
"address size 0x03 of DW_LNE_set_address opcode at offset 0x00000030 is " std::move(Recoverable),
"unsupported", FailedWithMessage("address size 0x03 of DW_LNE_set_address opcode at "
std::move(Recoverable)); "offset 0x00000030 is unsupported"));
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u); ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u);
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
@ -690,10 +676,10 @@ TEST_F(DebugLineBasicFixture, ErrorForAddressSizeGreaterThanByteSize) {
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
nullptr, RecordRecoverable); nullptr, RecordRecoverable);
checkError( EXPECT_THAT_ERROR(
"address size 0x108 of DW_LNE_set_address opcode at offset 0x00000031 is " std::move(Recoverable),
"unsupported", FailedWithMessage("address size 0x108 of DW_LNE_set_address opcode at "
std::move(Recoverable)); "offset 0x00000031 is unsupported"));
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
} }
@ -723,10 +709,10 @@ TEST_F(DebugLineBasicFixture, ErrorForUnsupportedAddressSizeDefinedInHeader) {
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
nullptr, RecordRecoverable); nullptr, RecordRecoverable);
checkError( EXPECT_THAT_ERROR(
"address size 0x09 of DW_LNE_set_address opcode at offset 0x00000038 is " std::move(Recoverable),
"unsupported", FailedWithMessage("address size 0x09 of DW_LNE_set_address opcode at "
std::move(Recoverable)); "offset 0x00000038 is unsupported"));
ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded()); ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u); ASSERT_EQ((*ExpectedLineTable)->Rows.size(), 3u);
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
@ -754,10 +740,10 @@ TEST_F(DebugLineBasicFixture, CallbackUsedForUnterminatedSequence) {
auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context, auto ExpectedLineTable = Line.getOrParseLineTable(LineData, 0, *Context,
nullptr, RecordRecoverable); nullptr, RecordRecoverable);
checkError("last sequence in debug line table at offset 0x00000000 is not " EXPECT_THAT_ERROR(std::move(Recoverable),
"terminated", FailedWithMessage("last sequence in debug line table at "
std::move(Recoverable)); "offset 0x00000000 is not terminated"));
ASSERT_TRUE(ExpectedLineTable.operator bool()); ASSERT_THAT_EXPECTED(ExpectedLineTable, Succeeded());
EXPECT_EQ((*ExpectedLineTable)->Rows.size(), 6u); EXPECT_EQ((*ExpectedLineTable)->Rows.size(), 6u);
// The unterminated sequence is not added to the sequence list. // The unterminated sequence is not added to the sequence list.
EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u); EXPECT_EQ((*ExpectedLineTable)->Sequences.size(), 1u);
@ -837,9 +823,11 @@ TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenParsing) {
EXPECT_TRUE(Parser.done()); EXPECT_TRUE(Parser.done());
EXPECT_FALSE(Recoverable); EXPECT_FALSE(Recoverable);
checkError("parsing line table prologue at offset 0x00000000 unsupported " EXPECT_THAT_ERROR(
"reserved unit length found of value 0xfffffff0", std::move(Unrecoverable),
std::move(Unrecoverable)); FailedWithMessage(
"parsing line table prologue at offset 0x00000000 unsupported "
"reserved unit length found of value 0xfffffff0"));
} }
TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenSkipping) { TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenSkipping) {
@ -858,9 +846,11 @@ TEST_F(DebugLineBasicFixture, ParserMovesToEndForBadLengthWhenSkipping) {
EXPECT_TRUE(Parser.done()); EXPECT_TRUE(Parser.done());
EXPECT_FALSE(Recoverable); EXPECT_FALSE(Recoverable);
checkError("parsing line table prologue at offset 0x00000000 unsupported " EXPECT_THAT_ERROR(
"reserved unit length found of value 0xfffffff0", std::move(Unrecoverable),
std::move(Unrecoverable)); FailedWithMessage(
"parsing line table prologue at offset 0x00000000 unsupported "
"reserved unit length found of value 0xfffffff0"));
} }
TEST_F(DebugLineBasicFixture, ParserReportsFirstErrorInEachTableWhenParsing) { TEST_F(DebugLineBasicFixture, ParserReportsFirstErrorInEachTableWhenParsing) {
@ -879,13 +869,14 @@ TEST_F(DebugLineBasicFixture, ParserReportsFirstErrorInEachTableWhenParsing) {
Parser.parseNext(RecordRecoverable, RecordUnrecoverable); Parser.parseNext(RecordRecoverable, RecordUnrecoverable);
EXPECT_TRUE(Parser.done()); EXPECT_TRUE(Parser.done());
EXPECT_FALSE(Recoverable); EXPECT_THAT_ERROR(std::move(Recoverable), Succeeded());
checkError({"parsing line table prologue at offset 0x00000000 found " EXPECT_THAT_ERROR(
"unsupported version 0", std::move(Unrecoverable),
"parsing line table prologue at offset 0x00000006 found " FailedWithMessage("parsing line table prologue at offset 0x00000000 "
"unsupported version 1"}, "found unsupported version 0",
std::move(Unrecoverable)); "parsing line table prologue at offset 0x00000006 "
"found unsupported version 1"));
} }
TEST_F(DebugLineBasicFixture, ParserReportsNonPrologueProblemsWhenParsing) { TEST_F(DebugLineBasicFixture, ParserReportsNonPrologueProblemsWhenParsing) {
@ -905,18 +896,18 @@ TEST_F(DebugLineBasicFixture, ParserReportsNonPrologueProblemsWhenParsing) {
Parser.parseNext(RecordRecoverable, RecordUnrecoverable); Parser.parseNext(RecordRecoverable, RecordUnrecoverable);
EXPECT_FALSE(Unrecoverable); EXPECT_FALSE(Unrecoverable);
ASSERT_FALSE(Parser.done()); ASSERT_FALSE(Parser.done());
checkError( EXPECT_THAT_ERROR(std::move(Recoverable),
"unexpected line op length at offset 0x00000030 expected 0x42 found 0x01", FailedWithMessage("unexpected line op length at offset "
std::move(Recoverable)); "0x00000030 expected 0x42 found 0x01"));
// Reset the error state so that it does not confuse the next set of checks. // Reset the error state so that it does not confuse the next set of checks.
Unrecoverable = Error::success(); Unrecoverable = Error::success();
Parser.parseNext(RecordRecoverable, RecordUnrecoverable); Parser.parseNext(RecordRecoverable, RecordUnrecoverable);
EXPECT_TRUE(Parser.done()); EXPECT_TRUE(Parser.done());
checkError("last sequence in debug line table at offset 0x00000031 is not " EXPECT_THAT_ERROR(std::move(Recoverable),
"terminated", FailedWithMessage("last sequence in debug line table at "
std::move(Recoverable)); "offset 0x00000031 is not terminated"));
EXPECT_FALSE(Unrecoverable); EXPECT_FALSE(Unrecoverable);
} }
@ -939,11 +930,12 @@ TEST_F(DebugLineBasicFixture,
EXPECT_TRUE(Parser.done()); EXPECT_TRUE(Parser.done());
EXPECT_FALSE(Recoverable); EXPECT_FALSE(Recoverable);
checkError({"parsing line table prologue at offset 0x00000000 found " EXPECT_THAT_ERROR(
"unsupported version 0", std::move(Unrecoverable),
"parsing line table prologue at offset 0x00000006 found " FailedWithMessage("parsing line table prologue at offset 0x00000000 "
"unsupported version 1"}, "found unsupported version 0",
std::move(Unrecoverable)); "parsing line table prologue at offset 0x00000006 "
"found unsupported version 1"));
} }
TEST_F(DebugLineBasicFixture, ParserIgnoresNonPrologueErrorsWhenSkipping) { TEST_F(DebugLineBasicFixture, ParserIgnoresNonPrologueErrorsWhenSkipping) {