github.com/core-coin/go-core/v2@v2.1.9/cmd/cvm/staterunner.go (about) 1 // Copyright 2017 by the Authors 2 // This file is part of go-core. 3 // 4 // go-core is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-core is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-core. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "encoding/json" 21 "errors" 22 "fmt" 23 "io/ioutil" 24 "os" 25 26 "gopkg.in/urfave/cli.v1" 27 28 "github.com/core-coin/go-core/v2/core/state" 29 "github.com/core-coin/go-core/v2/core/vm" 30 "github.com/core-coin/go-core/v2/log" 31 "github.com/core-coin/go-core/v2/tests" 32 ) 33 34 var stateTestCommand = cli.Command{ 35 Action: stateTestCmd, 36 Name: "statetest", 37 Usage: "executes the given state tests", 38 ArgsUsage: "<file>", 39 } 40 41 // StatetestResult contains the execution status after running a state test, any 42 // error that might have occurred and a dump of the final state if requested. 43 type StatetestResult struct { 44 Name string `json:"name"` 45 Pass bool `json:"pass"` 46 Fork string `json:"fork"` 47 Error string `json:"error,omitempty"` 48 State *state.Dump `json:"state,omitempty"` 49 } 50 51 func stateTestCmd(ctx *cli.Context) error { 52 if len(ctx.Args().First()) == 0 { 53 return errors.New("path-to-test argument required") 54 } 55 // Configure the go-core logger 56 glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) 57 glogger.Verbosity(log.Lvl(ctx.GlobalInt(VerbosityFlag.Name))) 58 log.Root().SetHandler(glogger) 59 60 // Configure the CVM logger 61 config := &vm.LogConfig{ 62 DisableMemory: ctx.GlobalBool(DisableMemoryFlag.Name), 63 DisableStack: ctx.GlobalBool(DisableStackFlag.Name), 64 DisableStorage: ctx.GlobalBool(DisableStorageFlag.Name), 65 DisableReturnData: ctx.GlobalBool(DisableReturnDataFlag.Name), 66 } 67 var ( 68 tracer vm.Tracer 69 debugger *vm.StructLogger 70 ) 71 switch { 72 case ctx.GlobalBool(MachineFlag.Name): 73 tracer = vm.NewJSONLogger(config, os.Stderr) 74 75 case ctx.GlobalBool(DebugFlag.Name): 76 debugger = vm.NewStructLogger(config) 77 tracer = debugger 78 79 default: 80 debugger = vm.NewStructLogger(config) 81 } 82 // Load the test content from the input file 83 src, err := ioutil.ReadFile(ctx.Args().First()) 84 if err != nil { 85 return err 86 } 87 var tests map[string]tests.StateTest 88 if err = json.Unmarshal(src, &tests); err != nil { 89 return err 90 } 91 // Iterate over all the tests, run them and aggregate the results 92 cfg := vm.Config{ 93 Tracer: tracer, 94 Debug: ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name), 95 } 96 results := make([]StatetestResult, 0, len(tests)) 97 for key, test := range tests { 98 for _, st := range test.Subtests() { 99 // Run the test and aggregate the result 100 result := &StatetestResult{Name: key, Fork: st.Fork, Pass: true} 101 _, state, err := test.Run(st, cfg, false) 102 // print state root for cvmlab tracing 103 if ctx.GlobalBool(MachineFlag.Name) && state != nil { 104 fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", state.IntermediateRoot(false)) 105 } 106 if err != nil { 107 // Test failed, mark as so and dump any state to aid debugging 108 result.Pass, result.Error = false, err.Error() 109 if ctx.GlobalBool(DumpFlag.Name) && state != nil { 110 dump := state.RawDump(false, false, true) 111 result.State = &dump 112 } 113 } 114 115 results = append(results, *result) 116 117 // Print any structured logs collected 118 if ctx.GlobalBool(DebugFlag.Name) { 119 if debugger != nil { 120 fmt.Fprintln(os.Stderr, "#### TRACE ####") 121 vm.WriteTrace(os.Stderr, debugger.StructLogs()) 122 } 123 } 124 } 125 } 126 out, _ := json.MarshalIndent(results, "", " ") 127 fmt.Println(string(out)) 128 return nil 129 }