github.com/jogo/docker@v1.7.0-rc1/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 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: stringid.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 := image.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: stringid.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(stringid.TruncateID(img.ID)); err != nil { 163 t.Fatal(err) 164 } 165 assertNImages(graph, t, 0) 166 } 167 168 func TestDelete(t *testing.T) { 169 graph, _ := tempGraph(t) 170 defer nukeGraph(graph) 171 archive, err := fakeTar() 172 if err != nil { 173 t.Fatal(err) 174 } 175 assertNImages(graph, t, 0) 176 img, err := graph.Create(archive, "", "", "Bla bla", "", nil, nil) 177 if err != nil { 178 t.Fatal(err) 179 } 180 assertNImages(graph, t, 1) 181 if err := graph.Delete(img.ID); err != nil { 182 t.Fatal(err) 183 } 184 assertNImages(graph, t, 0) 185 186 archive, err = fakeTar() 187 if err != nil { 188 t.Fatal(err) 189 } 190 // Test 2 create (same name) / 1 delete 191 img1, err := graph.Create(archive, "", "", "Testing", "", nil, nil) 192 if err != nil { 193 t.Fatal(err) 194 } 195 archive, err = fakeTar() 196 if err != nil { 197 t.Fatal(err) 198 } 199 if _, err = graph.Create(archive, "", "", "Testing", "", nil, nil); err != nil { 200 t.Fatal(err) 201 } 202 assertNImages(graph, t, 2) 203 if err := graph.Delete(img1.ID); err != nil { 204 t.Fatal(err) 205 } 206 assertNImages(graph, t, 1) 207 208 // Test delete wrong name 209 if err := graph.Delete("Not_foo"); err == nil { 210 t.Fatalf("Deleting wrong ID should return an error") 211 } 212 assertNImages(graph, t, 1) 213 214 archive, err = fakeTar() 215 if err != nil { 216 t.Fatal(err) 217 } 218 // Test delete twice (pull -> rm -> pull -> rm) 219 if err := graph.Register(img1, archive); err != nil { 220 t.Fatal(err) 221 } 222 if err := graph.Delete(img1.ID); err != nil { 223 t.Fatal(err) 224 } 225 assertNImages(graph, t, 1) 226 } 227 228 func TestByParent(t *testing.T) { 229 archive1, _ := fakeTar() 230 archive2, _ := fakeTar() 231 archive3, _ := fakeTar() 232 233 graph, _ := tempGraph(t) 234 defer nukeGraph(graph) 235 parentImage := &image.Image{ 236 ID: stringid.GenerateRandomID(), 237 Comment: "parent", 238 Created: time.Now(), 239 Parent: "", 240 } 241 childImage1 := &image.Image{ 242 ID: stringid.GenerateRandomID(), 243 Comment: "child1", 244 Created: time.Now(), 245 Parent: parentImage.ID, 246 } 247 childImage2 := &image.Image{ 248 ID: stringid.GenerateRandomID(), 249 Comment: "child2", 250 Created: time.Now(), 251 Parent: parentImage.ID, 252 } 253 _ = graph.Register(parentImage, archive1) 254 _ = graph.Register(childImage1, archive2) 255 _ = graph.Register(childImage2, archive3) 256 257 byParent, err := graph.ByParent() 258 if err != nil { 259 t.Fatal(err) 260 } 261 numChildren := len(byParent[parentImage.ID]) 262 if numChildren != 2 { 263 t.Fatalf("Expected 2 children, found %d", numChildren) 264 } 265 } 266 267 func createTestImage(graph *Graph, t *testing.T) *image.Image { 268 archive, err := fakeTar() 269 if err != nil { 270 t.Fatal(err) 271 } 272 img, err := graph.Create(archive, "", "", "Test image", "", nil, nil) 273 if err != nil { 274 t.Fatal(err) 275 } 276 return img 277 } 278 279 func assertNImages(graph *Graph, t *testing.T, n int) { 280 if images, err := graph.Map(); err != nil { 281 t.Fatal(err) 282 } else if actualN := len(images); actualN != n { 283 t.Fatalf("Expected %d images, found %d", n, actualN) 284 } 285 } 286 287 func tempGraph(t *testing.T) (*Graph, graphdriver.Driver) { 288 tmp, err := ioutil.TempDir("", "docker-graph-") 289 if err != nil { 290 t.Fatal(err) 291 } 292 driver, err := graphdriver.New(tmp, nil) 293 if err != nil { 294 t.Fatal(err) 295 } 296 graph, err := NewGraph(tmp, driver) 297 if err != nil { 298 t.Fatal(err) 299 } 300 return graph, driver 301 } 302 303 func nukeGraph(graph *Graph) { 304 graph.Driver().Cleanup() 305 os.RemoveAll(graph.Root) 306 }