Skip to content

Commit

Permalink
fix: change the tests to use the test address and fake server
Browse files Browse the repository at this point in the history
The previous tests used the blockchain directly. This reduced repeatability because all tests that modified the blockchain data would need to be edited after every run.
Also it introduced external failure points due to issues in the grpc-server or the blockchain connection

Now the tests use the python fake server. It verifies the request body is correct based on config.json and returns canned responses
  • Loading branch information
as-iotex authored and as-iotex committed Apr 17, 2022
1 parent 4c26429 commit 0af0be6
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 240 deletions.
46 changes: 46 additions & 0 deletions tests/include/constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

namespace
{
// Test server details - using the python fake server.
// See tools/server-fake.
const char serverHost[] = "localhost";
const int serverPort = 10000;
const char baseUrl[] = "";

// Address with all ones private key used for testing.
const char testAddressPrivateKey[] = "1111111111111111111111111111111111111111111111111111111111111111";
const uint8_t testAddressPrivateKeyBytes[] = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
const char testAddressPublicKey[] = "044f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa385b6b1b8ead809ca67454d9683fcf2ba03456d6fe2c4abe2b07f0fbdbb2f1c1";
const char testAddressIo[] = "io1r8n7xah8cgfm0el8u3kvwzja6zrd4le2zce7sk";
const char testAddressEth[] = "19e7e376e7c213b7e7e7e46cc70a5dd086daff2a";
const uint8_t testAddressEthBytes[] = { 0x19, 0xe7, 0xe3, 0x76, 0xe7, 0xc2, 0x13, 0xb7, 0xe7, 0xe7, 0xe4, 0x6c, 0xc7, 0x0a, 0x5d, 0xd0, 0x86, 0xda, 0xff, 0x2a};

// Another address used for tests
const char testAddress2Eth[] = "19e7e376e7c213b7e7e7e46cc70a5dd086daff2b";
const uint8_t testAddress2EthBytes[] = { 0x19, 0xe7, 0xe3, 0x76, 0xe7, 0xc2, 0x13, 0xb7, 0xe7, 0xe7, 0xe4, 0x6c, 0xc7, 0x0a, 0x5d, 0xd0, 0x86, 0xda, 0xff, 0x2b};

// Other constants used in tests.
const char testTransactionHash[] = "e19dfb0c84799fc43217287d0d81369348279a0b3b32d0ad2f973ee5aaa392ae";
const char testExecutionHash[] = "55b172298e80dff0fa929c7c7f7ecc266baf48e33aa226b3fd48d4de870b1efa";
const char vitaTokenAddress[] = "io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4tw";
const char sendDataContractAddress[] = "io1n49gavyahsukdvvxxandkxephdx93n3atcrqur";

inline void printhex(uint8_t* data, int length)
{
for (uint8_t i = 0; i < length; i++)
{
printf("%02x", data[i]);
}
printf("\n");
}

inline void printdec(uint8_t* data, int length)
{
for (uint8_t i = 0; i < length; i++)
{
printf("%u ", data[i]);
}
printf("\n");
}
}
189 changes: 63 additions & 126 deletions tests/src/account/accountTests_Execution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <fstream>
#include <sstream>

#include "secrets.h"
#include "constants.h"

#include "account/account.h"
#include "contract/contract.h"
Expand All @@ -18,55 +18,11 @@ using namespace iotex;
using namespace iotex::responsetypes;
using namespace iotex::abi;

namespace
{
const std::string ethAddr = ETH_ADDRESS;
const std::string iotexAddr = IOTEX_ADDRESS;
const std::string privateKey = PRIVATE_KEY;
const std::string publicKey = PUBLIC_KEY;

class Wallet
{
public:
Wallet(std::string eth, std::string iotex, std::string privateKeyStr, std::string publicKeyStr)
{
ethAddr = eth;
iotexAddr = iotex;
signer.str2hex(privateKeyStr.c_str(), privateKey, sizeof(privateKey));
signer.str2hex(publicKeyStr.c_str(), publicKey, sizeof(publicKey));
}

uint8_t privateKey[IOTEX_PRIVATE_KEY_SIZE];
uint8_t publicKey[IOTEX_PUBLIC_KEY_SIZE];
std::string ethAddr;
std::string iotexAddr;
};

void printhex(uint8_t* data, int length)
{
for (uint8_t i = 0; i < length; i++)
{
printf("%02x", data[i]);
}
printf("\n");
}

void printdec(uint8_t* data, int length)
{
for (uint8_t i = 0; i < length; i++)
{
printf("%u ", data[i]);
}
printf("\n");
}
}

