github.com/daaku/docker@v1.5.0/integration/graph_test.go (about)

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