Skip to content

Commit

Permalink
Adding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nagarev committed Feb 9, 2022
1 parent f931ab4 commit 62e2d42
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public JsonNode traceTransaction(String transactionHash, Map<String, String> tra

TraceOptions options = new TraceOptions(traceOptions);

if (options.getUnsupportedOptions().size() > 0) {
if (!options.getUnsupportedOptions().isEmpty()) {
// TODO: implement the logic that takes into account the remaining trace options.
logger.warn(
"Received {} unsupported trace options.",
Expand Down Expand Up @@ -102,7 +102,7 @@ public JsonNode traceBlock(String blockHash, Map<String, String> traceOptions) {

TraceOptions options = new TraceOptions(traceOptions);

if (options.getUnsupportedOptions().size() > 0) {
if (!options.getUnsupportedOptions().isEmpty()) {
// TODO: implement the logic that takes into account the remaining trace options.
logger.warn(
"Received {} unsupported trace options.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* This file is part of RskJ
* Copyright (C) 2017 RSK Labs Ltd.
* (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package co.rsk.rpc.modules.debug;

public enum DisableOption {
DISABLE_MEMORY("disableMemory", "memory"),
DISABLE_STACK("disableStack", "stack"),
DISABLE_STORAGE("disableStorage", "storage");

public final String option;
public final String value;

DisableOption(String option, String value) {
this.option = option;
this.value = value;
}
}
55 changes: 29 additions & 26 deletions rskj-core/src/main/java/co/rsk/rpc/modules/debug/TraceOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,46 +20,49 @@
package co.rsk.rpc.modules.debug;

import java.util.*;
import java.util.stream.Collectors;

public class TraceOptions {

private Set<String> disabledFields;
private Set<String> unsupportedOptions;
private final List<String> supportedOptions;
private final Set<String> disabledFields;
private final Set<String> unsupportedOptions;

private TraceOptions() {}
public TraceOptions() {
supportedOptions = Arrays.stream(DisableOption.values()).map(option -> option.option)
.collect(Collectors.toList());

this.disabledFields = new HashSet<>();
this.unsupportedOptions = new HashSet<>();
}

public TraceOptions(Map<String, String> traceOptions) {
disabledFields = new HashSet<>();
unsupportedOptions = new HashSet<>();
if (traceOptions != null) {
if (traceOptions.containsKey("disableStorage")) {
if (Boolean.parseBoolean(traceOptions.get("disableStorage"))) {
disabledFields.add("storage");
}
traceOptions.remove("disableStorage");
}
if (traceOptions.containsKey("disableMemory")) {
if (Boolean.parseBoolean(traceOptions.get("disableMemory"))) {
disabledFields.add("memory");
}
traceOptions.remove("disableMemory");
}
if (traceOptions.containsKey("disableStack")) {
if (Boolean.parseBoolean(traceOptions.get("disableStack"))) {
disabledFields.add("stack");
}
traceOptions.remove("disableStack");
this();

if (traceOptions == null || traceOptions.isEmpty()) return;

// Disabled Fields Parsing

for (DisableOption disableOption : DisableOption.values()) {
if (Boolean.parseBoolean(traceOptions.get(disableOption.option))) {
this.disabledFields.add(disableOption.value);
}
unsupportedOptions = traceOptions.keySet();
}

// Unsupported Options

traceOptions.keySet()
.stream()
.filter(key -> supportedOptions.stream().noneMatch(option -> option.equals(key)))
.forEach(unsupportedOptions::add);
}

public Set<String> getDisabledFields() {
return disabledFields;
return Collections.unmodifiableSet(disabledFields);
}

public Set<String> getUnsupportedOptions() {
return unsupportedOptions;
return Collections.unmodifiableSet(unsupportedOptions);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,15 @@
*/
public class ProgramTraceProcessor {

private static final ObjectMapper OBJECT_MAPPER = makeObjectMapper();

private final Map<Keccak256, ProgramTrace> traces = new HashMap<>();

private TraceOptions traceOptions;
private final TraceOptions traceOptions;

public ProgramTraceProcessor() {
traceOptions = new TraceOptions(Collections.emptyMap());
traceOptions = new TraceOptions();
}

public ProgramTraceProcessor(TraceOptions options) {
this();
traceOptions = options;
}

Expand All @@ -68,7 +65,7 @@ public JsonNode getProgramTracesAsJsonNode(List<Keccak256> txHashes) {
filterProvider.addFilter("opFilter",
SimpleBeanPropertyFilter.serializeAllExcept(traceOptions.getDisabledFields()));

return OBJECT_MAPPER.setFilterProvider(filterProvider).valueToTree(txTraces);
return makeObjectMapper().setFilterProvider(filterProvider).valueToTree(txTraces);
}

public JsonNode getProgramTraceAsJsonNode(Keccak256 txHash) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package co.rsk.rpc.modules.debug;

import co.rsk.net.MessageHandler;
Expand All @@ -36,8 +37,9 @@
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import static org.ethereum.rpc.TypeConverter.stringHexToByteArray;
Expand All @@ -52,7 +54,7 @@ public class DebugModuleImplTest {
private DebugModuleImpl debugModule;

@Before
public void setup(){
public void setup() {
blockStore = Web3Mocks.getMockBlockStore();
receiptStore = Web3Mocks.getMockReceiptStore();
messageHandler = Web3Mocks.getMockMessageHandler();
Expand All @@ -61,7 +63,7 @@ public void setup(){
}

@Test
public void debug_wireProtocolQueueSize_basic() throws IOException {
public void debug_wireProtocolQueueSize_basic() {
String result = debugModule.wireProtocolQueueSize();
try {
TypeConverter.JSonHexToLong(result);
Expand All @@ -71,7 +73,7 @@ public void debug_wireProtocolQueueSize_basic() throws IOException {
}

@Test
public void debug_wireProtocolQueueSize_value() throws IOException {
public void debug_wireProtocolQueueSize_value() {
when(messageHandler.getMessageQueueSize()).thenReturn(5L);
String result = debugModule.wireProtocolQueueSize();
try {
Expand All @@ -83,7 +85,7 @@ public void debug_wireProtocolQueueSize_value() throws IOException {
}

@Test
public void debug_traceTransaction_retrieveUnknownTransactionAsNull() throws Exception {
public void debug_traceTransaction_retrieveUnknownTransactionAsNull() {
byte[] hash = stringHexToByteArray("0x00");
when(receiptStore.getInMainChain(hash, blockStore)).thenReturn(Optional.empty());

Expand Down Expand Up @@ -212,13 +214,16 @@ public void debug_traceTransaction_retrieveSimpleAccountTransferWithTraceOptions

Assert.assertEquals(resultWithNoOptions, resultWithEmptyOptions);

JsonNode resultWithNonEmptyOptions = debugModule.traceTransaction(transaction.getHash().toJsonString(), Collections.singletonMap("disableStorage", "true"));
Map<String, String> traceOptions = new HashMap<>();
traceOptions.put("disableStorage", "true");

JsonNode resultWithNonEmptyOptions = debugModule.traceTransaction(transaction.getHash().toJsonString(), traceOptions);

Assert.assertEquals(resultWithNoOptions, resultWithNonEmptyOptions);
}

@Test
public void debug_traceBlock_retrieveUnknownBlockAsNull() throws Exception {
public void debug_traceBlock_retrieveUnknownBlockAsNull() {
byte[] hash = stringHexToByteArray("0x00");
when(blockStore.getBlockByHash(hash)).thenReturn(null);

Expand Down Expand Up @@ -256,4 +261,58 @@ public void debug_traceBlock_retrieveSimpleContractsCreationTrace() throws Excep
Assert.assertTrue(structLogs.size() > 0);
});
}

@Test
public void debug_traceTransaction_retrieveSimpleContractInvocationTrace_traceOptions_disableAllFields_OK() throws Exception {
DslParser parser = DslParser.fromResource("dsl/contracts02.txt");
ReceiptStore receiptStore = new ReceiptStoreImpl(new HashMapDB());
World world = new World(receiptStore);

WorldDslProcessor processor = new WorldDslProcessor(world);
processor.processCommands(parser);

Transaction transaction = world.getTransactionByName("tx02");

DebugModuleImpl debugModule = new DebugModuleImpl(world.getBlockStore(), receiptStore, messageHandler, world.getBlockExecutor());

Map<String, String> traceOptions = new HashMap<>();
traceOptions.put("disableStack", "true");
traceOptions.put("disableMemory", "true");
traceOptions.put("disableStorage", "true");

JsonNode witnessResult = debugModule.traceTransaction(transaction.getHash().toJsonString(), null);
JsonNode result = debugModule.traceTransaction(transaction.getHash().toJsonString(), traceOptions);

// Sanity Check

Assert.assertNotNull(witnessResult);
Assert.assertTrue(witnessResult.isObject());

ObjectNode oWitnessResult = (ObjectNode) witnessResult;
Assert.assertTrue(oWitnessResult.get("error").textValue().isEmpty());
Assert.assertTrue(oWitnessResult.get("result").textValue().isEmpty());
JsonNode witnessStructLogs = oWitnessResult.get("structLogs");
Assert.assertTrue(witnessStructLogs.isArray());
Assert.assertTrue(witnessStructLogs.size() > 0);

Assert.assertNotNull(result);
Assert.assertTrue(result.isObject());

ObjectNode oResult = (ObjectNode) result;
Assert.assertTrue(oResult.get("error").textValue().isEmpty());
Assert.assertTrue(oResult.get("result").textValue().isEmpty());
JsonNode structLogs = oResult.get("structLogs");
Assert.assertTrue(structLogs.isArray());
Assert.assertTrue(structLogs.size() > 0);

// Check Filters

Assert.assertNotEquals(witnessResult, result);
Assert.assertFalse(witnessStructLogs.findValues("stack").isEmpty());
Assert.assertFalse(witnessStructLogs.findValues("memory").isEmpty());
Assert.assertFalse(witnessStructLogs.findValues("storage").isEmpty());
Assert.assertTrue(structLogs.findValues("stack").isEmpty());
Assert.assertTrue(structLogs.findValues("memory").isEmpty());
Assert.assertTrue(structLogs.findValues("storage").isEmpty());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.junit.Assert;
import org.junit.Test;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -91,6 +92,16 @@ public void testTraceOptions_nullTraceOptionsGiven_disabledFieldsAndUnsupportedO
Assert.assertEquals(0, options.getUnsupportedOptions().size());
}

@Test
public void testTraceOptions_emptyTraceOptionsGiven_disabledFieldsAndUnsupportedOptionsShouldReturnEmptySet() {
// When
TraceOptions options = new TraceOptions(Collections.emptyMap());

// Then
Assert.assertEquals(0, options.getDisabledFields().size());
Assert.assertEquals(0, options.getUnsupportedOptions().size());
}

@Test
public void testTraceOptions_unsupportedOptionsGiven_unsupportedOptionsShouldReturnAllOfThem() {
// Given
Expand Down

0 comments on commit 62e2d42

Please sign in to comment.