github.com/stchris/docker@v1.4.2-0.20150106053530-1510a324dbd5/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 }