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