github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/cmd/ethtest/main.go (about) 1 // Copyright 2014 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 // ethtest executes Ethereum JSON tests. 18 package main 19 20 import ( 21 "fmt" 22 "io" 23 "io/ioutil" 24 "math/big" 25 "os" 26 "path/filepath" 27 "strings" 28 29 "github.com/ethereumproject/go-ethereum/logger/glog" 30 "github.com/ethereumproject/go-ethereum/tests" 31 "gopkg.in/urfave/cli.v1" 32 ) 33 34 // Version is the application revision identifier. It can be set with the linker 35 // as in: go build -ldflags "-X main.Version="`git describe --tags` 36 var Version = "unknown" 37 38 var ( 39 continueOnError = false 40 testExtension = ".json" 41 defaultTest = "all" 42 defaultDir = "." 43 allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests", "RLPTests"} 44 testDirMapping = map[string]string{"BlockTests": "BlockchainTests"} 45 skipTests = []string{} 46 47 TestFlag = cli.StringFlag{ 48 Name: "test", 49 Usage: "Test type (string): VMTests, TransactionTests, StateTests, BlockTests", 50 Value: defaultTest, 51 } 52 FileFlag = cli.StringFlag{ 53 Name: "file", 54 Usage: "Test file or directory. Directories are searched for .json files 1 level deep", 55 Value: defaultDir, 56 EnvVar: "ETHEREUM_TEST_PATH", 57 } 58 ContinueOnErrorFlag = cli.BoolFlag{ 59 Name: "continue", 60 Usage: "Continue running tests on error (true) or [default] exit immediately (false)", 61 } 62 ReadStdInFlag = cli.BoolFlag{ 63 Name: "stdin", 64 Usage: "Accept input from stdin instead of reading from file", 65 } 66 SkipTestsFlag = cli.StringFlag{ 67 Name: "skip", 68 Usage: "Tests names to skip", 69 } 70 TraceFlag = cli.BoolFlag{ 71 Name: "trace", 72 Usage: "Enable VM tracing", 73 } 74 ) 75 76 func runTestWithReader(test string, r io.Reader) error { 77 glog.Infoln("runTest", test) 78 var err error 79 switch strings.ToLower(test) { 80 case "bk", "block", "blocktest", "blockchaintest", "blocktests", "blockchaintests": 81 err = tests.RunBlockTestWithReader(big.NewInt(1150000), nil, r, skipTests) 82 case "st", "state", "statetest", "statetests": 83 rs := tests.RuleSet{HomesteadBlock: big.NewInt(1150000)} 84 err = tests.RunStateTestWithReader(rs, r, skipTests) 85 case "tx", "transactiontest", "transactiontests": 86 err = tests.RunTransactionTestsWithReader(r, skipTests) 87 case "vm", "vmtest", "vmtests": 88 err = tests.RunVmTestWithReader(r, skipTests) 89 case "rlp", "rlptest", "rlptests": 90 err = tests.RunRLPTestWithReader(r, skipTests) 91 default: 92 err = fmt.Errorf("Invalid test type specified: %v", test) 93 } 94 95 if err != nil { 96 return err 97 } 98 99 return nil 100 } 101 102 func getFiles(path string) ([]string, error) { 103 glog.Infoln("getFiles", path) 104 var files []string 105 f, err := os.Open(path) 106 if err != nil { 107 return nil, err 108 } 109 defer f.Close() 110 111 fi, err := f.Stat() 112 if err != nil { 113 return nil, err 114 } 115 116 switch mode := fi.Mode(); { 117 case mode.IsDir(): 118 fi, _ := ioutil.ReadDir(path) 119 files = make([]string, len(fi)) 120 for i, v := range fi { 121 // only go 1 depth and leave directory entires blank 122 if !v.IsDir() && v.Name()[len(v.Name())-len(testExtension):len(v.Name())] == testExtension { 123 files[i] = filepath.Join(path, v.Name()) 124 glog.Infoln("Found file", files[i]) 125 } 126 } 127 case mode.IsRegular(): 128 files = make([]string, 1) 129 files[0] = path 130 } 131 132 return files, nil 133 } 134 135 func runSuite(test, file string) { 136 var tests []string 137 138 if test == defaultTest { 139 tests = allTests 140 } else { 141 tests = []string{test} 142 } 143 144 for _, curTest := range tests { 145 glog.Infoln("runSuite", curTest, file) 146 var err error 147 var files []string 148 if test == defaultTest { 149 // check if we have an explicit directory mapping for the test 150 if _, ok := testDirMapping[curTest]; ok { 151 files, err = getFiles(filepath.Join(file, testDirMapping[curTest])) 152 } else { 153 // otherwise assume test name 154 files, err = getFiles(filepath.Join(file, curTest)) 155 } 156 } else { 157 files, err = getFiles(file) 158 } 159 if err != nil { 160 glog.Fatalln(err) 161 } 162 163 if len(files) == 0 { 164 glog.Warningln("No files matched path") 165 } 166 for _, curFile := range files { 167 // Skip blank entries 168 if len(curFile) == 0 { 169 continue 170 } 171 172 r, err := os.Open(curFile) 173 if err != nil { 174 glog.Fatalln(err) 175 } 176 defer r.Close() 177 178 err = runTestWithReader(curTest, r) 179 if err != nil { 180 if continueOnError { 181 glog.Errorln(err) 182 } else { 183 glog.Fatalln(err) 184 } 185 } 186 } 187 } 188 } 189 190 func setupApp(c *cli.Context) error { 191 flagTest := c.GlobalString(TestFlag.Name) 192 flagFile := c.GlobalString(FileFlag.Name) 193 continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name) 194 useStdIn := c.GlobalBool(ReadStdInFlag.Name) 195 skipTests = strings.Split(c.GlobalString(SkipTestsFlag.Name), " ") 196 197 if !useStdIn { 198 runSuite(flagTest, flagFile) 199 } else { 200 if err := runTestWithReader(flagTest, os.Stdin); err != nil { 201 glog.Fatalln(err) 202 } 203 } 204 return nil 205 } 206 207 func main() { 208 glog.SetToStderr(true) 209 210 app := cli.NewApp() 211 app.Name = filepath.Base(os.Args[0]) 212 app.Version = Version 213 app.Usage = "go-ethereum test interface" 214 app.Action = setupApp 215 216 app.Flags = []cli.Flag{ 217 TestFlag, 218 FileFlag, 219 ContinueOnErrorFlag, 220 ReadStdInFlag, 221 SkipTestsFlag, 222 TraceFlag, 223 } 224 225 if err := app.Run(os.Args); err != nil { 226 glog.Fatalln(err) 227 } 228 229 }