Show both expected and obtained gas expectations when failure happens.

This commit is contained in:
Djordje Mijovic 2021-03-09 21:27:38 +01:00
parent 12ef273d06
commit 2c575db0ea
3 changed files with 28 additions and 25 deletions

View File

@ -258,7 +258,10 @@ TestCase::TestResult SemanticTest::runTest(
bool outputMismatch = (output != test.call().expectations.rawBytes()); bool outputMismatch = (output != test.call().expectations.rawBytes());
if (!outputMismatch && !checkGasCostExpectation(test, _compileViaYul)) if (!outputMismatch && !checkGasCostExpectation(test, _compileViaYul))
{
success = false;
m_gasCostFailure = true; m_gasCostFailure = true;
}
// Pre byzantium, it was not possible to return failure data, so we disregard // Pre byzantium, it was not possible to return failure data, so we disregard
// output mismatch for those EVM versions. // output mismatch for those EVM versions.
@ -291,7 +294,7 @@ TestCase::TestResult SemanticTest::runTest(
for (TestFunctionCall const& test: m_tests) for (TestFunctionCall const& test: m_tests)
{ {
ErrorReporter errorReporter; ErrorReporter errorReporter;
_stream << test.format(errorReporter, _linePrefix, false, _formatted) << endl; _stream << test.format(errorReporter, _linePrefix, false, _formatted, false) << endl;
_stream << errorReporter.format(_linePrefix, _formatted); _stream << errorReporter.format(_linePrefix, _formatted);
} }
_stream << endl; _stream << endl;
@ -299,7 +302,7 @@ TestCase::TestResult SemanticTest::runTest(
for (TestFunctionCall const& test: m_tests) for (TestFunctionCall const& test: m_tests)
{ {
ErrorReporter errorReporter; ErrorReporter errorReporter;
_stream << test.format(errorReporter, _linePrefix, true, _formatted) << endl; _stream << test.format(errorReporter, _linePrefix, !m_gasCostFailure, _formatted, m_gasCostFailure) << endl;
_stream << errorReporter.format(_linePrefix, _formatted); _stream << errorReporter.format(_linePrefix, _formatted);
} }
AnsiColorized(_stream, _formatted, {BOLD, RED}) AnsiColorized(_stream, _formatted, {BOLD, RED})
@ -318,25 +321,12 @@ TestCase::TestResult SemanticTest::runTest(
return TestResult::Failure; return TestResult::Failure;
} }
if (m_gasCostFailure)
{
AnsiColorized(_stream, _formatted, {BOLD, CYAN})
<< _linePrefix << "Gas results missing or wrong, obtained result:" << endl;
for (auto const& test: m_tests)
{
ErrorReporter errorReporter;
_stream << test.format(errorReporter, _linePrefix, false, _formatted) << endl;
_stream << errorReporter.format(_linePrefix, _formatted);
}
return TestResult::Failure;
}
return TestResult::Success; return TestResult::Success;
} }
bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const
{ {
if (m_evmVersion != EVMVersion{}) if (m_evmVersion != EVMVersion{} || solidity::test::CommonOptions::get().useABIEncoderV1)
return true; return true;
string setting = string setting =
@ -402,7 +392,12 @@ void SemanticTest::printSource(ostream& _stream, string const& _linePrefix, bool
void SemanticTest::printUpdatedExpectations(ostream& _stream, string const&) const void SemanticTest::printUpdatedExpectations(ostream& _stream, string const&) const
{ {
for (TestFunctionCall const& test: m_tests) for (TestFunctionCall const& test: m_tests)
_stream << test.format("", /* _renderResult = */ !m_gasCostFailure, /* _highlight = */ false) << endl; _stream << test.format(
"",
/* _renderResult = */ !m_gasCostFailure,
/* _highlight = */ false,
/* _renderGasCostResult */ m_gasCostFailure
) << endl;
} }
void SemanticTest::printUpdatedSettings(ostream& _stream, string const& _linePrefix) void SemanticTest::printUpdatedSettings(ostream& _stream, string const& _linePrefix)

View File

@ -36,7 +36,8 @@ string TestFunctionCall::format(
ErrorReporter& _errorReporter, ErrorReporter& _errorReporter,
string const& _linePrefix, string const& _linePrefix,
bool const _renderResult, bool const _renderResult,
bool const _highlight bool const _highlight,
bool const _renderGasCostResult
) const ) const
{ {
stringstream stream; stringstream stream;
@ -204,7 +205,7 @@ string TestFunctionCall::format(
} }
} }
stream << formatGasExpectations(_linePrefix); stream << formatGasExpectations(_linePrefix, _renderGasCostResult);
}; };
formatOutput(m_call.displayMode == FunctionCall::DisplayMode::SingleLine); formatOutput(m_call.displayMode == FunctionCall::DisplayMode::SingleLine);
@ -320,10 +321,10 @@ string TestFunctionCall::formatRawParameters(
return os.str(); return os.str();
} }
string TestFunctionCall::formatGasExpectations(string const& _linePrefix) const string TestFunctionCall::formatGasExpectations(string const& _linePrefix, bool const _renderGasCostResult) const
{ {
stringstream os; stringstream os;
for (auto const& [runType, gasUsed]: m_gasCosts) for (auto const& [runType, gasUsed]: (_renderGasCostResult ? m_gasCosts : m_call.expectations.gasUsed))
if (!runType.empty()) if (!runType.empty())
os << endl << _linePrefix << "// gas " << runType << ": " << (gasUsed.str()); os << endl << _linePrefix << "// gas " << runType << ": " << (gasUsed.str());
return os.str(); return os.str();

View File

@ -49,6 +49,8 @@ public:
/// the actual result is used. /// the actual result is used.
/// If _highlight is false, it's formatted without colorized highlighting. If it's true, AnsiColorized is /// If _highlight is false, it's formatted without colorized highlighting. If it's true, AnsiColorized is
/// used to apply a colorized highlighting. /// used to apply a colorized highlighting.
/// If __renderGasCostResult is false, the expected gas costs will be used, if it's true
/// the actual gas costs will be used
/// If test expectations do not match, the contract ABI is consulted in order to get the /// If test expectations do not match, the contract ABI is consulted in order to get the
/// right encoding for returned bytes, based on the parsed return types. /// right encoding for returned bytes, based on the parsed return types.
/// Reports warnings and errors to the error reporter. /// Reports warnings and errors to the error reporter.
@ -56,7 +58,8 @@ public:
ErrorReporter& _errorReporter, ErrorReporter& _errorReporter,
std::string const& _linePrefix = "", std::string const& _linePrefix = "",
bool const _renderResult = false, bool const _renderResult = false,
bool const _highlight = false bool const _highlight = false,
bool const _renderGasCostResult = false
) const; ) const;
/// Overloaded version that passes an error reporter which is never used outside /// Overloaded version that passes an error reporter which is never used outside
@ -64,11 +67,12 @@ public:
std::string format( std::string format(
std::string const& _linePrefix = "", std::string const& _linePrefix = "",
bool const _renderResult = false, bool const _renderResult = false,
bool const _highlight = false bool const _highlight = false,
bool const _renderGasCostResult = false
) const ) const
{ {
ErrorReporter reporter; ErrorReporter reporter;
return format(reporter, _linePrefix, _renderResult, _highlight); return format(reporter, _linePrefix, _renderResult, _highlight, _renderGasCostResult);
} }
/// Resets current results in case the function was called and the result /// Resets current results in case the function was called and the result
@ -118,7 +122,10 @@ private:
) const; ) const;
/// Formats gas usage expectations one per line /// Formats gas usage expectations one per line
std::string formatGasExpectations(std::string const& _linePrefix) const; std::string formatGasExpectations(
std::string const& _linePrefix,
bool const _renderGasCostResult
) const;
/// Compares raw expectations (which are converted to a byte representation before), /// Compares raw expectations (which are converted to a byte representation before),
/// and also the expected transaction status of the function call to the actual test results. /// and also the expected transaction status of the function call to the actual test results.