package layout import ( "fmt" "path" "path/filepath" "reflect" "sort" "testing" "github.com/restic/restic/internal/backend" rtest "github.com/restic/restic/internal/test" ) func TestDefaultLayout(t *testing.T) { tempdir := rtest.TempDir(t) var tests = []struct { path string join func(...string) string backend.Handle filename string }{ { tempdir, filepath.Join, backend.Handle{Type: backend.PackFile, Name: "0123456"}, filepath.Join(tempdir, "data", "01", "0123456"), }, { tempdir, filepath.Join, backend.Handle{Type: backend.ConfigFile, Name: "CFG"}, filepath.Join(tempdir, "config"), }, { tempdir, filepath.Join, backend.Handle{Type: backend.SnapshotFile, Name: "123456"}, filepath.Join(tempdir, "snapshots", "123456"), }, { tempdir, filepath.Join, backend.Handle{Type: backend.IndexFile, Name: "123456"}, filepath.Join(tempdir, "index", "123456"), }, { tempdir, filepath.Join, backend.Handle{Type: backend.LockFile, Name: "123456"}, filepath.Join(tempdir, "locks", "123456"), }, { tempdir, filepath.Join, backend.Handle{Type: backend.KeyFile, Name: "123456"}, filepath.Join(tempdir, "keys", "123456"), }, { "", path.Join, backend.Handle{Type: backend.PackFile, Name: "0123456"}, "data/01/0123456", }, { "", path.Join, backend.Handle{Type: backend.ConfigFile, Name: "CFG"}, "config", }, { "", path.Join, backend.Handle{Type: backend.SnapshotFile, Name: "123456"}, "snapshots/123456", }, { "", path.Join, backend.Handle{Type: backend.IndexFile, Name: "123456"}, "index/123456", }, { "", path.Join, backend.Handle{Type: backend.LockFile, Name: "123456"}, "locks/123456", }, { "", path.Join, backend.Handle{Type: backend.KeyFile, Name: "123456"}, "keys/123456", }, } t.Run("Paths", func(t *testing.T) { l := &DefaultLayout{ Path: tempdir, Join: filepath.Join, } dirs := l.Paths() want := []string{ filepath.Join(tempdir, "data"), filepath.Join(tempdir, "snapshots"), filepath.Join(tempdir, "index"), filepath.Join(tempdir, "locks"), filepath.Join(tempdir, "keys"), } for i := 0; i < 256; i++ { want = append(want, filepath.Join(tempdir, "data", fmt.Sprintf("%02x", i))) } sort.Strings(want) sort.Strings(dirs) if !reflect.DeepEqual(dirs, want) { t.Fatalf("wrong paths returned, want:\n %v\ngot:\n %v", want, dirs) } }) for _, test := range tests { t.Run(fmt.Sprintf("%v/%v", test.Type, test.Handle.Name), func(t *testing.T) { l := &DefaultLayout{ Path: test.path, Join: test.join, } filename := l.Filename(test.Handle) if filename != test.filename { t.Fatalf("wrong filename, want %v, got %v", test.filename, filename) } }) } } func TestRESTLayout(t *testing.T) { path := rtest.TempDir(t) var tests = []struct { backend.Handle filename string }{ { backend.Handle{Type: backend.PackFile, Name: "0123456"}, filepath.Join(path, "data", "0123456"), }, { backend.Handle{Type: backend.ConfigFile, Name: "CFG"}, filepath.Join(path, "config"), }, { backend.Handle{Type: backend.SnapshotFile, Name: "123456"}, filepath.Join(path, "snapshots", "123456"), }, { backend.Handle{Type: backend.IndexFile, Name: "123456"}, filepath.Join(path, "index", "123456"), }, { backend.Handle{Type: backend.LockFile, Name: "123456"}, filepath.Join(path, "locks", "123456"), }, { backend.Handle{Type: backend.KeyFile, Name: "123456"}, filepath.Join(path, "keys", "123456"), }, } l := &RESTLayout{ Path: path, Join: filepath.Join, } t.Run("Paths", func(t *testing.T) { dirs := l.Paths() want := []string{ filepath.Join(path, "data"), filepath.Join(path, "snapshots"), filepath.Join(path, "index"), filepath.Join(path, "locks"), filepath.Join(path, "keys"), } sort.Strings(want) sort.Strings(dirs) if !reflect.DeepEqual(dirs, want) { t.Fatalf("wrong paths returned, want:\n %v\ngot:\n %v", want, dirs) } }) for _, test := range tests { t.Run(fmt.Sprintf("%v/%v", test.Type, test.Handle.Name), func(t *testing.T) { filename := l.Filename(test.Handle) if filename != test.filename { t.Fatalf("wrong filename, want %v, got %v", test.filename, filename) } }) } } func TestRESTLayoutURLs(t *testing.T) { var tests = []struct { l Layout h backend.Handle fn string dir string }{ { &RESTLayout{URL: "https://hostname.foo", Path: "", Join: path.Join}, backend.Handle{Type: backend.PackFile, Name: "foobar"}, "https://hostname.foo/data/foobar", "https://hostname.foo/data/", }, { &RESTLayout{URL: "https://hostname.foo:1234/prefix/repo", Path: "/", Join: path.Join}, backend.Handle{Type: backend.LockFile, Name: "foobar"}, "https://hostname.foo:1234/prefix/repo/locks/foobar", "https://hostname.foo:1234/prefix/repo/locks/", }, { &RESTLayout{URL: "https://hostname.foo:1234/prefix/repo", Path: "/", Join: path.Join}, backend.Handle{Type: backend.ConfigFile, Name: "foobar"}, "https://hostname.foo:1234/prefix/repo/config", "https://hostname.foo:1234/prefix/repo/", }, } for _, test := range tests { t.Run(fmt.Sprintf("%T", test.l), func(t *testing.T) { fn := test.l.Filename(test.h) if fn != test.fn { t.Fatalf("wrong filename, want %v, got %v", test.fn, fn) } dir := test.l.Dirname(test.h) if dir != test.dir { t.Fatalf("wrong dirname, want %v, got %v", test.dir, dir) } }) } }