Skip to content

Commit

Permalink
add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
QingyangKong committed Jul 20, 2018
1 parent abc8e71 commit 6571084
Show file tree
Hide file tree
Showing 19 changed files with 1,664 additions and 44 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ docs/build
.DS_Store

# config file
.properties
*.properties
2 changes: 1 addition & 1 deletion benchmark/src/main/java/org/web3j/benchmark/TokenTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ private CitaTransactionManager transactionManagerOf(Credentials credentials) {
}

private Token tokenOf(Credentials credentials) {
CitaTransactionManager manager = transactionManagerOf(credentials);
CitaTransactionManager manager = transactionManagerOf(credentials);
return Token.load(this.token.getContractAddress(), this.service, manager);
}

Expand Down
259 changes: 259 additions & 0 deletions tests/src/main/java/org/web3j/tests/AdvanceTransactionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
package org.web3j.tests;

import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Uint;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.methods.request.Call;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;


import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.*;

public class AdvanceTransactionTest {
static final String configPath = "tests/src/main/resources/config.properties";

static Properties props;
static Web3j service;
static String senderPrivateKey;
static int version;
static int chainId;

static {
props = Config.load(configPath);
service = Web3j.build(new HttpService(props.getProperty(Config.TEST_NET_ADDR)));
senderPrivateKey = props.getProperty(Config.SENDER_PRIVATE_KEY);
version = Integer.parseInt(props.getProperty(Config.VERSION));
chainId = Integer.parseInt(props.getProperty(Config.CHAIN_ID));
}

private Random random;
private long quota = 50000;
private long validUntilBlock;
private int sendCount;
private int threadCount;
private boolean isEd25519AndBlake2b;
private String contractAddress;
private String value = "0";

public AdvanceTransactionTest(int sdCount, int thdCount, boolean isEd25519AndBlake2b){
try {
random = new Random(System.currentTimeMillis());
this.validUntilBlock = testUtil.getValidUtilBlock(service, 100).longValue();
this.sendCount = sdCount;
this.threadCount = thdCount;
this.isEd25519AndBlake2b = isEd25519AndBlake2b;
System.out.println("Initial block height: "+ testUtil.getCurrentHeight(service));
} catch (Exception e){
e.printStackTrace();
System.exit(1);
}
}

// Deploy contract, return transaction hash
private String deployContract(boolean isEd25519AndBlake2b) throws Exception {
// contract.bin
String contractCode = "606060405260008055341561001357600080fd5b60de806100216000396000f30060606040526004361060525763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416634f2be91f811460575780636d4ce63c146069578063d826f88f14608b575b600080fd5b3415606157600080fd5b6067609b565b005b3415607357600080fd5b607960a6565b60405190815260200160405180910390f35b3415609557600080fd5b606760ac565b600080546001019055565b60005490565b600080555600a165627a7a723058201b541b114db7898755d2a3124410cef8903e8a119a5a0a59a119cb00412986220029";
BigInteger nonce = BigInteger.valueOf(Math.abs(this.random.nextLong()));
Transaction tx = Transaction.createContractTransaction(nonce, this.quota, this.validUntilBlock, version, chainId, value, contractCode);

String rawTx = tx.sign(senderPrivateKey, isEd25519AndBlake2b,false);

return service.ethSendRawTransaction(rawTx).send().getSendTransactionResult().getHash();
}

// Contract function reset call
private String funcResetCall(String contractAddress, boolean isEd25519AndBlake2b) throws Exception {
Function resetFunc = new Function(
"reset",
Collections.emptyList(),
Collections.emptyList()
);

String resetFuncData = FunctionEncoder.encode(resetFunc);

BigInteger nonce = testUtil.getNonce();
Transaction tx = Transaction.createFunctionCallTransaction(
contractAddress,
nonce,
this.quota,
this.validUntilBlock,
version,
chainId,
value,
resetFuncData);
String rawTx = tx.sign(senderPrivateKey, isEd25519AndBlake2b,false);

return service.ethSendRawTransaction(rawTx).send().getSendTransactionResult().getHash();
}

// Contract function add call
public void funcAddCall(String contractAddress, boolean isEd25519AndBlake2b) throws Exception {
Function addFunc = new Function(
"add",
Collections.emptyList(),
Collections.emptyList()
);
String addFuncData = FunctionEncoder.encode(addFunc);

BigInteger nonce = BigInteger.valueOf(Math.abs(this.random.nextLong()));
Transaction tx = Transaction.createFunctionCallTransaction(
contractAddress,
nonce,
this.quota,
this.validUntilBlock,
version,
chainId,
value,
addFuncData);
String rawTx = tx.sign(senderPrivateKey, isEd25519AndBlake2b,false);

service.ethSendRawTransaction(rawTx).send();
}

// eth_call
private String call(String from, String contractAddress, String callData) throws Exception {
Call call = new Call(from, contractAddress, callData);
return service.ethCall(call, DefaultBlockParameter.valueOf("latest")).send().getValue();
}

// Get transaction receipt
private TransactionReceipt getTransactionReceipt(String txHash) throws Exception {
return service.ethGetTransactionReceipt(txHash).send().getTransactionReceipt().get();
}

public void runContract() throws Exception{
boolean isEd25519AndBlake2b = this.isEd25519AndBlake2b;
long dealWithCount = 0;
String ethCallResult;
String from = "0x0dbd369a741319fa5107733e2c9db9929093e3c7";
long endBlock = 0;
long startBlock = testUtil.getCurrentHeight(service).longValue();
long oldBlock = startBlock;
long currentBlock = startBlock;

// deploy contract
String deployContractTxHash = deployContract(isEd25519AndBlake2b);
System.out.println("wait to deploy contract , txHash: " + deployContractTxHash);
// waiting for new block
while (true) {
endBlock = testUtil.getCurrentHeight(service).longValue();
if (endBlock > startBlock+3){
break;
}else{
Thread.sleep(2000);
}
}
// get contract address from receipt
TransactionReceipt txReceipt = getTransactionReceipt(deployContractTxHash);
this.contractAddress = txReceipt.getContractAddress();

String resetTxHash = funcResetCall(this.contractAddress, isEd25519AndBlake2b);
while(true){
Optional<TransactionReceipt> receipt = service.ethGetTransactionReceipt(resetTxHash).send().getTransactionReceipt();
if(receipt.isPresent()){
TransactionReceipt resetTxReceipt = receipt.get();
if(resetTxReceipt.getErrorMessage() == null){
System.out.println("Count is reset successfully.");
break;
}else{
System.out.println("Failed to reset count.");
System.exit(1);
}
}else{
Thread.sleep(2000);
}
}


System.out.println("Contract address: " + this.contractAddress + ", start call add...");
long startTime = System.currentTimeMillis();
//start thread
Thread[] threads = new Thread[this.threadCount];
int count_per_thread = this.sendCount;
for (int i = 0; i < this.threadCount; i++) {
Thread t = new Thread(
() -> {
try {
int j = 0;
while(j < count_per_thread){
funcAddCall(contractAddress, isEd25519AndBlake2b);
j++;
}
}catch(Exception e) {
System.out.println("Failed to call contract function.");
e.printStackTrace();
System.exit(1);
}
});

t.start();
threads[i] = t;
}

for (int k = 0; k < this.threadCount; k++) {
threads[k].join();
}
System.out.println("send tx use " + (System.currentTimeMillis() - startTime) + " ms");

//get result
while(true) {
Thread.sleep(2000);
currentBlock = testUtil.getCurrentHeight(service).longValue();
if (currentBlock < oldBlock) {
System.out.println("Error : Height is decreasing");
}
oldBlock = currentBlock;
if (currentBlock >= this.validUntilBlock) {
break;
}

Function getCall = new Function(
"get",
Collections.emptyList(),
Arrays.asList(new TypeReference<Uint>(){})
);

String getCallData = FunctionEncoder.encode(getCall);
ethCallResult = call(from, contractAddress, getCallData);
String ethCallResultReadable = FunctionReturnDecoder.decode(ethCallResult, getCall.getOutputParameters()).get(0).toString();
System.out.println("ethCallResult: " + ethCallResultReadable);
if (ethCallResult == null || ethCallResult.length() < 3){
continue;
}
dealWithCount = Long.valueOf(ethCallResult.substring(2),16);
System.out.println("eth_call result: " + dealWithCount);
if(dealWithCount == this.sendCount * this.threadCount){
break;
}
}
long endTime = System.currentTimeMillis();

System.out.println("complete input count : " + this.sendCount * this.threadCount + ", actual count: " + dealWithCount);
System.out.println("performance(transactioncount/s):");
System.out.println("start time: " + startTime + " ms\r\n"+ "end time: " + endTime + " ms");
double tps = dealWithCount / ((endTime - startTime) /1000.0);
DecimalFormat df = new DecimalFormat("0.00000000");
String outStr = "performance - send tx tese case ...... success , result : " + df.format(tps) + " TPS";
System.out.println(outStr);
}

public static void main(String[] args) throws Exception {

int sendcount = 20;
int threadcount = 1;
boolean isEd25519AndBlake2b = false;

System.out.println("sendCount: "+ sendcount+ " threadCount: " + threadcount + " isEd25519AndBlake2b: " + isEd25519AndBlake2b);
AdvanceTransactionTest advanceTxTest = new AdvanceTransactionTest(sendcount, threadcount, isEd25519AndBlake2b);
advanceTxTest.runContract();
System.out.println("Performance - test case complete");
}
}
47 changes: 47 additions & 0 deletions tests/src/main/java/org/web3j/tests/Config.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.web3j.tests;

