Open snapshot database only once

Prevents having multiple database connections open to a connection,
preventing bugs with locking by relying on the boltdb database
object to handle synchronization rather than file locking.

Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
Derek McGowan
2017-11-01 15:03:40 -07:00
parent c933088381
commit 68d3c77eae
5 changed files with 117 additions and 32 deletions

View File

@@ -122,3 +122,33 @@ func checkSnapshots(ctx context.Context, sn snapshot.Snapshotter, work string, a
return nil
}
// checkInfo checks that the infos are the same
func checkInfo(si1, si2 snapshot.Info) error {
if si1.Kind != si2.Kind {
return errors.Errorf("Expected kind %v, got %v", si1.Kind, si2.Kind)
}
if si1.Name != si2.Name {
return errors.Errorf("Expected name %v, got %v", si1.Name, si2.Name)
}
if si1.Parent != si2.Parent {
return errors.Errorf("Expected Parent %v, got %v", si1.Parent, si2.Parent)
}
if len(si1.Labels) != len(si2.Labels) {
return errors.Errorf("Expected %d labels, got %d", len(si1.Labels), len(si2.Labels))
}
for k, l1 := range si1.Labels {
l2 := si2.Labels[k]
if l1 != l2 {
return errors.Errorf("Expected label %v, got %v", l1, l2)
}
}
if si1.Created != si2.Created {
return errors.Errorf("Expected Created %v, got %v", si1.Created, si2.Created)
}
if si1.Updated != si2.Updated {
return errors.Errorf("Expected Updated %v, got %v", si1.Updated, si2.Updated)
}
return nil
}

View File

@@ -2,6 +2,8 @@ package testsuite
import (
"context"
"fmt"
"strings"
"testing"
"time"
@@ -151,6 +153,54 @@ func checkDirectoryPermissionOnCommit(ctx context.Context, t *testing.T, sn snap
}
}
// checkStatInWalk ensures that a stat can be called during a walk
func checkStatInWalk(ctx context.Context, t *testing.T, sn snapshot.Snapshotter, work string) {
prefix := "stats-in-walk-"
if err := createNamedSnapshots(ctx, sn, prefix); err != nil {
t.Fatal(err)
}
err := sn.Walk(ctx, func(ctx context.Context, si snapshot.Info) error {
if !strings.HasPrefix(si.Name, prefix) {
// Only stat snapshots from this test
return nil
}
si2, err := sn.Stat(ctx, si.Name)
if err != nil {
return err
}
return checkInfo(si, si2)
})
if err != nil {
t.Fatal(err)
}
}
func createNamedSnapshots(ctx context.Context, snapshotter snapshot.Snapshotter, ns string) error {
c1 := fmt.Sprintf("%sc1", ns)
c2 := fmt.Sprintf("%sc2", ns)
if _, err := snapshotter.Prepare(ctx, c1+"-a", ""); err != nil {
return err
}
if err := snapshotter.Commit(ctx, c1, c1+"-a"); err != nil {
return err
}
if _, err := snapshotter.Prepare(ctx, c2+"-a", c1); err != nil {
return err
}
if err := snapshotter.Commit(ctx, c2, c2+"-a"); err != nil {
return err
}
if _, err := snapshotter.Prepare(ctx, fmt.Sprintf("%sa1", ns), c2); err != nil {
return err
}
if _, err := snapshotter.View(ctx, fmt.Sprintf("%sv1", ns), c2); err != nil {
return err
}
return nil
}
// More issues to test
//
// checkRemoveAfterCommit
@@ -170,3 +220,6 @@ func checkDirectoryPermissionOnCommit(ctx context.Context, t *testing.T, sn snap
//
// checkChmod
// See https://github.com/docker/machine/issues/3327
//
// checkRemoveInWalk
// Allow mutations during walk without deadlocking

View File

@@ -42,6 +42,8 @@ func SnapshotterSuite(t *testing.T, name string, snapshotterFn func(ctx context.
//t.Run("Rename", makeTest(name, snapshotterFn, checkRename))
t.Run("ViewReadonly", makeTest(name, snapshotterFn, checkSnapshotterViewReadonly))
t.Run("StatInWalk", makeTest(name, snapshotterFn, checkStatInWalk))
}
func makeTest(name string, snapshotterFn func(ctx context.Context, root string) (snapshot.Snapshotter, func() error, error), fn func(ctx context.Context, t *testing.T, snapshotter snapshot.Snapshotter, work string)) func(t *testing.T) {