Skip to content

feat(test): improve tests coverage #6034

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ subprojects {
testAnnotationProcessor 'org.projectlombok:lombok:1.18.12'

testImplementation group: 'junit', name: 'junit', version: '4.13.2'
testImplementation "org.mockito:mockito-core:2.13.0"
testImplementation "org.mockito:mockito-core:3.10.0"
testImplementation group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.9'
testImplementation group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.9'

}

task sourcesJar(type: Jar, dependsOn: classes) {
Expand Down
27 changes: 26 additions & 1 deletion framework/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ plugins {
id "org.gradle.test-retry" version "1.5.9"
id "org.sonarqube" version "2.6"
id "com.gorylenko.gradle-git-properties" version "2.4.1"
id "io.github.surpsg.offlins" version "0.3.0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of introducing this dependency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To solve the incompatibility problem between jacoco and powermock

}

gitProperties.failOnNoGitDirectory = false;

apply plugin: 'application'
apply plugin: 'checkstyle'
apply plugin: "io.github.surpsg.offlins"

mainClassName = 'org.tron.program.FullNode'

Expand All @@ -16,7 +18,7 @@ def versions = [
]

jacoco {
toolVersion = "0.8.1"
toolVersion = "0.8.8"
}


Expand Down Expand Up @@ -121,10 +123,12 @@ test {
testLogging {
exceptionFormat = 'full'
}
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why annotate this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the report part configuration of the offlinsCoverage module

jacoco {
destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
classDumpDir = file("$buildDir/jacoco/classpathdumps")
}
*/
if (isWindows()) {
exclude '**/ShieldedTransferActuatorTest.class'
exclude '**/BackupDbUtilTest.class'
Expand All @@ -141,6 +145,7 @@ test {
}
}

/*
jacocoTestReport {
reports {
xml.enabled true
Expand All @@ -149,6 +154,26 @@ jacocoTestReport {
}
getExecutionData().setFrom(fileTree('../framework/build/jacoco').include("**.exec"))
}
*/

offlinsCoverage {
jacocoVersion = '0.8.8' // Optional. By default `0.8.8`

reports {
html.enabled.set true // Optional. By default `true`
html.location.set project.file('build/reports/jacoco/test/html') // Optional. By default `build/reports/jacoco/html`

xml.enabled.set true // Optional. By default `false`
xml.location.set project.file('build/reports/jacoco/test/jacocoTestReport.xml')
// Optional. By default `build/reports/jacoco/coverageReport.xml`

csv.enabled.set true // Optional. By default `false`
csv.location.set project.file('build/reports/jacoco/test/csvCoverage.csv')
// Optional. By default `build/reports/jacoco/coverageReport.csv`
}
}


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change the default output path?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default output path configured by offlinsCoverage is inconsistent with the original configuration of jacoco. In order to maintain the consistency of the coverage report document path.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the Jacoco coverage of each module still be output locally after this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and the path is still the same


def binaryRelease(taskName, jarName, mainClass) {
return tasks.create("${taskName}", Jar) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package org.tron.common.logsfilter;

import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;

import com.google.protobuf.ByteString;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
import org.tron.common.logsfilter.capsule.TransactionLogTriggerCapsule;
import org.tron.common.logsfilter.trigger.InternalTransactionPojo;
import org.tron.common.runtime.InternalTransaction;
import org.tron.common.runtime.ProgramResult;
import org.tron.common.runtime.RuntimeImpl;
import org.tron.common.utils.Sha256Hash;
import org.tron.core.capsule.BlockCapsule;
import org.tron.core.capsule.ReceiptCapsule;
import org.tron.core.capsule.TransactionCapsule;
import org.tron.core.db.TransactionTrace;
import org.tron.p2p.utils.ByteArray;
import org.tron.protos.Protocol;
import org.tron.protos.contract.BalanceContract;

@RunWith(PowerMockRunner.class)
@PrepareForTest({
TransactionLogTriggerCapsule.class,
TransactionTrace.class
})
public class TransactionLogTriggerCapsuleMockTest {

private static final String OWNER_ADDRESS = "41548794500882809695a8a687866e76d4271a1abc";
private static final String RECEIVER_ADDRESS = "41abd4b9367799eaa3197fecb144eb71de1e049150";
private static final String CONTRACT_ADDRESS = "A0B4750E2CD76E19DCA331BF5D089B71C3C2798548";

private TransactionCapsule transactionCapsule;
private BlockCapsule blockCapsule;

@Before
public void setup() {
blockCapsule = new BlockCapsule(1,
Sha256Hash.ZERO_HASH,
System.currentTimeMillis(),
Sha256Hash.ZERO_HASH.getByteString()
);
}

@After
public void clearMocks() {
Mockito.framework().clearInlineMocks();
}


@Test
public void testConstructorWithTransactionTrace() {
BalanceContract.TransferContract.Builder builder2 =
BalanceContract.TransferContract.newBuilder()
.setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))
.setToAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)));
transactionCapsule = spy(new TransactionCapsule(builder2.build(),
Protocol.Transaction.Contract.ContractType.TransferContract));