class AccountTests_Execution : public Test
{
public:
AccountTests_Execution() :
testWallet(ethAddr, iotexAddr, privateKey, publicKey),
account(testWallet.privateKey)
account(testAddressPrivateKeyBytes)
{
std::string file = std::string(TESTFILESDIR) + std::string("erc20tokenAbi.json");
std::ifstream ifs(file);
Expand All @@ -75,91 +31,27 @@ class AccountTests_Execution : public Test
contract = new Contract(content);
}

Wallet testWallet;
// Wallet testWallet;
Account account;
Contract *contract;
};

TEST_F(AccountTests_Execution, signExecutionAction)
{
ActionCore_Execution core;
uint8_t signature[IOTEX_SIGNATURE_SIZE] = {0};

const char gasPrice[] = "1000000000000";
const char amount[] = "0";
const char contractAddr[] = "io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4tw";
const char dataStr[] = "00000000";
const char expectedSignatureStr[] = "105dca6593d5d8c229a833901f9262d95cc05b3f9056534d5f31bcdc8fdddbed61bad38c95be2d0f68b3f437b40e2a80556d991b738725820b05b09ca4ea9e7100";
uint8_t expectedSignature[IOTEX_SIGNATURE_SIZE] = {0};
signer.str2hex(expectedSignatureStr, expectedSignature, IOTEX_SIGNATURE_SIZE);

core.version = 1;
core.nonce = 5;
core.gasLimit = 20000000;
strcpy(core.gasPrice, gasPrice);
strcpy(core.execution.amount, amount);
strcpy(core.execution.contract, contractAddr);
core.execution.data = dataStr;

uint8_t hash[IOTEX_HASH_SIZE] = {0};

account.signExecutionAction(core, signature, hash);

// uint8_t encodedCore[1024] = {0};
// size_t encodedCoreSize = encoder.protobuf_encodeExecution(core, encodedCore, sizeof(encodedCore));
// cout << "Proto: " << endl;
// printhex(encodedCore, encodedCoreSize);
// cout << "Hash: " << endl;
// printhex(hash, sizeof(hash));
// cout << "Signature: " << endl;
// printhex(signature, sizeof(signature));

ASSERT_EQ(0, memcmp(expectedSignature, signature, IOTEX_SIGNATURE_SIZE));
}

TEST_F(AccountTests_Execution, sendExecution_getTotalSupply_producesCorrectSignature)
{
uint8_t actionHash[IOTEX_HASH_SIZE];
const char gasPrice[] = "1000000000000";
const char amount[] = "0";
const char contractAddr[] = "io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4tw";
std::string dataStr = "";
const char expectedSignatureStr[] = "de76e7766d3cb41e55e410f5ca27ad2b4ed505834a9268ddfb169cdbc4d9e9582210e628f1192fedba77959763ef25447b9cc3cde825f165c5468991d06e1d4601";
uint8_t expectedSignature[IOTEX_SIGNATURE_SIZE] = {0};
signer.str2hex(expectedSignatureStr, expectedSignature, IOTEX_SIGNATURE_SIZE);
ParameterValuesDictionary params;

contract->generateCallData("totalSupply", params, dataStr);

ActionCore_Execution core;
core.version = 1;
core.nonce = 5;
core.gasLimit = 20000000;
strcpy(core.gasPrice, gasPrice);
strcpy(core.execution.amount, amount);
strcpy(core.execution.contract, contractAddr);
core.execution.data = dataStr;

uint8_t signature[IOTEX_SIGNATURE_SIZE] = {0};
account.signExecutionAction(core, signature);

ASSERT_EQ(0, memcmp(expectedSignature, signature, IOTEX_SIGNATURE_SIZE));
}
// --------------------- generateCallData ------------------------------

