| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- // Copyright 2014 The go-ethereum Authors
- // 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 <http://www.gnu.org/licenses/>.
- // ethtest executes Ethereum JSON tests.
- package main
- import (
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "github.com/ethereum/go-ethereum/logger/glog"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/tests"
- "gopkg.in/urfave/cli.v1"
- )
- var (
- continueOnError = false
- testExtension = ".json"
- defaultTest = "all"
- defaultDir = "."
- allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests", "RLPTests"}
- testDirMapping = map[string]string{"BlockTests": "BlockchainTests"}
- skipTests = []string{}
- 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",
- }
- SkipTestsFlag = cli.StringFlag{
- Name: "skip",
- Usage: "Tests names to skip",
- }
- TraceFlag = cli.BoolFlag{
- Name: "trace",
- Usage: "Enable VM tracing",
- }
- )
- func runTestWithReader(test string, r io.Reader) error {
- glog.Infoln("runTest", test)
- var err error
- switch strings.ToLower(test) {
- case "bk", "block", "blocktest", "blockchaintest", "blocktests", "blockchaintests":
- err = tests.RunBlockTestWithReader(params.MainNetHomesteadBlock, params.MainNetDAOForkBlock, params.MainNetHomesteadGasRepriceBlock, r, skipTests)
- case "st", "state", "statetest", "statetests":
- rs := ¶ms.ChainConfig{HomesteadBlock: params.MainNetHomesteadBlock, DAOForkBlock: params.MainNetDAOForkBlock, DAOForkSupport: true, EIP150Block: params.MainNetHomesteadGasRepriceBlock}
- err = tests.RunStateTestWithReader(rs, r, skipTests)
- case "tx", "transactiontest", "transactiontests":
- err = tests.RunTransactionTestsWithReader(r, skipTests)
- case "vm", "vmtest", "vmtests":
- err = tests.RunVmTestWithReader(r, skipTests)
- case "rlp", "rlptest", "rlptests":
- err = tests.RunRLPTestWithReader(r, skipTests)
- 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 {
- // check if we have an explicit directory mapping for the test
- if _, ok := testDirMapping[curTest]; ok {
- files, err = getFiles(filepath.Join(file, testDirMapping[curTest]))
- } else {
- // otherwise assume test name
- 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) error {
- flagTest := c.GlobalString(TestFlag.Name)
- flagFile := c.GlobalString(FileFlag.Name)
- continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name)
- useStdIn := c.GlobalBool(ReadStdInFlag.Name)
- skipTests = strings.Split(c.GlobalString(SkipTestsFlag.Name), " ")
- if !useStdIn {
- runSuite(flagTest, flagFile)
- } else {
- if err := runTestWithReader(flagTest, os.Stdin); err != nil {
- glog.Fatalln(err)
- }
- }
- return nil
- }
- 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,
- SkipTestsFlag,
- TraceFlag,
- }
- if err := app.Run(os.Args); err != nil {
- glog.Fatalln(err)
- }
- }
|