Merge remote-tracking branch 'upstream/develop' into addTests

This commit is contained in:
CJentzsch 2015-03-23 08:50:16 +01:00
commit fdc307889f
6 changed files with 180 additions and 9 deletions

View File

@ -3088,6 +3088,123 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_storage_static_dynamic)
BOOST_CHECK(callContractFunction("test()") == encodeArgs(9, 4));
}
BOOST_AUTO_TEST_CASE(array_copy_different_packing)
{
char const* sourceCode = R"(
contract c {
bytes8[] data1; // 4 per slot
bytes10[] data2; // 3 per slot
function test() returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e) {
data1.length = 9;
for (uint i = 0; i < data1.length; ++i)
data1[i] = bytes8(i);
data2 = data1;
a = data2[1];
b = data2[2];
c = data2[3];
d = data2[4];
e = data2[5];
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test()") == encodeArgs(
asString(fromHex("0000000000000001")),
asString(fromHex("0000000000000002")),
asString(fromHex("0000000000000003")),
asString(fromHex("0000000000000004")),
asString(fromHex("0000000000000005"))
));
}
BOOST_AUTO_TEST_CASE(array_copy_target_simple)
{
char const* sourceCode = R"(
contract c {
bytes8[9] data1; // 4 per slot
bytes17[10] data2; // 1 per slot, no offset counter
function test() returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e) {
for (uint i = 0; i < data1.length; ++i)
data1[i] = bytes8(i);
data2[8] = data2[9] = 2;
data2 = data1;
a = data2[1];
b = data2[2];
c = data2[3];
d = data2[4];
e = data2[9];
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test()") == encodeArgs(
asString(fromHex("0000000000000001")),
asString(fromHex("0000000000000002")),
asString(fromHex("0000000000000003")),
asString(fromHex("0000000000000004")),
asString(fromHex("0000000000000000"))
));
}
BOOST_AUTO_TEST_CASE(array_copy_target_leftover)
{
// test that leftover elements in the last slot of target are correctly cleared during assignment
char const* sourceCode = R"(
contract c {
byte[10] data1;
bytes2[32] data2;
function test() returns (uint check, uint res1, uint res2) {
uint i;
for (i = 0; i < data2.length; ++i)
data2[i] = 0xffff;
check = uint(data2[31]) * 0x10000 | uint(data2[14]);
for (i = 0; i < data1.length; ++i)
data1[i] = byte(uint8(1 + i));
data2 = data1;
for (i = 0; i < 16; ++i)
res1 |= uint(data2[i]) * 0x10000**i;
for (i = 0; i < 16; ++i)
res2 |= uint(data2[16 + i]) * 0x10000**i;
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test()") == encodeArgs(
u256("0xffffffff"),
asString(fromHex("0000000000000000""000000000a000900""0800070006000500""0400030002000100")),
asString(fromHex("0000000000000000""0000000000000000""0000000000000000""0000000000000000"))
));
}
BOOST_AUTO_TEST_CASE(array_copy_target_leftover2)
{
// since the copy always copies whole slots, we have to make sure that the source size maxes
// out a whole slot and at the same time there are still elements left in the target at that point
char const* sourceCode = R"(
contract c {
bytes8[4] data1; // fits into one slot
bytes10[6] data2; // 4 elements need two slots
function test() returns (bytes10 r1, bytes10 r2, bytes10 r3) {
data1[0] = 1;
data1[1] = 2;
data1[2] = 3;
data1[3] = 4;
for (uint i = 0; i < data2.length; ++i)
data2[i] = bytes10(0xffff00 | (1 + i));
data2 = data1;
r1 = data2[3];
r2 = data2[4];
r3 = data2[5];
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test()") == encodeArgs(
asString(fromHex("0000000000000004")),
asString(fromHex("0000000000000000")),
asString(fromHex("0000000000000000"))
));
}
BOOST_AUTO_TEST_CASE(array_copy_storage_storage_struct)
{
char const* sourceCode = R"(
@ -3214,7 +3331,7 @@ BOOST_AUTO_TEST_CASE(array_copy_nested_array)
char const* sourceCode = R"(
contract c {
uint[4][] a;
uint[5][] b;
uint[10][] b;
uint[][] c;
function test(uint[2][] d) external returns (uint) {
a = d;
@ -3480,6 +3597,30 @@ BOOST_AUTO_TEST_CASE(packed_storage_structs_delete)
BOOST_CHECK(m_state.storage(m_contractAddress).empty());
}
BOOST_AUTO_TEST_CASE(packed_storage_structs_with_bytes0)
{
char const* sourceCode = R"(
contract C {
struct str { uint8 a; bytes0 b; uint8 c; }
uint8 a;
bytes0 x;
uint8 b;
str data;
function test() returns (bool) {
a = 2;
b = 3;
data.a = 4;
data.c = 5;
delete x;
delete data.b;
return a == 2 && b == 3 && data.a == 4 && data.c == 5;
}
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("test()") == encodeArgs(true));
}
BOOST_AUTO_TEST_SUITE_END()
}

View File

@ -1446,6 +1446,16 @@ BOOST_AUTO_TEST_CASE(local_const_variable)
BOOST_CHECK_THROW(parseTextAndResolveNames(text), ParserError);
}
BOOST_AUTO_TEST_CASE(bytes0_array)
{
char const* text = R"(
contract Foo {
bytes0[] illegalArray;
}
)";
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
}
BOOST_AUTO_TEST_SUITE_END()
}

