Skip to content

Commit 4e22df4

Browse files
committed
nethtest: add --stateTest, --engineTest, --jsonout, --workers flags
1 parent 568a061 commit 4e22df4

File tree

5 files changed

+197
-61
lines changed

5 files changed

+197
-61
lines changed

src/Nethermind/Ethereum.Test.Base/BlockchainTestBase.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -351,16 +351,20 @@ private async static Task RunNewPayloads(TestEngineNewPayloadsJson[]? newPayload
351351
// RPC-level errors (e.g. wrong payload version) are valid for negative tests
352352
if (npResponse is JsonRpcErrorResponse errorResponse)
353353
{
354-
Assert.That(validationError, Is.Not.Null,
355-
$"engine_newPayloadV{newPayloadVersion} RPC error: {errorResponse.Error?.Code} {errorResponse.Error?.Message}");
354+
if (validationError is null)
355+
throw new Exception(
356+
$"engine_newPayloadV{newPayloadVersion} unexpected RPC error: {errorResponse.Error?.Code} {errorResponse.Error?.Message}");
356357
continue;
357358
}
358359

359360
PayloadStatusV1 payloadStatus = (PayloadStatusV1)((JsonRpcSuccessResponse)npResponse).Result!;
360361
string expectedStatus = validationError is null ? PayloadStatus.Valid : PayloadStatus.Invalid;
361-
Assert.That(payloadStatus.Status, Is.EqualTo(expectedStatus),
362-
$"engine_newPayloadV{newPayloadVersion} returned {payloadStatus.Status}, expected {expectedStatus}. " +
363-
$"ValidationError: {payloadStatus.ValidationError}");
362+
if (payloadStatus.Status != expectedStatus)
363+
throw new Exception(
364+
$"engine_newPayloadV{newPayloadVersion}: expected {expectedStatus} status" +
365+
(validationError is not null ? $" for validation error \"{validationError}\"" : "") +
366+
$", got {payloadStatus.Status}" +
367+
(payloadStatus.ValidationError is not null ? $" (err: {payloadStatus.ValidationError})" : ""));
364368

365369
if (payloadStatus.Status == PayloadStatus.Valid)
366370
{
@@ -383,8 +387,13 @@ private static Task<JsonRpcResponse> SendFcu(IJsonRpcService rpcService, JsonRpc
383387

384388
private static void AssertRpcSuccess(JsonRpcResponse response)
385389
{
386-
Assert.That(response, Is.InstanceOf<JsonRpcSuccessResponse>(),
387-
response is JsonRpcErrorResponse err ? $"RPC error: {err.Error?.Code} {err.Error?.Message}" : "unexpected response type");
390+
if (response is not JsonRpcSuccessResponse)
391+
{
392+
string message = response is JsonRpcErrorResponse err
393+
? $"RPC error: {err.Error?.Code} {err.Error?.Message}"
394+
: "unexpected response type";
395+
throw new Exception(message);
396+
}
388397
}
389398

390399
private static List<(Block Block, string ExpectedException)> DecodeRlps(BlockchainTest test, bool failOnInvalidRlp)

src/Nethermind/Ethereum.Test.Base/EthereumTestResult.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,11 @@ public EthereumTestResult(string? name, string? loadFailure)
3535
public double TimeInMs { get; set; }
3636

3737
public Hash256 StateRoot { get; set; } = Keccak.EmptyTreeHash;
38+
39+
/// <summary>
40+
/// The actual validation error string returned by the engine for each payload.
41+
/// Populated only for engine tests. Allows consume direct to perform exception mapping.
42+
/// </summary>
43+
public string? EngineValidationError { get; set; }
3844
}
3945
}

src/Nethermind/Nethermind.Test.Runner/BlockchainTestsRunner.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Text.RegularExpressions;
77
using System.Threading.Tasks;
88
using Ethereum.Test.Base;
9+
using Nethermind.Serialization.Json;
910

1011
namespace Nethermind.Test.Runner;
1112

@@ -15,11 +16,14 @@ public class BlockchainTestsRunner(
1516
ulong chainId,
1617
bool trace = false,
1718
bool traceMemory = false,
18-
bool traceNoStack = false)
19+
bool traceNoStack = false,
20+
bool jsonOutput = false,
21+
bool suppressOutput = false)
1922
: BlockchainTestBase, IBlockchainTestRunner
2023
{
2124
private readonly ConsoleColor _defaultColor = Console.ForegroundColor;
2225
private readonly ITestSourceLoader _testsSource = testsSource ?? throw new ArgumentNullException(nameof(testsSource));
26+
private static readonly IJsonSerializer _serializer = new EthereumJsonSerializer();
2327

2428
public async Task<IEnumerable<EthereumTestResult>> RunTestsAsync()
2529
{
@@ -29,7 +33,7 @@ public async Task<IEnumerable<EthereumTestResult>> RunTestsAsync()
2933
{
3034
if (loadedTest as FailedToLoadTest is not null)
3135
{
32-
WriteRed(loadedTest.LoadFailure);
36+
if (!jsonOutput && !suppressOutput) WriteRed(loadedTest.LoadFailure);
3337
testResults.Add(new EthereumTestResult(loadedTest.Name, loadedTest.LoadFailure));
3438
continue;
3539
}
@@ -43,10 +47,11 @@ public async Task<IEnumerable<EthereumTestResult>> RunTestsAsync()
4347

4448
if (filter is not null && test.Name is not null && !Regex.Match(test.Name, $"^({filter})").Success)
4549
continue;
46-
Console.Write($"{test,-120} ");
50+
51+
if (!jsonOutput && !suppressOutput) Console.Write($"{test,-120} ");
4752
if (test.LoadFailure is not null)
4853
{
49-
WriteRed(test.LoadFailure);
54+
if (!jsonOutput && !suppressOutput) WriteRed(test.LoadFailure);
5055
testResults.Add(new EthereumTestResult(test.Name, test.LoadFailure));
5156
}
5257
else
@@ -55,13 +60,21 @@ public async Task<IEnumerable<EthereumTestResult>> RunTestsAsync()
5560

5661
EthereumTestResult result = await RunTest(test, tracer: tracer);
5762
testResults.Add(result);
58-
if (result.Pass)
59-
WriteGreen("PASS");
60-
else
61-
WriteRed("FAIL");
63+
if (!jsonOutput && !suppressOutput)
64+
{
65+
if (result.Pass)
66+
WriteGreen("PASS");
67+
else
68+
WriteRed("FAIL");
69+
}
6270
}
6371
}
6472

73+
if (jsonOutput && !suppressOutput)
74+
{
75+
Console.Out.Write(_serializer.Serialize(testResults, true));
76+
}
77+
6578
return testResults;
6679
}
6780

0 commit comments

Comments
 (0)