TEST_F(AccountTests_Execution, sendExecution_transfer_producesCorrectCallData)
{
// Action hash: https://testnet.iotexscan.io/action/475458447962be19ff1b078eb3e0bb950a97bdf3eccea17fe9f7d2ff8d53edfb
uint8_t actionHash[IOTEX_HASH_SIZE];
const char gasPrice[] = "1000000000000";
const char amount[] = "0";
const char contractAddr[] = "io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4tw";
std::string callData = "";
const char expectedCallData[] = "a9059cbb000000000000000000000000fd3000ebcf4ec082256be18f4cc491d2a469ff610000000000000000000000000000000000000000000000000000000000000001";
const char expectedCallData[] = "a9059cbb00000000000000000000000019e7e376e7c213b7e7e7e46cc70a5dd086daff2b0000000000000000000000000000000000000000000000000000000000000001";
ParameterValuesDictionary params;

ParameterValue paramTo;
uint8_t toAddress[ETH_ADDRESS_SIZE];
const char toAddressStr[] = ETH_ADDRESS;
signer.str2hex(toAddressStr, toAddress, ETH_ADDRESS_SIZE);
uint8_t toAddress[ETH_ADDRESS_SIZE] = {0};
memcpy(toAddress, testAddress2EthBytes, ETH_ADDRESS_SIZE);
paramTo.value.bytes = toAddress;
paramTo.size = ETH_ADDRESS_SIZE;
params.AddParameter("_to", paramTo);
Expand All @@ -175,18 +67,18 @@ TEST_F(AccountTests_Execution, sendExecution_transfer_producesCorrectCallData)

TEST_F(AccountTests_Execution, sendExecution_balanceOf_producesCorrectCallData)
{
// Action hash: https://testnet.iotexscan.io/action/c5eb108f9d4491c9fd48f6bc2c557f954fb4d17235ced341899d4bd6b63bf6c4
uint8_t actionHash[IOTEX_HASH_SIZE];
const char gasPrice[] = "1000000000000";
const char amount[] = "0";
const char contractAddr[] = "io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4tw";
std::string callData = "";
const char expectedCallData[] = "70a08231000000000000000000000000fd3000ebcf4ec082256be18f4cc491d2a469ff61";
const char expectedCallData[] = "70a0823100000000000000000000000019e7e376e7c213b7e7e7e46cc70a5dd086daff2b";
ParameterValuesDictionary params;

uint8_t toAddress[ETH_ADDRESS_SIZE] = {0};
memcpy(toAddress, testAddress2EthBytes, ETH_ADDRESS_SIZE);
ParameterValue paramTo;
uint8_t toAddress[ETH_ADDRESS_SIZE];
const char toAddressStr[] = ETH_ADDRESS;
signer.str2hex(toAddressStr, toAddress, ETH_ADDRESS_SIZE);
paramTo.value.bytes = toAddress;
paramTo.size = ETH_ADDRESS_SIZE;
params.AddParameter("_owner", paramTo);
Expand All @@ -197,6 +89,7 @@ TEST_F(AccountTests_Execution, sendExecution_balanceOf_producesCorrectCallData)

TEST_F(AccountTests_Execution, sendExecution_sendData_producesCorrectCallData)
{
// Action hash: https://testnet.iotexscan.io/action/5bcb7ee42d3d8e9f524c9458d30ff4a032480679e7d0bfd3f8a66ccd8f452b6b
std::string file = std::string(TESTFILESDIR) + std::string("addData.json");
std::ifstream ifs(file);
std::string content( (std::istreambuf_iterator<char>(ifs) ),
Expand Down Expand Up @@ -232,21 +125,19 @@ TEST_F(AccountTests_Execution, sendExecution_sendData_producesCorrectCallData)
ASSERT_STREQ(expectedCallData, callData.c_str());
}

// --------------------- signExecution ------------------------------



// Signature
TEST_F(AccountTests_Execution, sendExecution_producesCorrectSignature)
{
const char callData[] = "a9059cbb000000000000000000000000fd3000ebcf4ec082256be18f4cc491d2a469ff610000000000000000000000000000000000000000000000000000000000000001";
const char expectedSignatureStr[] = "5e18a11445ff8427ce4f1fb4116e801eec3f1ac96ce072a56ba0afe22a6ec6566080ba1805eb488e28bf56512eea08aa4a16d5531975b9f7186821dda191fc0501";
const char callData[] = "70a0823100000000000000000000000019e7e376e7c213b7e7e7e46cc70a5dd086daff2b";
const char expectedSignatureStr[] = "36d727f0fa8499281ad6dc234ed6005bfaefc3e0e7c9a560b24ce32ce913e648433a2406be15a8623e98dae2c7cf08cc616aaa6c6036c8bceb5a47a74ca83ee401";

const char gasPrice[] = "1000000000000";
const char amount[] = "0";
const char contractAddr[] = "io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4tw";
ActionCore_Execution core;
core.version = 1;
core.nonce = 7;
core.nonce = 3;
core.gasLimit = 20000000;
strcpy(core.gasPrice, gasPrice);
strcpy(core.execution.amount, amount);
Expand All @@ -260,3 +151,49 @@ TEST_F(AccountTests_Execution, sendExecution_producesCorrectSignature)

ASSERT_STREQ(expectedSignatureStr, signatureStr);
}

TEST_F(AccountTests_Execution, sendExecution_getTotalSupply_producesCorrectSignature)
{
// Action hash: https://testnet.iotexscan.io/action/7fd783d6010912f9002a2d4ea47d110fbc76f8d5f30101407443ef47228c4207
uint8_t actionHash[IOTEX_HASH_SIZE];
const char gasPrice[] = "1000000000000"; // 0.000001 IOTX
const char amount[] = "0";
const char contractAddr[] = "io1hp6y4eqr90j7tmul4w2wa8pm7wx462hq0mg4tw";
std::string dataStr = "";
const char expectedSignatureStr[] = "9ad701f0e07765a8bd90b36535e61f694a5339399b56fe5b4dc2bfda27f6907f7b597634aba1fb13a14d5b1634b47b841e5daa9484ad7a928818940bfcfb702b00";
uint8_t expectedSignature[IOTEX_SIGNATURE_SIZE] = {0};
signer.str2hex(expectedSignatureStr, expectedSignature, IOTEX_SIGNATURE_SIZE);
ParameterValuesDictionary params;

contract->generateCallData("totalSupply", params, dataStr);

ActionCore_Execution core;
core.version = 1;
core.nonce = 1;
core.gasLimit = 20000000;
strcpy(core.gasPrice, gasPrice);
strcpy(core.execution.amount, amount);
strcpy(core.execution.contract, contractAddr);
core.execution.data = dataStr;

uint8_t signature[IOTEX_SIGNATURE_SIZE] = {0};
account.signExecutionAction(core, signature);
printhex(signature, sizeof(signature));

ASSERT_EQ(0, memcmp(expectedSignature, signature, IOTEX_SIGNATURE_SIZE));
}
// --------------------- sendExecution ------------------------------

TEST_F(AccountTests_Execution, sendExecution_InvalidTransaction_ReturnsGrpcError)
{
Connection<Api> connection(serverHost, serverPort, baseUrl);

std::string callData = "";

uint8_t actionHash[IOTEX_HASH_SIZE] = {0};
char signatureStr[IOTEX_SIGNATURE_STRLEN] = {0};
uint8_t signature[IOTEX_SIGNATURE_SIZE] = {0};
ResultCode result = account.sendExecutionAction(connection, 0, 20000000, "1000000000000", "GetInvalidNonce", "", callData, actionHash);

ASSERT_EQ(ResultCode::ERROR_GRPC, result);
}
Loading

0 comments on commit 0af0be6

Please sign in to comment.