From 54e95f43d9e9f9b1ccf840decf569c106be2c60c Mon Sep 17 00:00:00 2001 From: 3for <287494524@qq.com> Date: Thu, 27 Aug 2026 08:17:57 +0800 Subject: [PATCH 1/3] chore: clean stale dependency metadata and align account test - remove unused InfluxDB, c3p0, mchange, and HikariCP verification entries - align the null-address GetAccount test with the actual empty response - rename the test to reflect its expected behavior --- .../services/http/GetAccountServletTest.java | 8 ++--- gradle/verification-metadata.xml | 32 ------------------- 2 files changed, 4 insertions(+), 36 deletions(-) diff --git a/framework/src/test/java/org/tron/core/services/http/GetAccountServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetAccountServletTest.java index 1c1d42c9a5c..a0a024669d4 100644 --- a/framework/src/test/java/org/tron/core/services/http/GetAccountServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/GetAccountServletTest.java @@ -47,17 +47,17 @@ public void testGetAccountPost() throws Exception { } @Test - public void testGetAccountPostNullAddressKeepsDefault() throws Exception { + public void testGetAccountPostNullAddressReturnsEmptyResponse() throws Exception { MockHttpServletRequest request = postRequest("{\"address\": null}"); + when(wallet.getAccount(argThat(req -> req != null + && req.getAddress().equals(ByteString.EMPTY)))).thenReturn(null); MockHttpServletResponse response = newResponse(); servlet.doPost(request, response); assertEquals(200, response.getStatus()); verify(wallet).getAccount(argThat(req -> req != null && req.getAddress().equals(ByteString.EMPTY))); - String content = response.getContentAsString(); - assertFalse("Should not contain error", content.contains("\"Error\"")); - assertTrue("Should contain address", content.contains("address")); + assertEquals("{}", response.getContentAsString().trim()); } @Test diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 6a3e641d5d6..75b750f3432 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -287,14 +287,6 @@ - - - - - - - - @@ -873,22 +865,6 @@ - - - - - - - - - - - - - - - - @@ -962,14 +938,6 @@ - - - - - - - - From 53a72492928bc86b44688cf1cbb25f539e5cdd18 Mon Sep 17 00:00:00 2001 From: 3for <287494524@qq.com> Date: Fri, 18 Sep 2026 22:20:02 +0800 Subject: [PATCH 2/3] build: remove unused dependencies and stale verification metadata - Remove unused Shadow plugin, Commons Math, AspectJ tools and JCIP annotations - Drop redundant common-protos, bcprov and Error Prone dependency declarations - Clean up stale checksum entries in Gradle dependency verification metadata --- build.gradle | 2 - common/build.gradle | 1 - errorprone/build.gradle | 2 - gradle/verification-metadata.xml | 246 ------------------------------- plugins/build.gradle | 1 - protocol/build.gradle | 3 - 6 files changed, 255 deletions(-) diff --git a/build.gradle b/build.gradle index 65e72c0fb73..d5ad94290cd 100644 --- a/build.gradle +++ b/build.gradle @@ -79,7 +79,6 @@ subprojects { } dependencies { classpath 'com.google.protobuf:protobuf-gradle-plugin:0.9.1' - classpath "gradle.plugin.com.github.johnrengelman:shadow:7.1.2" } } @@ -98,7 +97,6 @@ subprojects { implementation "com.google.code.findbugs:jsr305:3.0.0" implementation group: 'org.springframework', name: 'spring-context', version: "${springVersion}" implementation "org.apache.commons:commons-lang3:3.4" - implementation group: 'org.apache.commons', name: 'commons-math', version: '2.2' implementation "org.apache.commons:commons-collections4:4.1" implementation group: 'joda-time', name: 'joda-time', version: '2.3' implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: '1.84' diff --git a/common/build.gradle b/common/build.gradle index 14d3eb4e637..7527fcd83d8 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -20,7 +20,6 @@ dependencies { // https://eclipse.dev/aspectj/doc/latest/release/JavaVersionCompatibility.html api 'org.aspectj:aspectjrt:1.9.8' api 'org.aspectj:aspectjweaver:1.9.8' - api 'org.aspectj:aspectjtools:1.9.8' api group: 'io.github.tronprotocol', name: 'libp2p', version: '2.2.9',{ exclude group: 'io.grpc', module: 'grpc-context' exclude group: 'io.grpc', module: 'grpc-core' diff --git a/errorprone/build.gradle b/errorprone/build.gradle index f8a634b7edc..83b25ac545c 100644 --- a/errorprone/build.gradle +++ b/errorprone/build.gradle @@ -4,9 +4,7 @@ if (!JavaVersion.current().isJava11Compatible()) { tasks.withType(Jar).configureEach { enabled = false } } else { dependencies { - compileOnly "com.google.errorprone:error_prone_annotations:${errorproneVersion}" compileOnly "com.google.errorprone:error_prone_check_api:${errorproneVersion}" - compileOnly "com.google.errorprone:error_prone_core:${errorproneVersion}" compileOnly "com.google.auto.service:auto-service:1.1.1" annotationProcessor "com.google.auto.service:auto-service:1.1.1" } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 75b750f3432..d661ca5b2e4 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -18,14 +18,6 @@ - - - - - - - - @@ -316,11 +308,6 @@ - - - - - @@ -416,14 +403,6 @@ - - - - - - - - @@ -440,11 +419,6 @@ - - - - - @@ -620,17 +594,6 @@ - - - - - - - - - - - @@ -642,17 +605,6 @@ - - - - - - - - - - - @@ -704,11 +656,6 @@ - - - - - @@ -991,14 +938,6 @@ - - - - - - - - @@ -1036,14 +975,6 @@ - - - - - - - - @@ -1567,14 +1498,6 @@ - - - - - - - - @@ -1657,27 +1580,6 @@ - - - - - - - - - - - - - - - - - - - - - @@ -1702,14 +1604,6 @@ - - - - - - - - @@ -1869,32 +1763,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1913,14 +1781,6 @@ - - - - - - - - @@ -2037,19 +1897,6 @@ - - - - - - - - - - - - - @@ -2304,14 +2151,6 @@ - - - - - - - - @@ -2392,14 +2231,6 @@ - - - - - - - - @@ -2445,24 +2276,11 @@ - - - - - - - - - - - - - @@ -2471,27 +2289,11 @@ - - - - - - - - - - - - - - - - @@ -2500,14 +2302,6 @@ - - - - - - - - @@ -2750,46 +2544,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/build.gradle b/plugins/build.gradle index 09a13a19b1b..4fa0306edc2 100644 --- a/plugins/build.gradle +++ b/plugins/build.gradle @@ -53,7 +53,6 @@ dependencies { implementation group: 'info.picocli', name: 'picocli', version: '4.6.3' implementation group: 'com.typesafe', name: 'config', version: '1.3.2' implementation group: 'me.tongfei', name: 'progressbar', version: '0.9.3' - implementation group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: '1.84' if (rootProject.archInfo.isArm64) { testRuntimeOnly group: 'org.fusesource.hawtjni', name: 'hawtjni-runtime', version: '1.18' // for test implementation project(":platform") diff --git a/protocol/build.gradle b/protocol/build.gradle index ed8914343b8..e33c638faf1 100644 --- a/protocol/build.gradle +++ b/protocol/build.gradle @@ -6,7 +6,6 @@ def protobufVersion = '3.25.8' dependencies { api group: 'com.google.protobuf', name: 'protobuf-java', version: protobufVersion api group: 'com.google.protobuf', name: 'protobuf-java-util', version: protobufVersion - api group: 'net.jcip', name: 'jcip-annotations', version: '1.0' // checkstyleConfig "com.puppycrawl.tools:checkstyle:${versions.checkstyle}" // google grpc @@ -17,8 +16,6 @@ dependencies { api group: 'io.grpc', name: 'grpc-services', version: rootProject.grpcVersion // end google grpc - - api group: 'com.google.api.grpc', name: 'proto-google-common-protos', version: '2.15.0' } tasks.matching { it instanceof Test }.all { From 636a0c2da01af1050fc695d310df58045dd4147e Mon Sep 17 00:00:00 2001 From: 3for <287494524@qq.com> Date: Fri, 18 Sep 2026 22:53:25 +0800 Subject: [PATCH 3/3] test: align existing tests with actual API and runtime behavior - Correct HTTP methods, request fields and Wallet mock responses - Verify RPC errors, validation messages and transaction processing - Replace ineffective assertions and fix serialization, collection and storage fixtures - Restore metrics assertions and initialize contract mappings explicitly --- .../common/storage/CheckOrInitEngineTest.java | 28 +- .../tron/common/utils/ByteArrayMapTest.java | 7 +- .../tron/common/utils/ByteArraySetTest.java | 16 +- .../org/tron/common/utils/JsonUtilTest.java | 30 ++- .../org/tron/core/BandwidthProcessorTest.java | 7 +- .../CancelAllUnfreezeV2ActuatorTest.java | 35 +-- .../DelegateResourceActuatorTest.java | 36 +-- .../actuator/ProposalCreateActuatorTest.java | 20 +- .../org/tron/core/db/ManagerMockTest.java | 193 ++++++-------- .../core/jsonrpc/BuildTransactionTest.java | 14 +- .../tron/core/metrics/MetricsUtilTest.java | 47 ++-- .../filter/LiteFnQueryHttpFilterTest.java | 27 +- .../filter/RpcApiAccessInterceptorTest.java | 14 +- .../services/http/BroadcastServletTest.java | 214 +++++---------- .../GetAssetIssueListByNameServletTest.java | 10 +- .../http/GetBandwidthPricesServletTest.java | 2 +- .../http/GetBlockByNumServletTest.java | 63 +++-- .../http/GetEnergyPricesServletTest.java | 2 +- .../http/GetMemoFeePricesServletTest.java | 2 +- ...TransactionListFromPendingServletTest.java | 2 +- .../tron/core/services/http/UtilMockTest.java | 7 +- ...GetTransactionByIdSolidityServletTest.java | 247 +++++------------- .../services/jsonrpc/JsonRpcServletTest.java | 56 ++-- 23 files changed, 449 insertions(+), 630 deletions(-) diff --git a/framework/src/test/java/org/tron/common/storage/CheckOrInitEngineTest.java b/framework/src/test/java/org/tron/common/storage/CheckOrInitEngineTest.java index 90aac10c0b6..62802d2d4b1 100644 --- a/framework/src/test/java/org/tron/common/storage/CheckOrInitEngineTest.java +++ b/framework/src/test/java/org/tron/common/storage/CheckOrInitEngineTest.java @@ -97,8 +97,8 @@ public void testCannotWritePropertyFile() throws IOException { fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(true); fileUtil.when(() -> FileUtil.createFileIfNotExists(engineFile)).thenReturn(true); - propUtil.when(() -> PropUtil.readProperty(engineFile, ENGINE_KEY)).thenReturn(null); - strings.when(() -> Strings.isNullOrEmpty(null)).thenReturn(true); + propUtil.when(() -> PropUtil.readProperty(engineFile, ENGINE_KEY)).thenReturn(""); + strings.when(() -> Strings.isNullOrEmpty("")).thenReturn(true); propUtil.when(() -> PropUtil.writeProperty(engineFile, ENGINE_KEY, ROCKSDB)) .thenReturn(false); @@ -142,27 +142,13 @@ public void testEngineMismatch() throws IOException { @Test public void testSuccessfulFirstTimeInit() throws IOException { - try (MockedStatic fileUtil = mockStatic(FileUtil.class); - MockedStatic propUtil = mockStatic(PropUtil.class); - MockedStatic strings = mockStatic(Strings.class)) { - - String dir = temporaryFolder.newFolder(ACCOUNT).toString(); - String engineFile = Paths.get(dir, ENGINE_FILE).toString(); - - fileUtil.when(() -> FileUtil.createDirIfNotExists(dir)).thenReturn(true); - fileUtil.when(() -> FileUtil.createFileIfNotExists(engineFile)).thenReturn(true); - - propUtil.when(() -> PropUtil.readProperty(engineFile, ENGINE_KEY)) - .thenReturn(null) - .thenReturn(LEVELDB); - strings.when(() -> Strings.isNullOrEmpty(null)).thenReturn(true); + String dir = new File(temporaryFolder.getRoot(), ACCOUNT).toString(); + File engineFile = Paths.get(dir, ENGINE_FILE).toFile(); - propUtil.when(() -> PropUtil.writeProperty(engineFile, ENGINE_KEY, LEVELDB)) - .thenReturn(true); + checkOrInitEngine(LEVELDB, dir, TronError.ErrCode.LEVELDB_INIT); - TronError.ErrCode errCode = TronError.ErrCode.LEVELDB_INIT; - checkOrInitEngine(LEVELDB, dir, errCode); - } + assertTrue(engineFile.isFile()); + assertEquals(LEVELDB, PropUtil.readProperty(engineFile.toString(), ENGINE_KEY)); } @Test diff --git a/framework/src/test/java/org/tron/common/utils/ByteArrayMapTest.java b/framework/src/test/java/org/tron/common/utils/ByteArrayMapTest.java index b367ade7e4f..def019f9f4c 100644 --- a/framework/src/test/java/org/tron/common/utils/ByteArrayMapTest.java +++ b/framework/src/test/java/org/tron/common/utils/ByteArrayMapTest.java @@ -9,6 +9,7 @@ import static org.junit.Assert.assertTrue; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Objects; @@ -16,6 +17,7 @@ import lombok.Getter; import org.junit.Before; import org.junit.Test; +import org.tron.core.db.ByteArrayWrapper; public class ByteArrayMapTest { @@ -139,7 +141,10 @@ public void test() { Map map = new ByteArrayMap<>(); Map testMap = createTestMap(); assertNotEquals(map, testMap); - assertTrue(testMap.hashCode() <= 0); + Map expected = new HashMap<>(); + expected.put(new ByteArrayWrapper("key1".getBytes()), "value1"); + expected.put(new ByteArrayWrapper("key2".getBytes()), "value2"); + assertEquals(expected.hashCode(), testMap.hashCode()); assertNotNull(testMap.toString()); } diff --git a/framework/src/test/java/org/tron/common/utils/ByteArraySetTest.java b/framework/src/test/java/org/tron/common/utils/ByteArraySetTest.java index 22695f713a7..223152f4f7e 100644 --- a/framework/src/test/java/org/tron/common/utils/ByteArraySetTest.java +++ b/framework/src/test/java/org/tron/common/utils/ByteArraySetTest.java @@ -1,9 +1,7 @@ package org.tron.common.utils; -import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -11,6 +9,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import org.junit.Before; import org.junit.Test; @@ -73,14 +72,16 @@ public void testIterator() { byteArraySet.add(bytes2); Iterator iterator = byteArraySet.iterator(); + Set actual = new HashSet<>(); assertTrue(iterator.hasNext()); - assertArrayEquals(bytes1, iterator.next()); + actual.add(ByteArray.toHexString(iterator.next())); assertTrue(iterator.hasNext()); - assertArrayEquals(bytes2, iterator.next()); + actual.add(ByteArray.toHexString(iterator.next())); assertFalse(iterator.hasNext()); + assertEquals(new HashSet<>(Arrays.asList("010203", "040506")), actual); } @Test @@ -94,8 +95,11 @@ public void testToArray() { byte[][] array = byteArraySet.toArray(new byte[0][]); assertEquals(2, array.length); - assertArrayEquals(bytes1, array[0]); - assertArrayEquals(bytes2, array[1]); + Set actual = new HashSet<>(); + for (byte[] bytes : array) { + actual.add(ByteArray.toHexString(bytes)); + } + assertEquals(new HashSet<>(Arrays.asList("010203", "040506")), actual); } @Test diff --git a/framework/src/test/java/org/tron/common/utils/JsonUtilTest.java b/framework/src/test/java/org/tron/common/utils/JsonUtilTest.java index 8681ff58270..05a10c1ec96 100644 --- a/framework/src/test/java/org/tron/common/utils/JsonUtilTest.java +++ b/framework/src/test/java/org/tron/common/utils/JsonUtilTest.java @@ -2,8 +2,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.tron.common.utils.JsonUtil.json2Obj; import static org.tron.common.utils.JsonUtil.obj2Json; @@ -46,17 +46,13 @@ public void test() { @Test public void testObj2JsonWithCircularReference() { - Node node1 = new Node("Node1"); - Node node2 = new Node("Node2"); - node1.setNext(node2); - node2.setNext(node1); - - try { - obj2Json(node1); - fail("Expected a RuntimeException to be thrown"); - } catch (RuntimeException e) { - assertTrue(e.getCause() instanceof com.fasterxml.jackson.databind.JsonMappingException); - } + Node node = new Node("Node1"); + assertTrue(obj2Json(node).contains("\"name\":\"Node1\"")); + node.setNext(node); + + RuntimeException exception = assertThrows(RuntimeException.class, () -> obj2Json(node)); + assertTrue(exception.getCause() instanceof com.fasterxml.jackson.databind.JsonMappingException); + assertTrue(exception.getCause().getMessage().contains("Direct self-reference")); } @Test(expected = RuntimeException.class) @@ -65,7 +61,7 @@ public void testInvalidJson() { json2Obj(invalidJson, String.class); } - class Node { + public static class Node { private String name; private org.tron.common.utils.JsonUtilTest.Node next; @@ -73,6 +69,14 @@ public Node(String name) { this.name = name; } + public String getName() { + return name; + } + + public Node getNext() { + return next; + } + public void setNext(org.tron.common.utils.JsonUtilTest.Node next) { this.next = next; } diff --git a/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java b/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java index cf652af3650..57e780b82f1 100755 --- a/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java +++ b/framework/src/test/java/org/tron/core/BandwidthProcessorTest.java @@ -570,9 +570,12 @@ public void testConsumeBandwidthTooBigTransactionResultException() { trx.setInBlock(false); TransactionTrace trace = new TransactionTrace(trx, StoreFactory .getInstance(), new RuntimeImpl()); - assertThrows( - "Too big transaction result, TxId %s, the result size is %d bytes, maxResultSize %d", + TooBigTransactionResultException exception = assertThrows( TooBigTransactionResultException.class, () -> dbManager.consumeBandwidth(trx, trace)); + Assert.assertEquals(String.format( + "Too big transaction result, TxId %s, the result size is %d bytes, maxResultSize %d", + trx.getTransactionId(), trx.getResultSizeWithMaxContractRet(), Constant.MAX_RESULT_SIZE_IN_TX), + exception.getMessage()); } /** diff --git a/framework/src/test/java/org/tron/core/actuator/CancelAllUnfreezeV2ActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/CancelAllUnfreezeV2ActuatorTest.java index 3d4ec67c6af..ee33f74aed9 100644 --- a/framework/src/test/java/org/tron/core/actuator/CancelAllUnfreezeV2ActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/CancelAllUnfreezeV2ActuatorTest.java @@ -114,8 +114,8 @@ public void testNullTransactionResultCapsule() { } catch (ContractValidateException e) { fail(); } - assertThrows(ActuatorConstant.TX_RESULT_NULL, - RuntimeException.class, () -> actuator.execute(null)); + assertEquals(ActuatorConstant.TX_RESULT_NULL, + assertThrows(RuntimeException.class, () -> actuator.execute(null)).getMessage()); } @Test @@ -123,7 +123,8 @@ public void testInvalidOwnerAddress() { CancelAllUnfreezeV2Actuator actuator = new CancelAllUnfreezeV2Actuator(); actuator.setChainBaseManager(dbManager.getChainBaseManager()) .setAny(getCancelAllUnfreezeV2ContractInvalidAddress()); - assertThrows("Invalid address", ContractValidateException.class, actuator::validate); + assertEquals("Invalid address", + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } @Test @@ -131,8 +132,8 @@ public void testInvalidOwnerAccount() { CancelAllUnfreezeV2Actuator actuator = new CancelAllUnfreezeV2Actuator(); actuator.setChainBaseManager(dbManager.getChainBaseManager()) .setAny(getCancelAllUnfreezeV2ContractInvalidAccount()); - assertThrows("Account[" + OWNER_ACCOUNT_INVALID + "] does not exist", - ContractValidateException.class, actuator::validate); + assertEquals("Account[" + OWNER_ACCOUNT_INVALID + "] not exists", + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } @Test @@ -140,24 +141,24 @@ public void testInvalidOwnerUnfreezeV2List() { CancelAllUnfreezeV2Actuator actuator = new CancelAllUnfreezeV2Actuator(); actuator.setChainBaseManager(dbManager.getChainBaseManager()) .setAny(getCancelAllUnfreezeV2Contract()); - assertThrows("no unfreezeV2 list to cancel", - ContractValidateException.class, actuator::validate); + assertEquals("No unfreezeV2 list to cancel", + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } @Test public void testInvalidCancelAllUnfreezeV2Contract() { CancelAllUnfreezeV2Actuator actuator = new CancelAllUnfreezeV2Actuator(); actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny(null); - assertThrows(ActuatorConstant.CONTRACT_NOT_EXIST, - ContractValidateException.class, actuator::validate); + assertEquals(ActuatorConstant.CONTRACT_NOT_EXIST, + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } @Test public void testInvalidAccountStore() { CancelAllUnfreezeV2Actuator actuator = new CancelAllUnfreezeV2Actuator(); actuator.setChainBaseManager(null).setAny(getCancelAllUnfreezeV2Contract()); - assertThrows(ActuatorConstant.STORE_NOT_EXIST, - ContractValidateException.class, actuator::validate); + assertEquals(ActuatorConstant.STORE_NOT_EXIST, + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } @Test @@ -166,9 +167,9 @@ public void testSupportAllowCancelAllUnfreezeV2() { CancelAllUnfreezeV2Actuator actuator = new CancelAllUnfreezeV2Actuator(); actuator.setChainBaseManager(dbManager.getChainBaseManager()) .setAny(getCancelAllUnfreezeV2Contract()); - assertThrows( + assertEquals( "Not support CancelAllUnfreezeV2 transaction, need to be opened by the committee", - ContractValidateException.class, actuator::validate); + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } @Test @@ -176,10 +177,10 @@ public void testErrorContract() { dbManager.getDynamicPropertiesStore().saveAllowCancelAllUnfreezeV2(1); CancelAllUnfreezeV2Actuator actuator = new CancelAllUnfreezeV2Actuator(); actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny(getErrorContract()); - assertThrows( + assertEquals( "contract type error, expected type [CancelAllUnfreezeV2Contract], " - + "real type[WithdrawExpireUnfreezeContract]", - ContractValidateException.class, actuator::validate); + + "real type[class com.google.protobuf.Any]", + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } private Any getCancelAllUnfreezeV2Contract() { @@ -204,4 +205,4 @@ private Any getCancelAllUnfreezeV2ContractInvalidAccount() { ByteString.copyFrom(ByteArray.fromHexString(OWNER_ACCOUNT_INVALID))).build() ); } -} \ No newline at end of file +} diff --git a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java index e9263cc4adb..29c494f67ff 100644 --- a/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/DelegateResourceActuatorTest.java @@ -450,8 +450,9 @@ public void testMaxDelegateLockPeriodForBandwidthWrongLockPeriod1() { actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny( getMaxDelegateLockPeriodContractForBandwidth( delegateBalance, 370 * 24 * 3600)); - assertThrows("The lock period of delegate resources cannot exceed 1 year!", - ContractValidateException.class, actuator::validate); + assertEquals("The lock period of delegate resource cannot be less than 0 and cannot exceed " + + "86401!", + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); dbManager.getDynamicPropertiesStore().saveMaxDelegateLockPeriod(DELEGATE_PERIOD / 3000); } @@ -478,9 +479,9 @@ public void testMaxDelegateLockPeriodForBandwidthWrongLockPeriod2() { actuator1.setChainBaseManager(dbManager.getChainBaseManager()).setAny( getMaxDelegateLockPeriodContractForBandwidth( delegateBalance, 30)); - assertThrows("The lock period for bandwidth this time cannot be less than the remaining" - + " time[60000s] of the last lock period for bandwidth!", - ContractValidateException.class, actuator1::validate); + assertEquals("The lock period for BANDWIDTH this time cannot be less than the remaining" + + " time[180000ms] of the last lock period for BANDWIDTH!", + assertThrows(ContractValidateException.class, actuator1::validate).getMessage()); dbManager.getDynamicPropertiesStore().saveMaxDelegateLockPeriod(DELEGATE_PERIOD / 3000); } @@ -589,9 +590,9 @@ public void testMaxDelegateLockPeriodForEnergyWrongLockPeriod2() { actuator1.setChainBaseManager(dbManager.getChainBaseManager()).setAny( getMaxDelegateLockPeriodContractForEnergy( delegateBalance, 30)); - assertThrows("The lock period for energy this time cannot be less than the remaining" - + " time[60000s] of the last lock period for energy!", - ContractValidateException.class, actuator1::validate); + assertEquals("The lock period for ENERGY this time cannot be less than the remaining" + + " time[180000ms] of the last lock period for ENERGY!", + assertThrows(ContractValidateException.class, actuator1::validate).getMessage()); } @Test @@ -743,7 +744,8 @@ public void invalidReceiverAddress() { actuator.setChainBaseManager(dbManager.getChainBaseManager()) .setAny(getDelegateContractForBandwidth( OWNER_ADDRESS, OWNER_ADDRESS_INVALID, 1_000_000_000L)); - assertThrows("Invalid receiverAddress", ContractValidateException.class, actuator::validate); + assertEquals("Invalid receiverAddress", + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } @Test @@ -797,9 +799,9 @@ public void testSupportDelegateResource() { OWNER_ADDRESS, RECEIVER_ADDRESS, 1_000_000_000L)); - assertThrows( + assertEquals( "No support for resource delegate", - ContractValidateException.class, actuator::validate); + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } @Test @@ -811,19 +813,19 @@ public void testSupportUnfreezeDelay() { OWNER_ADDRESS, RECEIVER_ADDRESS, 1_000_000_000L)); - assertThrows( + assertEquals( "Not support Delegate resource transaction, need to be opened by the committee", - ContractValidateException.class, actuator::validate); + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } @Test public void testErrorContract() { DelegateResourceActuator actuator = new DelegateResourceActuator(); actuator.setChainBaseManager(dbManager.getChainBaseManager()).setAny(getErrorContract()); - assertThrows( - "contract type error, expected type [DelegateResourceContract], " - + "real type[WithdrawExpireUnfreezeContract]", - ContractValidateException.class, actuator::validate); + assertEquals( + "contract type error,expected type [DelegateResourceContract]," + + "real type[class com.google.protobuf.Any]", + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } private Any getErrorContract() { diff --git a/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java b/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java index 687cc7385cd..37a409623b9 100644 --- a/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java +++ b/framework/src/test/java/org/tron/core/actuator/ProposalCreateActuatorTest.java @@ -292,9 +292,9 @@ public void invalidPara() { actuator.setChainBaseManager(dbManager.getChainBaseManager()) .setForkUtils(dbManager.getChainBaseManager().getForkController()) .setAny(getContract(OWNER_ADDRESS_FIRST, paras)); - assertThrows( + Assert.assertEquals( "Bad chain parameter id [MAX_DELEGATE_LOCK_PERIOD]", - ContractValidateException.class, actuator::validate); + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); actuator = new ProposalCreateActuator(); ForkController forkController = Mockito.mock(ForkController.class); @@ -304,10 +304,10 @@ public void invalidPara() { .setAny(getContract(OWNER_ADDRESS_FIRST, paras)); dbManager.getDynamicPropertiesStore().saveMaxDelegateLockPeriod(86400L); long maxDelegateLockPeriod = dbManager.getDynamicPropertiesStore().getMaxDelegateLockPeriod(); - assertThrows( + Assert.assertEquals( "This value[MAX_DELEGATE_LOCK_PERIOD] is only allowed to be greater than " - + maxDelegateLockPeriod + " and less than or equal to " + ONE_YEAR_BLOCK_NUMBERS + "!", - ContractValidateException.class, actuator::validate); + + maxDelegateLockPeriod + " and less than or equal to " + ONE_YEAR_BLOCK_NUMBERS + " !", + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); // verify Proposal No. 82 paras = new HashMap<>(); @@ -316,19 +316,19 @@ public void invalidPara() { actuator.setChainBaseManager(dbManager.getChainBaseManager()) .setForkUtils(dbManager.getChainBaseManager().getForkController()) .setAny(getContract(OWNER_ADDRESS_FIRST, paras)); - assertThrows( - "Bad chain parameter id [ALLOW_ENERGY_ADJUSTMENT]", - ContractValidateException.class, actuator::validate); + Assert.assertEquals( + "Bad chain parameter id [MAX_CREATE_ACCOUNT_TX_SIZE]", + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); actuator = new ProposalCreateActuator(); actuator.setChainBaseManager(dbManager.getChainBaseManager()) .setForkUtils(forkController) .setAny(getContract(OWNER_ADDRESS_FIRST, paras)); - assertThrows( + Assert.assertEquals( "This value[MAX_CREATE_ACCOUNT_TX_SIZE] is only allowed to be greater than or equal " + "to " + CREATE_ACCOUNT_TRANSACTION_MIN_BYTE_SIZE + " and less than or equal to " + CREATE_ACCOUNT_TRANSACTION_MAX_BYTE_SIZE + "!", - ContractValidateException.class, actuator::validate); + assertThrows(ContractValidateException.class, actuator::validate).getMessage()); } /** diff --git a/framework/src/test/java/org/tron/core/db/ManagerMockTest.java b/framework/src/test/java/org/tron/core/db/ManagerMockTest.java index 946bef022d2..03cd91f9f3a 100644 --- a/framework/src/test/java/org/tron/core/db/ManagerMockTest.java +++ b/framework/src/test/java/org/tron/core/db/ManagerMockTest.java @@ -4,9 +4,10 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockConstruction; @@ -35,8 +36,6 @@ import org.mockito.MockedConstruction; import org.mockito.MockedStatic; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; import org.tron.common.cron.CronExpression; import org.tron.common.logsfilter.EventPluginLoader; @@ -77,101 +76,73 @@ public void clearMocks() { } @Test - public void processTransactionCostTimeMoreThan100() throws Exception { - TransactionTrace traceMock = mock(TransactionTrace.class); - BandwidthProcessor bandwidthProcessorMock = mock(BandwidthProcessor.class); - try (MockedConstruction mockedConstruction2 - = mockConstruction(TransactionTrace.class,(mock, context) -> { - when(mock).thenReturn(traceMock); }); - MockedConstruction mockedConstruction3 - = mockConstruction(BandwidthProcessor.class,(mock, context) -> { - when(mock).thenReturn(bandwidthProcessorMock); - }); + public void testProcessTransactionPersistsSuccessfulResult() throws Exception { + ProgramResult result = new ProgramResult(); + result.setResultCode(Protocol.Transaction.Result.contractResult.SUCCESS); + try (MockedConstruction traces + = mockConstruction(TransactionTrace.class, (trace, context) -> + when(trace.getRuntimeResult()).thenReturn(result)); MockedStatic mockedStatic = mockStatic(TransactionUtil.class)) { - Manager dbManager = mock(Manager.class); + Manager dbManager = spy(new Manager()); BalanceContract.TransferContract transferContract = BalanceContract.TransferContract.newBuilder() .setAmount(10) .setOwnerAddress(ByteString.copyFromUtf8("aaa")) .setToAddress(ByteString.copyFromUtf8("bbb")) .build(); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < 6666; i++) { - sb.append("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); - } Protocol.Transaction transaction = Protocol.Transaction.newBuilder().setRawData( Protocol.Transaction.raw.newBuilder() - .setData(ByteString.copyFrom(sb.toString().getBytes(StandardCharsets.UTF_8))) .addContract( Protocol.Transaction.Contract.newBuilder() .setParameter(Any.pack(transferContract)) .setType(Protocol.Transaction.Contract.ContractType.TransferContract))) .build(); - TransactionCapsule trxCap = new TransactionCapsule(transaction); - ProgramResult result = new ProgramResult(); - result.setResultCode(Protocol.Transaction.Result.contractResult.SUCCESS); - + TransactionCapsule trxCap = spy(new TransactionCapsule(transaction)); Sha256Hash transactionId = trxCap.getTransactionId(); - TransactionCapsule trxCapMock = mock(TransactionCapsule.class); ChainBaseManager chainBaseManagerMock = mock(ChainBaseManager.class); BalanceTraceStore balanceTraceStoreMock = mock(BalanceTraceStore.class); TransactionStore transactionStoreMock = mock(TransactionStore.class); - TransactionInfoCapsule transactionInfoCapsuleMock = mock(TransactionInfoCapsule.class); - Protocol.TransactionInfo transactionInfo = Protocol.TransactionInfo.newBuilder().build(); + Protocol.TransactionInfo transactionInfo = Protocol.TransactionInfo.newBuilder() + .setId(transactionId.getByteString()).setFee(100L).build(); - Field field = dbManager.getClass().getDeclaredField("chainBaseManager"); + Field field = Manager.class.getDeclaredField("chainBaseManager"); field.setAccessible(true); field.set(dbManager, chainBaseManagerMock); BlockCapsule blockCapMock = Mockito.mock(BlockCapsule.class); - when(TransactionUtil - .buildTransactionInfoInstance(trxCapMock, blockCapMock, traceMock)) - .thenReturn(transactionInfoCapsuleMock); - - // this make cost > 100 cond is true - when(blockCapMock.isMerkleRootEmpty()).thenAnswer(new Answer() { - @Override - public Boolean answer(InvocationOnMock invocation) throws Throwable { - Thread.sleep(100); - return true; - } - }); + mockedStatic.when(() -> TransactionUtil.buildTransactionInfoInstance( + eq(trxCap), eq(blockCapMock), any(TransactionTrace.class))) + .thenReturn(new TransactionInfoCapsule(transactionInfo)); + when(blockCapMock.isMerkleRootEmpty()).thenReturn(true); when(chainBaseManagerMock.getBalanceTraceStore()).thenReturn(balanceTraceStoreMock); when(chainBaseManagerMock.getAccountStore()).thenReturn(mock(AccountStore.class)); when(chainBaseManagerMock.getDynamicPropertiesStore()) .thenReturn(mock(DynamicPropertiesStore.class)); when(chainBaseManagerMock.getTransactionStore()).thenReturn(transactionStoreMock); - when(trxCapMock.getTransactionId()).thenReturn(transactionId); - when(traceMock.getRuntimeResult()).thenReturn(result); - when(transactionInfoCapsuleMock.getId()).thenReturn(transactionId.getBytes()); - when(transactionInfoCapsuleMock.getInstance()).thenReturn(transactionInfo); - when(trxCapMock.getInstance()).thenReturn(trxCap.getInstance()); - when(trxCapMock.validatePubSignature( - Mockito.any(AccountStore.class), - Mockito.any(DynamicPropertiesStore.class))).thenReturn(true); - when(trxCapMock.validateSignature( - Mockito.any(AccountStore.class), - Mockito.any(DynamicPropertiesStore.class))).thenReturn(true); - - doNothing().when(dbManager).validateTapos(trxCapMock); - doNothing().when(dbManager).validateCommon(trxCapMock); - doNothing().when(dbManager).validateDup(trxCapMock); - - - doNothing().when(transactionStoreMock).put(transactionId.getBytes(), trxCapMock); - doNothing().when(bandwidthProcessorMock).consume(trxCapMock, traceMock); - doNothing().when(dbManager).consumeBandwidth(trxCapMock, traceMock); - doNothing().when(balanceTraceStoreMock).initCurrentTransactionBalanceTrace(trxCapMock); - doNothing().when(balanceTraceStoreMock).updateCurrentTransactionStatus(anyString()); - doNothing().when(balanceTraceStoreMock).resetCurrentTransactionTrace(); - - - assertNotNull( - when(dbManager.processTransaction(trxCapMock, blockCapMock)).thenCallRealMethod() - ); + doReturn(true).when(trxCap).validateSignature( + any(AccountStore.class), any(DynamicPropertiesStore.class)); + doNothing().when(dbManager).validateTapos(trxCap); + doNothing().when(dbManager).validateCommon(trxCap); + doNothing().when(dbManager).validateDup(trxCap); + doNothing().when(dbManager).consumeBandwidth(eq(trxCap), any(TransactionTrace.class)); + + Assert.assertEquals(transactionInfo, dbManager.processTransaction(trxCap, blockCapMock)); + + Assert.assertEquals(1, traces.constructed().size()); + TransactionTrace trace = traces.constructed().get(0); + verify(trace).init(blockCapMock, false); + verify(trace).exec(); + verify(trace).finalization(); + verify(transactionStoreMock).put(transactionId.getBytes(), trxCap); + verify(balanceTraceStoreMock).initCurrentTransactionBalanceTrace(trxCap); + verify(balanceTraceStoreMock).updateCurrentTransactionStatus("SUCCESS"); + verify(balanceTraceStoreMock).resetCurrentTransactionTrace(); + assertTrue(trxCap.isInBlock()); + Assert.assertEquals(100L, trxCap.getOrder()); + Assert.assertNull(trxCap.getTrxTrace()); } } @@ -179,35 +150,30 @@ private void initMockEnv(Manager dbManager, long headNum, long headTime, long exitHeight, long exitCount, String blockTime) throws Exception { ChainBaseManager chainBaseManagerMock = mock(ChainBaseManager.class); - Args argsMock = mock(Args.class); - - when(Args.getInstance()).thenReturn(argsMock); + CommonParameter parameter = new CommonParameter(); + parameter.setShutdownBlockHeight(exitHeight); + parameter.setShutdownBlockCount(exitCount); + parameter.setShutdownBlockTime(blockTime == null ? null : new CronExpression(blockTime)); + when(CommonParameter.getInstance()).thenReturn(parameter); when(chainBaseManagerMock.getHeadBlockNum()).thenReturn(headNum); when(chainBaseManagerMock.getHeadBlockTimeStamp()).thenReturn(headTime); - when(argsMock.getShutdownBlockHeight()).thenReturn(exitHeight); - when(argsMock.getShutdownBlockCount()).thenReturn(exitCount); - when(argsMock.isP2pDisable()).thenReturn(false); - when(argsMock.getShutdownBlockTime()) - .thenReturn(new CronExpression(blockTime)); //"0 0 12 * * ?" - - Field field = dbManager.getClass().getDeclaredField("chainBaseManager"); + Field field = Manager.class.getDeclaredField("chainBaseManager"); field.setAccessible(true); field.set(dbManager, chainBaseManagerMock); } @Test public void testInitAutoStop() throws Exception { - Manager dbManager = spy(new Manager()); + Manager dbManager = new Manager(); try (MockedStatic methodTestMockedStatic = mockStatic(CommonParameter.class)) { initMockEnv(dbManager, 100L, 12345L, - 10L, 0L, "0 0 12 * * ?"); + 10L, -1L, null); - assertThrows( - "shutDownBlockHeight 10 is less than headNum 100", - Exception.class, + InvocationTargetException thrown = assertThrows( + InvocationTargetException.class, () -> { Method privateMethod = Manager.class.getDeclaredMethod( "initAutoStop"); @@ -215,21 +181,23 @@ public void testInitAutoStop() throws Exception { privateMethod.invoke(dbManager); } ); + Assert.assertEquals(IllegalArgumentException.class, thrown.getCause().getClass()); + Assert.assertEquals("shutDownBlockHeight 10 is less than headNum 100", + thrown.getCause().getMessage()); } } @Test public void testInitAutoStop1() throws Exception { - Manager dbManager = spy(new Manager()); + Manager dbManager = new Manager(); try (MockedStatic methodTestMockedStatic = mockStatic(CommonParameter.class)) { initMockEnv(dbManager,10L, 12345L, - 100L, 0L, "0 0 12 * * ?"); + 0L, 0L, null); - assertThrows( - "shutDownBlockCount 0 is less than 1", - Exception.class, + InvocationTargetException thrown = assertThrows( + InvocationTargetException.class, () -> { Method privateMethod = Manager.class.getDeclaredMethod( "initAutoStop"); @@ -237,20 +205,22 @@ public void testInitAutoStop1() throws Exception { privateMethod.invoke(dbManager); } ); + Assert.assertEquals(IllegalArgumentException.class, thrown.getCause().getClass()); + Assert.assertEquals("shutDownBlockCount 0 is less than 1", thrown.getCause().getMessage()); } } @Test public void testInitAutoStop2() throws Exception { - Manager dbManager = spy(new Manager()); + Manager dbManager = new Manager(); try (MockedStatic methodTestMockedStatic = mockStatic(CommonParameter.class)) { - initMockEnv(dbManager,10L, 99726143865000L, - 100L, 1L, "0 0 12 * * ?"); + // The scheduled time in 2020 has passed at this head timestamp (2021-01-01 UTC). + initMockEnv(dbManager, 10L, 1609459200000L, + 0L, -1L, "0 0 12 1 1 ? 2020"); - assertThrows( - "shutDownBlockTime 0 0 12 * * ? is illegal", - Exception.class, + InvocationTargetException thrown = assertThrows( + InvocationTargetException.class, () -> { Method privateMethod = Manager.class.getDeclaredMethod( "initAutoStop"); @@ -258,21 +228,23 @@ public void testInitAutoStop2() throws Exception { privateMethod.invoke(dbManager); } ); + Assert.assertEquals(IllegalArgumentException.class, thrown.getCause().getClass()); + Assert.assertEquals("shutDownBlockTime 0 0 12 1 1 ? 2020 is illegal", + thrown.getCause().getMessage()); } } @Test public void testInitAutoStop3() throws Exception { - Manager dbManager = spy(new Manager()); + Manager dbManager = new Manager(); try (MockedStatic methodTestMockedStatic = mockStatic(CommonParameter.class)) { initMockEnv(dbManager,10L, 12345L, - 100L, 1L, "0 0 12 * * ?"); + 100L, 1L, null); - assertThrows( - "shutDownBlockHeight 100 and shutDownBlockCount 1 set both", - Exception.class, + InvocationTargetException thrown = assertThrows( + InvocationTargetException.class, () -> { Method privateMethod = Manager.class.getDeclaredMethod( "initAutoStop"); @@ -280,21 +252,23 @@ public void testInitAutoStop3() throws Exception { privateMethod.invoke(dbManager); } ); + Assert.assertEquals(IllegalArgumentException.class, thrown.getCause().getClass()); + Assert.assertEquals("shutDownBlockHeight 100 and shutDownBlockCount 1 set both", + thrown.getCause().getMessage()); } } @Test public void testInitAutoStop4() throws Exception { - Manager dbManager = spy(new Manager()); + Manager dbManager = new Manager(); try (MockedStatic methodTestMockedStatic = mockStatic(CommonParameter.class)) { initMockEnv(dbManager, 10L, 12345L, 100L, -1L, "0 0 12 * * ?"); - assertThrows( - "shutDownBlockHeight 100 and shutDownBlockTime 0 0 12 * * ? set both", - Exception.class, + InvocationTargetException thrown = assertThrows( + InvocationTargetException.class, () -> { Method privateMethod = Manager.class.getDeclaredMethod( "initAutoStop"); @@ -302,21 +276,23 @@ public void testInitAutoStop4() throws Exception { privateMethod.invoke(dbManager); } ); + Assert.assertEquals(IllegalArgumentException.class, thrown.getCause().getClass()); + Assert.assertEquals("shutDownBlockHeight 100 and shutDownBlockTime 0 0 12 * * ? set both", + thrown.getCause().getMessage()); } } @Test public void testInitAutoStop5() throws Exception { - Manager dbManager = spy(new Manager()); + Manager dbManager = new Manager(); try (MockedStatic methodTestMockedStatic = mockStatic(CommonParameter.class)) { initMockEnv(dbManager,10L, 12345L, 0L, 1L, "0 0 12 * * ?"); - assertThrows( - "shutDownBlockCount 1 and shutDownBlockTime 0 0 12 * * ? set both", - Exception.class, + InvocationTargetException thrown = assertThrows( + InvocationTargetException.class, () -> { Method privateMethod = Manager.class.getDeclaredMethod( "initAutoStop"); @@ -324,6 +300,9 @@ public void testInitAutoStop5() throws Exception { privateMethod.invoke(dbManager); } ); + Assert.assertEquals(IllegalArgumentException.class, thrown.getCause().getClass()); + Assert.assertEquals("shutDownBlockCount 1 and shutDownBlockTime 0 0 12 * * ? set both", + thrown.getCause().getMessage()); } } @@ -722,4 +701,4 @@ private static Field findField(Class cls, String name) throws NoSuchFieldExce throw new NoSuchFieldException(name); } -} \ No newline at end of file +} diff --git a/framework/src/test/java/org/tron/core/jsonrpc/BuildTransactionTest.java b/framework/src/test/java/org/tron/core/jsonrpc/BuildTransactionTest.java index 56cfd25ae5d..4c276c9a98d 100644 --- a/framework/src/test/java/org/tron/core/jsonrpc/BuildTransactionTest.java +++ b/framework/src/test/java/org/tron/core/jsonrpc/BuildTransactionTest.java @@ -13,6 +13,7 @@ import org.tron.core.capsule.AccountCapsule; import org.tron.core.capsule.ContractCapsule; import org.tron.core.config.args.Args; +import org.tron.core.exception.jsonrpc.JsonRpcInvalidRequestException; import org.tron.core.services.jsonrpc.types.BuildArguments; import org.tron.protos.Protocol; import org.tron.protos.Protocol.Transaction.Contract.ContractType; @@ -165,16 +166,13 @@ public void testTriggerSmartContract() { } @Test - public void testNoToNoData() { + public void testTransferWithoutValueIsRejected() { BuildArguments buildArguments = new BuildArguments(); buildArguments.setFrom("0xabd4b9367799eaa3197fecb144eb71de1e049abc"); buildArguments.setTo("0x548794500882809695a8a687866e76d4271a1abc"); - try { - ContractType contractType = buildArguments.getContractType(wallet); - Assert.assertEquals(ContractType.TriggerSmartContract, contractType); - } catch (Exception e) { - Assert.assertEquals("invalid json request", e.getMessage()); - } + JsonRpcInvalidRequestException error = Assert.assertThrows(JsonRpcInvalidRequestException.class, + () -> buildArguments.getContractType(wallet)); + Assert.assertEquals("invalid json request", error.getMessage()); } -} \ No newline at end of file +} diff --git a/framework/src/test/java/org/tron/core/metrics/MetricsUtilTest.java b/framework/src/test/java/org/tron/core/metrics/MetricsUtilTest.java index 74ff6821b46..7365e3e2e47 100644 --- a/framework/src/test/java/org/tron/core/metrics/MetricsUtilTest.java +++ b/framework/src/test/java/org/tron/core/metrics/MetricsUtilTest.java @@ -1,38 +1,51 @@ package org.tron.core.metrics; +import java.util.UUID; +import org.junit.After; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; +import org.tron.common.parameter.CommonParameter; public class MetricsUtilTest { - private String test1 = "test1"; - private String test2 = "test2"; - private String test3 = "test3"; - private String test4 = "test4"; + private boolean originalMetricsEnabled; + private String key; + + @Before + public void setUp() { + originalMetricsEnabled = CommonParameter.getInstance().isNodeMetricsEnable(); + CommonParameter.getInstance().setNodeMetricsEnable(true); + key = MetricsUtilTest.class.getName() + "." + UUID.randomUUID(); + } + + @After + public void tearDown() { + CommonParameter.getInstance().setNodeMetricsEnable(originalMetricsEnabled); + } @Test public void testCounterInc() { - MetricsUtil.counterInc(test1); - //Assert - // .assertEquals(1, MetricsUtil.getCounter(test1).getCount()); + MetricsUtil.counterInc(key); + Assert.assertEquals(1, MetricsUtil.getCounter(key).getCount()); } - //@Test + @Test public void testMeterMark() { - MetricsUtil.meterMark(test2); - Assert.assertEquals(1, MetricsUtil.getMeter(test2).getCount()); + MetricsUtil.meterMark(key); + Assert.assertEquals(1, MetricsUtil.getMeter(key).getCount()); } - //@Test + @Test public void testMeterMark2() { - MetricsUtil.meterMark(test3, 1); - Assert.assertEquals(1, MetricsUtil.getMeter(test3).getCount()); + MetricsUtil.meterMark(key, 3); + Assert.assertEquals(3, MetricsUtil.getMeter(key).getCount()); } - //@Test + @Test public void testHistogramUpdate() { - MetricsUtil.histogramUpdate(test4, 1); - Assert.assertEquals(1, - MetricsUtil.getHistogram(test4).getCount()); + MetricsUtil.histogramUpdate(key, 7); + Assert.assertEquals(1, MetricsUtil.getHistogram(key).getCount()); + Assert.assertEquals(7, MetricsUtil.getHistogram(key).getSnapshot().getMax()); } } diff --git a/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java b/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java index 5c9b1d9a52c..d403016d489 100644 --- a/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java +++ b/framework/src/test/java/org/tron/core/services/filter/LiteFnQueryHttpFilterTest.java @@ -56,9 +56,9 @@ public void init() { } @Test - public void testHttpFilter() { + public void testHttpFilter() throws IOException { Set urlPathSets = LiteFnQueryHttpFilter.getFilterPaths(); - urlPathSets.forEach(urlPath -> { + for (String urlPath : urlPathSets) { if (urlPath.contains("/walletsolidity")) { fullHttpPort = Args.getInstance().getSolidityHttpPort(); } else if (urlPath.contains("/walletpbft")) { @@ -72,9 +72,13 @@ public void testHttpFilter() { Args.getInstance().setOpenHistoryQueryWhenLiteFN(false); String response = sendGetRequest(url); logger.info("response:{}", response); + // This endpoint is registered on all three services; some legacy filter paths are not. + if (urlPath.endsWith("/getblockbynum")) { + Assert.assertEquals("this API is closed because this node is a lite fullnode", response); + } // test lite fullnode with history query opened - chainBaseManager.setNodeType(FULL); + chainBaseManager.setNodeType(LITE); Args.getInstance().setOpenHistoryQueryWhenLiteFN(true); response = sendGetRequest(url); Assert.assertNotEquals("this API is closed because this node is a lite fullnode", @@ -82,32 +86,27 @@ public void testHttpFilter() { // test normal fullnode chainBaseManager.setNodeType(FULL); - Args.getInstance().setOpenHistoryQueryWhenLiteFN(true); + Args.getInstance().setOpenHistoryQueryWhenLiteFN(false); response = sendGetRequest(url); Assert.assertNotEquals("this API is closed because this node is a lite fullnode", response); - }); + } } - private String sendGetRequest(String url) { + private String sendGetRequest(String url) throws IOException { HttpGet request = new HttpGet(url); request.setHeader("User-Agent", "Java client"); - HttpResponse response; - try { - response = httpClient.execute(request); - BufferedReader rd = new BufferedReader( - new InputStreamReader(response.getEntity().getContent())); + HttpResponse response = httpClient.execute(request); + try (BufferedReader rd = new BufferedReader( + new InputStreamReader(response.getEntity().getContent()))) { StringBuilder result = new StringBuilder(); String line; while ((line = rd.readLine()) != null) { result.append(line); } return result.toString(); - } catch (IOException e) { - e.printStackTrace(); } - return null; } private String sendPostRequest(String url, String body) throws IOException { diff --git a/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java b/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java index 07821d10343..52d3a02bcb7 100644 --- a/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java +++ b/framework/src/test/java/org/tron/core/services/filter/RpcApiAccessInterceptorTest.java @@ -1,5 +1,6 @@ package org.tron.core.services.filter; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; @@ -7,6 +8,7 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; +import io.grpc.Status; import io.grpc.StatusRuntimeException; import io.grpc.stub.ServerCallStreamObserver; import java.io.IOException; @@ -120,8 +122,10 @@ public void testAccessDisabledFullNode() { Args.getInstance().setDisabledApiList(disabledApiList); final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); - assertThrows("this API is unavailable due to config", StatusRuntimeException.class, + StatusRuntimeException error = assertThrows(StatusRuntimeException.class, () -> blockingStubFull.getBlockByNum(message)); + assertEquals(Status.Code.UNAVAILABLE, error.getStatus().getCode()); + assertEquals("this API is unavailable due to config", error.getStatus().getDescription()); } @Test @@ -237,8 +241,10 @@ public void testAccessDisabledSolidityNode() { Args.getInstance().setDisabledApiList(disabledApiList); final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); - assertThrows("this API is unavailable due to config", StatusRuntimeException.class, + StatusRuntimeException error = assertThrows(StatusRuntimeException.class, () -> blockingStubSolidity.getBlockByNum(message)); + assertEquals(Status.Code.UNAVAILABLE, error.getStatus().getCode()); + assertEquals("this API is unavailable due to config", error.getStatus().getDescription()); } @Test @@ -249,8 +255,10 @@ public void testAccessDisabledPBFTNode() { Args.getInstance().setDisabledApiList(disabledApiList); final NumberMessage message = NumberMessage.newBuilder().setNum(0).build(); - assertThrows("this API is unavailable due to config", StatusRuntimeException.class, + StatusRuntimeException error = assertThrows(StatusRuntimeException.class, () -> blockingStubPBFT.getBlockByNum(message)); + assertEquals(Status.Code.UNAVAILABLE, error.getStatus().getCode()); + assertEquals("this API is unavailable due to config", error.getStatus().getDescription()); } @Test diff --git a/framework/src/test/java/org/tron/core/services/http/BroadcastServletTest.java b/framework/src/test/java/org/tron/core/services/http/BroadcastServletTest.java index d6bf3850f30..4faef09d8e8 100644 --- a/framework/src/test/java/org/tron/core/services/http/BroadcastServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/BroadcastServletTest.java @@ -1,162 +1,70 @@ package org.tron.core.services.http; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLStreamHandlerFactory; -import java.nio.charset.StandardCharsets; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import lombok.extern.slf4j.Slf4j; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import java.math.BigInteger; import org.junit.Test; -import org.tron.common.utils.FileUtil; -import org.tron.common.utils.PublicMethod; -import org.tron.core.services.http.solidity.mockito.HttpUrlStreamHandler; - -@Slf4j -public class BroadcastServletTest { - - private static HttpUrlStreamHandler httpUrlStreamHandler; - private BroadcastServlet broadcastServlet; - private HttpServletRequest request; - private HttpServletResponse response; - private HttpURLConnection httpUrlConnection; - private OutputStreamWriter outputStreamWriter; - private URL url; - - /** - * init before class. - */ - @BeforeClass - public static void init() { - // Allows for mocking URL connections - URLStreamHandlerFactory urlStreamHandlerFactory = mock(URLStreamHandlerFactory.class); - try { - URL.setURLStreamHandlerFactory(urlStreamHandlerFactory); - } catch (Error e) { - logger.info("Ignore error: {}", e.getMessage()); - } - - - httpUrlStreamHandler = new HttpUrlStreamHandler(); - given(urlStreamHandlerFactory.createURLStreamHandler("http")).willReturn(httpUrlStreamHandler); - - } - - /** - * set up. - * - */ - @Before - public void setUp() { - broadcastServlet = new BroadcastServlet(); - this.request = mock(HttpServletRequest.class); - this.response = mock(HttpServletResponse.class); - this.httpUrlConnection = mock(HttpURLConnection.class); - this.outputStreamWriter = mock(OutputStreamWriter.class); - httpUrlStreamHandler.resetConnections(); - } - - /** - * after test. - */ - @After - public void tearDown() { - if (FileUtil.deleteDir(new File("temp.txt"))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.api.GrpcAPI.Return; +import org.tron.common.crypto.ECKey; +import org.tron.common.utils.ByteArray; +import org.tron.core.actuator.TransactionFactory; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.json.JSONObject; +import org.tron.protos.Protocol.Transaction; +import org.tron.protos.Protocol.Transaction.Contract; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; +import org.tron.protos.contract.BalanceContract.TransferContract; + +public class BroadcastServletTest extends BaseHttpTest { + + private static final String RECIPIENT = "410000000000000000000000000000000000000002"; + private Transaction transaction; + private String requestBody; + private BroadcastServlet servlet; + + @Override + protected void setUpMocks() throws Exception { + TransactionFactory.register(ContractType.TransferContract, null, TransferContract.class); + servlet = new BroadcastServlet(); + injectWallet(servlet); + ECKey owner = ECKey.fromPrivate(BigInteger.ONE); + long now = System.currentTimeMillis(); + Transaction unsigned = Transaction.newBuilder() + .setRawData(Transaction.raw.newBuilder().setTimestamp(now).setExpiration(now + 60_000L) + .addContract(Contract.newBuilder() + .setType(ContractType.TransferContract) + .setParameter(Any.pack(TransferContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(owner.getAddress())) + .setToAddress(ByteString.copyFrom(ByteArray.fromHexString(RECIPIENT))) + .setAmount(1000L) + .build())))) + .build(); + TransactionCapsule capsule = new TransactionCapsule(unsigned); + capsule.sign(owner.getPrivKeyBytes()); + transaction = capsule.getInstance(); + requestBody = Util.printTransaction(transaction, false); } @Test - public void doPostTest() throws IOException { - URLStreamHandlerFactory urlStreamHandlerFactory = mock(URLStreamHandlerFactory.class); - httpUrlStreamHandler = new HttpUrlStreamHandler(); - given(urlStreamHandlerFactory.createURLStreamHandler("http")).willReturn(httpUrlStreamHandler); - - broadcastServlet = new BroadcastServlet(); - this.request = mock(HttpServletRequest.class); - this.response = mock(HttpServletResponse.class); - this.httpUrlConnection = mock(HttpURLConnection.class); - this.outputStreamWriter = mock(OutputStreamWriter.class); - httpUrlStreamHandler.resetConnections(); - - final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); - System.setOut(new PrintStream(outContent)); - String href = "http://127.0.0.1:" - + PublicMethod.chooseRandomPort() + "/wallet/broadcasttransaction"; - httpUrlStreamHandler.addConnection(new URL(href), httpUrlConnection); - httpUrlConnection.setRequestMethod("POST"); - httpUrlConnection.setRequestProperty("Content-Type", "application/json"); - httpUrlConnection.setRequestProperty("Connection", "Keep-Alive"); - httpUrlConnection.setUseCaches(false); - httpUrlConnection.setDoOutput(true); - String postData = "{\"signature\":[\"97c825b41c77de2a8bd65b3df55cd4c0df59c307c0187e" - + "42321dcc1cc455ddba583dd9502e17cfec5945b34cad0511985a6165999092a6dec84c2bdd9" - + "7e649fc01\"],\"txID\":\"454f156bf1256587ff6ccdbc56e64ad0c51e4f8efea5490dcbc7" - + "20ee606bc7b8\",\"raw_data\":{\"contract\":[{\"parame" - + "ter\":{\"value\":{\"amount\":1000,\"owner_address\":\"41e552f6" - + "487585c2b58bc2c9bb4492bc1f17132cd0\",\"to_address\":\"41d1e7a6bc354106cb410e" - + "65ff8b181c600ff14292\"},\"type_url\":\"type.googl" - + "eapis.com/protocol.TransferContract\"},\"type\":\"TransferCon" - + "tract\"}],\"ref_block_bytes\":\"267e\",\"ref_block_hash\":\"9a447d222e8" - + "de9f2\",\"expiration\":1530893064000,\"timestamp\":1530893006233}}"; - httpUrlConnection.setRequestProperty("Content-Length", String.valueOf(postData.length())); - - when(httpUrlConnection.getOutputStream()).thenReturn(outContent); - OutputStreamWriter out = new OutputStreamWriter(httpUrlConnection.getOutputStream(), - StandardCharsets.UTF_8); - out.write(postData); - out.flush(); - out.close(); - PrintWriter writer = new PrintWriter("temp.txt"); - when(response.getWriter()).thenReturn(writer); - - broadcastServlet.doPost(request, response); - // Get Response Body - String line; - StringBuilder result = new StringBuilder(); - - byte[] buffer = new byte[1024]; - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer); - when(httpUrlConnection.getInputStream()).thenReturn(byteArrayInputStream); - BufferedReader in = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream(), - StandardCharsets.UTF_8)); - - while ((line = in.readLine()) != null) { - result.append(line).append("\n"); - } - Assert.assertNotNull(result); - in.close(); - writer.flush(); - FileInputStream fileInputStream = new FileInputStream("temp.txt"); - InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); - BufferedReader bufferedReader = new BufferedReader(inputStreamReader); - - StringBuilder sb = new StringBuilder(); - String text; - while ((text = bufferedReader.readLine()) != null) { - sb.append(text); - } - Assert.assertTrue(sb.toString().contains("null")); - httpUrlConnection.disconnect(); + public void testPostReturnsBroadcastResultAndTransactionId() throws Exception { + when(wallet.broadcastTransaction(eq(transaction))) + .thenReturn(Return.newBuilder().setResult(true).build()); + + MockHttpServletResponse response = newResponse(); + servlet.doPost(postRequest(requestBody), response); + + verify(wallet).broadcastTransaction(eq(transaction)); + JSONObject result = JSONObject.parseObject(response.getContentAsString()); + assertEquals(Boolean.TRUE, result.getBoolean("result")); + assertEquals(new TransactionCapsule(transaction).getTransactionId().toString(), + result.getString("txid")); + assertFalse(result.containsKey("Error")); } -} \ No newline at end of file +} diff --git a/framework/src/test/java/org/tron/core/services/http/GetAssetIssueListByNameServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetAssetIssueListByNameServletTest.java index e3055e21f99..44e3fbc125c 100644 --- a/framework/src/test/java/org/tron/core/services/http/GetAssetIssueListByNameServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/GetAssetIssueListByNameServletTest.java @@ -1,7 +1,6 @@ package org.tron.core.services.http; import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -10,6 +9,7 @@ import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.api.GrpcAPI.AssetIssueList; import org.tron.common.utils.ByteArray; public class GetAssetIssueListByNameServletTest extends BaseHttpTest { @@ -21,11 +21,13 @@ public class GetAssetIssueListByNameServletTest extends BaseHttpTest { protected void setUpMocks() throws Exception { servlet = new GetAssetIssueListByNameServlet(); injectWallet(servlet); - when(wallet.getAssetIssueListByName(any())).thenReturn(null); + // A nonempty name with no matches returns an empty list, not null. + when(wallet.getAssetIssueListByName(eq(data))) + .thenReturn(AssetIssueList.getDefaultInstance()); } @Test - public void testPost() throws Exception { + public void testPostNoMatchingAssets() throws Exception { String jsonParam = "{\"value\": \"74657374\"}"; MockHttpServletRequest request = postRequest(jsonParam); @@ -36,7 +38,7 @@ public void testPost() throws Exception { } @Test - public void testGet() throws Exception { + public void testGetNoMatchingAssets() throws Exception { MockHttpServletRequest request = getRequest("value", "74657374"); MockHttpServletResponse response = newResponse(); diff --git a/framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java index 2ddfda17bef..6113cda7252 100644 --- a/framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/GetBandwidthPricesServletTest.java @@ -31,7 +31,7 @@ public static void init() { public void testGet() { MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); MockHttpServletResponse response = new MockHttpServletResponse(); - getBandwidthPricesServlet.doPost(request, response); + getBandwidthPricesServlet.doGet(request, response); try { String contentAsString = response.getContentAsString(); JSONObject result = JSONObject.parseObject(contentAsString); diff --git a/framework/src/test/java/org/tron/core/services/http/GetBlockByNumServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetBlockByNumServletTest.java index b28e1d33308..88a82b79016 100644 --- a/framework/src/test/java/org/tron/core/services/http/GetBlockByNumServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/GetBlockByNumServletTest.java @@ -1,16 +1,22 @@ package org.tron.core.services.http; -import static org.junit.Assert.assertTrue; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.tron.common.utils.client.utils.HttpMethed.createRequest; -import java.io.UnsupportedEncodingException; +import com.google.protobuf.ByteString; import javax.annotation.Resource; +import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; +import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.tron.common.BaseTest; import org.tron.common.TestConstants; +import org.tron.common.utils.Sha256Hash; +import org.tron.core.capsule.BlockCapsule; import org.tron.core.config.args.Args; import org.tron.json.JSONObject; @@ -19,6 +25,8 @@ public class GetBlockByNumServletTest extends BaseTest { @Resource private GetBlockByNumServlet getBlockByNumServlet; + private BlockCapsule block; + static { Args.setParam( new String[]{ @@ -27,41 +35,42 @@ public class GetBlockByNumServletTest extends BaseTest { ); } + @Before + public void initBlock() { + block = new BlockCapsule(1, Sha256Hash.ZERO_HASH, 123L, + ByteString.copyFrom(new byte[21])); + chainBaseManager.getBlockIndexStore().put(block.getBlockId()); + chainBaseManager.getBlockStore().put(block.getBlockId().getBytes(), block); + } + @Test - public void testGetBlockByNum() { - String jsonParam = "{\"number\": 1}"; + public void testGetBlockByNum() throws Exception { + String jsonParam = "{\"num\": 1}"; MockHttpServletRequest request = createRequest(HttpPost.METHOD_NAME); request.setContentType("application/json"); - request.setContent(jsonParam.getBytes()); + request.setContent(jsonParam.getBytes(UTF_8)); MockHttpServletResponse response = new MockHttpServletResponse(); - try { - getBlockByNumServlet.doPost(request, response); - String contentAsString = response.getContentAsString(); - JSONObject result = JSONObject.parseObject(contentAsString); - assertTrue(result.containsKey("blockID")); - assertTrue(result.containsKey("transactions")); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } + getBlockByNumServlet.doPost(request, response); + assertRequestedBlock(response); } @Test - public void testGet() { - String jsonParam = "{\"number\": 1}"; - MockHttpServletRequest request = createRequest("application/json"); - request.setContent(jsonParam.getBytes()); + public void testGet() throws Exception { + MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); + request.addParameter("num", "1"); MockHttpServletResponse response = new MockHttpServletResponse(); - try { - getBlockByNumServlet.doPost(request, response); - String contentAsString = response.getContentAsString(); - JSONObject result = JSONObject.parseObject(contentAsString); - assertTrue(result.containsKey("blockID")); - assertTrue(result.containsKey("transactions")); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } + getBlockByNumServlet.doGet(request, response); + assertRequestedBlock(response); } + private void assertRequestedBlock(MockHttpServletResponse response) throws Exception { + assertEquals(200, response.getStatus()); + JSONObject result = JSONObject.parseObject(response.getContentAsString()); + assertEquals(block.getBlockId().toString(), result.getString("blockID")); + assertEquals(1L, result.getJSONObject("block_header").getJSONObject("raw_data") + .getLongValue("number")); + assertFalse("An empty block omits transactions", result.containsKey("transactions")); + } } diff --git a/framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java index f0fe69fe450..28b13a11405 100644 --- a/framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/GetEnergyPricesServletTest.java @@ -31,7 +31,7 @@ public static void init() { public void testGet() { MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); MockHttpServletResponse response = new MockHttpServletResponse(); - getEnergyPricesServlet.doPost(request, response); + getEnergyPricesServlet.doGet(request, response); try { String contentAsString = response.getContentAsString(); JSONObject result = JSONObject.parseObject(contentAsString); diff --git a/framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java index b9440aa948f..d8e961303ba 100644 --- a/framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/GetMemoFeePricesServletTest.java @@ -31,7 +31,7 @@ public static void init() { public void testGet() { MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); MockHttpServletResponse response = new MockHttpServletResponse(); - getMemoFeePricesServlet.doPost(request, response); + getMemoFeePricesServlet.doGet(request, response); try { String contentAsString = response.getContentAsString(); JSONObject result = JSONObject.parseObject(contentAsString); diff --git a/framework/src/test/java/org/tron/core/services/http/GetTransactionListFromPendingServletTest.java b/framework/src/test/java/org/tron/core/services/http/GetTransactionListFromPendingServletTest.java index 52277992850..3fcb7032f2e 100644 --- a/framework/src/test/java/org/tron/core/services/http/GetTransactionListFromPendingServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/GetTransactionListFromPendingServletTest.java @@ -31,7 +31,7 @@ public class GetTransactionListFromPendingServletTest extends BaseTest { public void testGet() { MockHttpServletRequest request = createRequest(HttpGet.METHOD_NAME); MockHttpServletResponse response = new MockHttpServletResponse(); - getTransactionListFromPendingServlet.doPost(request, response); + getTransactionListFromPendingServlet.doGet(request, response); assertEquals(200, response.getStatus()); } diff --git a/framework/src/test/java/org/tron/core/services/http/UtilMockTest.java b/framework/src/test/java/org/tron/core/services/http/UtilMockTest.java index d4124c90adf..35e8dbf7019 100644 --- a/framework/src/test/java/org/tron/core/services/http/UtilMockTest.java +++ b/framework/src/test/java/org/tron/core/services/http/UtilMockTest.java @@ -334,7 +334,12 @@ public void testConvertLogAddressToTronAddress() { .addAllLog(logs); List logList = Util.convertLogAddressToTronAddress(builder.build()); - Assert.assertNotNull(logList.size() > 0); + Assert.assertEquals(1, logList.size()); + Assert.assertArrayEquals( + ByteArray.fromHexString("410000000000000000000000000061646472657373"), + logList.get(0).getAddress().toByteArray()); + Assert.assertEquals(logs.get(0).getData(), logList.get(0).getData()); + Assert.assertEquals(logs.get(0).getTopicsList(), logList.get(0).getTopicsList()); } @Test diff --git a/framework/src/test/java/org/tron/core/services/http/solidity/GetTransactionByIdSolidityServletTest.java b/framework/src/test/java/org/tron/core/services/http/solidity/GetTransactionByIdSolidityServletTest.java index e1abb41d1e1..0f6ef605de6 100644 --- a/framework/src/test/java/org/tron/core/services/http/solidity/GetTransactionByIdSolidityServletTest.java +++ b/framework/src/test/java/org/tron/core/services/http/solidity/GetTransactionByIdSolidityServletTest.java @@ -1,202 +1,81 @@ package org.tron.core.services.http.solidity; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLStreamHandlerFactory; -import java.nio.charset.StandardCharsets; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import lombok.extern.slf4j.Slf4j; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; import org.junit.Test; -import org.tron.common.utils.FileUtil; -import org.tron.common.utils.PublicMethod; -import org.tron.core.services.http.solidity.mockito.HttpUrlStreamHandler; - - -@Slf4j -public class GetTransactionByIdSolidityServletTest { - - private static HttpUrlStreamHandler httpUrlStreamHandler; - private GetTransactionByIdSolidityServlet getTransactionByIdSolidityServlet; - private HttpServletRequest request; - private HttpServletResponse response; - private HttpURLConnection httpUrlConnection; - private OutputStreamWriter outputStreamWriter; - private URL url; - - /** - * . - */ - @BeforeClass - public static void init() { - // Allows for mocking URL connections - URLStreamHandlerFactory urlStreamHandlerFactory = mock(URLStreamHandlerFactory.class); - try { - URL.setURLStreamHandlerFactory(urlStreamHandlerFactory); - } catch (Error e) { - logger.info("Ignore error: {}", e.getMessage()); - } - - httpUrlStreamHandler = new HttpUrlStreamHandler(); - given(urlStreamHandlerFactory.createURLStreamHandler("http")).willReturn(httpUrlStreamHandler); - } - - /** - * Init. - */ - - @Before - public void setUp() { - getTransactionByIdSolidityServlet = new GetTransactionByIdSolidityServlet(); - this.request = mock(HttpServletRequest.class); - this.response = mock(HttpServletResponse.class); - this.httpUrlConnection = mock(HttpURLConnection.class); - this.outputStreamWriter = mock(OutputStreamWriter.class); - httpUrlStreamHandler.resetConnections(); - } - - /** - * Release Resource. - */ - @After - public void tearDown() { - if (FileUtil.deleteDir(new File("temp.txt"))) { - logger.info("Release resources successful."); - } else { - logger.info("Release resources failure."); - } +import org.springframework.mock.web.MockHttpServletResponse; +import org.tron.common.utils.ByteArray; +import org.tron.core.actuator.TransactionFactory; +import org.tron.core.capsule.TransactionCapsule; +import org.tron.core.services.http.BaseHttpTest; +import org.tron.json.JSONObject; +import org.tron.protos.Protocol.Transaction; +import org.tron.protos.Protocol.Transaction.Contract; +import org.tron.protos.Protocol.Transaction.Contract.ContractType; +import org.tron.protos.contract.BalanceContract.TransferContract; + +public class GetTransactionByIdSolidityServletTest extends BaseHttpTest { + + private final Transaction transaction = Transaction.newBuilder() + .setRawData(Transaction.raw.newBuilder().addContract(Contract.newBuilder() + .setType(ContractType.TransferContract) + .setParameter(Any.pack(TransferContract.newBuilder() + .setOwnerAddress(ByteString.copyFrom(ByteArray.fromHexString( + "410000000000000000000000000000000000000001"))) + .setToAddress(ByteString.copyFrom(ByteArray.fromHexString( + "410000000000000000000000000000000000000002"))) + .setAmount(1000L) + .build())))) + .build(); + private final ByteString transactionId = new TransactionCapsule(transaction) + .getTransactionId().getByteString(); + private final String transactionIdHex = ByteArray.toHexString(transactionId.toByteArray()); + + private GetTransactionByIdSolidityServlet servlet; + + @Override + protected void setUpMocks() throws Exception { + TransactionFactory.register(ContractType.TransferContract, null, TransferContract.class); + servlet = new GetTransactionByIdSolidityServlet(); + injectWallet(servlet); } @Test - public void doPostTest() throws IOException { + public void testPostReturnsTransactionWhenFound() throws Exception { + when(wallet.getTransactionById(eq(transactionId))).thenReturn(transaction); + MockHttpServletResponse response = newResponse(); - //send Post request + servlet.doPost(postRequest("{\"value\":\"" + transactionIdHex + "\"}"), response); - final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); - System.setOut(new PrintStream(outContent)); - String href = "http://127.0.0.1:" - + PublicMethod.chooseRandomPort() + "/walletsolidity/gettransactioninfobyid"; - httpUrlStreamHandler.addConnection(new URL(href), httpUrlConnection); - httpUrlConnection.setRequestMethod("POST"); - httpUrlConnection.setRequestProperty("Content-Type", "application/json"); - httpUrlConnection.setRequestProperty("Connection", "Keep-Alive"); - httpUrlConnection.setUseCaches(false); - httpUrlConnection.setDoOutput(true); - String postData = "{\"value\": \"309b6fa3d01353e46f57dd8a8f27611f98e392b50d035cef21" - + "3f2c55225a8bd2\"}"; - httpUrlConnection.setRequestProperty("Content-Length", String.valueOf(postData.length())); - - when(httpUrlConnection.getOutputStream()).thenReturn(outContent); - OutputStreamWriter out = new OutputStreamWriter(httpUrlConnection.getOutputStream(), - StandardCharsets.UTF_8); - out.write(postData); - out.flush(); - out.close(); - PrintWriter writer = new PrintWriter("temp.txt"); - when(response.getWriter()).thenReturn(writer); - - getTransactionByIdSolidityServlet.doPost(request, response); - // Get Response Body - String line; - StringBuilder result = new StringBuilder(); - - byte[] buffer = new byte[1024]; - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer); - when(httpUrlConnection.getInputStream()).thenReturn(byteArrayInputStream); - BufferedReader in = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream(), - StandardCharsets.UTF_8)); - - while ((line = in.readLine()) != null) { - result.append(line).append("\n"); - } - Assert.assertNotNull(result); - in.close(); - writer.flush(); - FileInputStream fileInputStream = new FileInputStream("temp.txt"); - InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); - BufferedReader bufferedReader = new BufferedReader(inputStreamReader); - - StringBuilder sb = new StringBuilder(); - String text; - while ((text = bufferedReader.readLine()) != null) { - sb.append(text); - } - Assert.assertTrue(sb.toString().contains("null")); - httpUrlConnection.disconnect(); + verify(wallet).getTransactionById(eq(transactionId)); + assertTransaction(response); } @Test - public void doGetTest() throws IOException { + public void testGetReturnsTransactionWhenFound() throws Exception { + when(wallet.getTransactionById(eq(transactionId))).thenReturn(transaction); + MockHttpServletResponse response = newResponse(); - final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); - System.setOut(new PrintStream(outContent)); - String href = "http://127.0.0.1:" - + PublicMethod.chooseRandomPort() + "/walletsolidity/gettransactioninfobyid"; - httpUrlStreamHandler.addConnection(new URL(href), httpUrlConnection); - httpUrlConnection.setRequestMethod("GET"); - httpUrlConnection.setRequestProperty("Content-Type", "application/json"); - httpUrlConnection.setRequestProperty("Connection", "Keep-Alive"); - httpUrlConnection.setUseCaches(false); - httpUrlConnection.setDoOutput(true); - String postData = "{\"value\": \"309b6fa3d01353e46f57dd8a8f27611f98e392b50d035cef21" - + "3f2c55225a8bd2\"}"; - httpUrlConnection.setRequestProperty("Content-Length", String.valueOf(postData.length())); + servlet.doGet(getRequest("value", transactionIdHex), response); - when(httpUrlConnection.getOutputStream()).thenReturn(outContent); - OutputStreamWriter out = new OutputStreamWriter(httpUrlConnection.getOutputStream(), - StandardCharsets.UTF_8); - out.write(postData); - out.flush(); - out.close(); - PrintWriter writer = new PrintWriter("temp.txt"); - when(response.getWriter()).thenReturn(writer); - - getTransactionByIdSolidityServlet.doPost(request, response); - // Get Response Body - String line; - StringBuilder result = new StringBuilder(); - - byte[] buffer = new byte[1024]; - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer); - when(httpUrlConnection.getInputStream()).thenReturn(byteArrayInputStream); - BufferedReader in = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream(), - StandardCharsets.UTF_8)); - - while ((line = in.readLine()) != null) { - result.append(line).append("\n"); - } - Assert.assertNotNull(result); - in.close(); - writer.flush(); - FileInputStream fileInputStream = new FileInputStream("temp.txt"); - InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); - BufferedReader bufferedReader = new BufferedReader(inputStreamReader); + verify(wallet).getTransactionById(eq(transactionId)); + assertTransaction(response); + } - StringBuilder sb = new StringBuilder(); - String text; - while ((text = bufferedReader.readLine()) != null) { - sb.append(text); - } - Assert.assertTrue(sb.toString().contains("null")); - httpUrlConnection.disconnect(); + private void assertTransaction(MockHttpServletResponse response) throws Exception { + JSONObject result = JSONObject.parseObject(response.getContentAsString()); + assertFalse(result.containsKey("Error")); + assertEquals(transactionIdHex, result.getString("txID")); + JSONObject contract = result.getJSONObject("raw_data").getJSONArray("contract") + .getJSONObject(0); + assertEquals("TransferContract", contract.getString("type")); + assertEquals(1000L, contract.getJSONObject("parameter").getJSONObject("value") + .getLongValue("amount")); } } - diff --git a/framework/src/test/java/org/tron/core/services/jsonrpc/JsonRpcServletTest.java b/framework/src/test/java/org/tron/core/services/jsonrpc/JsonRpcServletTest.java index d6c843b5aea..c34e35e1934 100644 --- a/framework/src/test/java/org/tron/core/services/jsonrpc/JsonRpcServletTest.java +++ b/framework/src/test/java/org/tron/core/services/jsonrpc/JsonRpcServletTest.java @@ -9,6 +9,9 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -41,9 +44,7 @@ public class JsonRpcServletTest { public void setUp() throws Exception { servlet = new TestableServlet(); mockRpcServer = mock(JsonRpcServer.class); - Field f = JsonRpcServlet.class.getDeclaredField("rpcServer"); - f.setAccessible(true); - f.set(servlet, mockRpcServer); + setRpcServer(mockRpcServer); savedMaxBatchSize = CommonParameter.getInstance().jsonRpcMaxBatchSize; savedMaxResponseSize = CommonParameter.getInstance().jsonRpcMaxResponseSize; } @@ -93,20 +94,20 @@ public void batchExceedsLimit_returnsExceedLimitAsArray() throws Exception { @Test public void batchWithinLimit_proceedsToRpcServer() throws Exception { CommonParameter.getInstance().jsonRpcMaxBatchSize = 5; - byte[] singleResp = "{\"jsonrpc\":\"2.0\",\"result\":\"ok\",\"id\":1}" - .getBytes(StandardCharsets.UTF_8); - doAnswer(inv -> { - OutputStream out = inv.getArgument(1); - out.write(singleResp); - return 0; - }).when(mockRpcServer).handleRequest(any(InputStream.class), any(OutputStream.class)); + TronJsonRpc rpc = useRealRpcServer(); - MockHttpServletResponse resp = doPost("[{\"id\":1},{\"id\":2}]"); + MockHttpServletResponse resp = doPost("[" + + "{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"id\":1}," + + "{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"id\":2}]"); assertEquals(200, resp.getStatus()); JsonNode body = MAPPER.readTree(resp.getContentAsByteArray()); assertTrue("batch response must be a JSON array", body.isArray()); assertEquals("each sub-request must produce a response", 2, body.size()); - assertEquals("ok", body.get(0).get("result").asText()); + assertEquals("0x1", body.get(0).get("result").asText()); + assertEquals("0x1", body.get(1).get("result").asText()); + assertEquals(1, body.get(0).get("id").asInt()); + assertEquals(2, body.get(1).get("id").asInt()); + verify(rpc, times(2)).getLatestBlockNum(); } @Test @@ -123,16 +124,14 @@ public void emptyBatch_returnsInvalidRequest() throws Exception { @Test public void batchLimitDisabled_largeBatchAllowed() throws Exception { CommonParameter.getInstance().jsonRpcMaxBatchSize = 0; - // write nothing — simulates notifications (no response expected) - doAnswer(inv -> 0).when(mockRpcServer) - .handleRequest(any(InputStream.class), any(OutputStream.class)); + TronJsonRpc rpc = useRealRpcServer(); StringBuilder sb = new StringBuilder("["); for (int i = 0; i < 500; i++) { if (i > 0) { sb.append(','); } - sb.append("{}"); + sb.append("{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\"}"); } sb.append("]"); MockHttpServletResponse resp = doPost(sb.toString()); @@ -140,6 +139,7 @@ public void batchLimitDisabled_largeBatchAllowed() throws Exception { assertEquals("all-notification batch must return empty body per JSON-RPC 2.0 §6", 0, resp.getContentLength()); assertEquals("", resp.getContentAsString()); + verify(rpc, times(500)).getLatestBlockNum(); } // --- rpcServer.handle exceptions --- @@ -195,7 +195,8 @@ public void batchResponseTooLarge_returnsErrorArray() throws Exception { return 0; }).when(mockRpcServer).handleRequest(any(InputStream.class), any(OutputStream.class)); - MockHttpServletResponse resp = doPost("[{\"method\":\"eth_getLogs\"}]"); + MockHttpServletResponse resp = doPost( + "[{\"jsonrpc\":\"2.0\",\"method\":\"eth_getLogs\",\"id\":1}]"); assertEquals(200, resp.getStatus()); JsonNode body = MAPPER.readTree(resp.getContentAsString()); assertTrue("batch response-too-large must be an array", body.isArray()); @@ -273,14 +274,14 @@ public void batchResponse_contentTypeIsApplicationJsonRpc() throws Exception { @Test public void allNotificationBatch_contentTypeIsApplicationJsonRpc() throws Exception { - // notification: rpcServer returns 0 bytes → empty batchResult → early return path - doAnswer(inv -> 0).when(mockRpcServer) - .handleRequest(any(InputStream.class), any(OutputStream.class)); + TronJsonRpc rpc = useRealRpcServer(); - MockHttpServletResponse resp = doPost("[{\"method\":\"eth_blockNumber\"}]"); + MockHttpServletResponse resp = doPost( + "[{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\"}]"); assertEquals(200, resp.getStatus()); assertEquals(0, resp.getContentLength()); assertEquals("application/json-rpc", resp.getContentType()); + verify(rpc).getLatestBlockNum(); } // --- Primitive root node → Invalid Request (-32600), id must be JSON null --- @@ -417,6 +418,19 @@ public void tooManyTokens_returnsParseError() throws Exception { // --- helpers --- + private void setRpcServer(JsonRpcServer server) throws Exception { + Field f = JsonRpcServlet.class.getDeclaredField("rpcServer"); + f.setAccessible(true); + f.set(servlet, server); + } + + private TronJsonRpc useRealRpcServer() throws Exception { + TronJsonRpc rpc = mock(TronJsonRpc.class); + when(rpc.getLatestBlockNum()).thenReturn("0x1"); + setRpcServer(new JsonRpcServer(rpc, TronJsonRpc.class)); + return rpc; + } + private MockHttpServletResponse doPost(String body) throws Exception { MockHttpServletRequest req = new MockHttpServletRequest("POST", "/jsonrpc"); req.setContent(body.getBytes(StandardCharsets.UTF_8));