Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Staging immutable caching #222

Merged
merged 2 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions repo/format/format_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
"time"

"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/kopia/kopia/internal/blobtesting"
"github.com/kopia/kopia/internal/cache"
"github.com/kopia/kopia/internal/epoch"
"github.com/kopia/kopia/internal/faketime"
"github.com/kopia/kopia/internal/feature"
Expand Down Expand Up @@ -169,6 +171,141 @@
format.ErrAlreadyInitialized)
}

func TestInitializeWithRetention(t *testing.T) {
ctx := testlogging.Context(t)

startTime := time.Date(2020, 1, 1, 12, 0, 0, 0, time.UTC)
ta := faketime.NewTimeAdvance(startTime, 0)
nowFunc := ta.NowFunc()

st := blobtesting.NewVersionedMapStorage(nowFunc).(cache.Storage)
cache := format.NewMemoryBlobCache(nowFunc)
mode := blob.Governance
period := time.Hour * 48

// success
require.NoError(t, format.Initialize(
ctx,
st,
&format.KopiaRepositoryJSON{},
rc,
format.BlobStorageConfiguration{
RetentionMode: mode,
RetentionPeriod: period,
},
"some-password",
))

mgr, err := format.NewManagerWithCache(ctx, st, cacheDuration, "some-password", nowFunc, cache)
require.NoError(t, err, "getting format manager")

// New retention parameters should be available from the format manager.
blobCfg := mustGetBlobStorageConfiguration(t, mgr)
assert.Equal(t, mode, blobCfg.RetentionMode)
assert.Equal(t, period, blobCfg.RetentionPeriod)

// Attempting to touch the blobs the format manager writes should return
// errors as they should have retention enabled. Mod time adjustment (duration
// param) doesn't matter in this context.
_, err = st.TouchBlob(ctx, format.KopiaRepositoryBlobID, time.Minute)
assert.ErrorIs(t, err, blobtesting.ErrBlobLocked, "Altering locked repo blob should fail")

Check failure on line 211 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Code Coverage Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 211 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Code Coverage Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 211 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 211 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Tests

undefined: blobtesting.ErrBlobLocked

_, err = st.TouchBlob(ctx, format.KopiaBlobCfgBlobID, time.Minute)
assert.ErrorIs(t, err, blobtesting.ErrBlobLocked, "Altering locked blob storage config should fail")

Check failure on line 214 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Code Coverage Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 214 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Code Coverage Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 214 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 214 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Tests

undefined: blobtesting.ErrBlobLocked
}

func TestUpdateRetention(t *testing.T) {
ctx := testlogging.Context(t)

startTime := time.Date(2020, 1, 1, 12, 0, 0, 0, time.UTC)
ta := faketime.NewTimeAdvance(startTime, 0)
nowFunc := ta.NowFunc()

st := blobtesting.NewVersionedMapStorage(nowFunc).(cache.Storage)
cache := format.NewMemoryBlobCache(nowFunc)
mode := blob.Governance
period := time.Hour * 48

// success
require.NoError(t, format.Initialize(ctx, st, &format.KopiaRepositoryJSON{}, rc, format.BlobStorageConfiguration{}, "some-password"))

mgr, err := format.NewManagerWithCache(ctx, st, cacheDuration, "some-password", nowFunc, cache)
require.NoError(t, err, "getting format manager")

mp := mustGetMutableParameters(t, mgr)
rf := mustGetRequiredFeatures(t, mgr)

err = mgr.SetParameters(
ctx,
mp,
format.BlobStorageConfiguration{
RetentionMode: mode,
RetentionPeriod: period,
},
rf,
)
require.NoError(t, err, "setting repo parameters")

// New retention parameters should be available from the format manager.
blobCfg := mustGetBlobStorageConfiguration(t, mgr)
assert.Equal(t, mode, blobCfg.RetentionMode)
assert.Equal(t, period, blobCfg.RetentionPeriod)

// Attempting to touch the blobs the format manager writes should return
// errors as they should have retention enabled. Mod time adjustment (duration
// param) doesn't matter in this context.
_, err = st.TouchBlob(ctx, format.KopiaRepositoryBlobID, time.Minute)
assert.ErrorIs(t, err, blobtesting.ErrBlobLocked, "Altering locked repo blob should fail")

Check failure on line 258 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Code Coverage Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 258 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Code Coverage Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 258 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 258 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Tests

undefined: blobtesting.ErrBlobLocked

_, err = st.TouchBlob(ctx, format.KopiaBlobCfgBlobID, time.Minute)
assert.ErrorIs(t, err, blobtesting.ErrBlobLocked, "Altering locked blob storage config should fail")

Check failure on line 261 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Code Coverage Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 261 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Code Coverage Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 261 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Tests

undefined: blobtesting.ErrBlobLocked

Check failure on line 261 in repo/format/format_manager_test.go

View workflow job for this annotation

GitHub Actions / Tests

undefined: blobtesting.ErrBlobLocked
}

func TestUpdateRetentionNegativeValue(t *testing.T) {
ctx := testlogging.Context(t)

startTime := time.Date(2020, 1, 1, 12, 0, 0, 0, time.UTC)
ta := faketime.NewTimeAdvance(startTime, 0)
nowFunc := ta.NowFunc()

st := blobtesting.NewVersionedMapStorage(nowFunc).(cache.Storage)
cache := format.NewMemoryBlobCache(nowFunc)
mode := blob.Governance
period := -time.Hour * 48

// success
require.NoError(t, format.Initialize(ctx, st, &format.KopiaRepositoryJSON{}, rc, format.BlobStorageConfiguration{}, "some-password"))

mgr, err := format.NewManagerWithCache(ctx, st, cacheDuration, "some-password", nowFunc, cache)
require.NoError(t, err, "getting format manager")

mp := mustGetMutableParameters(t, mgr)
rf := mustGetRequiredFeatures(t, mgr)

err = mgr.SetParameters(
ctx,
mp,
format.BlobStorageConfiguration{
RetentionMode: mode,
RetentionPeriod: period,
},
rf,
)
require.Error(t, err, "setting repo parameters")

// Old retention parameters should be available from the format manager.
blobCfg := mustGetBlobStorageConfiguration(t, mgr)
assert.Empty(t, blobCfg.RetentionMode)
assert.Zero(t, blobCfg.RetentionPeriod)

// Retention wasn't set so no error should occur.
_, err = st.TouchBlob(ctx, format.KopiaRepositoryBlobID, time.Minute)
assert.NoError(t, err, "altering repo blob")

_, err = st.TouchBlob(ctx, format.KopiaBlobCfgBlobID, time.Minute)
assert.NoError(t, err, "altering storage config")
}

func TestChangePassword(t *testing.T) {
ctx := testlogging.Context(t)

Expand Down
5 changes: 5 additions & 0 deletions repo/format/format_set_parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ func (m *Manager) SetParameters(
return errors.Wrap(err, "unable to write blobcfg blob")
}

// At this point the new blobcfg is persisted in the blob layer. Setting this
// here also ensures the call below properly sets retention on the kopia
// repository blob.
m.blobCfgBlob = blobcfg

if err := m.j.WriteKopiaRepositoryBlob(ctx, m.blobs, m.blobCfgBlob); err != nil {
return errors.Wrap(err, "unable to write format blob")
}
Expand Down
Loading