main.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. "github.com/codegangsta/cli"
  27. "github.com/ethereum/go-ethereum/logger/glog"
  28. "github.com/ethereum/go-ethereum/tests"
  29. )
  30. var (
  31. continueOnError = false
  32. testExtension = ".json"
  33. defaultTest = "all"
  34. defaultDir = "."
  35. allTests = []string{"BlockTests", "StateTests", "TransactionTests", "VMTests"}
  36. TestFlag = cli.StringFlag{
  37. Name: "test",
  38. Usage: "Test type (string): VMTests, TransactionTests, StateTests, BlockTests",
  39. Value: defaultTest,
  40. }
  41. FileFlag = cli.StringFlag{
  42. Name: "file",
  43. Usage: "Test file or directory. Directories are searched for .json files 1 level deep",
  44. Value: defaultDir,
  45. EnvVar: "ETHEREUM_TEST_PATH",
  46. }
  47. ContinueOnErrorFlag = cli.BoolFlag{
  48. Name: "continue",
  49. Usage: "Continue running tests on error (true) or [default] exit immediately (false)",
  50. }
  51. ReadStdInFlag = cli.BoolFlag{
  52. Name: "stdin",
  53. Usage: "Accept input from stdin instead of reading from file",
  54. }
  55. )
  56. func runTestWithReader(test string, r io.Reader) error {
  57. glog.Infoln("runTest", test)
  58. var err error
  59. switch test {
  60. case "bt", "BlockTest", "BlockTests", "BlockChainTest":
  61. err = tests.RunBlockTestWithReader(r)
  62. case "st", "state", "StateTest", "StateTests":
  63. err = tests.RunStateTestWithReader(r)
  64. case "tx", "TransactionTest", "TransactionTests":
  65. err = tests.RunTransactionTestsWithReader(r)
  66. case "vm", "VMTest", "VMTests":
  67. err = tests.RunVmTestWithReader(r)
  68. default:
  69. err = fmt.Errorf("Invalid test type specified: %v", test)
  70. }
  71. if err != nil {
  72. return err
  73. }
  74. return nil
  75. }
  76. func getFiles(path string) ([]string, error) {
  77. glog.Infoln("getFiles", path)
  78. var files []string
  79. f, err := os.Open(path)
  80. if err != nil {
  81. return nil, err
  82. }
  83. defer f.Close()
  84. fi, err := f.Stat()
  85. if err != nil {
  86. return nil, err
  87. }
  88. switch mode := fi.Mode(); {
  89. case mode.IsDir():
  90. fi, _ := ioutil.ReadDir(path)
  91. files = make([]string, len(fi))
  92. for i, v := range fi {
  93. // only go 1 depth and leave directory entires blank
  94. if !v.IsDir() && v.Name()[len(v.Name())-len(testExtension):len(v.Name())] == testExtension {
  95. files[i] = filepath.Join(path, v.Name())
  96. glog.Infoln("Found file", files[i])
  97. }
  98. }
  99. case mode.IsRegular():
  100. files = make([]string, 1)
  101. files[0] = path
  102. }
  103. return files, nil
  104. }
  105. func runSuite(test, file string) {
  106. var tests []string
  107. if test == defaultTest {
  108. tests = allTests
  109. } else {
  110. tests = []string{test}
  111. }
  112. for _, curTest := range tests {
  113. glog.Infoln("runSuite", curTest, file)
  114. var err error
  115. var files []string
  116. if test == defaultTest {
  117. files, err = getFiles(filepath.Join(file, curTest))
  118. } else {
  119. files, err = getFiles(file)
  120. }
  121. if err != nil {
  122. glog.Fatalln(err)
  123. }
  124. if len(files) == 0 {
  125. glog.Warningln("No files matched path")
  126. }
  127. for _, curFile := range files {
  128. // Skip blank entries
  129. if len(curFile) == 0 {
  130. continue
  131. }
  132. r, err := os.Open(curFile)
  133. if err != nil {
  134. glog.Fatalln(err)
  135. }
  136. defer r.Close()
  137. err = runTestWithReader(curTest, r)
  138. if err != nil {
  139. if continueOnError {
  140. glog.Errorln(err)
  141. } else {
  142. glog.Fatalln(err)
  143. }
  144. }
  145. }
  146. }
  147. }
  148. func setupApp(c *cli.Context) {
  149. flagTest := c.GlobalString(TestFlag.Name)
  150. flagFile := c.GlobalString(FileFlag.Name)
  151. continueOnError = c.GlobalBool(ContinueOnErrorFlag.Name)
  152. useStdIn := c.GlobalBool(ReadStdInFlag.Name)
  153. if !useStdIn {
  154. runSuite(flagTest, flagFile)
  155. } else {
  156. if err := runTestWithReader(flagTest, os.Stdin); err != nil {
  157. glog.Fatalln(err)
  158. }
  159. }
  160. }
  161. func main() {
  162. glog.SetToStderr(true)
  163. app := cli.NewApp()
  164. app.Name = "ethtest"
  165. app.Usage = "go-ethereum test interface"
  166. app.Action = setupApp
  167. app.Version = "0.2.0"
  168. app.Author = "go-ethereum team"
  169. app.Flags = []cli.Flag{
  170. TestFlag,
  171. FileFlag,
  172. ContinueOnErrorFlag,
  173. ReadStdInFlag,
  174. }
  175. if err := app.Run(os.Args); err != nil {
  176. glog.Fatalln(err)
  177. }
  178. }