github.com/ethereum/go-ethereum@v1.16.1/cmd/evm/blockrunner.go (about) 1 // Copyright 2023 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum 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-ethereum 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-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "encoding/json" 21 "errors" 22 "fmt" 23 "maps" 24 "os" 25 "regexp" 26 "slices" 27 28 "github.com/ethereum/go-ethereum/core" 29 "github.com/ethereum/go-ethereum/core/rawdb" 30 "github.com/ethereum/go-ethereum/tests" 31 "github.com/urfave/cli/v2" 32 ) 33 34 var blockTestCommand = &cli.Command{ 35 Action: blockTestCmd, 36 Name: "blocktest", 37 Usage: "Executes the given blockchain tests", 38 ArgsUsage: "<path>", 39 Flags: slices.Concat([]cli.Flag{ 40 DumpFlag, 41 HumanReadableFlag, 42 RunFlag, 43 WitnessCrossCheckFlag, 44 }, traceFlags), 45 } 46 47 func blockTestCmd(ctx *cli.Context) error { 48 path := ctx.Args().First() 49 if len(path) == 0 { 50 return errors.New("path argument required") 51 } 52 var ( 53 collected = collectFiles(path) 54 results []testResult 55 ) 56 for _, fname := range collected { 57 r, err := runBlockTest(ctx, fname) 58 if err != nil { 59 return err 60 } 61 results = append(results, r...) 62 } 63 report(ctx, results) 64 return nil 65 } 66 67 func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) { 68 src, err := os.ReadFile(fname) 69 if err != nil { 70 return nil, err 71 } 72 var tests map[string]*tests.BlockTest 73 if err = json.Unmarshal(src, &tests); err != nil { 74 return nil, err 75 } 76 re, err := regexp.Compile(ctx.String(RunFlag.Name)) 77 if err != nil { 78 return nil, fmt.Errorf("invalid regex -%s: %v", RunFlag.Name, err) 79 } 80 tracer := tracerFromFlags(ctx) 81 82 // Pull out keys to sort and ensure tests are run in order. 83 keys := slices.Sorted(maps.Keys(tests)) 84 85 // Run all the tests. 86 var results []testResult 87 for _, name := range keys { 88 if !re.MatchString(name) { 89 continue 90 } 91 result := &testResult{Name: name, Pass: true} 92 if err := tests[name].Run(false, rawdb.HashScheme, ctx.Bool(WitnessCrossCheckFlag.Name), tracer, func(res error, chain *core.BlockChain) { 93 if ctx.Bool(DumpFlag.Name) { 94 if s, _ := chain.State(); s != nil { 95 result.State = dump(s) 96 } 97 } 98 }); err != nil { 99 result.Pass, result.Error = false, err.Error() 100 } 101 results = append(results, *result) 102 } 103 return results, nil 104 }