github.com/christopherobin/docker@v1.6.2/integration/graph_test.go (about)

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