mirror of
https://github.com/kopia/kopia.git
synced 2026-01-24 06:18:02 -05:00
155 lines
3.6 KiB
Go
155 lines
3.6 KiB
Go
package dir
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/kopia/kopia/fs"
|
|
"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 bundledFileEntry(n string, l int64) *Entry {
|
|
return &Entry{
|
|
EntryMetadata: fs.EntryMetadata{
|
|
Name: n,
|
|
FileSize: l,
|
|
Type: fs.EntryTypeFile,
|
|
},
|
|
}
|
|
}
|
|
|
|
func entryWithSection(n string, l int64, start int64, length int64, baseID repo.ObjectID) *Entry {
|
|
return &Entry{
|
|
EntryMetadata: fs.EntryMetadata{
|
|
Name: n,
|
|
FileSize: l,
|
|
Type: fs.EntryTypeFile,
|
|
},
|
|
ObjectID: repo.SectionObjectID(start, length, baseID),
|
|
}
|
|
}
|
|
|
|
func bundleEntry(n string, l int64, oid repo.ObjectID, children []*Entry) *Entry {
|
|
return &Entry{
|
|
EntryMetadata: fs.EntryMetadata{
|
|
Name: n,
|
|
FileSize: l,
|
|
Type: EntryTypeBundle,
|
|
},
|
|
ObjectID: oid,
|
|
BundledChildren: children,
|
|
}
|
|
}
|
|
|
|
func TestFlattenBundles(t *testing.T) {
|
|
base := repo.ObjectID{StorageBlock: "5555"}
|
|
sources := []*Entry{
|
|
bundleEntry("bundle1", 170, base, []*Entry{
|
|
bundledFileEntry("a1", 50),
|
|
bundledFileEntry("z1", 120),
|
|
}),
|
|
}
|
|
|
|
entries, err := flattenBundles(sources)
|
|
if err != nil {
|
|
t.Errorf("can't read directory entries: %v", err)
|
|
return
|
|
}
|
|
|
|
expectedEntries := []*Entry{
|
|
entryWithSection("a1", 50, 0, 50, base),
|
|
entryWithSection("z1", 120, 50, 120, base),
|
|
}
|
|
|
|
verifyDirectory(t, entries, expectedEntries)
|
|
}
|
|
|
|
func TestFlattenBundlesInconsistentBundleSize(t *testing.T) {
|
|
sources := []*Entry{
|
|
bundleEntry("bundle1", 171, repo.ObjectID{StorageBlock: "5555"}, []*Entry{
|
|
bundledFileEntry("a1", 50),
|
|
bundledFileEntry("z1", 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 := []*Entry{
|
|
bundleEntry("bundle1", 170, base1, []*Entry{
|
|
bundledFileEntry("a1", 50),
|
|
bundledFileEntry("z1", 120),
|
|
}),
|
|
bundleEntry("bundle3", 7, base3, []*Entry{
|
|
bundledFileEntry("a3", 5),
|
|
bundledFileEntry("z3", 2),
|
|
}),
|
|
bundleEntry("bundle2", 300, base2, []*Entry{
|
|
bundledFileEntry("a2", 100),
|
|
bundledFileEntry("z2", 200),
|
|
}),
|
|
}
|
|
|
|
entries, err := flattenBundles(sources)
|
|
if err != nil {
|
|
t.Errorf("can't read directory entries: %v", err)
|
|
return
|
|
}
|
|
|
|
expectedEntries := []*Entry{
|
|
entryWithSection("a1", 50, 0, 50, base1),
|
|
entryWithSection("a2", 100, 0, 100, base2),
|
|
entryWithSection("a3", 5, 0, 5, base3),
|
|
entryWithSection("z1", 120, 50, 120, base1),
|
|
entryWithSection("z2", 200, 100, 200, base2),
|
|
entryWithSection("z3", 2, 5, 2, base3),
|
|
}
|
|
|
|
verifyDirectory(t, entries, expectedEntries)
|
|
}
|
|
|
|
func verifyDirectory(t *testing.T, entries []*Entry, expectedEntries []*Entry) {
|
|
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 mustParseTimestamp(s string) time.Time {
|
|
t, err := time.Parse(time.RFC3339Nano, s)
|
|
if err != nil {
|
|
panic("cannot parse timestamp: " + s)
|
|
}
|
|
return t
|
|
}
|