Files
kopia/fs/dir_test.go
2016-08-21 09:28:52 -07:00

220 lines
4.9 KiB
Go

package fs
import (
"reflect"
"strings"
"testing"
"time"
"github.com/kopia/kopia/repo"
)
var (
time1 = mustParseTimestamp("2016-04-06T02:34:10Z")
time2 = mustParseTimestamp("2016-04-02T02:39:44.123456789Z")
time3 = mustParseTimestamp("2016-04-02T02:36:19Z")
)
func TestFlattenBundles(t *testing.T) {
base := repo.ObjectID{StorageBlock: "5555"}
sources := []*EntryMetadata{
&EntryMetadata{
Name: "bundle1",
FileSize: 170,
ObjectID: base,
BundledChildren: []*EntryMetadata{
&EntryMetadata{Name: "a1", FileSize: 50},
&EntryMetadata{Name: "z1", FileSize: 120},
},
},
}
entries, err := flattenBundles(sources)
if err != nil {
t.Errorf("can't read directory entries: %v", err)
return
}
expectedEntries := []*EntryMetadata{
&EntryMetadata{Name: "a1", FileSize: 50, ObjectID: repo.ObjectID{Section: &repo.ObjectIDSection{
Start: 0,
Length: 50,
Base: base,
}}},
&EntryMetadata{Name: "z1", FileSize: 120, ObjectID: repo.ObjectID{Section: &repo.ObjectIDSection{
Start: 50,
Length: 120,
Base: base,
}}},
}
verifyDirectory(t, entries, expectedEntries)
}
func TestFlattenBundlesInconsistentBundleSize(t *testing.T) {
sources := []*EntryMetadata{
&EntryMetadata{
Name: "bundle1",
FileSize: 171,
ObjectID: repo.ObjectID{StorageBlock: "5555"},
BundledChildren: []*EntryMetadata{
&EntryMetadata{Name: "a1", FileSize: 50},
&EntryMetadata{Name: "z1", FileSize: 120},
},
},
}
_, err := flattenBundles(sources)
if err == nil {
t.Errorf("expected error")
return
}
if ok := strings.Contains(err.Error(), "inconsistent size of 'bundle1'"); !ok {
t.Errorf("invalid error: %v", err)
}
}
func TestFlattenThreeBundles(t *testing.T) {
base1 := repo.ObjectID{StorageBlock: "5555"}
base2 := repo.ObjectID{StorageBlock: "6666"}
base3 := repo.ObjectID{StorageBlock: "7777"}
sources := []*EntryMetadata{
&EntryMetadata{
Name: "bundle1",
FileSize: 170,
ObjectID: base1,
BundledChildren: []*EntryMetadata{
&EntryMetadata{Name: "a1", FileSize: 50},
&EntryMetadata{Name: "z1", FileSize: 120},
},
},
&EntryMetadata{
Name: "bundle3",
FileSize: 7,
ObjectID: base3,
BundledChildren: []*EntryMetadata{
&EntryMetadata{Name: "a3", FileSize: 5},
&EntryMetadata{Name: "z3", FileSize: 2},
},
},
&EntryMetadata{
Name: "bundle2",
FileSize: 300,
ObjectID: base2,
BundledChildren: []*EntryMetadata{
&EntryMetadata{Name: "a2", FileSize: 100},
&EntryMetadata{Name: "z2", FileSize: 200},
},
},
}
entries, err := flattenBundles(sources)
if err != nil {
t.Errorf("can't read directory entries: %v", err)
return
}
expectedEntries := []*EntryMetadata{
&EntryMetadata{Name: "a1", FileSize: 50, ObjectID: repo.ObjectID{Section: &repo.ObjectIDSection{
Start: 0,
Length: 50,
Base: base1,
}}},
&EntryMetadata{Name: "a2", FileSize: 100, ObjectID: repo.ObjectID{Section: &repo.ObjectIDSection{
Start: 0,
Length: 100,
Base: base2,
}}},
&EntryMetadata{Name: "a3", FileSize: 5, ObjectID: repo.ObjectID{Section: &repo.ObjectIDSection{
Start: 0,
Length: 5,
Base: base3,
}}},
&EntryMetadata{Name: "z1", FileSize: 120, ObjectID: repo.ObjectID{Section: &repo.ObjectIDSection{
Start: 50,
Length: 120,
Base: base1,
}}},
&EntryMetadata{Name: "z2", FileSize: 200, ObjectID: repo.ObjectID{Section: &repo.ObjectIDSection{
Start: 100,
Length: 200,
Base: base2,
}}},
&EntryMetadata{Name: "z3", FileSize: 2, ObjectID: repo.ObjectID{Section: &repo.ObjectIDSection{
Start: 5,
Length: 2,
Base: base3,
}}},
}
verifyDirectory(t, entries, expectedEntries)
}
func verifyDirectory(t *testing.T, entries []*EntryMetadata, expectedEntries []*EntryMetadata) {
if len(entries) != len(expectedEntries) {
t.Errorf("expected %v entries, got %v", len(expectedEntries), len(entries))
}
for i, expected := range expectedEntries {
if i < len(entries) {
actual := entries[i]
if !reflect.DeepEqual(expected, actual) {
t.Errorf("invalid entry at index %v:\nexpected: %#v\nactual: %#v", i,
expected, actual)
}
}
}
}
func TestDirectoryNameOrder(t *testing.T) {
sortedNames := []string{
"a/a/a",
"a/a/",
"a/b",
"a/b1",
"a/b2",
"a/",
"bar/a/a",
"bar/a/",
"bar/a.b",
"bar/a.c/",
"bar/a1/a",
"bar/a1/",
"bar/a2",
"bar/a3",
"bar/",
"foo/a/a",
"foo/a/",
"foo/b",
"foo/c/a",
"foo/c/",
"foo/d/",
"foo/e1/",
"foo/e2/",
"foo/",
"goo/a/a",
"goo/a/",
"goo/",
}
for i, n1 := range sortedNames {
for j, n2 := range sortedNames {
expected := i <= j
actual := isLessOrEqual(n1, n2)
if actual != expected {
t.Errorf("unexpected value for isLessOrEqual('%v','%v'), expected: %v, got: %v", n1, n2, expected, actual)
}
}
}
}
func mustParseTimestamp(s string) time.Time {
t, err := time.Parse(time.RFC3339Nano, s)
if err != nil {
panic("cannot parse timestamp: " + s)
}
return t
}