From 132d0028ba5b3ab608e3a6fc198d4196466bab27 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Fri, 23 Jan 2015 13:58:28 -0500 Subject: [PATCH] Adds unit tests for volumes Cleans up some dead code Signed-off-by: Brian Goff --- volumes/repository.go | 18 +--- volumes/repository_test.go | 164 +++++++++++++++++++++++++++++++++++++ volumes/volume_test.go | 19 +++++ 3 files changed, 184 insertions(+), 17 deletions(-) create mode 100644 volumes/repository_test.go create mode 100644 volumes/volume_test.go diff --git a/volumes/repository.go b/volumes/repository.go index e125677680..f9aaaa50b2 100644 --- a/volumes/repository.go +++ b/volumes/repository.go @@ -125,12 +125,6 @@ func (r *Repository) get(path string) *Volume { return r.volumes[filepath.Clean(path)] } -func (r *Repository) Add(volume *Volume) error { - r.lock.Lock() - defer r.lock.Unlock() - return r.add(volume) -} - func (r *Repository) add(volume *Volume) error { if vol := r.get(volume.Path); vol != nil { return fmt.Errorf("Volume exists: %s", volume.ID) @@ -139,16 +133,6 @@ func (r *Repository) add(volume *Volume) error { return nil } -func (r *Repository) Remove(volume *Volume) { - r.lock.Lock() - r.remove(volume) - r.lock.Unlock() -} - -func (r *Repository) remove(volume *Volume) { - delete(r.volumes, volume.Path) -} - func (r *Repository) Delete(path string) error { r.lock.Lock() defer r.lock.Unlock() @@ -178,7 +162,7 @@ func (r *Repository) Delete(path string) error { } } - r.remove(volume) + delete(r.volumes, volume.Path) return nil } diff --git a/volumes/repository_test.go b/volumes/repository_test.go new file mode 100644 index 0000000000..801c225f75 --- /dev/null +++ b/volumes/repository_test.go @@ -0,0 +1,164 @@ +package volumes + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/docker/docker/daemon/graphdriver" + _ "github.com/docker/docker/daemon/graphdriver/vfs" +) + +func TestRepositoryFindOrCreate(t *testing.T) { + root, err := ioutil.TempDir(os.TempDir(), "volumes") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(root) + repo, err := newRepo(root) + if err != nil { + t.Fatal(err) + } + + // no path + v, err := repo.FindOrCreateVolume("", true) + if err != nil { + t.Fatal(err) + } + + // FIXME: volumes are heavily dependent on the vfs driver, but this should not be so! + expected := filepath.Join(root, "repo-graph", "vfs", "dir", v.ID) + if v.Path != expected { + t.Fatalf("expected new path to be created in %s, got %s", expected, v.Path) + } + + // with a non-existant path + dir := filepath.Join(root, "doesntexist") + v, err = repo.FindOrCreateVolume(dir, true) + if err != nil { + t.Fatal(err) + } + + if v.Path != dir { + t.Fatalf("expected new path to be created in %s, got %s", dir, v.Path) + } + + if _, err := os.Stat(v.Path); err != nil { + t.Fatal(err) + } + + // with a pre-existing path + // can just use the same path from above since it now exists + v, err = repo.FindOrCreateVolume(dir, true) + if err != nil { + t.Fatal(err) + } + if v.Path != dir { + t.Fatalf("expected new path to be created in %s, got %s", dir, v.Path) + } + +} + +func TestRepositoryGet(t *testing.T) { + root, err := ioutil.TempDir(os.TempDir(), "volumes") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(root) + repo, err := newRepo(root) + if err != nil { + t.Fatal(err) + } + + v, err := repo.FindOrCreateVolume("", true) + if err != nil { + t.Fatal(err) + } + + v2 := repo.Get(v.Path) + if v2 == nil { + t.Fatalf("expected to find volume but didn't") + } + if v2 != v { + t.Fatalf("expected get to return same volume") + } +} + +func TestRepositoryDelete(t *testing.T) { + root, err := ioutil.TempDir(os.TempDir(), "volumes") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(root) + repo, err := newRepo(root) + if err != nil { + t.Fatal(err) + } + + // with a normal volume + v, err := repo.FindOrCreateVolume("", true) + if err != nil { + t.Fatal(err) + } + + if err := repo.Delete(v.Path); err != nil { + t.Fatal(err) + } + + if v := repo.Get(v.Path); v != nil { + t.Fatalf("expected volume to not exist") + } + + if _, err := os.Stat(v.Path); err == nil { + t.Fatalf("expected volume files to be removed") + } + + // with a bind mount + dir := filepath.Join(root, "test") + v, err = repo.FindOrCreateVolume(dir, true) + if err != nil { + t.Fatal(err) + } + + if err := repo.Delete(v.Path); err != nil { + t.Fatal(err) + } + + if v := repo.Get(v.Path); v != nil { + t.Fatalf("expected volume to not exist") + } + + if _, err := os.Stat(v.Path); err != nil && os.IsNotExist(err) { + t.Fatalf("expected bind volume data to persist after destroying volume") + } + + // with container refs + dir = filepath.Join(root, "test") + v, err = repo.FindOrCreateVolume(dir, true) + if err != nil { + t.Fatal(err) + } + v.AddContainer("1234") + + if err := repo.Delete(v.Path); err == nil { + t.Fatalf("expected volume delete to fail due to container refs") + } + + v.RemoveContainer("1234") + if err := repo.Delete(v.Path); err != nil { + t.Fatal(err) + } + +} + +func newRepo(root string) (*Repository, error) { + configPath := filepath.Join(root, "repo-config") + graphDir := filepath.Join(root, "repo-graph") + + driver, err := graphdriver.GetDriver("vfs", graphDir, []string{}) + if err != nil { + return nil, err + } + return NewRepository(configPath, driver) +} diff --git a/volumes/volume_test.go b/volumes/volume_test.go new file mode 100644 index 0000000000..5f3fdcfe6b --- /dev/null +++ b/volumes/volume_test.go @@ -0,0 +1,19 @@ +package volumes + +import "testing" + +func TestContainers(t *testing.T) { + v := &Volume{containers: make(map[string]struct{})} + id := "1234" + + v.AddContainer(id) + + if v.Containers()[0] != id { + t.Fatalf("adding a container ref failed") + } + + v.RemoveContainer(id) + if len(v.Containers()) != 0 { + t.Fatalf("removing container failed") + } +}