Browse Source

solidity endToEnd testing gets equivalent CPP contracts

- Just testing the waters of our codebase by introducing C++
  version of the contract functions in the end to end solidity tests

- This way there is no need to check for some specific output but
  instead strive for consistency between the C++ and solidity code.
cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
57dab7bcb5
  1. 163
      test/solidityEndToEndTest.cpp

163
test/solidityEndToEndTest.cpp

@ -60,6 +60,16 @@ public:
return callFunction(_index, toBigEndian(_argument1)); return callFunction(_index, toBigEndian(_argument1));
} }
bool testSolidityAgainstCpp(byte _index, std::function<u256(u256)> const& _cppfun, u256 const& _argument1)
{
return toBigEndian(_cppfun(_argument1)) == callFunction(_index, toBigEndian(_argument1));
}
bool testSolidityAgainstCpp(byte _index, std::function<u256()> const& _cppfun)
{
return toBigEndian(_cppfun()) == callFunction(_index, bytes());
}
private: private:
void sendMessage(bytes const& _data, bool _isCreation) void sendMessage(bytes const& _data, bool _isCreation)
{ {
@ -123,11 +133,18 @@ BOOST_AUTO_TEST_CASE(recursive_calls)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callFunction(0, u256(0)) == toBigEndian(u256(1))); std::function<u256(u256)> recursive_calls_cpp = [&recursive_calls_cpp] (u256 const& n) -> u256 {
BOOST_CHECK(callFunction(0, u256(1)) == toBigEndian(u256(1))); if (n <= 1)
BOOST_CHECK(callFunction(0, u256(2)) == toBigEndian(u256(2))); return 1;
BOOST_CHECK(callFunction(0, u256(3)) == toBigEndian(u256(6))); else
BOOST_CHECK(callFunction(0, u256(4)) == toBigEndian(u256(24))); 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)));
} }
BOOST_AUTO_TEST_CASE(while_loop) BOOST_AUTO_TEST_CASE(while_loop)
@ -140,11 +157,21 @@ BOOST_AUTO_TEST_CASE(while_loop)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callFunction(0, u256(0)) == toBigEndian(u256(1)));
BOOST_CHECK(callFunction(0, u256(1)) == toBigEndian(u256(1))); auto while_loop_cpp = [] (u256 const& n) -> u256 {
BOOST_CHECK(callFunction(0, u256(2)) == toBigEndian(u256(2))); u256 nfac = 1;
BOOST_CHECK(callFunction(0, u256(3)) == toBigEndian(u256(6))); u256 i = 2;
BOOST_CHECK(callFunction(0, u256(4)) == toBigEndian(u256(24))); while (i <= n)
nfac *= i++;
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)));
} }
BOOST_AUTO_TEST_CASE(break_outside_loop) BOOST_AUTO_TEST_CASE(break_outside_loop)
@ -182,18 +209,42 @@ BOOST_AUTO_TEST_CASE(nested_loops)
"}\n"; "}\n";
ExecutionFramework framework; ExecutionFramework framework;
framework.compileAndRun(sourceCode); framework.compileAndRun(sourceCode);
BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(0)));
BOOST_CHECK(framework.callFunction(0, u256(1)) == toBigEndian(u256(1))); auto nested_loops_cpp = [] (u256 n) -> u256 {
BOOST_CHECK(framework.callFunction(0, u256(2)) == toBigEndian(u256(1))); while (n > 1)
BOOST_CHECK(framework.callFunction(0, u256(3)) == toBigEndian(u256(2))); {
BOOST_CHECK(framework.callFunction(0, u256(4)) == toBigEndian(u256(2))); if (n == 10)
BOOST_CHECK(framework.callFunction(0, u256(5)) == toBigEndian(u256(4))); break;
BOOST_CHECK(framework.callFunction(0, u256(6)) == toBigEndian(u256(5))); while (n > 5)
BOOST_CHECK(framework.callFunction(0, u256(7)) == toBigEndian(u256(5))); {
BOOST_CHECK(framework.callFunction(0, u256(8)) == toBigEndian(u256(7))); if (n == 8)
BOOST_CHECK(framework.callFunction(0, u256(9)) == toBigEndian(u256(8))); break;
BOOST_CHECK(framework.callFunction(0, u256(10)) == toBigEndian(u256(10))); n--;
BOOST_CHECK(framework.callFunction(0, u256(11)) == toBigEndian(u256(10))); if (n == 6)
continue;
return n;
}
n--;
if (n == 3)
continue;
break;
}
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)));
} }
BOOST_AUTO_TEST_CASE(calling_other_functions) BOOST_AUTO_TEST_CASE(calling_other_functions)
@ -214,11 +265,32 @@ BOOST_AUTO_TEST_CASE(calling_other_functions)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callFunction(2, u256(0)) == toBigEndian(u256(0)));
BOOST_CHECK(callFunction(2, u256(1)) == toBigEndian(u256(1))); auto evenStep_cpp = [] (u256 const& n) -> u256 {
BOOST_CHECK(callFunction(2, u256(2)) == toBigEndian(u256(1))); return n / 2;
BOOST_CHECK(callFunction(2, u256(8)) == toBigEndian(u256(1))); };
BOOST_CHECK(callFunction(2, u256(127)) == toBigEndian(u256(1)));
auto oddStep_cpp = [] (u256 const& n) -> u256 {
return 3 * n + 1;
};
auto collatz_cpp = [&evenStep_cpp, &oddStep_cpp] (u256 n) -> u256 {
u256 y;
while ((y = n) > 1)
{
if (n % 2 == 0)
n = evenStep_cpp(n);
else
n = oddStep_cpp(n);
}
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)));
} }
BOOST_AUTO_TEST_CASE(many_local_variables) BOOST_AUTO_TEST_CASE(many_local_variables)
@ -270,8 +342,14 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callFunction(0, u256(0)) == toBigEndian(u256(0)));
BOOST_CHECK(callFunction(0, u256(1)) == toBigEndian(u256(8))); auto short_circuiting_cpp = [] (u256 n) -> u256 {
n == 0 || (n = 8) > 0;
return n;
};
BOOST_CHECK(testSolidityAgainstCpp(0, short_circuiting_cpp, u256(0)));
BOOST_CHECK(testSolidityAgainstCpp(0, short_circuiting_cpp, u256(1)));
} }
BOOST_AUTO_TEST_CASE(high_bits_cleaning) BOOST_AUTO_TEST_CASE(high_bits_cleaning)
@ -284,7 +362,13 @@ BOOST_AUTO_TEST_CASE(high_bits_cleaning)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callFunction(0, bytes()) == toBigEndian(u256(9))); auto high_bits_cleaning_cpp = []() -> u256 {
uint32_t x = uint32_t(0xffffffff) + 10;
if (x >= 0xffffffff)
return 0;
return x;
};
BOOST_CHECK(testSolidityAgainstCpp(0, high_bits_cleaning_cpp));
} }
BOOST_AUTO_TEST_CASE(sign_extension) BOOST_AUTO_TEST_CASE(sign_extension)
@ -297,7 +381,13 @@ BOOST_AUTO_TEST_CASE(sign_extension)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callFunction(0, bytes()) == toBigEndian(u256(0xff))); auto sign_extension_cpp = []() -> u256 {
int64_t x = -int32_t(0xff);
if (x >= 0xff)
return 0;
return u256(x) * -1;
};
BOOST_CHECK(testSolidityAgainstCpp(0, sign_extension_cpp));
} }
BOOST_AUTO_TEST_CASE(small_unsigned_types) BOOST_AUTO_TEST_CASE(small_unsigned_types)
@ -309,7 +399,11 @@ BOOST_AUTO_TEST_CASE(small_unsigned_types)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callFunction(0, bytes()) == toBigEndian(u256(0xfe0000))); auto small_unsigned_types_cpp = []() -> u256 {
uint32_t x = uint32_t(0xffffff) * 0xffffff;
return x / 0x100;
};
BOOST_CHECK(testSolidityAgainstCpp(0, small_unsigned_types_cpp));
} }
BOOST_AUTO_TEST_CASE(small_signed_types) BOOST_AUTO_TEST_CASE(small_signed_types)
@ -320,7 +414,10 @@ BOOST_AUTO_TEST_CASE(small_signed_types)
" }\n" " }\n"
"}\n"; "}\n";
compileAndRun(sourceCode); compileAndRun(sourceCode);
BOOST_CHECK(callFunction(0, bytes()) == toBigEndian(u256(200))); auto small_signed_types_cpp = []() -> u256 {
return -int32_t(10) * -int64_t(20);
};
BOOST_CHECK(testSolidityAgainstCpp(0, small_signed_types_cpp));
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

Loading…
Cancel
Save