Create tests showing when caching is used
Add kopia tests that show what fields can be changed to cause a file to be marked as uncached.
This commit is contained in:
parent
070622fd08
commit
42d0e5d196
@ -20,6 +20,7 @@ type MockExchangeDataCollection struct {
|
|||||||
Data [][]byte
|
Data [][]byte
|
||||||
Names []string
|
Names []string
|
||||||
ModTimes []time.Time
|
ModTimes []time.Time
|
||||||
|
Versions []uint32
|
||||||
ColState data.CollectionState
|
ColState data.CollectionState
|
||||||
PrevPath path.Path
|
PrevPath path.Path
|
||||||
DeletedItems []bool
|
DeletedItems []bool
|
||||||
@ -31,6 +32,7 @@ var (
|
|||||||
_ data.Stream = &MockExchangeData{}
|
_ data.Stream = &MockExchangeData{}
|
||||||
_ data.StreamInfo = &MockExchangeData{}
|
_ data.StreamInfo = &MockExchangeData{}
|
||||||
_ data.StreamSize = &MockExchangeData{}
|
_ data.StreamSize = &MockExchangeData{}
|
||||||
|
_ data.Versioner = &MockExchangeData{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewMockExchangeDataCollection creates an data collection that will return the specified number of
|
// NewMockExchangeDataCollection creates an data collection that will return the specified number of
|
||||||
@ -54,6 +56,8 @@ func NewMockExchangeCollection(pathRepresentation path.Path, numMessagesToReturn
|
|||||||
c.DeletedItems = append(c.DeletedItems, false)
|
c.DeletedItems = append(c.DeletedItems, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Versions = make([]uint32, c.messageCount)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,6 +128,7 @@ func (medc *MockExchangeDataCollection) Items() <-chan data.Stream {
|
|||||||
size: int64(len(medc.Data[i])),
|
size: int64(len(medc.Data[i])),
|
||||||
modifiedTime: medc.ModTimes[i],
|
modifiedTime: medc.ModTimes[i],
|
||||||
deleted: medc.DeletedItems[i],
|
deleted: medc.DeletedItems[i],
|
||||||
|
version: medc.Versions[i],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -139,6 +144,7 @@ type MockExchangeData struct {
|
|||||||
size int64
|
size int64
|
||||||
modifiedTime time.Time
|
modifiedTime time.Time
|
||||||
deleted bool
|
deleted bool
|
||||||
|
version uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (med *MockExchangeData) UUID() string {
|
func (med *MockExchangeData) UUID() string {
|
||||||
@ -175,6 +181,10 @@ func (med *MockExchangeData) ModTime() time.Time {
|
|||||||
return med.modifiedTime
|
return med.modifiedTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (med *MockExchangeData) Version() uint32 {
|
||||||
|
return med.version
|
||||||
|
}
|
||||||
|
|
||||||
type errReader struct {
|
type errReader struct {
|
||||||
readErr error
|
readErr error
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
stdpath "path"
|
stdpath "path"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/kopia/kopia/repo"
|
"github.com/kopia/kopia/repo"
|
||||||
@ -510,6 +511,251 @@ func (suite *KopiaIntegrationSuite) TestBackupCollectionsHandlesNoCollections()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type KopiaCachedBackupSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
w *Wrapper
|
||||||
|
ctx context.Context
|
||||||
|
snapshotBase IncrementalBase
|
||||||
|
|
||||||
|
testPath path.Path
|
||||||
|
baseFileName string
|
||||||
|
baseModTime time.Time
|
||||||
|
baseVersion uint32
|
||||||
|
|
||||||
|
tags map[string]string
|
||||||
|
expectedTags map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKopiaCachedBackupSuite(t *testing.T) {
|
||||||
|
tester.RunOnAny(
|
||||||
|
t,
|
||||||
|
tester.CorsoCITests,
|
||||||
|
tester.CorsoKopiaWrapperTests)
|
||||||
|
|
||||||
|
suite.Run(t, new(KopiaCachedBackupSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KopiaCachedBackupSuite) SetupSuite() {
|
||||||
|
tester.MustGetEnvSets(suite.T(), tester.AWSStorageCredEnvs)
|
||||||
|
|
||||||
|
tmp, err := path.Builder{}.Append(testInboxDir).ToDataLayerExchangePathForCategory(
|
||||||
|
testTenant,
|
||||||
|
testUser,
|
||||||
|
path.EmailCategory,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
require.NoError(suite.T(), err)
|
||||||
|
|
||||||
|
suite.testPath = tmp
|
||||||
|
|
||||||
|
// tags that are supplied by the caller. This includes basic tags to support
|
||||||
|
// lookups and extra tags the caller may want to apply.
|
||||||
|
suite.tags = map[string]string{
|
||||||
|
"fnords": "smarf",
|
||||||
|
"brunhilda": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
reasons := []Reason{
|
||||||
|
{
|
||||||
|
ResourceOwner: suite.testPath.ResourceOwner(),
|
||||||
|
Service: suite.testPath.Service(),
|
||||||
|
Category: suite.testPath.Category(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, r := range reasons {
|
||||||
|
for _, k := range r.TagKeys() {
|
||||||
|
suite.tags[k] = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suite.expectedTags = map[string]string{}
|
||||||
|
|
||||||
|
maps.Copy(suite.expectedTags, normalizeTagKVs(suite.tags))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KopiaCachedBackupSuite) SetupTest() {
|
||||||
|
t := suite.T()
|
||||||
|
|
||||||
|
//nolint:forbidigo
|
||||||
|
suite.ctx, _ = logger.SeedLevel(context.Background(), logger.Development)
|
||||||
|
c, err := openKopiaRepo(t, suite.ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
suite.w = &Wrapper{c}
|
||||||
|
|
||||||
|
baseCollection := mockconnector.NewMockExchangeCollection(suite.testPath, 1)
|
||||||
|
|
||||||
|
suite.baseFileName = baseCollection.Names[0]
|
||||||
|
suite.baseModTime = baseCollection.ModTimes[0]
|
||||||
|
suite.baseVersion = baseCollection.Versions[0]
|
||||||
|
|
||||||
|
// Make a backup to start with as the base.
|
||||||
|
stats, deets, _, err := suite.w.BackupCollections(
|
||||||
|
suite.ctx,
|
||||||
|
nil,
|
||||||
|
[]data.Collection{baseCollection},
|
||||||
|
nil,
|
||||||
|
suite.tags,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(suite.T(), 1, stats.TotalFileCount, "total files")
|
||||||
|
assert.Equal(suite.T(), 1, stats.UncachedFileCount, "uncached files")
|
||||||
|
assert.Equal(suite.T(), 0, stats.CachedFileCount, "cached files")
|
||||||
|
assert.Equal(suite.T(), 5, stats.TotalDirectoryCount)
|
||||||
|
assert.Equal(suite.T(), 0, stats.IgnoredErrorCount)
|
||||||
|
assert.Equal(suite.T(), 0, stats.ErrorCount)
|
||||||
|
assert.False(suite.T(), stats.Incomplete)
|
||||||
|
|
||||||
|
// 1 file and 5 folder entries.
|
||||||
|
details := deets.Details().Entries
|
||||||
|
assert.Len(
|
||||||
|
suite.T(),
|
||||||
|
details,
|
||||||
|
6,
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, entry := range details {
|
||||||
|
assert.True(suite.T(), entry.Updated)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSnapshotTags(
|
||||||
|
t,
|
||||||
|
suite.ctx,
|
||||||
|
suite.w.c,
|
||||||
|
suite.expectedTags,
|
||||||
|
stats.SnapshotID,
|
||||||
|
)
|
||||||
|
|
||||||
|
snap, err := snapshot.LoadSnapshot(
|
||||||
|
suite.ctx,
|
||||||
|
suite.w.c,
|
||||||
|
manifest.ID(stats.SnapshotID),
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
suite.snapshotBase = IncrementalBase{
|
||||||
|
Manifest: snap,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KopiaCachedBackupSuite) TearDownTest() {
|
||||||
|
assert.NoError(suite.T(), suite.w.Close(suite.ctx))
|
||||||
|
logger.Flush(suite.ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *KopiaCachedBackupSuite) TestBackupCollections_WithModTimeAndVersion() {
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
col func() data.Collection
|
||||||
|
expectedUploadedFiles int
|
||||||
|
expectedCachedFiles int
|
||||||
|
// Whether entries in the resulting details should be marked as updated.
|
||||||
|
deetsUpdated bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "NoUpdates",
|
||||||
|
col: func() data.Collection {
|
||||||
|
res := mockconnector.NewMockExchangeCollection(suite.testPath, 1)
|
||||||
|
res.Names[0] = suite.baseFileName
|
||||||
|
res.ModTimes[0] = suite.baseModTime
|
||||||
|
res.Versions[0] = suite.baseVersion
|
||||||
|
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
expectedUploadedFiles: 0,
|
||||||
|
expectedCachedFiles: 1,
|
||||||
|
deetsUpdated: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "UpdatedModTime",
|
||||||
|
col: func() data.Collection {
|
||||||
|
res := mockconnector.NewMockExchangeCollection(suite.testPath, 1)
|
||||||
|
res.Names[0] = suite.baseFileName
|
||||||
|
res.ModTimes[0] = suite.baseModTime.Add(1 * time.Minute)
|
||||||
|
res.Versions[0] = suite.baseVersion
|
||||||
|
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
expectedUploadedFiles: 1,
|
||||||
|
expectedCachedFiles: 0,
|
||||||
|
deetsUpdated: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "UpdatedVersion",
|
||||||
|
col: func() data.Collection {
|
||||||
|
res := mockconnector.NewMockExchangeCollection(suite.testPath, 1)
|
||||||
|
res.Names[0] = suite.baseFileName
|
||||||
|
res.ModTimes[0] = suite.baseModTime
|
||||||
|
res.Versions[0] = suite.baseVersion + 1
|
||||||
|
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
expectedUploadedFiles: 1,
|
||||||
|
expectedCachedFiles: 0,
|
||||||
|
deetsUpdated: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "UpdatedModTimeAndVersion",
|
||||||
|
col: func() data.Collection {
|
||||||
|
res := mockconnector.NewMockExchangeCollection(suite.testPath, 1)
|
||||||
|
res.Names[0] = suite.baseFileName
|
||||||
|
res.ModTimes[0] = suite.baseModTime.Add(1 * time.Minute)
|
||||||
|
res.Versions[0] = suite.baseVersion + 1
|
||||||
|
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
expectedUploadedFiles: 1,
|
||||||
|
expectedCachedFiles: 0,
|
||||||
|
deetsUpdated: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range table {
|
||||||
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
|
stats, deets, _, err := suite.w.BackupCollections(
|
||||||
|
suite.ctx,
|
||||||
|
[]IncrementalBase{suite.snapshotBase},
|
||||||
|
[]data.Collection{test.col()},
|
||||||
|
nil,
|
||||||
|
suite.tags,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, test.expectedUploadedFiles, stats.TotalFileCount, "total files")
|
||||||
|
assert.Equal(t, test.expectedUploadedFiles, stats.UncachedFileCount, "uncached files")
|
||||||
|
assert.Equal(t, test.expectedCachedFiles, stats.CachedFileCount, "cached files")
|
||||||
|
assert.Equal(t, 5, stats.TotalDirectoryCount)
|
||||||
|
assert.Equal(t, 0, stats.IgnoredErrorCount)
|
||||||
|
assert.Equal(t, 0, stats.ErrorCount)
|
||||||
|
assert.False(t, stats.Incomplete)
|
||||||
|
|
||||||
|
// 1 file and 5 folder entries.
|
||||||
|
details := deets.Details().Entries
|
||||||
|
assert.Len(
|
||||||
|
t,
|
||||||
|
details,
|
||||||
|
test.expectedUploadedFiles+test.expectedCachedFiles+5,
|
||||||
|
)
|
||||||
|
|
||||||
|
for _, entry := range details {
|
||||||
|
assert.Equal(t, test.deetsUpdated, entry.Updated)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkSnapshotTags(
|
||||||
|
t,
|
||||||
|
suite.ctx,
|
||||||
|
suite.w.c,
|
||||||
|
suite.expectedTags,
|
||||||
|
stats.SnapshotID,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type KopiaSimpleRepoIntegrationSuite struct {
|
type KopiaSimpleRepoIntegrationSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
w *Wrapper
|
w *Wrapper
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user