From 649f7891903c58539b031b415e91506b851f43ca Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 18 Sep 2016 18:13:39 +0200 Subject: [PATCH 1/2] fuse: Fix test for timestamps with same second --- src/cmds/restic/integration_fuse_test.go | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/cmds/restic/integration_fuse_test.go b/src/cmds/restic/integration_fuse_test.go index bfaeaf0a3..2f7a5fa9f 100644 --- a/src/cmds/restic/integration_fuse_test.go +++ b/src/cmds/restic/integration_fuse_test.go @@ -4,6 +4,7 @@ package main import ( + "fmt" "io/ioutil" "os" "path/filepath" @@ -116,10 +117,28 @@ func TestMount(t *testing.T) { for _, id := range snapshotIDs { snapshot, err := restic.LoadSnapshot(repo, id) OK(t, err) - _, ok := namesMap[snapshot.Time.Format(time.RFC3339)] - Assert(t, ok, "Snapshot %s isn't present in fuse dir", snapshot.Time.Format(time.RFC3339)) - namesMap[snapshot.Time.Format(time.RFC3339)] = true + + ts := snapshot.Time.Format(time.RFC3339) + present, ok := namesMap[ts] + if !ok { + t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts) + } + + for i := 1; present; i++ { + ts = fmt.Sprintf("%s-%d", snapshot.Time.Format(time.RFC3339), i) + present, ok = namesMap[ts] + if !ok { + t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts) + } + + if !present { + break + } + } + + namesMap[ts] = true } + for name, present := range namesMap { Assert(t, present, "Directory %s is present in fuse dir but is not a snapshot", name) } From 68b462d057796de37e52fe42171ec47583088c65 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 18 Sep 2016 18:30:25 +0200 Subject: [PATCH 2/2] fuse: Add test for same timestamps --- src/cmds/restic/integration_fuse_test.go | 139 +++++++++++------- .../testdata/repo-same-timestamps.tar.gz | Bin 0 -> 3243 bytes 2 files changed, 82 insertions(+), 57 deletions(-) create mode 100644 src/cmds/restic/testdata/repo-same-timestamps.tar.gz diff --git a/src/cmds/restic/integration_fuse_test.go b/src/cmds/restic/integration_fuse_test.go index 2f7a5fa9f..8a4aa4860 100644 --- a/src/cmds/restic/integration_fuse_test.go +++ b/src/cmds/restic/integration_fuse_test.go @@ -84,65 +84,66 @@ func listSnapshots(t testing.TB, dir string) []string { return names } +func checkSnapshots(t testing.TB, global GlobalOptions, repo *repository.Repository, mountpoint, repodir string, snapshotIDs restic.IDs) { + t.Logf("checking for %d snapshots: %v", len(snapshotIDs), snapshotIDs) + go mount(t, global, mountpoint) + waitForMount(t, mountpoint) + defer umount(t, global, mountpoint) + + if !snapshotsDirExists(t, mountpoint) { + t.Fatal(`virtual directory "snapshots" doesn't exist`) + } + + ids := listSnapshots(t, repodir) + t.Logf("found %v snapshots in repo: %v", len(ids), ids) + + namesInSnapshots := listSnapshots(t, mountpoint) + t.Logf("found %v snapshots in fuse mount: %v", len(namesInSnapshots), namesInSnapshots) + Assert(t, + len(namesInSnapshots) == len(snapshotIDs), + "Invalid number of snapshots: expected %d, got %d", len(snapshotIDs), len(namesInSnapshots)) + + namesMap := make(map[string]bool) + for _, name := range namesInSnapshots { + namesMap[name] = false + } + + for _, id := range snapshotIDs { + snapshot, err := restic.LoadSnapshot(repo, id) + OK(t, err) + + ts := snapshot.Time.Format(time.RFC3339) + present, ok := namesMap[ts] + if !ok { + t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts) + } + + for i := 1; present; i++ { + ts = fmt.Sprintf("%s-%d", snapshot.Time.Format(time.RFC3339), i) + present, ok = namesMap[ts] + if !ok { + t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts) + } + + if !present { + break + } + } + + namesMap[ts] = true + } + + for name, present := range namesMap { + Assert(t, present, "Directory %s is present in fuse dir but is not a snapshot", name) + } +} + func TestMount(t *testing.T) { if !RunFuseTest { t.Skip("Skipping fuse tests") } withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { - checkSnapshots := func(repo *repository.Repository, mountpoint string, snapshotIDs restic.IDs) { - t.Logf("checking for %d snapshots: %v", len(snapshotIDs), snapshotIDs) - go mount(t, global, mountpoint) - waitForMount(t, mountpoint) - defer umount(t, global, mountpoint) - - if !snapshotsDirExists(t, mountpoint) { - t.Fatal(`virtual directory "snapshots" doesn't exist`) - } - - ids := listSnapshots(t, env.repo) - t.Logf("found %v snapshots in repo: %v", len(ids), ids) - - namesInSnapshots := listSnapshots(t, mountpoint) - t.Logf("found %v snapshots in fuse mount: %v", len(namesInSnapshots), namesInSnapshots) - Assert(t, - len(namesInSnapshots) == len(snapshotIDs), - "Invalid number of snapshots: expected %d, got %d", len(snapshotIDs), len(namesInSnapshots)) - - namesMap := make(map[string]bool) - for _, name := range namesInSnapshots { - namesMap[name] = false - } - - for _, id := range snapshotIDs { - snapshot, err := restic.LoadSnapshot(repo, id) - OK(t, err) - - ts := snapshot.Time.Format(time.RFC3339) - present, ok := namesMap[ts] - if !ok { - t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts) - } - - for i := 1; present; i++ { - ts = fmt.Sprintf("%s-%d", snapshot.Time.Format(time.RFC3339), i) - present, ok = namesMap[ts] - if !ok { - t.Errorf("Snapshot %v (%q) isn't present in fuse dir", id.Str(), ts) - } - - if !present { - break - } - } - - namesMap[ts] = true - } - - for name, present := range namesMap { - Assert(t, present, "Directory %s is present in fuse dir but is not a snapshot", name) - } - } cmdInit(t, global) repo, err := global.OpenRepository() @@ -154,7 +155,7 @@ func TestMount(t *testing.T) { // We remove the mountpoint now to check that cmdMount creates it RemoveAll(t, mountpoint) - checkSnapshots(repo, mountpoint, []restic.ID{}) + checkSnapshots(t, global, repo, mountpoint, env.repo, []restic.ID{}) SetupTarTestFixture(t, env.testdata, filepath.Join("testdata", "backup-data.tar.gz")) @@ -164,7 +165,7 @@ func TestMount(t *testing.T) { Assert(t, len(snapshotIDs) == 1, "expected one snapshot, got %v", snapshotIDs) - checkSnapshots(repo, mountpoint, snapshotIDs) + checkSnapshots(t, global, repo, mountpoint, env.repo, snapshotIDs) // second backup, implicit incremental cmdBackup(t, global, []string{env.testdata}, nil) @@ -172,7 +173,7 @@ func TestMount(t *testing.T) { Assert(t, len(snapshotIDs) == 2, "expected two snapshots, got %v", snapshotIDs) - checkSnapshots(repo, mountpoint, snapshotIDs) + checkSnapshots(t, global, repo, mountpoint, env.repo, snapshotIDs) // third backup, explicit incremental cmdBackup(t, global, []string{env.testdata}, &snapshotIDs[0]) @@ -180,6 +181,30 @@ func TestMount(t *testing.T) { Assert(t, len(snapshotIDs) == 3, "expected three snapshots, got %v", snapshotIDs) - checkSnapshots(repo, mountpoint, snapshotIDs) + checkSnapshots(t, global, repo, mountpoint, env.repo, snapshotIDs) + }) +} + +func TestMountSameTimestamps(t *testing.T) { + if !RunFuseTest { + t.Skip("Skipping fuse tests") + } + + withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { + SetupTarTestFixture(t, env.base, filepath.Join("testdata", "repo-same-timestamps.tar.gz")) + + repo, err := global.OpenRepository() + OK(t, err) + + mountpoint, err := ioutil.TempDir(TestTempDir, "restic-test-mount-") + OK(t, err) + + ids := []restic.ID{ + restic.TestParseID("280303689e5027328889a06d718b729e96a1ce6ae9ef8290bff550459ae611ee"), + restic.TestParseID("75ad6cdc0868e082f2596d5ab8705e9f7d87316f5bf5690385eeff8dbe49d9f5"), + restic.TestParseID("5fd0d8b2ef0fa5d23e58f1e460188abb0f525c0f0c4af8365a1280c807a80a1b"), + } + + checkSnapshots(t, global, repo, mountpoint, env.repo, ids) }) } diff --git a/src/cmds/restic/testdata/repo-same-timestamps.tar.gz b/src/cmds/restic/testdata/repo-same-timestamps.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..42cf2b2bb5f3db013d6c6b78924d13ff3ed210f8 GIT binary patch literal 3243 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 literal 0 HcmV?d00001