| 
									
										
										
										
											2016-09-04 14:29:04 +02:00
										 |  |  | package test | 
					
						
							| 
									
										
										
										
											2015-04-09 20:11:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-08-19 21:00:17 +02:00
										 |  |  | 	"compress/bzip2" | 
					
						
							|  |  |  | 	"compress/gzip" | 
					
						
							| 
									
										
										
										
											2015-04-09 20:11:19 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-08-19 21:00:17 +02:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2015-07-04 16:51:59 +02:00
										 |  |  | 	"os" | 
					
						
							|  |  |  | 	"os/exec" | 
					
						
							| 
									
										
										
										
											2015-04-09 20:11:19 +02:00
										 |  |  | 	"path/filepath" | 
					
						
							|  |  |  | 	"reflect" | 
					
						
							|  |  |  | 	"runtime" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-23 14:21:03 +02:00
										 |  |  | 	"github.com/restic/restic/internal/errors" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-22 22:08:23 +01:00
										 |  |  | 	mrand "math/rand" | 
					
						
							| 
									
										
										
										
											2015-04-09 20:11:19 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Assert fails the test if the condition is false. | 
					
						
							|  |  |  | func Assert(tb testing.TB, condition bool, msg string, v ...interface{}) { | 
					
						
							|  |  |  | 	if !condition { | 
					
						
							|  |  |  | 		_, file, line, _ := runtime.Caller(1) | 
					
						
							|  |  |  | 		fmt.Printf("\033[31m%s:%d: "+msg+"\033[39m\n\n", append([]interface{}{filepath.Base(file), line}, v...)...) | 
					
						
							|  |  |  | 		tb.FailNow() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-02 16:22:43 +02:00
										 |  |  | // OK fails the test if an err is not nil. | 
					
						
							| 
									
										
										
										
											2015-04-09 20:11:19 +02:00
										 |  |  | func OK(tb testing.TB, err error) { | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		_, file, line, _ := runtime.Caller(1) | 
					
						
							| 
									
										
										
										
											2016-09-03 13:34:04 +02:00
										 |  |  | 		fmt.Printf("\033[31m%s:%d: unexpected error: %+v\033[39m\n\n", filepath.Base(file), line, err) | 
					
						
							| 
									
										
										
										
											2015-04-09 20:11:19 +02:00
										 |  |  | 		tb.FailNow() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-11 16:00:49 +02:00
										 |  |  | // OKs fails the test if any error from errs is not nil. | 
					
						
							|  |  |  | func OKs(tb testing.TB, errs []error) { | 
					
						
							|  |  |  | 	errFound := false | 
					
						
							|  |  |  | 	for _, err := range errs { | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			errFound = true | 
					
						
							|  |  |  | 			_, file, line, _ := runtime.Caller(1) | 
					
						
							| 
									
										
										
										
											2016-09-25 18:27:03 +02:00
										 |  |  | 			fmt.Printf("\033[31m%s:%d: unexpected error: %+v\033[39m\n\n", filepath.Base(file), line, err.Error()) | 
					
						
							| 
									
										
										
										
											2015-07-11 16:00:49 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if errFound { | 
					
						
							|  |  |  | 		tb.FailNow() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-02 16:22:43 +02:00
										 |  |  | // Equals fails the test if exp is not equal to act. | 
					
						
							| 
									
										
										
										
											2015-04-09 20:11:19 +02:00
										 |  |  | func Equals(tb testing.TB, exp, act interface{}) { | 
					
						
							|  |  |  | 	if !reflect.DeepEqual(exp, act) { | 
					
						
							|  |  |  | 		_, file, line, _ := runtime.Caller(1) | 
					
						
							|  |  |  | 		fmt.Printf("\033[31m%s:%d:\n\n\texp: %#v\n\n\tgot: %#v\033[39m\n\n", filepath.Base(file), line, exp, act) | 
					
						
							|  |  |  | 		tb.FailNow() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-12 09:36:14 +02:00
										 |  |  | // Random returns size bytes of pseudo-random data derived from the seed. | 
					
						
							|  |  |  | func Random(seed, count int) []byte { | 
					
						
							| 
									
										
										
										
											2016-01-24 17:46:18 +01:00
										 |  |  | 	p := make([]byte, count) | 
					
						
							| 
									
										
										
										
											2015-04-12 09:36:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-22 22:08:23 +01:00
										 |  |  | 	rnd := mrand.New(mrand.NewSource(int64(seed))) | 
					
						
							| 
									
										
										
										
											2016-01-24 17:46:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < len(p); i += 8 { | 
					
						
							|  |  |  | 		val := rnd.Int63() | 
					
						
							|  |  |  | 		var data = []byte{ | 
					
						
							|  |  |  | 			byte((val >> 0) & 0xff), | 
					
						
							|  |  |  | 			byte((val >> 8) & 0xff), | 
					
						
							|  |  |  | 			byte((val >> 16) & 0xff), | 
					
						
							|  |  |  | 			byte((val >> 24) & 0xff), | 
					
						
							|  |  |  | 			byte((val >> 32) & 0xff), | 
					
						
							|  |  |  | 			byte((val >> 40) & 0xff), | 
					
						
							|  |  |  | 			byte((val >> 48) & 0xff), | 
					
						
							|  |  |  | 			byte((val >> 56) & 0xff), | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for j := range data { | 
					
						
							|  |  |  | 			cur := i + j | 
					
						
							| 
									
										
										
										
											2017-01-25 13:25:39 +01:00
										 |  |  | 			if cur >= len(p) { | 
					
						
							| 
									
										
										
										
											2016-01-24 17:46:18 +01:00
										 |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			p[cur] = data[j] | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-04-12 09:36:14 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-24 17:46:18 +01:00
										 |  |  | 	return p | 
					
						
							| 
									
										
										
										
											2015-04-12 09:36:14 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-04 16:51:59 +02:00
										 |  |  | // SetupTarTestFixture extracts the tarFile to outputDir. | 
					
						
							|  |  |  | func SetupTarTestFixture(t testing.TB, outputDir, tarFile string) { | 
					
						
							| 
									
										
										
										
											2015-08-19 21:00:17 +02:00
										 |  |  | 	input, err := os.Open(tarFile) | 
					
						
							| 
									
										
										
										
											2015-07-04 16:51:59 +02:00
										 |  |  | 	OK(t, err) | 
					
						
							| 
									
										
										
										
											2021-01-30 19:35:46 +01:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		OK(t, input.Close()) | 
					
						
							|  |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2015-07-04 16:51:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-19 21:00:17 +02:00
										 |  |  | 	var rd io.Reader | 
					
						
							|  |  |  | 	switch filepath.Ext(tarFile) { | 
					
						
							|  |  |  | 	case ".gz": | 
					
						
							|  |  |  | 		r, err := gzip.NewReader(input) | 
					
						
							|  |  |  | 		OK(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-30 19:35:46 +01:00
										 |  |  | 		defer func() { | 
					
						
							|  |  |  | 			OK(t, r.Close()) | 
					
						
							|  |  |  | 		}() | 
					
						
							| 
									
										
										
										
											2015-08-19 21:00:17 +02:00
										 |  |  | 		rd = r | 
					
						
							|  |  |  | 	case ".bzip2": | 
					
						
							|  |  |  | 		rd = bzip2.NewReader(input) | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		rd = input | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cmd := exec.Command("tar", "xf", "-") | 
					
						
							| 
									
										
										
										
											2015-08-16 23:02:02 +02:00
										 |  |  | 	cmd.Dir = outputDir | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-19 21:00:17 +02:00
										 |  |  | 	cmd.Stdin = rd | 
					
						
							| 
									
										
										
										
											2015-07-04 16:51:59 +02:00
										 |  |  | 	cmd.Stdout = os.Stdout | 
					
						
							|  |  |  | 	cmd.Stderr = os.Stderr | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 20:37:27 +01:00
										 |  |  | 	err = cmd.Run() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatalf("running command %v %v failed: %v", cmd.Path, cmd.Args, err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-04 16:51:59 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-04 14:29:04 +02:00
										 |  |  | // Env creates a test environment and extracts the repository fixture. | 
					
						
							|  |  |  | // Returned is the repo path and a cleanup function. | 
					
						
							|  |  |  | func Env(t testing.TB, repoFixture string) (repodir string, cleanup func()) { | 
					
						
							| 
									
										
										
										
											2022-12-02 19:36:43 +01:00
										 |  |  | 	tempdir, err := os.MkdirTemp(TestTempDir, "restic-test-env-") | 
					
						
							| 
									
										
										
										
											2015-07-04 16:51:59 +02:00
										 |  |  | 	OK(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fd, err := os.Open(repoFixture) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-09-04 14:29:04 +02:00
										 |  |  | 		t.Fatal(err) | 
					
						
							| 
									
										
										
										
											2015-07-04 16:51:59 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	OK(t, fd.Close()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	SetupTarTestFixture(t, tempdir, repoFixture) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-04 14:29:04 +02:00
										 |  |  | 	return filepath.Join(tempdir, "repo"), func() { | 
					
						
							|  |  |  | 		if !TestCleanupTempDirs { | 
					
						
							|  |  |  | 			t.Logf("leaving temporary directory %v used for test", tempdir) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-07-04 16:51:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-04 14:29:04 +02:00
										 |  |  | 		RemoveAll(t, tempdir) | 
					
						
							| 
									
										
										
										
											2015-07-04 16:51:59 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-08-18 21:05:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func isFile(fi os.FileInfo) bool { | 
					
						
							|  |  |  | 	return fi.Mode()&(os.ModeType|os.ModeCharDevice) == 0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ResetReadOnly recursively resets the read-only flag recursively for dir. | 
					
						
							|  |  |  | // This is mainly used for tests on Windows, which is unable to delete a file | 
					
						
							|  |  |  | // set read-only. | 
					
						
							|  |  |  | func ResetReadOnly(t testing.TB, dir string) { | 
					
						
							| 
									
										
										
										
											2017-05-01 22:46:32 +02:00
										 |  |  | 	err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error { | 
					
						
							|  |  |  | 		if fi == nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-18 21:05:49 +02:00
										 |  |  | 		if fi.IsDir() { | 
					
						
							|  |  |  | 			return os.Chmod(path, 0777) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if isFile(fi) { | 
					
						
							|  |  |  | 			return os.Chmod(path, 0666) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return nil | 
					
						
							| 
									
										
										
										
											2017-05-01 22:46:32 +02:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-06-13 20:35:37 +02:00
										 |  |  | 	if errors.Is(err, os.ErrNotExist) { | 
					
						
							| 
									
										
										
										
											2017-05-01 22:46:32 +02:00
										 |  |  | 		err = nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-08-18 21:05:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // RemoveAll recursively resets the read-only flag of all files and dirs and | 
					
						
							|  |  |  | // afterwards uses os.RemoveAll() to remove the path. | 
					
						
							|  |  |  | func RemoveAll(t testing.TB, path string) { | 
					
						
							|  |  |  | 	ResetReadOnly(t, path) | 
					
						
							| 
									
										
										
										
											2017-05-01 22:46:32 +02:00
										 |  |  | 	err := os.RemoveAll(path) | 
					
						
							| 
									
										
										
										
											2022-06-13 20:35:37 +02:00
										 |  |  | 	if errors.Is(err, os.ErrNotExist) { | 
					
						
							| 
									
										
										
										
											2017-05-01 22:46:32 +02:00
										 |  |  | 		err = nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	OK(t, err) | 
					
						
							| 
									
										
										
										
											2015-08-18 21:05:49 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-26 20:40:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // TempDir returns a temporary directory that is removed when cleanup is | 
					
						
							|  |  |  | // called, except if TestCleanupTempDirs is set to false. | 
					
						
							|  |  |  | func TempDir(t testing.TB) (path string, cleanup func()) { | 
					
						
							| 
									
										
										
										
											2022-12-02 19:36:43 +01:00
										 |  |  | 	tempdir, err := os.MkdirTemp(TestTempDir, "restic-test-") | 
					
						
							| 
									
										
										
										
											2017-03-26 20:40:45 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tempdir, func() { | 
					
						
							|  |  |  | 		if !TestCleanupTempDirs { | 
					
						
							|  |  |  | 			t.Logf("leaving temporary directory %v used for test", tempdir) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		RemoveAll(t, tempdir) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-02-17 13:24:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Chdir changes the current directory to dest. | 
					
						
							|  |  |  | // The function back returns to the previous directory. | 
					
						
							|  |  |  | func Chdir(t testing.TB, dest string) (back func()) { | 
					
						
							|  |  |  | 	t.Helper() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	prev, err := os.Getwd() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Logf("chdir to %v", dest) | 
					
						
							|  |  |  | 	err = os.Chdir(dest) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return func() { | 
					
						
							|  |  |  | 		t.Helper() | 
					
						
							|  |  |  | 		t.Logf("chdir back to %v", prev) | 
					
						
							|  |  |  | 		err = os.Chdir(prev) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatal(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |