Просмотр исходного кода

Fix the behavior of Graph.Register so that it can be interrupted without side effect

Solomon Hykes 12 лет назад
Родитель
Сommit
13d9e26edd
2 измененных файлов с 28 добавлено и 1 удалено
  1. 1 1
      graph.go
  2. 27 0
      graph_test.go

+ 1 - 1
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)

+ 27 - 0
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) {