TransactionTrace trace = mock(TransactionTrace.class);
ReceiptCapsule receiptCapsule = new ReceiptCapsule(Sha256Hash.ZERO_HASH);
RuntimeImpl runtime = mock(RuntimeImpl.class);
List<Protocol.TransactionInfo.Log> logs = new ArrayList<>();
logs.add(Protocol.TransactionInfo.Log.newBuilder()
.setAddress(ByteString.copyFrom("address".getBytes()))
.setData(ByteString.copyFrom("data".getBytes()))
.addTopics(ByteString.copyFrom("topic".getBytes()))
.build());

Protocol.TransactionInfo.Builder builder = Protocol.TransactionInfo.newBuilder()
.addAllLog(logs);

ProgramResult programResult = ProgramResult.createEmpty();
programResult.setHReturn("hreturn".getBytes());
programResult.setContractAddress(CONTRACT_ADDRESS.getBytes());

when(transactionCapsule.getTrxTrace()).thenReturn(trace);
when(trace.getReceipt()).thenReturn(receiptCapsule);
when(trace.getRuntime()).thenReturn(runtime);
when(runtime.getResult()).thenReturn(programResult);

transactionCapsule.setTrxTrace(trace);

TransactionLogTriggerCapsule triggerCapsule = new TransactionLogTriggerCapsule(
transactionCapsule, blockCapsule,0,0,0,
builder.build(),0);

Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger());
}

@Test
public void testGetInternalTransactionList() throws Exception {
BalanceContract.TransferContract.Builder builder2 =
BalanceContract.TransferContract.newBuilder()
.setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))
.setToAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)));
transactionCapsule = new TransactionCapsule(builder2.build(),
Protocol.Transaction.Contract.ContractType.TransferContract);
InternalTransaction internalTransaction = new InternalTransaction(
"parentHash".getBytes(), 10, 0,
"sendAddress".getBytes(),
"transferToAddress".getBytes(),
100L, "data".getBytes(), "note",
0L, new HashMap<>()
);
List<InternalTransaction> internalTransactionList = new ArrayList<>();
internalTransactionList.add(internalTransaction);
TransactionLogTriggerCapsule triggerCapsule =
new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule);

List<InternalTransactionPojo> pojoList = Whitebox.invokeMethod(triggerCapsule,
"getInternalTransactionList", internalTransactionList);

Assert.assertNotNull(pojoList);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@
import org.tron.core.capsule.TransactionCapsule;
import org.tron.p2p.utils.ByteArray;
import org.tron.protos.Protocol;
import org.tron.protos.contract.AssetIssueContractOuterClass;
import org.tron.protos.contract.BalanceContract;
import org.tron.protos.contract.Common;
import org.tron.protos.contract.SmartContractOuterClass;

public class TransactionLogTriggerCapsuleTest {

private static final String OWNER_ADDRESS = "41548794500882809695a8a687866e76d4271a1abc";
private static final String RECEIVER_ADDRESS = "41abd4b9367799eaa3197fecb144eb71de1e049150";
private static final String CONTRACT_ADDRESS = "A0B4750E2CD76E19DCA331BF5D089B71C3C2798548";

public TransactionCapsule transactionCapsule;
public BlockCapsule blockCapsule;
Expand Down Expand Up @@ -175,4 +178,70 @@ public void testConstructorWithCancelAllUnfreezeTrxCapsule() {
triggerCapsule.getTransactionLogTrigger().getExtMap().get(BANDWIDTH.name()).longValue());
}

