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  }