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 }