@Test
public void testConstructorWithTransferCapsule() {
BalanceContract.TransferContract.Builder builder2 =
BalanceContract.TransferContract.newBuilder()
.setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))
.setToAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)));
transactionCapsule = new TransactionCapsule(builder2.build(),
Protocol.Transaction.Contract.ContractType.TransferContract);

TransactionLogTriggerCapsule triggerCapsule =
new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule);

Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress());
Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getToAddress());
}

@Test
public void testConstructorWithTransferAssetCapsule() {
AssetIssueContractOuterClass.TransferAssetContract.Builder builder2 =
AssetIssueContractOuterClass.TransferAssetContract.newBuilder()
.setAssetName(ByteString.copyFrom("AssetName".getBytes()))
.setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))
.setToAddress(ByteString.copyFrom(ByteArray.fromHexString(RECEIVER_ADDRESS)));
transactionCapsule = new TransactionCapsule(builder2.build(),
Protocol.Transaction.Contract.ContractType.TransferAssetContract);

TransactionLogTriggerCapsule triggerCapsule =
new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule);

Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress());
Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getToAddress());
}

@Test
public void testConstructorWithTriggerSmartContract() {
SmartContractOuterClass.TriggerSmartContract.Builder builder2 =
SmartContractOuterClass.TriggerSmartContract.newBuilder()
.setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)))
.setContractAddress(ByteString.copyFrom(ByteArray.fromHexString(CONTRACT_ADDRESS)));
transactionCapsule = new TransactionCapsule(builder2.build(),
Protocol.Transaction.Contract.ContractType.TriggerSmartContract);

TransactionLogTriggerCapsule triggerCapsule =
new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule);

Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress());
Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getToAddress());
}

@Test
public void testConstructorWithCreateSmartContract() {
SmartContractOuterClass.CreateSmartContract.Builder builder2 =
SmartContractOuterClass.CreateSmartContract.newBuilder()
.setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString(OWNER_ADDRESS)));
transactionCapsule = new TransactionCapsule(builder2.build(),
Protocol.Transaction.Contract.ContractType.CreateSmartContract);

TransactionLogTriggerCapsule triggerCapsule =
new TransactionLogTriggerCapsule(transactionCapsule, blockCapsule);

Assert.assertNotNull(triggerCapsule.getTransactionLogTrigger().getFromAddress());
}




}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.tron.common.runtime;

import lombok.extern.slf4j.Slf4j;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
import org.tron.core.vm.program.Program;

@RunWith(PowerMockRunner.class)
@PrepareForTest({RuntimeImpl.class})
@Slf4j
public class RuntimeImplMockTest {
@After
public void clearMocks() {
Mockito.framework().clearInlineMocks();
}

@Test
public void testSetResultCode1() throws Exception {
RuntimeImpl runtime = new RuntimeImpl();
ProgramResult programResult = new ProgramResult();

Program.BadJumpDestinationException badJumpDestinationException
= new Program.BadJumpDestinationException("Operation with pc isn't 'JUMPDEST': PC[%d];", 0);
programResult.setException(badJumpDestinationException);
Whitebox.invokeMethod(runtime,"setResultCode", programResult);

Program.OutOfTimeException outOfTimeException
= new Program.OutOfTimeException("CPU timeout for 0x0a executing");
programResult.setException(outOfTimeException);
Whitebox.invokeMethod(runtime,"setResultCode", programResult);

Program.PrecompiledContractException precompiledContractException
= new Program.PrecompiledContractException("precompiled contract exception");
programResult.setException(precompiledContractException);
Whitebox.invokeMethod(runtime,"setResultCode", programResult);

Program.StackTooSmallException stackTooSmallException
= new Program.StackTooSmallException("Expected stack size %d but actual %d;", 100, 10);
programResult.setException(stackTooSmallException);
Whitebox.invokeMethod(runtime,"setResultCode", programResult);

Program.JVMStackOverFlowException jvmStackOverFlowException
= new Program.JVMStackOverFlowException();
programResult.setException(jvmStackOverFlowException);
Whitebox.invokeMethod(runtime,"setResultCode", programResult);

Assert.assertTrue(true);
}

}

Loading
Loading