From 13d9e26edd62228597cf8f060ed397f7ae00298a Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Wed, 17 Apr 2013 16:35:22 -0700 Subject: [PATCH] Fix the behavior of Graph.Register so that it can be interrupted without side effect --- graph.go | 2 +- graph_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/graph.go b/graph.go index e7044c25a0..afb89cd02b 100644 --- a/graph.go +++ b/graph.go @@ -111,7 +111,7 @@ func (graph *Graph) Register(layerData Archive, img *Image) error { if graph.Exists(img.Id) { return fmt.Errorf("Image %s already exists", img.Id) } - tmp, err := graph.Mktemp(img.Id) + tmp, err := graph.Mktemp("") defer os.RemoveAll(tmp) if err != nil { return fmt.Errorf("Mktemp failed: %s", err) diff --git a/graph_test.go b/graph_test.go index 7c40330aa4..8f28983494 100644 --- a/graph_test.go +++ b/graph_test.go @@ -3,6 +3,7 @@ package docker import ( "archive/tar" "bytes" + "errors" "io" "io/ioutil" "os" @@ -26,6 +27,32 @@ func TestInit(t *testing.T) { } } +// Test that Register can be interrupted cleanly without side effects +func TestInterruptedRegister(t *testing.T) { + graph := tempGraph(t) + defer os.RemoveAll(graph.Root) + badArchive, w := io.Pipe() // Use a pipe reader as a fake archive which never yields data + image := &Image{ + Id: GenerateId(), + Comment: "testing", + Created: time.Now(), + } + go graph.Register(badArchive, image) + time.Sleep(200 * time.Millisecond) + w.CloseWithError(errors.New("But I'm not a tarball!")) // (Nobody's perfect, darling) + if _, err := graph.Get(image.Id); err == nil { + t.Fatal("Image should not exist after Register is interrupted") + } + // Registering the same image again should succeed if the first register was interrupted + goodArchive, err := fakeTar() + if err != nil { + t.Fatal(err) + } + if err := graph.Register(goodArchive, image); err != nil { + t.Fatal(err) + } +} + // FIXME: Do more extensive tests (ex: create multiple, delete, recreate; // create multiple, check the amount of images and paths, etc..) func TestGraphCreate(t *testing.T) {