cache: add coverage for Mount readonly parameter.

This adds test coverage for ensuring the readonly parameter is honored
as expected in the ref Mount methods. There was a regression introduced
during #2335 that went unnoticed until identified and fixed in #2562.
This test coverage should help prevent similar regressions in the
future.

Signed-off-by: Erik Sipsma <erik@sipsma.dev>
master
Erik Sipsma 2022-01-17 16:33:45 -08:00
parent 6471f316d3
commit 0eca53360b
1 changed files with 85 additions and 0 deletions

85
cache/manager_test.go vendored
View File

@ -26,6 +26,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/leases"
ctdmetadata "github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/snapshots"
"github.com/containerd/containerd/snapshots/native"
@ -1683,6 +1684,75 @@ func TestMergeOp(t *testing.T) {
checkDiskUsage(ctx, t, cm, 0, 0)
}
func TestMountReadOnly(t *testing.T) {
t.Parallel()
if runtime.GOOS != "linux" {
t.Skipf("unsupported GOOS: %s", runtime.GOOS)
}
ctx := namespaces.WithNamespace(context.Background(), "buildkit-test")
tmpdir, err := ioutil.TempDir("", "cachemanager")
require.NoError(t, err)
defer os.RemoveAll(tmpdir)
snapshotter, err := native.NewSnapshotter(filepath.Join(tmpdir, "snapshots"))
require.NoError(t, err)
co, cleanup, err := newCacheManager(ctx, cmOpt{
snapshotter: snapshotter,
snapshotterName: "overlay",
})
require.NoError(t, err)
defer cleanup()
cm := co.manager
mutRef, err := cm.New(ctx, nil, nil)
require.NoError(t, err)
for i := 0; i < 2; i++ {
rwMntable, err := mutRef.Mount(ctx, false, nil)
require.NoError(t, err)
rwMnts, release, err := rwMntable.Mount()
require.NoError(t, err)
defer release()
require.Len(t, rwMnts, 1)
require.False(t, isReadOnly(rwMnts[0]))
roMntable, err := mutRef.Mount(ctx, true, nil)
require.NoError(t, err)
roMnts, release, err := roMntable.Mount()
require.NoError(t, err)
defer release()
require.Len(t, roMnts, 1)
require.True(t, isReadOnly(roMnts[0]))
immutRef, err := mutRef.Commit(ctx)
require.NoError(t, err)
roMntable, err = immutRef.Mount(ctx, true, nil)
require.NoError(t, err)
roMnts, release, err = roMntable.Mount()
require.NoError(t, err)
defer release()
require.Len(t, roMnts, 1)
require.True(t, isReadOnly(roMnts[0]))
rwMntable, err = immutRef.Mount(ctx, false, nil)
require.NoError(t, err)
rwMnts, release, err = rwMntable.Mount()
require.NoError(t, err)
defer release()
require.Len(t, rwMnts, 1)
// once immutable, even when readonly=false, the mount is still readonly
require.True(t, isReadOnly(rwMnts[0]))
// repeat with a ref that has a parent
mutRef, err = cm.New(ctx, immutRef, nil)
require.NoError(t, err)
}
}
func checkDiskUsage(ctx context.Context, t *testing.T, cm Manager, inuse, unused int) {
du, err := cm.DiskUsage(ctx, client.DiskUsageInfo{})
require.NoError(t, err)
@ -1919,3 +1989,18 @@ func mapToSystemTarBlob(m map[string]string) ([]byte, ocispecs.Descriptor, error
},
}, nil
}
func isReadOnly(mnt mount.Mount) bool {
var hasUpperdir bool
for _, o := range mnt.Options {
if o == "ro" {
return true
} else if strings.HasPrefix(o, "upperdir=") {
hasUpperdir = true
}
}
if mnt.Type == "overlay" {
return !hasUpperdir
}
return false
}