containerd/snapshot/testsuite/issues.go
Derek McGowan 750771f6d0
Remove snapshot test suite as a parallel test runner
The testsuite alters global state by setting the umask, avoid
running the testsuite in parallel and move umask manipulation
to the test suite level to individual tests may run in parallel.

Added better error messaging and handling.

Removed reliance on testing object for handling cleanup failure.
When a cleanup error occurred, it would fail the test but the log
would get skipped. With this change the failure will show up for
the running test.

Update test unmounting to set the detach flag, avoiding races with
btrfs which may see the device as busy when attempting to unmount.

Signed-off-by: Derek McGowan <derek@mcgstyle.net>
2017-08-22 16:29:17 -07:00

173 lines
5.6 KiB
Go

package testsuite
import (
"context"
"testing"
"time"
"github.com/containerd/containerd/fs/fstest"
"github.com/containerd/containerd/snapshot"
)
// Checks which cover former issues found in older layering models.
//
// NOTE: In older models, applying with tar was used to create read only layers,
// however with the snapshot model read only layers are created just using
// mounts and commits. Read write layers are a separate type of snapshot which
// is not committed, avoiding any confusion in the snapshotter about whether
// a snapshot will be mutated in the future.
// checkLayerFileUpdate tests the update of a single file in an upper layer
// Cause of issue was originally related to tar, snapshot should be able to
// avoid such issues by not relying on tar to create layers.
// See https://github.com/docker/docker/issues/21555
func checkLayerFileUpdate(ctx context.Context, t *testing.T, sn snapshot.Snapshotter, work string) {
l1Init := fstest.Apply(
fstest.CreateDir("/etc", 0700),
fstest.CreateFile("/etc/hosts", []byte("mydomain 10.0.0.1"), 0644),
fstest.CreateFile("/etc/profile", []byte("PATH=/usr/bin"), 0644),
)
l2Init := fstest.Apply(
fstest.CreateFile("/etc/hosts", []byte("mydomain 10.0.0.2"), 0644),
fstest.CreateFile("/etc/profile", []byte("PATH=/usr/bin"), 0666),
fstest.CreateDir("/root", 0700),
fstest.CreateFile("/root/.bashrc", []byte("PATH=/usr/sbin:/usr/bin"), 0644),
)
var sleepTime time.Duration
// run 5 times to account for sporadic failure
for i := 0; i < 5; i++ {
time.Sleep(sleepTime)
if err := checkSnapshots(ctx, sn, work, l1Init, l2Init); err != nil {
t.Fatalf("Check snapshots failed: %+v", err)
}
// Sleep until next second boundary before running again
nextTime := time.Now()
sleepTime = time.Unix(nextTime.Unix()+1, 0).Sub(nextTime)
}
}
// checkRemoveDirectoryInLowerLayer
// See https://github.com/docker/docker/issues/25244
func checkRemoveDirectoryInLowerLayer(ctx context.Context, t *testing.T, sn snapshot.Snapshotter, work string) {
l1Init := fstest.Apply(
fstest.CreateDir("/lib", 0700),
fstest.CreateFile("/lib/hidden", []byte{}, 0644),
)
l2Init := fstest.Apply(
fstest.RemoveAll("/lib"),
fstest.CreateDir("/lib", 0700),
fstest.CreateFile("/lib/not-hidden", []byte{}, 0644),
)
l3Init := fstest.Apply(
fstest.CreateFile("/lib/newfile", []byte{}, 0644),
)
if err := checkSnapshots(ctx, sn, work, l1Init, l2Init, l3Init); err != nil {
t.Fatalf("Check snapshots failed: %+v", err)
}
}
// checkChown
// See https://github.com/docker/docker/issues/20240 aufs
// See https://github.com/docker/docker/issues/24913 overlay
// see https://github.com/docker/docker/issues/28391 overlay2
func checkChown(ctx context.Context, t *testing.T, sn snapshot.Snapshotter, work string) {
l1Init := fstest.Apply(
fstest.CreateDir("/opt", 0700),
fstest.CreateDir("/opt/a", 0700),
fstest.CreateDir("/opt/a/b", 0700),
fstest.CreateFile("/opt/a/b/file.txt", []byte("hello"), 0644),
)
l2Init := fstest.Apply(
fstest.Chown("/opt", 1, 1),
fstest.Chown("/opt/a", 1, 1),
fstest.Chown("/opt/a/b", 1, 1),
fstest.Chown("/opt/a/b/file.txt", 1, 1),
)
if err := checkSnapshots(ctx, sn, work, l1Init, l2Init); err != nil {
t.Fatalf("Check snapshots failed: %+v", err)
}
}
// checkRename
// https://github.com/docker/docker/issues/25409
func checkRename(ctx context.Context, t *testing.T, sn snapshot.Snapshotter, work string) {
l1Init := fstest.Apply(
fstest.CreateDir("/dir1", 0700),
fstest.CreateDir("/somefiles", 0700),
fstest.CreateFile("/somefiles/f1", []byte("was here first!"), 0644),
fstest.CreateFile("/somefiles/f2", []byte("nothing interesting"), 0644),
)
l2Init := fstest.Apply(
fstest.Rename("/dir1", "/dir2"),
fstest.CreateFile("/somefiles/f1-overwrite", []byte("new content 1"), 0644),
fstest.Rename("/somefiles/f1-overwrite", "/somefiles/f1"),
fstest.Rename("/somefiles/f2", "/somefiles/f3"),
)
if err := checkSnapshots(ctx, sn, work, l1Init, l2Init); err != nil {
t.Fatalf("Check snapshots failed: %+v", err)
}
}
// checkDirectoryPermissionOnCommit
// https://github.com/docker/docker/issues/27298
func checkDirectoryPermissionOnCommit(ctx context.Context, t *testing.T, sn snapshot.Snapshotter, work string) {
l1Init := fstest.Apply(
fstest.CreateDir("/dir1", 0700),
fstest.CreateDir("/dir2", 0700),
fstest.CreateDir("/dir3", 0700),
fstest.CreateDir("/dir4", 0700),
fstest.CreateFile("/dir4/f1", []byte("..."), 0644),
fstest.CreateDir("/dir5", 0700),
fstest.CreateFile("/dir5/f1", []byte("..."), 0644),
fstest.Chown("/dir1", 1, 1),
fstest.Chown("/dir2", 1, 1),
fstest.Chown("/dir3", 1, 1),
fstest.Chown("/dir5", 1, 1),
fstest.Chown("/dir5/f1", 1, 1),
)
l2Init := fstest.Apply(
fstest.Chown("/dir2", 0, 0),
fstest.RemoveAll("/dir3"),
fstest.Chown("/dir4", 1, 1),
fstest.Chown("/dir4/f1", 1, 1),
)
l3Init := fstest.Apply(
fstest.CreateDir("/dir3", 0700),
fstest.Chown("/dir3", 1, 1),
fstest.RemoveAll("/dir5"),
fstest.CreateDir("/dir5", 0700),
fstest.Chown("/dir5", 1, 1),
)
if err := checkSnapshots(ctx, sn, work, l1Init, l2Init, l3Init); err != nil {
t.Fatalf("Check snapshots failed: %+v", err)
}
}
// More issues to test
//
// checkRemoveAfterCommit
// See https://github.com/docker/docker/issues/24309
//
// checkUnixDomainSockets
// See https://github.com/docker/docker/issues/12080
//
// checkDirectoryInodeStability
// See https://github.com/docker/docker/issues/19647
//
// checkOpenFileInodeStability
// See https://github.com/docker/docker/issues/12327
//
// checkGetCWD
// See https://github.com/docker/docker/issues/19082
//
// checkChmod
// See https://github.com/docker/machine/issues/3327