graph_test.go 7.0 KB

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