github.com/crquan/docker@v1.8.1/graph/graph_test.go (about)

     1  package graph
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"path"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/docker/docker/autogen/dockerversion"
    13  	"github.com/docker/docker/daemon/graphdriver"
    14  	"github.com/docker/docker/image"
    15  	"github.com/docker/docker/pkg/stringid"
    16  )
    17  
    18  func TestMount(t *testing.T) {
    19  	graph, driver := tempGraph(t)
    20  	defer os.RemoveAll(graph.root)
    21  	defer driver.Cleanup()
    22  
    23  	archive, err := fakeTar()
    24  	if err != nil {
    25  		t.Fatal(err)
    26  	}
    27  	image, err := graph.Create(archive, "", "", "Testing", "", nil, nil)
    28  	if err != nil {
    29  		t.Fatal(err)
    30  	}
    31  	tmp, err := ioutil.TempDir("", "docker-test-graph-mount-")
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  	defer os.RemoveAll(tmp)
    36  	rootfs := path.Join(tmp, "rootfs")
    37  	if err := os.MkdirAll(rootfs, 0700); err != nil {
    38  		t.Fatal(err)
    39  	}
    40  	rw := path.Join(tmp, "rw")
    41  	if err := os.MkdirAll(rw, 0700); err != nil {
    42  		t.Fatal(err)
    43  	}
    44  
    45  	if _, err := driver.Get(image.ID, ""); err != nil {
    46  		t.Fatal(err)
    47  	}
    48  
    49  }
    50  
    51  func TestInit(t *testing.T) {
    52  	graph, _ := tempGraph(t)
    53  	defer nukeGraph(graph)
    54  	// Root should exist
    55  	if _, err := os.Stat(graph.root); err != nil {
    56  		t.Fatal(err)
    57  	}
    58  	// Map() should be empty
    59  	l := graph.Map()
    60  	if len(l) != 0 {
    61  		t.Fatalf("len(Map()) should return %d, not %d", 0, len(l))
    62  	}
    63  }
    64  
    65  // Test that Register can be interrupted cleanly without side effects
    66  func TestInterruptedRegister(t *testing.T) {
    67  	graph, _ := tempGraph(t)
    68  	defer nukeGraph(graph)
    69  	badArchive, w := io.Pipe() // Use a pipe reader as a fake archive which never yields data
    70  	image := &image.Image{
    71  		ID:      stringid.GenerateRandomID(),
    72  		Comment: "testing",
    73  		Created: time.Now(),
    74  	}
    75  	w.CloseWithError(errors.New("But I'm not a tarball!")) // (Nobody's perfect, darling)
    76  	graph.Register(image, badArchive)
    77  	if _, err := graph.Get(image.ID); err == nil {
    78  		t.Fatal("Image should not exist after Register is interrupted")
    79  	}
    80  	// Registering the same image again should succeed if the first register was interrupted
    81  	goodArchive, err := fakeTar()
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  	if err := graph.Register(image, goodArchive); err != nil {
    86  		t.Fatal(err)
    87  	}
    88  }
    89  
    90  // FIXME: Do more extensive tests (ex: create multiple, delete, recreate;
    91  //       create multiple, check the amount of images and paths, etc..)
    92  func TestGraphCreate(t *testing.T) {
    93  	graph, _ := tempGraph(t)
    94  	defer nukeGraph(graph)
    95  	archive, err := fakeTar()
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  	img, err := graph.Create(archive, "", "", "Testing", "", nil, nil)
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  	if err := image.ValidateID(img.ID); err != nil {
   104  		t.Fatal(err)
   105  	}
   106  	if img.Comment != "Testing" {
   107  		t.Fatalf("Wrong comment: should be '%s', not '%s'", "Testing", img.Comment)
   108  	}
   109  	if img.DockerVersion != dockerversion.VERSION {
   110  		t.Fatalf("Wrong docker_version: should be '%s', not '%s'", dockerversion.VERSION, img.DockerVersion)
   111  	}
   112  	images := graph.Map()
   113  	if l := len(images); l != 1 {
   114  		t.Fatalf("Wrong number of images. Should be %d, not %d", 1, l)
   115  	}
   116  	if images[img.ID] == nil {
   117  		t.Fatalf("Could not find image with id %s", img.ID)
   118  	}
   119  }
   120  
   121  func TestRegister(t *testing.T) {
   122  	graph, _ := tempGraph(t)
   123  	defer nukeGraph(graph)
   124  	archive, err := fakeTar()
   125  	if err != nil {
   126  		t.Fatal(err)
   127  	}
   128  	image := &image.Image{
   129  		ID:      stringid.GenerateRandomID(),
   130  		Comment: "testing",
   131  		Created: time.Now(),
   132  	}
   133  	err = graph.Register(image, archive)
   134  	if err != nil {
   135  		t.Fatal(err)
   136  	}
   137  	images := graph.Map()
   138  	if l := len(images); l != 1 {
   139  		t.Fatalf("Wrong number of images. Should be %d, not %d", 1, l)
   140  	}
   141  	if resultImg, err := graph.Get(image.ID); err != nil {
   142  		t.Fatal(err)
   143  	} else {
   144  		if resultImg.ID != image.ID {
   145  			t.Fatalf("Wrong image ID. Should be '%s', not '%s'", image.ID, resultImg.ID)
   146  		}
   147  		if resultImg.Comment != image.Comment {
   148  			t.Fatalf("Wrong image comment. Should be '%s', not '%s'", image.Comment, resultImg.Comment)
   149  		}
   150  	}
   151  }
   152  
   153  // Test that an image can be deleted by its shorthand prefix
   154  func TestDeletePrefix(t *testing.T) {
   155  	graph, _ := tempGraph(t)
   156  	defer nukeGraph(graph)
   157  	img := createTestImage(graph, t)
   158  	if err := graph.Delete(stringid.TruncateID(img.ID)); err != nil {
   159  		t.Fatal(err)
   160  	}
   161  	assertNImages(graph, t, 0)
   162  }
   163  
   164  func TestDelete(t *testing.T) {
   165  	graph, _ := tempGraph(t)
   166  	defer nukeGraph(graph)
   167  	archive, err := fakeTar()
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  	assertNImages(graph, t, 0)
   172  	img, err := graph.Create(archive, "", "", "Bla bla", "", nil, nil)
   173  	if err != nil {
   174  		t.Fatal(err)
   175  	}
   176  	assertNImages(graph, t, 1)
   177  	if err := graph.Delete(img.ID); err != nil {
   178  		t.Fatal(err)
   179  	}
   180  	assertNImages(graph, t, 0)
   181  
   182  	archive, err = fakeTar()
   183  	if err != nil {
   184  		t.Fatal(err)
   185  	}
   186  	// Test 2 create (same name) / 1 delete
   187  	img1, err := graph.Create(archive, "", "", "Testing", "", nil, nil)
   188  	if err != nil {
   189  		t.Fatal(err)
   190  	}
   191  	archive, err = fakeTar()
   192  	if err != nil {
   193  		t.Fatal(err)
   194  	}
   195  	if _, err = graph.Create(archive, "", "", "Testing", "", nil, nil); err != nil {
   196  		t.Fatal(err)
   197  	}
   198  	assertNImages(graph, t, 2)
   199  	if err := graph.Delete(img1.ID); err != nil {
   200  		t.Fatal(err)
   201  	}
   202  	assertNImages(graph, t, 1)
   203  
   204  	// Test delete wrong name
   205  	if err := graph.Delete("Not_foo"); err == nil {
   206  		t.Fatalf("Deleting wrong ID should return an error")
   207  	}
   208  	assertNImages(graph, t, 1)
   209  
   210  	archive, err = fakeTar()
   211  	if err != nil {
   212  		t.Fatal(err)
   213  	}
   214  	// Test delete twice (pull -> rm -> pull -> rm)
   215  	if err := graph.Register(img1, archive); err != nil {
   216  		t.Fatal(err)
   217  	}
   218  	if err := graph.Delete(img1.ID); err != nil {
   219  		t.Fatal(err)
   220  	}
   221  	assertNImages(graph, t, 1)
   222  }
   223  
   224  func TestByParent(t *testing.T) {
   225  	archive1, _ := fakeTar()
   226  	archive2, _ := fakeTar()
   227  	archive3, _ := fakeTar()
   228  
   229  	graph, _ := tempGraph(t)
   230  	defer nukeGraph(graph)
   231  	parentImage := &image.Image{
   232  		ID:      stringid.GenerateRandomID(),
   233  		Comment: "parent",
   234  		Created: time.Now(),
   235  		Parent:  "",
   236  	}
   237  	childImage1 := &image.Image{
   238  		ID:      stringid.GenerateRandomID(),
   239  		Comment: "child1",
   240  		Created: time.Now(),
   241  		Parent:  parentImage.ID,
   242  	}
   243  	childImage2 := &image.Image{
   244  		ID:      stringid.GenerateRandomID(),
   245  		Comment: "child2",
   246  		Created: time.Now(),
   247  		Parent:  parentImage.ID,
   248  	}
   249  	_ = graph.Register(parentImage, archive1)
   250  	_ = graph.Register(childImage1, archive2)
   251  	_ = graph.Register(childImage2, archive3)
   252  
   253  	byParent := graph.ByParent()
   254  	numChildren := len(byParent[parentImage.ID])
   255  	if numChildren != 2 {
   256  		t.Fatalf("Expected 2 children, found %d", numChildren)
   257  	}
   258  }
   259  
   260  func createTestImage(graph *Graph, t *testing.T) *image.Image {
   261  	archive, err := fakeTar()
   262  	if err != nil {
   263  		t.Fatal(err)
   264  	}
   265  	img, err := graph.Create(archive, "", "", "Test image", "", nil, nil)
   266  	if err != nil {
   267  		t.Fatal(err)
   268  	}
   269  	return img
   270  }
   271  
   272  func assertNImages(graph *Graph, t *testing.T, n int) {
   273  	images := graph.Map()
   274  	if actualN := len(images); actualN != n {
   275  		t.Fatalf("Expected %d images, found %d", n, actualN)
   276  	}
   277  }
   278  
   279  func tempGraph(t *testing.T) (*Graph, graphdriver.Driver) {
   280  	tmp, err := ioutil.TempDir("", "docker-graph-")
   281  	if err != nil {
   282  		t.Fatal(err)
   283  	}
   284  	driver, err := graphdriver.New(tmp, nil)
   285  	if err != nil {
   286  		t.Fatal(err)
   287  	}
   288  	graph, err := NewGraph(tmp, driver)
   289  	if err != nil {
   290  		t.Fatal(err)
   291  	}
   292  	return graph, driver
   293  }
   294  
   295  func nukeGraph(graph *Graph) {
   296  	graph.driver.Cleanup()
   297  	os.RemoveAll(graph.root)
   298  }