import java.util.Properties;
import java.io.FileInputStream;

public class Config {
private static final String configPath = "tests/src/main/resources/config.properties";
public static Properties props;

public final static String CHAIN_ID = "ChainId";
public final static String VERSION = "Version";
public final static String TEST_NET_ADDR = "TestNetIpAddr";
public final static String SENDER_PRIVATE_KEY = "SenderPrivateKey";
public final static String SENDER_ADDR = "SenderAddress";
public final static String TEST_PRIVATE_KEY_1 = "TestPrivateKey1";
public final static String TEST_ADDR_1 = "TestAddress1";
public final static String TEST_PRIVATE_KEY_2 = "TestPrivateKey2";
public final static String TEST_ADDR_2 = "TestAddress2";
public final static String TOKEN_SOLIDITY = "TokenSolidity";
public final static String TOKEN_BIN = "TokenBin";
public final static String TOKEN_ABI = "TokenAbi";
public final static String DEFAULT_QUOTA = "DefaultQuota";

public static Properties load(String path) {
props = new Properties();
try{
props.load(new FileInputStream(path));
}catch (Exception e){
System.out.println("Failed to read config at path " + path);
System.exit(1);
}
return props;
}

public static Properties load() {
try{
props = new Properties();
props.load(new FileInputStream(configPath));
}catch (Exception e){
System.out.println("Failed to read config file. Error: " + e);
e.printStackTrace();
System.exit(1);
}
return props;
}

}
Loading

0 comments on commit 6571084

Please sign in to comment.