1717package main
1818
1919import (
20+ "bufio"
2021 "encoding/json"
21- "errors"
2222 "fmt"
2323 "os"
2424
@@ -34,7 +34,7 @@ import (
3434var stateTestCommand = & cli.Command {
3535 Action : stateTestCmd ,
3636 Name : "statetest" ,
37- Usage : "executes the given state tests" ,
37+ Usage : "Executes the given state tests. Filenames can be fed via standard input (batch mode) or as an argument (one-off execution). " ,
3838 ArgsUsage : "<file>" ,
3939}
4040
@@ -50,9 +50,6 @@ type StatetestResult struct {
5050}
5151
5252func stateTestCmd (ctx * cli.Context ) error {
53- if len (ctx .Args ().First ()) == 0 {
54- return errors .New ("path-to-test argument required" )
55- }
5653 // Configure the go-ethereum logger
5754 glogger := log .NewGlogHandler (log .StreamHandler (os .Stderr , log .TerminalFormat (false )))
5855 glogger .Verbosity (log .Lvl (ctx .Int (VerbosityFlag .Name )))
@@ -65,34 +62,43 @@ func stateTestCmd(ctx *cli.Context) error {
6562 DisableStorage : ctx .Bool (DisableStorageFlag .Name ),
6663 EnableReturnData : ! ctx .Bool (DisableReturnDataFlag .Name ),
6764 }
68- var (
69- tracer vm.EVMLogger
70- debugger * logger.StructLogger
71- )
65+ var cfg vm.Config
7266 switch {
7367 case ctx .Bool (MachineFlag .Name ):
74- tracer = logger .NewJSONLogger (config , os .Stderr )
68+ cfg . Tracer = logger .NewJSONLogger (config , os .Stderr )
7569
7670 case ctx .Bool (DebugFlag .Name ):
77- debugger = logger .NewStructLogger (config )
78- tracer = debugger
79-
80- default :
81- debugger = logger .NewStructLogger (config )
71+ cfg .Tracer = logger .NewStructLogger (config )
8272 }
8373 // Load the test content from the input file
84- src , err := os .ReadFile (ctx .Args ().First ())
74+ if len (ctx .Args ().First ()) != 0 {
75+ return runStateTest (ctx .Args ().First (), cfg , ctx .Bool (MachineFlag .Name ), ctx .Bool (DumpFlag .Name ))
76+ }
77+ // Read filenames from stdin and execute back-to-back
78+ scanner := bufio .NewScanner (os .Stdin )
79+ for scanner .Scan () {
80+ fname := scanner .Text ()
81+ if len (fname ) == 0 {
82+ return nil
83+ }
84+ if err := runStateTest (fname , cfg , ctx .Bool (MachineFlag .Name ), ctx .Bool (DumpFlag .Name )); err != nil {
85+ return err
86+ }
87+ }
88+ return nil
89+ }
90+
91+ // runStateTest loads the state-test given by fname, and executes the test.
92+ func runStateTest (fname string , cfg vm.Config , jsonOut , dump bool ) error {
93+ src , err := os .ReadFile (fname )
8594 if err != nil {
8695 return err
8796 }
8897 var tests map [string ]tests.StateTest
89- if err = json .Unmarshal (src , & tests ); err != nil {
98+ if err : = json .Unmarshal (src , & tests ); err != nil {
9099 return err
91100 }
92101 // Iterate over all the tests, run them and aggregate the results
93- cfg := vm.Config {
94- Tracer : tracer ,
95- }
96102 results := make ([]StatetestResult , 0 , len (tests ))
97103 for key , test := range tests {
98104 for _ , st := range test .Subtests () {
@@ -103,28 +109,20 @@ func stateTestCmd(ctx *cli.Context) error {
103109 if s != nil {
104110 root := s .IntermediateRoot (false )
105111 result .Root = & root
106- if ctx . Bool ( MachineFlag . Name ) {
112+ if jsonOut {
107113 fmt .Fprintf (os .Stderr , "{\" stateRoot\" : \" %#x\" }\n " , root )
108114 }
109115 }
110116 if err != nil {
111117 // Test failed, mark as so and dump any state to aid debugging
112118 result .Pass , result .Error = false , err .Error ()
113- if ctx . Bool ( DumpFlag . Name ) && s != nil {
119+ if dump && s != nil {
114120 dump := s .RawDump (nil )
115121 result .State = & dump
116122 }
117123 }
118124
119125 results = append (results , * result )
120-
121- // Print any structured logs collected
122- if ctx .Bool (DebugFlag .Name ) {
123- if debugger != nil {
124- fmt .Fprintln (os .Stderr , "#### TRACE ####" )
125- logger .WriteTrace (os .Stderr , debugger .StructLogs ())
126- }
127- }
128126 }
129127 }
130128 out , _ := json .MarshalIndent (results , "" , " " )
0 commit comments