mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #501 from chriseth/sol_testFramework
Tests on ranges of input data.
This commit is contained in:
commit
d064028e16
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <libethereum/State.h>
|
||||
#include <libethereum/Executive.h>
|
||||
@ -41,7 +42,7 @@ class ExecutionFramework
|
||||
public:
|
||||
ExecutionFramework() { g_logVerbosity = 0; }
|
||||
|
||||
bytes const& compileAndRun(std::string const& _sourceCode)
|
||||
bytes const& compileAndRun(string const& _sourceCode)
|
||||
{
|
||||
bytes code = dev::solidity::CompilerStack::compile(_sourceCode);
|
||||
sendMessage(code, true);
|
||||
@ -49,28 +50,64 @@ public:
|
||||
return m_output;
|
||||
}
|
||||
|
||||
bytes const& callFunction(byte _index, bytes const& _data)
|
||||
bytes const& callContractFunction(byte _index, bytes const& _data = bytes())
|
||||
{
|
||||
sendMessage(bytes(1, _index) + _data, false);
|
||||
return m_output;
|
||||
}
|
||||
|
||||
bytes const& callFunction(byte _index, u256 const& _argument1)
|
||||
template <class... Args>
|
||||
bytes const& callContractFunction(byte _index, Args const&... _arguments)
|
||||
{
|
||||
return callFunction(_index, toBigEndian(_argument1));
|
||||
return callContractFunction(_index, argsToBigEndian(_arguments...));
|
||||
}
|
||||
|
||||
bool testSolidityAgainstCpp(byte _index, std::function<u256(u256)> const& _cppfun, u256 const& _argument1)
|
||||
template <class CppFunction, class... Args>
|
||||
void testSolidityAgainstCpp(byte _index, CppFunction const& _cppFunction, Args const&... _arguments)
|
||||
{
|
||||
return toBigEndian(_cppfun(_argument1)) == callFunction(_index, toBigEndian(_argument1));
|
||||
bytes solidityResult = callContractFunction(_index, _arguments...);
|
||||
bytes cppResult = callCppAndEncodeResult(_cppFunction, _arguments...);
|
||||
BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match."
|
||||
"\nSolidity: " + toHex(solidityResult) + "\nC++: " + toHex(cppResult));
|
||||
}
|
||||
|
||||
bool testSolidityAgainstCpp(byte _index, std::function<u256()> const& _cppfun)
|
||||
template <class CppFunction, class... Args>
|
||||
void testSolidityAgainstCppOnRange(byte _index, CppFunction const& _cppFunction,
|
||||
u256 const& _rangeStart, u256 const& _rangeEnd)
|
||||
{
|
||||
return toBigEndian(_cppfun()) == callFunction(_index, bytes());
|
||||
for (u256 argument = _rangeStart; argument < _rangeEnd; ++argument)
|
||||
{
|
||||
bytes solidityResult = callContractFunction(_index, argument);
|
||||
bytes cppResult = callCppAndEncodeResult(_cppFunction, argument);
|
||||
BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match."
|
||||
"\nSolidity: " + toHex(solidityResult) + "\nC++: " + toHex(cppResult) +
|
||||
"\nArgument: " + toHex(toBigEndian(argument)));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template <class FirstArg, class... Args>
|
||||
bytes argsToBigEndian(FirstArg const& _firstArg, Args const&... _followingArgs) const
|
||||
{
|
||||
return toBigEndian(_firstArg) + argsToBigEndian(_followingArgs...);
|
||||
}
|
||||
|
||||
bytes argsToBigEndian() const { return bytes(); }
|
||||
|
||||
template <class CppFunction, class... Args>
|
||||
auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
|
||||
-> typename enable_if<is_void<decltype(_cppFunction(_arguments...))>::value, bytes>::type
|
||||
{
|
||||
_cppFunction(_arguments...);
|
||||
return bytes();
|
||||
}
|
||||
template <class CppFunction, class... Args>
|
||||
auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
|
||||
-> typename enable_if<!is_void<decltype(_cppFunction(_arguments...))>::value, bytes>::type
|
||||
{
|
||||
return toBigEndian(_cppFunction(_arguments...));
|
||||
}
|
||||
|
||||
void sendMessage(bytes const& _data, bool _isCreation)
|
||||
{
|
||||
eth::Executive executive(m_state);
|
||||
@ -91,7 +128,10 @@ private:
|
||||
BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress));
|
||||
BOOST_REQUIRE(!executive.call(m_contractAddress, Address(), 0, m_gasPrice, &_data, m_gas, Address()));
|
||||
}
|
||||
BOOST_REQUIRE(executive.go());
|
||||
executive.finalize();
|
||||
m_output = executive.out().toVector();
|
||||
@ -112,8 +152,7 @@ BOOST_AUTO_TEST_CASE(smoke_test)
|
||||
" function f(uint a) returns(uint d) { return a * 7; }\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
u256 a = 0x200030004;
|
||||
BOOST_CHECK(callFunction(0, a) == toBigEndian(a * 7));
|
||||
testSolidityAgainstCppOnRange(0, [](u256 const& a) -> u256 { return a * 7; }, 0, 100);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_contract)
|
||||
@ -121,7 +160,7 @@ BOOST_AUTO_TEST_CASE(empty_contract)
|
||||
char const* sourceCode = "contract test {\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFunction(0, bytes()).empty());
|
||||
BOOST_CHECK(callContractFunction(0, bytes()).empty());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(recursive_calls)
|
||||
@ -133,7 +172,7 @@ BOOST_AUTO_TEST_CASE(recursive_calls)
|
||||
" }\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
std::function<u256(u256)> recursive_calls_cpp = [&recursive_calls_cpp](u256 const& n) -> u256
|
||||
function<u256(u256)> recursive_calls_cpp = [&recursive_calls_cpp](u256 const& n) -> u256
|
||||
{
|
||||
if (n <= 1)
|
||||
return 1;
|
||||
@ -141,11 +180,7 @@ BOOST_AUTO_TEST_CASE(recursive_calls)
|
||||
return n * recursive_calls_cpp(n - 1);
|
||||
};
|
||||
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(0)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(1)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(2)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(3)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(4)));
|
||||
testSolidityAgainstCppOnRange(0, recursive_calls_cpp, 0, 5);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(multiple_functions)
|
||||
@ -185,11 +220,7 @@ BOOST_AUTO_TEST_CASE(while_loop)
|
||||
return nfac;
|
||||
};
|
||||
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, while_loop_cpp, u256(0)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, while_loop_cpp, u256(1)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, while_loop_cpp, u256(2)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, while_loop_cpp, u256(3)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, while_loop_cpp, u256(4)));
|
||||
testSolidityAgainstCppOnRange(0, while_loop_cpp, 0, 5);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(break_outside_loop)
|
||||
@ -200,9 +231,8 @@ BOOST_AUTO_TEST_CASE(break_outside_loop)
|
||||
" break; continue; return 2;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
ExecutionFramework framework;
|
||||
framework.compileAndRun(sourceCode);
|
||||
BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(2)));
|
||||
compileAndRun(sourceCode);
|
||||
testSolidityAgainstCpp(0, [](u256 const& _a) -> u256 { return 2; }, u256(0));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(nested_loops)
|
||||
@ -225,8 +255,7 @@ BOOST_AUTO_TEST_CASE(nested_loops)
|
||||
" return x;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
ExecutionFramework framework;
|
||||
framework.compileAndRun(sourceCode);
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto nested_loops_cpp = [](u256 n) -> u256
|
||||
{
|
||||
@ -252,18 +281,7 @@ BOOST_AUTO_TEST_CASE(nested_loops)
|
||||
return n;
|
||||
};
|
||||
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(0)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(1)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(2)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(3)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(4)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(5)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(6)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(7)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(8)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(9)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(10)));
|
||||
BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(11)));
|
||||
testSolidityAgainstCppOnRange(0, nested_loops_cpp, 0, 12);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(calling_other_functions)
|
||||
@ -295,7 +313,8 @@ BOOST_AUTO_TEST_CASE(calling_other_functions)
|
||||
return 3 * n + 1;
|
||||
};
|
||||
|
||||
auto collatz_cpp = [&evenStep_cpp, &oddStep_cpp] (u256 n) -> u256 {
|
||||
auto collatz_cpp = [&evenStep_cpp, &oddStep_cpp](u256 n) -> u256
|
||||
{
|
||||
u256 y;
|
||||
while ((y = n) > 1)
|
||||
{
|
||||
@ -307,11 +326,11 @@ BOOST_AUTO_TEST_CASE(calling_other_functions)
|
||||
return y;
|
||||
};
|
||||
|
||||
BOOST_CHECK(testSolidityAgainstCpp(2, collatz_cpp, u256(0)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(2, collatz_cpp, u256(1)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(2, collatz_cpp, u256(2)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(2, collatz_cpp, u256(8)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(2, collatz_cpp, u256(127)));
|
||||
testSolidityAgainstCpp(2, collatz_cpp, u256(0));
|
||||
testSolidityAgainstCpp(2, collatz_cpp, u256(1));
|
||||
testSolidityAgainstCpp(2, collatz_cpp, u256(2));
|
||||
testSolidityAgainstCpp(2, collatz_cpp, u256(8));
|
||||
testSolidityAgainstCpp(2, collatz_cpp, u256(127));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(many_local_variables)
|
||||
@ -324,8 +343,15 @@ BOOST_AUTO_TEST_CASE(many_local_variables)
|
||||
" }\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFunction(0, toBigEndian(u256(0x1000)) + toBigEndian(u256(0x10000)) + toBigEndian(u256(0x100000)))
|
||||
== toBigEndian(u256(0x121121)));
|
||||
auto f = [](u256 const& x1, u256 const& x2, u256 const& x3) -> u256
|
||||
{
|
||||
u256 a = 0x1;
|
||||
u256 b = 0x10;
|
||||
u256 c = 0x100;
|
||||
u256 y = a + b + c + x1 + x2 + x3;
|
||||
return y + b + x2;
|
||||
};
|
||||
testSolidityAgainstCpp(0, f, u256(0x1000), u256(0x10000), u256(0x100000));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(packing_unpacking_types)
|
||||
@ -338,7 +364,7 @@ BOOST_AUTO_TEST_CASE(packing_unpacking_types)
|
||||
" }\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFunction(0, fromHex("01""0f0f0f0f""f0f0f0f0f0f0f0f0"))
|
||||
BOOST_CHECK(callContractFunction(0, fromHex("01""0f0f0f0f""f0f0f0f0f0f0f0f0"))
|
||||
== fromHex("00000000000000000000000000000000000000""01""f0f0f0f0""0f0f0f0f0f0f0f0f"));
|
||||
}
|
||||
|
||||
@ -350,7 +376,7 @@ BOOST_AUTO_TEST_CASE(multiple_return_values)
|
||||
" }\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFunction(0, bytes(1, 1) + toBigEndian(u256(0xcd)))
|
||||
BOOST_CHECK(callContractFunction(0, bytes(1, 1) + toBigEndian(u256(0xcd)))
|
||||
== toBigEndian(u256(0xcd)) + bytes(1, 1) + toBigEndian(u256(0)));
|
||||
}
|
||||
|
||||
@ -370,8 +396,7 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
|
||||
return n;
|
||||
};
|
||||
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, short_circuiting_cpp, u256(0)));
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, short_circuiting_cpp, u256(1)));
|
||||
testSolidityAgainstCppOnRange(0, short_circuiting_cpp, 0, 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(high_bits_cleaning)
|
||||
@ -391,7 +416,7 @@ BOOST_AUTO_TEST_CASE(high_bits_cleaning)
|
||||
return 0;
|
||||
return x;
|
||||
};
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, high_bits_cleaning_cpp));
|
||||
testSolidityAgainstCpp(0, high_bits_cleaning_cpp);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sign_extension)
|
||||
@ -411,7 +436,7 @@ BOOST_AUTO_TEST_CASE(sign_extension)
|
||||
return 0;
|
||||
return u256(x) * -1;
|
||||
};
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, sign_extension_cpp));
|
||||
testSolidityAgainstCpp(0, sign_extension_cpp);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(small_unsigned_types)
|
||||
@ -428,7 +453,7 @@ BOOST_AUTO_TEST_CASE(small_unsigned_types)
|
||||
uint32_t x = uint32_t(0xffffff) * 0xffffff;
|
||||
return x / 0x100;
|
||||
};
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, small_unsigned_types_cpp));
|
||||
testSolidityAgainstCpp(0, small_unsigned_types_cpp);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(small_signed_types)
|
||||
@ -443,7 +468,7 @@ BOOST_AUTO_TEST_CASE(small_signed_types)
|
||||
{
|
||||
return -int32_t(10) * -int64_t(20);
|
||||
};
|
||||
BOOST_CHECK(testSolidityAgainstCpp(0, small_signed_types_cpp));
|
||||
testSolidityAgainstCpp(0, small_signed_types_cpp);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(state_smoke_test)
|
||||
@ -461,14 +486,14 @@ BOOST_AUTO_TEST_CASE(state_smoke_test)
|
||||
" }\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0)));
|
||||
BOOST_CHECK(callFunction(0, bytes(1, 0x01)) == toBigEndian(u256(0)));
|
||||
BOOST_CHECK(callFunction(1, bytes(1, 0x00) + toBigEndian(u256(0x1234))) == bytes());
|
||||
BOOST_CHECK(callFunction(1, bytes(1, 0x01) + toBigEndian(u256(0x8765))) == bytes());
|
||||
BOOST_CHECK(callFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x1234)));
|
||||
BOOST_CHECK(callFunction(0, bytes(1, 0x01)) == toBigEndian(u256(0x8765)));
|
||||
BOOST_CHECK(callFunction(1, bytes(1, 0x00) + toBigEndian(u256(0x3))) == bytes());
|
||||
BOOST_CHECK(callFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x3)));
|
||||
BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0)));
|
||||
BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == toBigEndian(u256(0)));
|
||||
BOOST_CHECK(callContractFunction(1, bytes(1, 0x00) + toBigEndian(u256(0x1234))) == bytes());
|
||||
BOOST_CHECK(callContractFunction(1, bytes(1, 0x01) + toBigEndian(u256(0x8765))) == bytes());
|
||||
BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x1234)));
|
||||
BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == toBigEndian(u256(0x8765)));
|
||||
BOOST_CHECK(callContractFunction(1, bytes(1, 0x00) + toBigEndian(u256(0x3))) == bytes());
|
||||
BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x3)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
Loading…
Reference in New Issue
Block a user