Completely remove the testGroup events

This was done because they were 1:1 mapping to testRun events, and
I could not think of a reasonable way to make them their own thing.
This commit is contained in:
Martin Hořeňovský 2021-09-06 22:59:40 +02:00
parent ab3fe0053d
commit e5938007f7
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
25 changed files with 17874 additions and 18036 deletions

View File

@ -77,7 +77,6 @@ namespace Catch {
Totals execute() {
auto const& invalidArgs = m_config->testSpec().getInvalidArgs();
Totals totals;
m_context.testGroupStarting(m_config->name(), 1, 1);
for (auto const& testCase : m_tests) {
if (!m_context.aborting())
totals += m_context.runTest(*testCase);
@ -97,7 +96,6 @@ namespace Catch {
m_reporter->reportInvalidArguments(invalidArg);
}
m_context.testGroupEnded(m_config->name(), totals, 1, 1);
return totals;
}

View File

@ -32,17 +32,9 @@ namespace Catch {
TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}
GroupInfo::GroupInfo( std::string const& _name,
std::size_t _groupIndex,
std::size_t _groupsCount )
: name( _name ),
groupIndex( _groupIndex ),
groupsCounts( _groupsCount )
{}
AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
std::vector<MessageInfo> const& _infoMessages,
Totals const& _totals )
AssertionStats::AssertionStats( AssertionResult const& _assertionResult,
std::vector<MessageInfo> const& _infoMessages,
Totals const& _totals )
: assertionResult( _assertionResult ),
infoMessages( _infoMessages ),
totals( _totals )
@ -84,20 +76,6 @@ namespace Catch {
{}
TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,
Totals const& _totals,
bool _aborting )
: groupInfo( _groupInfo ),
totals( _totals ),
aborting( _aborting )
{}
TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )
: groupInfo( _groupInfo ),
aborting( false )
{}
TestRunStats::TestRunStats( TestRunInfo const& _runInfo,
Totals const& _totals,
bool _aborting )

View File

@ -48,15 +48,6 @@ namespace Catch {
TestRunInfo( std::string const& _name );
std::string name;
};
struct GroupInfo {
GroupInfo( std::string const& _name,
std::size_t _groupIndex,
std::size_t _groupsCount );
std::string name;
std::size_t groupIndex;
std::size_t groupsCounts;
};
struct AssertionStats {
AssertionStats( AssertionResult const& _assertionResult,
@ -99,17 +90,6 @@ namespace Catch {
bool aborting;
};
struct TestGroupStats {
TestGroupStats( GroupInfo const& _groupInfo,
Totals const& _totals,
bool _aborting );
TestGroupStats( GroupInfo const& _groupInfo );
GroupInfo groupInfo;
Totals totals;
bool aborting;
};
struct TestRunStats {
TestRunStats( TestRunInfo const& _runInfo,
Totals const& _totals,
@ -196,7 +176,6 @@ namespace Catch {
virtual void reportInvalidArguments(std::string const&) {}
virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
@ -213,7 +192,6 @@ namespace Catch {
virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
virtual void skipTest( TestCaseInfo const& testInfo ) = 0;

View File

@ -175,14 +175,6 @@ namespace Catch {
m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));
}
void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {
m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));
}
void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {
m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));
}
Totals RunContext::runTest(TestCaseHandle const& testCase) {
Totals prevTotals = m_totals;
@ -389,7 +381,6 @@ namespace Catch {
std::string(),
false));
m_totals.testCases.failed++;
testGroupEnded(std::string(), m_totals, 1, 1);
m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));
}

View File

