github.com/advanderveer/restic@v0.8.1-0.20171209104529-42a8c19aaea6/internal/test/helpers.go (about)

     1  package test
     2  
     3  import (
     4  	"compress/bzip2"
     5  	"compress/gzip"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  	"os"
    10  	"os/exec"
    11  	"path/filepath"
    12  	"reflect"
    13  	"runtime"
    14  	"testing"
    15  
    16  	"github.com/restic/restic/internal/errors"
    17  
    18  	mrand "math/rand"
    19  )
    20  
    21  // Assert fails the test if the condition is false.
    22  func Assert(tb testing.TB, condition bool, msg string, v ...interface{}) {
    23  	if !condition {
    24  		_, file, line, _ := runtime.Caller(1)
    25  		fmt.Printf("\033[31m%s:%d: "+msg+"\033[39m\n\n", append([]interface{}{filepath.Base(file), line}, v...)...)
    26  		tb.FailNow()
    27  	}
    28  }
    29  
    30  // OK fails the test if an err is not nil.
    31  func OK(tb testing.TB, err error) {
    32  	if err != nil {
    33  		_, file, line, _ := runtime.Caller(1)
    34  		fmt.Printf("\033[31m%s:%d: unexpected error: %+v\033[39m\n\n", filepath.Base(file), line, err)
    35  		tb.FailNow()
    36  	}
    37  }
    38  
    39  // OKs fails the test if any error from errs is not nil.
    40  func OKs(tb testing.TB, errs []error) {
    41  	errFound := false
    42  	for _, err := range errs {
    43  		if err != nil {
    44  			errFound = true
    45  			_, file, line, _ := runtime.Caller(1)
    46  			fmt.Printf("\033[31m%s:%d: unexpected error: %+v\033[39m\n\n", filepath.Base(file), line, err.Error())
    47  		}
    48  	}
    49  	if errFound {
    50  		tb.FailNow()
    51  	}
    52  }
    53  
    54  // Equals fails the test if exp is not equal to act.
    55  func Equals(tb testing.TB, exp, act interface{}) {
    56  	if !reflect.DeepEqual(exp, act) {
    57  		_, file, line, _ := runtime.Caller(1)
    58  		fmt.Printf("\033[31m%s:%d:\n\n\texp: %#v\n\n\tgot: %#v\033[39m\n\n", filepath.Base(file), line, exp, act)
    59  		tb.FailNow()
    60  	}
    61  }
    62  
    63  // Random returns size bytes of pseudo-random data derived from the seed.
    64  func Random(seed, count int) []byte {
    65  	p := make([]byte, count)
    66  
    67  	rnd := mrand.New(mrand.NewSource(int64(seed)))
    68  
    69  	for i := 0; i < len(p); i += 8 {
    70  		val := rnd.Int63()
    71  		var data = []byte{
    72  			byte((val >> 0) & 0xff),
    73  			byte((val >> 8) & 0xff),
    74  			byte((val >> 16) & 0xff),
    75  			byte((val >> 24) & 0xff),
    76  			byte((val >> 32) & 0xff),
    77  			byte((val >> 40) & 0xff),
    78  			byte((val >> 48) & 0xff),
    79  			byte((val >> 56) & 0xff),
    80  		}
    81  
    82  		for j := range data {
    83  			cur := i + j
    84  			if cur >= len(p) {
    85  				break
    86  			}
    87  			p[cur] = data[j]
    88  		}
    89  	}
    90  
    91  	return p
    92  }
    93  
    94  // SetupTarTestFixture extracts the tarFile to outputDir.
    95  func SetupTarTestFixture(t testing.TB, outputDir, tarFile string) {
    96  	input, err := os.Open(tarFile)
    97  	OK(t, err)
    98  	defer input.Close()
    99  
   100  	var rd io.Reader
   101  	switch filepath.Ext(tarFile) {
   102  	case ".gz":
   103  		r, err := gzip.NewReader(input)
   104  		OK(t, err)
   105  
   106  		defer r.Close()
   107  		rd = r
   108  	case ".bzip2":
   109  		rd = bzip2.NewReader(input)
   110  	default:
   111  		rd = input
   112  	}
   113  
   114  	cmd := exec.Command("tar", "xf", "-")
   115  	cmd.Dir = outputDir
   116  
   117  	cmd.Stdin = rd
   118  	cmd.Stdout = os.Stdout
   119  	cmd.Stderr = os.Stderr
   120  
   121  	OK(t, cmd.Run())
   122  }
   123  
   124  // Env creates a test environment and extracts the repository fixture.
   125  // Returned is the repo path and a cleanup function.
   126  func Env(t testing.TB, repoFixture string) (repodir string, cleanup func()) {
   127  	tempdir, err := ioutil.TempDir(TestTempDir, "restic-test-env-")
   128  	OK(t, err)
   129  
   130  	fd, err := os.Open(repoFixture)
   131  	if err != nil {
   132  		t.Fatal(err)
   133  	}
   134  	OK(t, fd.Close())
   135  
   136  	SetupTarTestFixture(t, tempdir, repoFixture)
   137  
   138  	return filepath.Join(tempdir, "repo"), func() {
   139  		if !TestCleanupTempDirs {
   140  			t.Logf("leaving temporary directory %v used for test", tempdir)
   141  			return
   142  		}
   143  
   144  		RemoveAll(t, tempdir)
   145  	}
   146  }
   147  
   148  func isFile(fi os.FileInfo) bool {
   149  	return fi.Mode()&(os.ModeType|os.ModeCharDevice) == 0
   150  }
   151  
   152  // ResetReadOnly recursively resets the read-only flag recursively for dir.
   153  // This is mainly used for tests on Windows, which is unable to delete a file
   154  // set read-only.
   155  func ResetReadOnly(t testing.TB, dir string) {
   156  	err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
   157  		if fi == nil {
   158  			return err
   159  		}
   160  
   161  		if fi.IsDir() {
   162  			return os.Chmod(path, 0777)
   163  		}
   164  
   165  		if isFile(fi) {
   166  			return os.Chmod(path, 0666)
   167  		}
   168  
   169  		return nil
   170  	})
   171  	if os.IsNotExist(errors.Cause(err)) {
   172  		err = nil
   173  	}
   174  	OK(t, err)
   175  }
   176  
   177  // RemoveAll recursively resets the read-only flag of all files and dirs and
   178  // afterwards uses os.RemoveAll() to remove the path.
   179  func RemoveAll(t testing.TB, path string) {
   180  	ResetReadOnly(t, path)
   181  	err := os.RemoveAll(path)
   182  	if os.IsNotExist(errors.Cause(err)) {
   183  		err = nil
   184  	}
   185  	OK(t, err)
   186  }
   187  
   188  // TempDir returns a temporary directory that is removed when cleanup is
   189  // called, except if TestCleanupTempDirs is set to false.
   190  func TempDir(t testing.TB) (path string, cleanup func()) {
   191  	tempdir, err := ioutil.TempDir(TestTempDir, "restic-test-")
   192  	if err != nil {
   193  		t.Fatal(err)
   194  	}
   195  
   196  	return tempdir, func() {
   197  		if !TestCleanupTempDirs {
   198  			t.Logf("leaving temporary directory %v used for test", tempdir)
   199  			return
   200  		}
   201  
   202  		RemoveAll(t, tempdir)
   203  	}
   204  }