Check that functions exist in isoltest.

This commit is contained in:
chriseth 2020-02-12 18:28:30 +01:00 committed by Mathias Baumann
parent f31332533f
commit 9aed40ab19
9 changed files with 32 additions and 3 deletions

View File

@ -80,6 +80,12 @@ SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVer
m_settings.erase("revertStrings"); m_settings.erase("revertStrings");
} }
if (m_settings.count("allowNonExistingFunctions"))
{
m_validatedSettings["allowNonExistingFunctions"] = true;
m_settings.erase("allowNonExistingFunctions");
}
parseExpectations(file); parseExpectations(file);
soltestAssert(!m_tests.empty(), "No tests specified in " + _filename); soltestAssert(!m_tests.empty(), "No tests specified in " + _filename);
} }
@ -143,13 +149,22 @@ TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePref
} }
else else
{ {
bytes output = test.call().useCallWithoutSignature ? bytes output;
callLowLevel(test.call().arguments.rawBytes(), test.call().value) : if (test.call().useCallWithoutSignature)
callContractFunctionWithValueNoEncoding( output = callLowLevel(test.call().arguments.rawBytes(), test.call().value);
else
{
soltestAssert(
m_validatedSettings.count("allowNonExistingFunctions") || m_compiler.methodIdentifiers(m_compiler.lastContractName()).isMember(test.call().signature),
"The function " + test.call().signature + " is not known to the compiler"
);
output = callContractFunctionWithValueNoEncoding(
test.call().signature, test.call().signature,
test.call().value, test.call().value,
test.call().arguments.rawBytes() test.call().arguments.rawBytes()
); );
}
if ((m_transactionSuccessful == test.call().expectations.failure) || (output != test.call().expectations.rawBytes())) if ((m_transactionSuccessful == test.call().expectations.failure) || (output != test.call().expectations.rawBytes()))
success = false; success = false;

View File

@ -2,5 +2,6 @@ contract test {
} }
// ==== // ====
// compileViaYul: also // compileViaYul: also
// allowNonExistingFunctions: true
// ---- // ----
// i_am_not_there() -> FAILURE // i_am_not_there() -> FAILURE

View File

@ -13,6 +13,7 @@ contract test {
uint256 super_secret_data; uint256 super_secret_data;
} }
// ==== // ====
// allowNonExistingFunctions: true
// compileViaYul: also // compileViaYul: also
// ---- // ----
// data() -> 8 // data() -> 8

View File

@ -4,6 +4,8 @@ contract test {
function c() public returns(uint n) { return 2; } function c() public returns(uint n) { return 2; }
function f() public returns(uint n) { return 3; } function f() public returns(uint n) { return 3; }
} }
// ====
// allowNonExistingFunctions: true
// ---- // ----
// a() -> 0 // a() -> 0
// b() -> 1 // b() -> 1

View File

@ -14,6 +14,7 @@ contract C {
} }
} }
// ==== // ====
// allowNonExistingFunctions: true
// EVMVersion: >homestead // EVMVersion: >homestead
// ---- // ----
// _() -> FAILURE // _() -> FAILURE

View File

@ -4,6 +4,7 @@ contract C {
} }
} }
// ==== // ====
// allowNonExistingFunctions: true
// compileViaYul: also // compileViaYul: also
// ---- // ----
// f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1 // f(uint256,uint256,uint256,uint256,uint256): 1, 1, 1, 1, 1

View File

@ -1,6 +1,7 @@
contract C { contract C {
} }
// ==== // ====
// allowNonExistingFunctions: true
// compileViaYul: true // compileViaYul: true
// ---- // ----
// f() -> FAILURE // f() -> FAILURE

View File

@ -114,6 +114,9 @@ string TestFunctionCall::format(
} }
else else
{ {
if (m_calledNonExistingFunction)
_errorReporter.warning("The function \"" + m_call.signature + "\" is not known to the compiler.");
bytes output = m_rawBytes; bytes output = m_rawBytes;
bool const isFailure = m_failure; bool const isFailure = m_failure;
result = isFailure ? result = isFailure ?
@ -300,6 +303,7 @@ void TestFunctionCall::reset()
{ {
m_rawBytes = bytes{}; m_rawBytes = bytes{};
m_failure = true; m_failure = true;
m_calledNonExistingFunction = false;
} }
bool TestFunctionCall::matchesExpectation() const bool TestFunctionCall::matchesExpectation() const

View File

@ -77,6 +77,7 @@ public:
void reset(); void reset();
FunctionCall const& call() const { return m_call; } FunctionCall const& call() const { return m_call; }
void calledNonExistingFunction() { m_calledNonExistingFunction = true; }
void setFailure(const bool _failure) { m_failure = _failure; } void setFailure(const bool _failure) { m_failure = _failure; }
void setRawBytes(const bytes _rawBytes) { m_rawBytes = _rawBytes; } void setRawBytes(const bytes _rawBytes) { m_rawBytes = _rawBytes; }
void setContractABI(Json::Value _contractABI) { m_contractABI = std::move(_contractABI); } void setContractABI(Json::Value _contractABI) { m_contractABI = std::move(_contractABI); }
@ -129,6 +130,8 @@ private:
/// JSON object which holds the contract ABI and that is used to set the output formatting /// JSON object which holds the contract ABI and that is used to set the output formatting
/// in the interactive update routine. /// in the interactive update routine.
Json::Value m_contractABI; Json::Value m_contractABI;
/// Flags that the test failed because the called function is not known to exist on the contract.
bool m_calledNonExistingFunction = false;
}; };
} }