/* This file is part of go-ethereum go-ethereum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. go-ethereum is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with go-ethereum. If not, see . */ /** * @authors: * Jeffrey Wilcke * Taylor Gerring */ package main import ( "fmt" "io" "io/ioutil" "os" "path/filepath" "github.com/codegangsta/cli" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/tests" ) var ( continueOnError = false testExtension = ".json" defaultTest = "all" defaultDir = "." allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests"} TestFlag = cli.StringFlag{ Name: "test", Usage: "Test type (string): VMTests, TransactionTests, StateTests, BlockTests", Value: defaultTest, } FileFlag = cli.StringFlag{ Name: "file", Usage: "Test file or directory. Directories are searched for .json files 1 level deep", Value: defaultDir, EnvVar: "ETHEREUM_TEST_PATH", } ContinueOnErrorFlag = cli.BoolFlag{ Name: "continue", Usage: "Continue running tests on error (true) or [default] exit immediately (false)", } ReadStdInFlag = cli.BoolFlag{ Name: "stdin", Usage: "Accept input from stdin instead of reading from file", } ) func runTestWithReader(test string, r io.Reader) error { glog.Infoln("runTest", test) var err error switch test { case "bt", "BlockTest", "BlockTests", "BlockChainTest": err = tests.RunBlockTestWithReader(r) case "st", "state", "StateTest", "StateTests": err = tests.RunStateTestWithReader(r) case "tx", "TransactionTest", "TransactionTests": err = tests.RunTransactionTestsWithReader(r) case "vm", "VMTest", "VMTests": err = tests.RunVmTestWithReader(r) default: err = fmt.Errorf("Invalid test type specified: %v", test) } if err != nil { return err } return nil } func getFiles(path string) ([]string, error) { glog.Infoln("getFiles", path) var files []string f, err := os.Open(path) if err != nil { return nil, err } defer f.Close() fi, err := f.Stat() if err != nil { return nil, err } switch mode := fi.Mode(); { case mode.IsDir(): fi, _ := ioutil.ReadDir(path) files = make([]string, len(fi)) for i, v := range fi { // only go 1 depth and leave directory entires blank if !v.IsDir() && v.Name()[len(v.Name())-len(testExtension):len(v.Name())] == testExtension { files[i] = filepath.Join(path, v.Name()) glog.Infoln("Found file", files[i]) } } case mode.IsRegular(): files = make([]string, 1) files[0] = path } return files, nil } func runSuite(test, file string) { var tests []string if test == defaultTest { tests = allTests } else { tests = []string{test} } for _, curTest := range tests { glog.Infoln("runSuite", curTest, file) var err error var files []string if test == defaultTest { files, err = getFiles(filepath.Join(file, curTest)) } else { files, err = getFiles(file) } if err != nil { glog.Fatalln(err) } if len(files) == 0 { glog.Warningln("No files matched path") } for _, curFile := range files { // Skip blank entries if len(curFile) == 0 { continue } r, err := os.Open(curFile) if err != nil { glog.Fatalln(err) } defer r.Close() err = runTestWithReader(curTest, r) if err != nil { if continueOnError { glog.Errorln(err) } else { glog.Fatalln(err) } } } } } func setupApp(c *cli.Context) { flagTest := c.GlobalString(TestFlag.Name) flagFile := c.GlobalString(FileFlag.Name) continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name) useStdIn := c.GlobalBool(ReadStdInFlag.Name) if !useStdIn { runSuite(flagTest, flagFile) } else { if err := runTestWithReader(flagTest, os.Stdin); err != nil { glog.Fatalln(err) } } } func main() { glog.SetToStderr(true) app := cli.NewApp() app.Name = "ethtest" app.Usage = "go-ethereum test interface" app.Action = setupApp app.Version = "0.2.0" app.Author = "go-ethereum team" app.Flags = []cli.Flag{ TestFlag, FileFlag, ContinueOnErrorFlag, ReadStdInFlag, } if err := app.Run(os.Args); err != nil { glog.Fatalln(err) } }