View File

@ -75,6 +75,17 @@ BOOST_AUTO_TEST_CASE(storage_layout_mapping)
BOOST_CHECK(*members.getMemberStorageOffset("final") == make_pair(u256(3), unsigned(0)));
}
BOOST_AUTO_TEST_CASE(storage_layout_arrays)
{
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(1), 32).getStorageSize() == 1);
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(1), 33).getStorageSize() == 2);
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(2), 31).getStorageSize() == 2);
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(7), 8).getStorageSize() == 2);
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(7), 9).getStorageSize() == 3);
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(31), 9).getStorageSize() == 9);
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(32), 9).getStorageSize() == 9);
}
BOOST_AUTO_TEST_SUITE_END()
}

View File

@ -240,7 +240,7 @@ byte toByte(json_spirit::mValue const& _v)
bytes importByteArray(std::string const& _str)
{
return fromHex(_str.substr(0, 2) == "0x" ? _str.substr(2) : _str, ThrowType::Throw);
return fromHex(_str.substr(0, 2) == "0x" ? _str.substr(2) : _str, WhenError::Throw);
}
bytes importData(json_spirit::mObject& _o)

15
net.cpp
View File

@ -53,7 +53,7 @@ protected:
struct TestNodeTable: public NodeTable
{
/// Constructor
TestNodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _port = 30300): NodeTable(_io, _alias, _port) {}
TestNodeTable(ba::io_service& _io, KeyPair _alias, bi::address const& _addr, uint16_t _port = 30300): NodeTable(_io, _alias, _addr, _port) {}
static std::vector<std::pair<KeyPair,unsigned>> createTestNodes(unsigned _count)
{
@ -89,7 +89,16 @@ struct TestNodeTable: public NodeTable
bi::address ourIp = bi::address::from_string("127.0.0.1");
for (auto& n: _testNodes)
if (_count--)
{
// manually add node for test
{
Guard ln(x_nodes);
shared_ptr<NodeEntry> node(new NodeEntry(m_node, n.first.pub(), NodeIPEndpoint(bi::udp::endpoint(ourIp, n.second), bi::tcp::endpoint(ourIp, n.second))));
node->pending = false;
m_nodes[node->id] = node;
}
noteActiveNode(n.first.pub(), bi::udp::endpoint(ourIp, n.second));
}
else
break;
}
@ -106,10 +115,10 @@ struct TestNodeTable: public NodeTable
*/
struct TestNodeTableHost: public TestHost
{
TestNodeTableHost(unsigned _count = 8): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias)), testNodes(TestNodeTable::createTestNodes(_count)) {};
TestNodeTableHost(unsigned _count = 8): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias, bi::address::from_string("127.0.0.1"))), testNodes(TestNodeTable::createTestNodes(_count)) {};
~TestNodeTableHost() { m_io.stop(); stopWorking(); }
void setup() { for (auto n: testNodes) nodeTables.push_back(make_shared<TestNodeTable>(m_io,n.first,n.second)); }
void setup() { for (auto n: testNodes) nodeTables.push_back(make_shared<TestNodeTable>(m_io,n.first, bi::address::from_string("127.0.0.1"),n.second)); }
void pingAll() { for (auto& t: nodeTables) t->pingTestNodes(testNodes); }

View File

@ -35,8 +35,8 @@ BOOST_AUTO_TEST_CASE(host)
auto oldLogVerbosity = g_logVerbosity;
g_logVerbosity = 10;
NetworkPreferences host1prefs(30301, "127.0.0.1", true, true);
NetworkPreferences host2prefs(30302, "127.0.0.1", true, true);
NetworkPreferences host1prefs(30301, "127.0.0.1", false, true);
NetworkPreferences host2prefs(30302, "127.0.0.1", false, true);
Host host1("Test", host1prefs);
host1.start();
@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE(save_nodes)
std::list<Host*> hosts;
for (auto i:{0,1,2,3,4,5})
{
Host* h = new Host("Test", NetworkPreferences(30300 + i, "127.0.0.1", true, true));
Host* h = new Host("Test", NetworkPreferences(30300 + i, "127.0.0.1", false, true));
h->setIdealPeerCount(10);
// starting host is required so listenport is available
h->start();
@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(save_nodes)
RLP r(firstHostNetwork);
BOOST_REQUIRE(r.itemCount() == 3);
BOOST_REQUIRE(r[0].toInt<int>() == 1);
BOOST_REQUIRE(r[0].toInt<unsigned>() == dev::p2p::c_protocolVersion);
BOOST_REQUIRE_EQUAL(r[1].toBytes().size(), 32); // secret
BOOST_REQUIRE_EQUAL(r[2].itemCount(), 5);
}