github.com/ndau/noms@v1.0.5/go/util/clienttest/client_test_suite.go (about) 1 // Copyright 2016 Attic Labs, Inc. All rights reserved. 2 // Licensed under the Apache License, version 2.0: 3 // http://www.apache.org/licenses/LICENSE-2.0 4 5 package clienttest 6 7 import ( 8 "fmt" 9 "io/ioutil" 10 "os" 11 "path" 12 13 "github.com/ndau/noms/go/d" 14 "github.com/ndau/noms/go/util/exit" 15 "github.com/stretchr/testify/suite" 16 ) 17 18 const DefaultMemTableSize = 8 * (1 << 20) // 8MB 19 20 type ClientTestSuite struct { 21 suite.Suite 22 TempDir string 23 DBDir string 24 DBDir2 string 25 ExitStatus int 26 out *os.File 27 err *os.File 28 } 29 30 type ExitError struct { 31 Code int 32 } 33 34 func (e ExitError) Error() string { 35 return fmt.Sprintf("main exited with code: %d", e.Code) 36 } 37 38 func (suite *ClientTestSuite) SetupSuite() { 39 dir, err := ioutil.TempDir(os.TempDir(), "nomstest") 40 d.Chk.NoError(err) 41 stdOutput, err := ioutil.TempFile(dir, "out") 42 d.Chk.NoError(err) 43 errOutput, err := ioutil.TempFile(dir, "err") 44 d.Chk.NoError(err) 45 46 suite.TempDir = dir 47 suite.DBDir = path.Join(dir, "db") 48 suite.DBDir2 = path.Join(suite.TempDir, "db2") 49 suite.out = stdOutput 50 suite.err = errOutput 51 exit.Exit = MockExit 52 53 os.Mkdir(suite.DBDir, 0777) 54 os.Mkdir(suite.DBDir2, 0777) 55 } 56 57 func (suite *ClientTestSuite) TearDownSuite() { 58 suite.out.Close() 59 suite.err.Close() 60 defer d.Chk.NoError(os.RemoveAll(suite.TempDir)) 61 } 62 63 // MustRun is a wrapper around Run that will panic on Exit or Panic 64 func (suite *ClientTestSuite) MustRun(m func(), args []string) (stdout string, stderr string) { 65 var err interface{} 66 if stdout, stderr, err = suite.Run(m, args); err != nil { 67 panic(err) 68 } 69 return 70 } 71 72 // Run will execute a function passing to it commandline args, and captures stdout,stderr. 73 // If m() panics the panic is caught, and returned with recoveredError 74 // If m() calls exit.Exit() m() will panic and return ExitError with recoveredError 75 func (suite *ClientTestSuite) Run(m func(), args []string) (stdout string, stderr string, recoveredErr interface{}) { 76 fmt.Println(args) 77 origArgs := os.Args 78 origOut := os.Stdout 79 origErr := os.Stderr 80 81 os.Args = append([]string{"cmd"}, args...) 82 os.Stdout = suite.out 83 os.Stderr = suite.err 84 85 defer func() { 86 recoveredErr = recover() 87 88 // Reset everything right away so that error-checking below goes to terminal. 89 os.Args = origArgs 90 os.Stdout = origOut 91 os.Stderr = origErr 92 93 _, err := suite.out.Seek(0, 0) 94 d.Chk.NoError(err) 95 capturedOut, err := ioutil.ReadAll(suite.out) 96 d.Chk.NoError(err) 97 98 _, err = suite.out.Seek(0, 0) 99 d.Chk.NoError(err) 100 err = suite.out.Truncate(0) 101 d.Chk.NoError(err) 102 103 _, err = suite.err.Seek(0, 0) 104 d.Chk.NoError(err) 105 capturedErr, err := ioutil.ReadAll(suite.err) 106 d.Chk.NoError(err) 107 108 _, err = suite.err.Seek(0, 0) 109 d.Chk.NoError(err) 110 err = suite.err.Truncate(0) 111 d.Chk.NoError(err) 112 stdout, stderr = string(capturedOut), string(capturedErr) 113 }() 114 115 suite.ExitStatus = 0 116 m() 117 return 118 } 119 120 // Mock exit.Exit() implementation for use during testing. 121 func MockExit(status int) { 122 panic(ExitError{status}) 123 }