main.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. This file is part of go-ethereum
  3. go-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. go-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /**
  15. * @authors:
  16. * Jeffrey Wilcke <i@jev.io>
  17. * Taylor Gerring <taylor.gerring@gmail.com>
  18. */
  19. package main
  20. import (
  21. "fmt"
  22. "io"
  23. "io/ioutil"
  24. "os"
  25. "path/filepath"
  26. "strings"
  27. "github.com/codegangsta/cli"
  28. "github.com/ethereum/go-ethereum/logger/glog"
  29. "github.com/ethereum/go-ethereum/tests"
  30. )
  31. var (
  32. continueOnError = false
  33. testExtension = ".json"
  34. defaultTest = "all"
  35. defaultDir = "."
  36. allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests"}
  37. skipTests = []string{}
  38. TestFlag = cli.StringFlag{
  39. Name: "test",
  40. Usage: "Test type (string): VMTests, TransactionTests, StateTests, BlockTests",
  41. Value: defaultTest,
  42. }
  43. FileFlag = cli.StringFlag{
  44. Name: "file",
  45. Usage: "Test file or directory. Directories are searched for .json files 1 level deep",
  46. Value: defaultDir,
  47. EnvVar: "ETHEREUM_TEST_PATH",
  48. }
  49. ContinueOnErrorFlag = cli.BoolFlag{
  50. Name: "continue",
  51. Usage: "Continue running tests on error (true) or [default] exit immediately (false)",
  52. }
  53. ReadStdInFlag = cli.BoolFlag{
  54. Name: "stdin",
  55. Usage: "Accept input from stdin instead of reading from file",
  56. }
  57. SkipTestsFlag = cli.StringFlag{
  58. Name: "skip",
  59. Usage: "Tests names to skip",
  60. }
  61. )
  62. func runTestWithReader(test string, r io.Reader) error {
  63. glog.Infoln("runTest", test)
  64. var err error
  65. switch test {
  66. case "bt", "BlockTest", "BlockTests", "BlockChainTest":
  67. err = tests.RunBlockTestWithReader(r, skipTests)
  68. case "st", "state", "StateTest", "StateTests":
  69. err = tests.RunStateTestWithReader(r, skipTests)
  70. case "tx", "TransactionTest", "TransactionTests":
  71. err = tests.RunTransactionTestsWithReader(r, skipTests)
  72. case "vm", "VMTest", "VMTests":
  73. err = tests.RunVmTestWithReader(r, skipTests)
  74. default:
  75. err = fmt.Errorf("Invalid test type specified: %v", test)
  76. }
  77. if err != nil {
  78. return err
  79. }
  80. return nil
  81. }
  82. func getFiles(path string) ([]string, error) {
  83. glog.Infoln("getFiles", path)
  84. var files []string
  85. f, err := os.Open(path)
  86. if err != nil {
  87. return nil, err
  88. }
  89. defer f.Close()
  90. fi, err := f.Stat()
  91. if err != nil {
  92. return nil, err
  93. }
  94. switch mode := fi.Mode(); {
  95. case mode.IsDir():
  96. fi, _ := ioutil.ReadDir(path)
  97. files = make([]string, len(fi))
  98. for i, v := range fi {
  99. // only go 1 depth and leave directory entires blank
  100. if !v.IsDir() && v.Name()[len(v.Name())-len(testExtension):len(v.Name())] == testExtension {
  101. files[i] = filepath.Join(path, v.Name())
  102. glog.Infoln("Found file", files[i])
  103. }
  104. }
  105. case mode.IsRegular():
  106. files = make([]string, 1)
  107. files[0] = path
  108. }
  109. return files, nil
  110. }
  111. func runSuite(test, file string) {
  112. var tests []string
  113. if test == defaultTest {
  114. tests = allTests
  115. } else {
  116. tests = []string{test}
  117. }
  118. for _, curTest := range tests {
  119. glog.Infoln("runSuite", curTest, file)
  120. var err error
  121. var files []string
  122. if test == defaultTest {
  123. files, err = getFiles(filepath.Join(file, curTest))
  124. } else {
  125. files, err = getFiles(file)
  126. }
  127. if err != nil {
  128. glog.Fatalln(err)
  129. }
  130. if len(files) == 0 {
  131. glog.Warningln("No files matched path")
  132. }
  133. for _, curFile := range files {
  134. // Skip blank entries
  135. if len(curFile) == 0 {
  136. continue
  137. }
  138. r, err := os.Open(curFile)
  139. if err != nil {
  140. glog.Fatalln(err)
  141. }
  142. defer r.Close()
  143. err = runTestWithReader(curTest, r)
  144. if err != nil {
  145. if continueOnError {
  146. glog.Errorln(err)
  147. } else {
  148. glog.Fatalln(err)
  149. }
  150. }
  151. }
  152. }
  153. }
  154. func setupApp(c *cli.Context) {
  155. flagTest := c.GlobalString(TestFlag.Name)
  156. flagFile := c.GlobalString(FileFlag.Name)
  157. continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name)
  158. useStdIn := c.GlobalBool(ReadStdInFlag.Name)
  159. skipTests = strings.Split(c.GlobalString(SkipTestsFlag.Name), " ")
  160. if !useStdIn {
  161. runSuite(flagTest, flagFile)
  162. } else {
  163. if err := runTestWithReader(flagTest, os.Stdin); err != nil {
  164. glog.Fatalln(err)
  165. }
  166. }
  167. }
  168. func main() {
  169. glog.SetToStderr(true)
  170. app := cli.NewApp()
  171. app.Name = "ethtest"
  172. app.Usage = "go-ethereum test interface"
  173. app.Action = setupApp
  174. app.Version = "0.2.0"
  175. app.Author = "go-ethereum team"
  176. app.Flags = []cli.Flag{
  177. TestFlag,
  178. FileFlag,
  179. ContinueOnErrorFlag,
  180. ReadStdInFlag,
  181. SkipTestsFlag,
  182. }
  183. if err := app.Run(os.Args); err != nil {
  184. glog.Fatalln(err)
  185. }
  186. }