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