mount_test.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package layer
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "path/filepath"
  6. "runtime"
  7. "sort"
  8. "testing"
  9. "github.com/docker/docker/pkg/archive"
  10. )
  11. func TestMountInit(t *testing.T) {
  12. // TODO Windows: Figure out why this is failing
  13. if runtime.GOOS == "windows" {
  14. t.Skip("Failing on Windows")
  15. }
  16. ls, _, cleanup := newTestStore(t)
  17. defer cleanup()
  18. basefile := newTestFile("testfile.txt", []byte("base data!"), 0644)
  19. initfile := newTestFile("testfile.txt", []byte("init data!"), 0777)
  20. li := initWithFiles(basefile)
  21. layer, err := createLayer(ls, "", li)
  22. if err != nil {
  23. t.Fatal(err)
  24. }
  25. mountInit := func(root string) error {
  26. return initfile.ApplyFile(root)
  27. }
  28. m, err := ls.CreateRWLayer("fun-mount", layer.ChainID(), "", mountInit, nil)
  29. if err != nil {
  30. t.Fatal(err)
  31. }
  32. path, err := m.Mount("")
  33. if err != nil {
  34. t.Fatal(err)
  35. }
  36. f, err := os.Open(filepath.Join(path, "testfile.txt"))
  37. if err != nil {
  38. t.Fatal(err)
  39. }
  40. defer f.Close()
  41. fi, err := f.Stat()
  42. if err != nil {
  43. t.Fatal(err)
  44. }
  45. b, err := ioutil.ReadAll(f)
  46. if err != nil {
  47. t.Fatal(err)
  48. }
  49. if expected := "init data!"; string(b) != expected {
  50. t.Fatalf("Unexpected test file contents %q, expected %q", string(b), expected)
  51. }
  52. if fi.Mode().Perm() != 0777 {
  53. t.Fatalf("Unexpected filemode %o, expecting %o", fi.Mode().Perm(), 0777)
  54. }
  55. }
  56. func TestMountSize(t *testing.T) {
  57. // TODO Windows: Figure out why this is failing
  58. if runtime.GOOS == "windows" {
  59. t.Skip("Failing on Windows")
  60. }
  61. ls, _, cleanup := newTestStore(t)
  62. defer cleanup()
  63. content1 := []byte("Base contents")
  64. content2 := []byte("Mutable contents")
  65. contentInit := []byte("why am I excluded from the size ☹")
  66. li := initWithFiles(newTestFile("file1", content1, 0644))
  67. layer, err := createLayer(ls, "", li)
  68. if err != nil {
  69. t.Fatal(err)
  70. }
  71. mountInit := func(root string) error {
  72. return newTestFile("file-init", contentInit, 0777).ApplyFile(root)
  73. }
  74. m, err := ls.CreateRWLayer("mount-size", layer.ChainID(), "", mountInit, nil)
  75. if err != nil {
  76. t.Fatal(err)
  77. }
  78. path, err := m.Mount("")
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. if err := ioutil.WriteFile(filepath.Join(path, "file2"), content2, 0755); err != nil {
  83. t.Fatal(err)
  84. }
  85. mountSize, err := m.Size()
  86. if err != nil {
  87. t.Fatal(err)
  88. }
  89. if expected := len(content2); int(mountSize) != expected {
  90. t.Fatalf("Unexpected mount size %d, expected %d", int(mountSize), expected)
  91. }
  92. }
  93. func TestMountChanges(t *testing.T) {
  94. // TODO Windows: Figure out why this is failing
  95. if runtime.GOOS == "windows" {
  96. t.Skip("Failing on Windows")
  97. }
  98. ls, _, cleanup := newTestStore(t)
  99. defer cleanup()
  100. basefiles := []FileApplier{
  101. newTestFile("testfile1.txt", []byte("base data!"), 0644),
  102. newTestFile("testfile2.txt", []byte("base data!"), 0644),
  103. newTestFile("testfile3.txt", []byte("base data!"), 0644),
  104. }
  105. initfile := newTestFile("testfile1.txt", []byte("init data!"), 0777)
  106. li := initWithFiles(basefiles...)
  107. layer, err := createLayer(ls, "", li)
  108. if err != nil {
  109. t.Fatal(err)
  110. }
  111. mountInit := func(root string) error {
  112. return initfile.ApplyFile(root)
  113. }
  114. m, err := ls.CreateRWLayer("mount-changes", layer.ChainID(), "", mountInit, nil)
  115. if err != nil {
  116. t.Fatal(err)
  117. }
  118. path, err := m.Mount("")
  119. if err != nil {
  120. t.Fatal(err)
  121. }
  122. if err := os.Chmod(filepath.Join(path, "testfile1.txt"), 0755); err != nil {
  123. t.Fatal(err)
  124. }
  125. if err := ioutil.WriteFile(filepath.Join(path, "testfile1.txt"), []byte("mount data!"), 0755); err != nil {
  126. t.Fatal(err)
  127. }
  128. if err := os.Remove(filepath.Join(path, "testfile2.txt")); err != nil {
  129. t.Fatal(err)
  130. }
  131. if err := os.Chmod(filepath.Join(path, "testfile3.txt"), 0755); err != nil {
  132. t.Fatal(err)
  133. }
  134. if err := ioutil.WriteFile(filepath.Join(path, "testfile4.txt"), []byte("mount data!"), 0644); err != nil {
  135. t.Fatal(err)
  136. }
  137. changes, err := m.Changes()
  138. if err != nil {
  139. t.Fatal(err)
  140. }
  141. if expected := 4; len(changes) != expected {
  142. t.Fatalf("Wrong number of changes %d, expected %d", len(changes), expected)
  143. }
  144. sortChanges(changes)
  145. assertChange(t, changes[0], archive.Change{
  146. Path: "/testfile1.txt",
  147. Kind: archive.ChangeModify,
  148. })
  149. assertChange(t, changes[1], archive.Change{
  150. Path: "/testfile2.txt",
  151. Kind: archive.ChangeDelete,
  152. })
  153. assertChange(t, changes[2], archive.Change{
  154. Path: "/testfile3.txt",
  155. Kind: archive.ChangeModify,
  156. })
  157. assertChange(t, changes[3], archive.Change{
  158. Path: "/testfile4.txt",
  159. Kind: archive.ChangeAdd,
  160. })
  161. }
  162. func assertChange(t *testing.T, actual, expected archive.Change) {
  163. if actual.Path != expected.Path {
  164. t.Fatalf("Unexpected change path %s, expected %s", actual.Path, expected.Path)
  165. }
  166. if actual.Kind != expected.Kind {
  167. t.Fatalf("Unexpected change type %s, expected %s", actual.Kind, expected.Kind)
  168. }
  169. }
  170. func sortChanges(changes []archive.Change) {
  171. cs := &changeSorter{
  172. changes: changes,
  173. }
  174. sort.Sort(cs)
  175. }
  176. type changeSorter struct {
  177. changes []archive.Change
  178. }
  179. func (cs *changeSorter) Len() int {
  180. return len(cs.changes)
  181. }
  182. func (cs *changeSorter) Swap(i, j int) {
  183. cs.changes[i], cs.changes[j] = cs.changes[j], cs.changes[i]
  184. }
  185. func (cs *changeSorter) Less(i, j int) bool {
  186. return cs.changes[i].Path < cs.changes[j].Path
  187. }