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");
}
if (m_settings.count("allowNonExistingFunctions"))
{
m_validatedSettings["allowNonExistingFunctions"] = true;
m_settings.erase("allowNonExistingFunctions");
}
parseExpectations(file);
soltestAssert(!m_tests.empty(), "No tests specified in " + _filename);
}
@ -143,13 +149,22 @@ TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePref
}
else
{
bytes output = test.call().useCallWithoutSignature ?
callLowLevel(test.call().arguments.rawBytes(), test.call().value) :
callContractFunctionWithValueNoEncoding(
bytes output;
if (test.call().useCallWithoutSignature)
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().value,
test.call().arguments.rawBytes()
);
}
if ((m_transactionSuccessful == test.call().expectations.failure) || (output != test.call().expectations.rawBytes()))
success = false;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -77,6 +77,7 @@ public:
void reset();
FunctionCall const& call() const { return m_call; }
void calledNonExistingFunction() { m_calledNonExistingFunction = true; }
void setFailure(const bool _failure) { m_failure = _failure; }
void setRawBytes(const bytes _rawBytes) { m_rawBytes = _rawBytes; }
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
/// in the interactive update routine.
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;
};
}