@ -40,9 +40,6 @@ namespace Catch {
~RunContext() override;
void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
Totals runTest(TestCaseHandle const& testCase);
public: // IResultCapture

View File

@ -231,12 +231,10 @@ namespace Catch {
void EventListenerBase::listTags( std::vector<TagInfo> const& ) {}
void EventListenerBase::noMatchingTestCases( std::string const& ) {}
void EventListenerBase::testRunStarting( TestRunInfo const& ) {}
void EventListenerBase::testGroupStarting( GroupInfo const& ) {}
void EventListenerBase::testCaseStarting( TestCaseInfo const& ) {}
void EventListenerBase::sectionStarting( SectionInfo const& ) {}
void EventListenerBase::sectionEnded( SectionStats const& ) {}
void EventListenerBase::testCaseEnded( TestCaseStats const& ) {}
void EventListenerBase::testGroupEnded( TestGroupStats const& ) {}
void EventListenerBase::testRunEnded( TestRunStats const& ) {}
void EventListenerBase::skipTest( TestCaseInfo const& ) {}
} // namespace Catch

View File

@ -487,15 +487,6 @@ void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {
StreamingReporterBase::testCaseEnded(_testCaseStats);
m_headerPrinted = false;
}
void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {
if (currentGroupInfo.used) {
printSummaryDivider();
stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
printTotals(_testGroupStats.totals);
stream << "\n\n" << std::flush;
}
StreamingReporterBase::testGroupEnded(_testGroupStats);
}
void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {
printTotalsDivider(_testRunStats.totals);
printTotals(_testRunStats.totals);
@ -515,11 +506,9 @@ void ConsoleReporter::lazyPrint() {
void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {
if (!currentTestRunInfo.used)
if ( !currentTestRunInfo.used ) {
lazyPrintRunInfo();
if (!currentGroupInfo.used)
lazyPrintGroupInfo();
}
if (!m_headerPrinted) {
printTestCaseAndSectionHeader();
m_headerPrinted = true;
@ -537,12 +526,6 @@ void ConsoleReporter::lazyPrintRunInfo() {
currentTestRunInfo.used = true;
}
void ConsoleReporter::lazyPrintGroupInfo() {
if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {
printClosedHeader("Group: " + currentGroupInfo->name);
currentGroupInfo.used = true;
}
}
void ConsoleReporter::printTestCaseAndSectionHeader() {
assert(!m_sectionStack.empty());
printOpenHeader(currentTestCaseInfo->name);

View File

@ -40,7 +40,6 @@ namespace Catch {
void benchmarkFailed( StringRef error ) override;
void testCaseEnded(TestCaseStats const& _testCaseStats) override;
void testGroupEnded(TestGroupStats const& _testGroupStats) override;
void testRunEnded(TestRunStats const& _testRunStats) override;
void testRunStarting(TestRunInfo const& _testRunInfo) override;
private:
@ -49,7 +48,6 @@ namespace Catch {
void lazyPrintWithoutClosingBenchmarkTable();
void lazyPrintRunInfo();
void lazyPrintGroupInfo();
void printTestCaseAndSectionHeader();
void printClosedHeader(std::string const& _name);

View File

@ -98,16 +98,10 @@ namespace Catch {
m_deepestSection->stdErr = testCaseStats.stdErr;
}
void CumulativeReporterBase::testGroupEnded(
TestGroupStats const& testGroupStats ) {
auto node = Detail::make_unique<TestGroupNode>( testGroupStats );
node->children.swap( m_testCases );
m_testGroups.push_back( CATCH_MOVE(node) );
}
void CumulativeReporterBase::testRunEnded( TestRunStats const& testRunStats ) {
m_testRuns.emplace_back( testRunStats );
m_testRuns.back().children.swap( m_testGroups );
m_testRuns.back().children.swap( m_testCases );
testRunEndedCumulative();
}

View File

@ -42,8 +42,7 @@ namespace Catch {
using TestCaseNode = Node<TestCaseStats, SectionNode>;
using TestGroupNode = Node<TestGroupStats, TestCaseNode>;
using TestRunNode = Node<TestRunStats, TestGroupNode>;
using TestRunNode = Node<TestRunStats, TestCaseNode>;
CumulativeReporterBase( ReporterConfig const& _config ):
IStreamingReporter( _config.fullConfig() ),
@ -51,7 +50,6 @@ namespace Catch {
~CumulativeReporterBase() override;
void testRunStarting( TestRunInfo const& ) override {}
void testGroupStarting( GroupInfo const& ) override {}
void testCaseStarting( TestCaseInfo const& ) override {}
@ -62,7 +60,6 @@ namespace Catch {
bool assertionEnded( AssertionStats const& assertionStats ) override;
void sectionEnded( SectionStats const& sectionStats ) override;
void testCaseEnded( TestCaseStats const& testCaseStats ) override;
void testGroupEnded( TestGroupStats const& testGroupStats ) override;
void testRunEnded( TestRunStats const& testRunStats ) override;
//! Customization point: called after last test finishes (testRunEnded has been handled)
virtual void testRunEndedCumulative() = 0;
@ -78,7 +75,6 @@ namespace Catch {
// Note: We rely on pointer identity being stable, which is why
// which is why we store around pointers rather than values.
std::vector<Detail::unique_ptr<TestCaseNode>> m_testCases;
std::vector<Detail::unique_ptr<TestGroupNode>> m_testGroups;
std::vector<TestRunNode> m_testRuns;

View File

@ -34,12 +34,10 @@ namespace Catch {
void noMatchingTestCases( std::string const& spec ) override;
void testRunStarting( TestRunInfo const& testRunInfo ) override;
void testGroupStarting( GroupInfo const& groupInfo ) override;
void testCaseStarting( TestCaseInfo const& testInfo ) override;
void sectionStarting( SectionInfo const& sectionInfo ) override;
void sectionEnded( SectionStats const& sectionStats ) override;
void testCaseEnded( TestCaseStats const& testCaseStats ) override;
void testGroupEnded( TestGroupStats const& testGroupStats ) override;
void testRunEnded( TestRunStats const& testRunStats ) override;
void skipTest( TestCaseInfo const& testInfo ) override;
};

View File

@ -75,14 +75,10 @@ namespace Catch {
void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) {
CumulativeReporterBase::testRunStarting( runInfo );
xml.startElement( "testsuites" );
}
void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
suiteTimer.start();
stdOutForSuite.clear();
stdErrForSuite.clear();
unexpectedExceptions = 0;
CumulativeReporterBase::testGroupStarting( groupInfo );
}
void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
@ -101,21 +97,20 @@ namespace Catch {
CumulativeReporterBase::testCaseEnded( testCaseStats );
}
void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
double suiteTime = suiteTimer.getElapsedSeconds();
CumulativeReporterBase::testGroupEnded( testGroupStats );
writeGroup( *m_testGroups.back(), suiteTime );
}
void JunitReporter::testRunEndedCumulative() {
const auto suiteTime = suiteTimer.getElapsedSeconds();
// HACK: There can only be one testRunNode? This needs to be
// refactored after the group nodes are excised.
assert(m_testRuns.size() == 1);
writeRun( m_testRuns.back(), suiteTime );
xml.endElement();
}
void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
void JunitReporter::writeRun( TestRunNode const& testRunNode, double suiteTime ) {
XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
TestGroupStats const& stats = groupNode.value;
xml.writeAttribute( "name"_sr, stats.groupInfo.name );
TestRunStats const& stats = testRunNode.value;
xml.writeAttribute( "name"_sr, stats.runInfo.name );
xml.writeAttribute( "errors"_sr, unexpectedExceptions );
xml.writeAttribute( "failures"_sr, stats.totals.assertions.failed-unexpectedExceptions );
xml.writeAttribute( "tests"_sr, stats.totals.assertions.total() );
@ -142,7 +137,7 @@ namespace Catch {
}
// Write test cases
for( auto const& child : groupNode.children )
for( auto const& child : testRunNode.children )
writeTestCase( *child );
xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );

View File

@ -27,19 +27,15 @@ namespace Catch {
void testRunStarting(TestRunInfo const& runInfo) override;
void testGroupStarting(GroupInfo const& groupInfo) override;
void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
bool assertionEnded(AssertionStats const& assertionStats) override;
void testCaseEnded(TestCaseStats const& testCaseStats) override;
void testGroupEnded(TestGroupStats const& testGroupStats) override;
void testRunEndedCumulative() override;
private:
void writeGroup(TestGroupNode const& groupNode, double suiteTime);
void writeRun(TestRunNode const& testRunNode, double suiteTime);
void writeTestCase(TestCaseNode const& testCaseNode);

View File

@ -69,14 +69,6 @@ namespace Catch {
m_reporter->testRunStarting( testRunInfo );
}
void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {
for ( auto& listener : m_listeners ) {
listener->testGroupStarting( groupInfo );
}
m_reporter->testGroupStarting( groupInfo );
}
void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
for ( auto& listener : m_listeners ) {
listener->testCaseStarting( testInfo );
@ -120,13 +112,6 @@ namespace Catch {
m_reporter->testCaseEnded( testCaseStats );
}
void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
for ( auto& listener : m_listeners ) {
listener->testGroupEnded( testGroupStats );
}
m_reporter->testGroupEnded( testGroupStats );
}
void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {
for ( auto& listener : m_listeners ) {
listener->testRunEnded( testRunStats );

View File

@ -40,7 +40,6 @@ namespace Catch {
void benchmarkFailed( StringRef error ) override;
void testRunStarting( TestRunInfo const& testRunInfo ) override;
void testGroupStarting( GroupInfo const& groupInfo ) override;
void testCaseStarting( TestCaseInfo const& testInfo ) override;
void sectionStarting( SectionInfo const& sectionInfo ) override;
void assertionStarting( AssertionInfo const& assertionInfo ) override;
@ -49,7 +48,6 @@ namespace Catch {
bool assertionEnded( AssertionStats const& assertionStats ) override;
void sectionEnded( SectionStats const& sectionStats ) override;
void testCaseEnded( TestCaseStats const& testCaseStats ) override;
void testGroupEnded( TestGroupStats const& testGroupStats ) override;
void testRunEnded( TestRunStats const& testRunStats ) override;
void skipTest( TestCaseInfo const& testInfo ) override;

View File

@ -22,20 +22,17 @@ namespace Catch {
xml.writeAttribute("version"_sr, '1');
}
void SonarQubeReporter::testGroupEnded(TestGroupStats const& testGroupStats) {
CumulativeReporterBase::testGroupEnded(testGroupStats);
writeGroup(*m_testGroups.back());
}
void SonarQubeReporter::writeGroup(TestGroupNode const& groupNode) {
void SonarQubeReporter::writeRun( TestRunNode const& runNode ) {
std::map<std::string, std::vector<TestCaseNode const*>> testsPerFile;
for ( auto const& child : groupNode.children ) {
for ( auto const& child : runNode.children ) {
testsPerFile[child->value.testInfo->lineInfo.file].push_back(
child.get() );
}
for (auto const& kv : testsPerFile)
writeTestFile(kv.first, kv.second);
for ( auto const& kv : testsPerFile ) {
writeTestFile( kv.first, kv.second );
}
}
void SonarQubeReporter::writeTestFile(std::string const& filename, std::vector<TestCaseNode const*> const& testCaseNodes) {

View File

@ -32,15 +32,17 @@ namespace Catch {
void noMatchingTestCases(std::string const& /*spec*/) override {}
void testRunStarting(TestRunInfo const& testRunInfo) override;
void testGroupEnded(TestGroupStats const& testGroupStats) override;
void testRunStarting( TestRunInfo const& testRunInfo ) override;
void testRunEndedCumulative() override {
// HACK: There can only be one testRunNode? This needs to be
// refactored after the group nodes are excised.
assert( m_testRuns.size() == 1 );
writeRun( m_testRuns.back() );
xml.endElement();
}
void writeGroup(TestGroupNode const& groupNode);
void writeRun( TestRunNode const& groupNode );
void writeTestFile(std::string const& filename, std::vector<TestCaseNode const*> const& testCaseNodes);

View File

@ -17,18 +17,8 @@ namespace Catch {
currentTestRunInfo = _testRunInfo;
}
void
StreamingReporterBase::testGroupStarting( GroupInfo const& _groupInfo ) {
currentGroupInfo = _groupInfo;
}
void StreamingReporterBase::testGroupEnded( TestGroupStats const& ) {
currentGroupInfo.reset();
}
void StreamingReporterBase::testRunEnded( TestRunStats const& ) {
currentTestCaseInfo = nullptr;
currentGroupInfo.reset();
currentTestRunInfo.reset();
}

View File

@ -48,8 +48,6 @@ namespace Catch {
void testRunStarting( TestRunInfo const& _testRunInfo ) override;
void testGroupStarting( GroupInfo const& _groupInfo ) override;
void testCaseStarting(TestCaseInfo const& _testInfo) override {
currentTestCaseInfo = &_testInfo;
}
@ -63,7 +61,6 @@ namespace Catch {
void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {
currentTestCaseInfo = nullptr;
}
void testGroupEnded( TestGroupStats const& ) override;
void testRunEnded( TestRunStats const& /* _testRunStats */ ) override;
void skipTest(TestCaseInfo const&) override {
@ -78,7 +75,6 @@ namespace Catch {
std::ostream& stream;
LazyStat<TestRunInfo> currentTestRunInfo;
LazyStat<GroupInfo> currentGroupInfo;
TestCaseInfo const* currentTestCaseInfo = nullptr;
std::vector<SectionInfo> m_sectionStack;

View File

@ -46,16 +46,14 @@ namespace Catch {
TeamCityReporter::~TeamCityReporter() {}
void TeamCityReporter::testGroupStarting(GroupInfo const& groupInfo) {
StreamingReporterBase::testGroupStarting(groupInfo);
stream << "##teamcity[testSuiteStarted name='"
<< escape(groupInfo.name) << "']\n";
void TeamCityReporter::testRunStarting( TestRunInfo const& runInfo ) {
stream << "##teamcity[testSuiteStarted name='" << escape( runInfo.name )
<< "']\n";
}
void TeamCityReporter::testGroupEnded(TestGroupStats const& testGroupStats) {
StreamingReporterBase::testGroupEnded(testGroupStats);
void TeamCityReporter::testRunEnded( TestRunStats const& runStats ) {
stream << "##teamcity[testSuiteFinished name='"
<< escape(testGroupStats.groupInfo.name) << "']\n";
<< escape( runStats.runInfo.name ) << "']\n";
}
bool TeamCityReporter::assertionEnded(AssertionStats const& assertionStats) {

View File

@ -38,8 +38,8 @@ namespace Catch {
void noMatchingTestCases( std::string const& /* spec */ ) override {}
void testGroupStarting(GroupInfo const& groupInfo) override;
void testGroupEnded(TestGroupStats const& testGroupStats) override;
void testRunStarting( TestRunInfo const& groupInfo ) override;
void testRunEnded( TestRunStats const& testGroupStats ) override;
void assertionStarting(AssertionInfo const&) override {}

View File

@ -55,7 +55,7 @@ namespace Catch {
std::string stylesheetRef = getStylesheetRef();
if( !stylesheetRef.empty() )
m_xml.writeStylesheetRef( stylesheetRef );
m_xml.startElement( "Catch" );
m_xml.startElement( "Catch2TestRun" );
if( !m_config->name().empty() )
m_xml.writeAttribute( "name"_sr, m_config->name() );
if (m_config->testSpec().hasFilters())
@ -65,12 +65,6 @@ namespace Catch {
.writeAttribute( "seed"_sr, m_config->rngSeed() );
}
void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {
StreamingReporterBase::testGroupStarting( groupInfo );
m_xml.startElement( "Group" )
.writeAttribute( "name"_sr, groupInfo.name );
}
void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
StreamingReporterBase::testCaseStarting(testInfo);
m_xml.startElement( "TestCase" )
@ -202,20 +196,6 @@ namespace Catch {
m_xml.endElement();
}
void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
StreamingReporterBase::testGroupEnded( testGroupStats );
// TODO: Check testGroupStats.aborting and act accordingly.
m_xml.scopedElement( "OverallResults" )
.writeAttribute( "successes"_sr, testGroupStats.totals.assertions.passed )
.writeAttribute( "failures"_sr, testGroupStats.totals.assertions.failed )
.writeAttribute( "expectedFailures"_sr, testGroupStats.totals.assertions.failedButOk );
m_xml.scopedElement( "OverallResultsCases")
.writeAttribute( "successes"_sr, testGroupStats.totals.testCases.passed )
.writeAttribute( "failures"_sr, testGroupStats.totals.testCases.failed )
.writeAttribute( "expectedFailures"_sr, testGroupStats.totals.testCases.failedButOk );
m_xml.endElement();
}
void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {
StreamingReporterBase::testRunEnded( testRunStats );
m_xml.scopedElement( "OverallResults" )

View File

@ -33,8 +33,6 @@ namespace Catch {
void testRunStarting(TestRunInfo const& testInfo) override;
void testGroupStarting(GroupInfo const& groupInfo) override;
void testCaseStarting(TestCaseInfo const& testInfo) override;
void sectionStarting(SectionInfo const& sectionInfo) override;
@ -47,8 +45,6 @@ namespace Catch {
void testCaseEnded(TestCaseStats const& testCaseStats) override;
void testGroupEnded(TestGroupStats const& testGroupStats) override;
void testRunEnded(TestRunStats const& testRunStats) override;
void benchmarkPreparing( StringRef name ) override;

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact
>
<testsuite name="<exe-name>" errors="17" failures="130" tests="2121" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="129" tests="2120" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/>
<property name="random-seed" value="1"/>

File diff suppressed because it is too large Load Diff