graphtest.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. package graphtest
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "path"
  7. "syscall"
  8. "testing"
  9. "github.com/docker/docker/daemon/graphdriver"
  10. )
  11. var (
  12. drv *Driver
  13. )
  14. // Driver conforms to graphdriver.Driver interface and
  15. // contains information such as root and reference count of the number of clients using it.
  16. // This helps in testing drivers added into the framework.
  17. type Driver struct {
  18. graphdriver.Driver
  19. root string
  20. refCount int
  21. }
  22. // InitLoopbacks ensures that the loopback devices are properly created within
  23. // the system running the device mapper tests.
  24. func InitLoopbacks() error {
  25. statT, err := getBaseLoopStats()
  26. if err != nil {
  27. return err
  28. }
  29. // create at least 8 loopback files, ya, that is a good number
  30. for i := 0; i < 8; i++ {
  31. loopPath := fmt.Sprintf("/dev/loop%d", i)
  32. // only create new loopback files if they don't exist
  33. if _, err := os.Stat(loopPath); err != nil {
  34. if mkerr := syscall.Mknod(loopPath,
  35. uint32(statT.Mode|syscall.S_IFBLK), int((7<<8)|(i&0xff)|((i&0xfff00)<<12))); mkerr != nil {
  36. return mkerr
  37. }
  38. os.Chown(loopPath, int(statT.Uid), int(statT.Gid))
  39. }
  40. }
  41. return nil
  42. }
  43. // getBaseLoopStats inspects /dev/loop0 to collect uid,gid, and mode for the
  44. // loop0 device on the system. If it does not exist we assume 0,0,0660 for the
  45. // stat data
  46. func getBaseLoopStats() (*syscall.Stat_t, error) {
  47. loop0, err := os.Stat("/dev/loop0")
  48. if err != nil {
  49. if os.IsNotExist(err) {
  50. return &syscall.Stat_t{
  51. Uid: 0,
  52. Gid: 0,
  53. Mode: 0660,
  54. }, nil
  55. }
  56. return nil, err
  57. }
  58. return loop0.Sys().(*syscall.Stat_t), nil
  59. }
  60. func newDriver(t *testing.T, name string) *Driver {
  61. root, err := ioutil.TempDir("/var/tmp", "docker-graphtest-")
  62. if err != nil {
  63. t.Fatal(err)
  64. }
  65. if err := os.MkdirAll(root, 0755); err != nil {
  66. t.Fatal(err)
  67. }
  68. d, err := graphdriver.GetDriver(name, root, nil)
  69. if err != nil {
  70. t.Logf("graphdriver: %v\n", err)
  71. if err == graphdriver.ErrNotSupported || err == graphdriver.ErrPrerequisites || err == graphdriver.ErrIncompatibleFS {
  72. t.Skipf("Driver %s not supported", name)
  73. }
  74. t.Fatal(err)
  75. }
  76. return &Driver{d, root, 1}
  77. }
  78. func cleanup(t *testing.T, d *Driver) {
  79. if err := drv.Cleanup(); err != nil {
  80. t.Fatal(err)
  81. }
  82. os.RemoveAll(d.root)
  83. }
  84. // GetDriver create a new driver with given name or return a existing driver with the name updating the reference count.
  85. func GetDriver(t *testing.T, name string) graphdriver.Driver {
  86. if drv == nil {
  87. drv = newDriver(t, name)
  88. } else {
  89. drv.refCount++
  90. }
  91. return drv
  92. }
  93. // PutDriver removes the driver if it is no longer used and updates the reference count.
  94. func PutDriver(t *testing.T) {
  95. if drv == nil {
  96. t.Skip("No driver to put!")
  97. }
  98. drv.refCount--
  99. if drv.refCount == 0 {
  100. cleanup(t, drv)
  101. drv = nil
  102. }
  103. }
  104. func verifyFile(t *testing.T, path string, mode os.FileMode, uid, gid uint32) {
  105. fi, err := os.Stat(path)
  106. if err != nil {
  107. t.Fatal(err)
  108. }
  109. if fi.Mode()&os.ModeType != mode&os.ModeType {
  110. t.Fatalf("Expected %s type 0x%x, got 0x%x", path, mode&os.ModeType, fi.Mode()&os.ModeType)
  111. }
  112. if fi.Mode()&os.ModePerm != mode&os.ModePerm {
  113. t.Fatalf("Expected %s mode %o, got %o", path, mode&os.ModePerm, fi.Mode()&os.ModePerm)
  114. }
  115. if fi.Mode()&os.ModeSticky != mode&os.ModeSticky {
  116. t.Fatalf("Expected %s sticky 0x%x, got 0x%x", path, mode&os.ModeSticky, fi.Mode()&os.ModeSticky)
  117. }
  118. if fi.Mode()&os.ModeSetuid != mode&os.ModeSetuid {
  119. t.Fatalf("Expected %s setuid 0x%x, got 0x%x", path, mode&os.ModeSetuid, fi.Mode()&os.ModeSetuid)
  120. }
  121. if fi.Mode()&os.ModeSetgid != mode&os.ModeSetgid {
  122. t.Fatalf("Expected %s setgid 0x%x, got 0x%x", path, mode&os.ModeSetgid, fi.Mode()&os.ModeSetgid)
  123. }
  124. if stat, ok := fi.Sys().(*syscall.Stat_t); ok {
  125. if stat.Uid != uid {
  126. t.Fatalf("%s no owned by uid %d", path, uid)
  127. }
  128. if stat.Gid != gid {
  129. t.Fatalf("%s not owned by gid %d", path, gid)
  130. }
  131. }
  132. }
  133. // readDir reads a directory just like ioutil.ReadDir()
  134. // then hides specific files (currently "lost+found")
  135. // so the tests don't "see" it
  136. func readDir(dir string) ([]os.FileInfo, error) {
  137. a, err := ioutil.ReadDir(dir)
  138. if err != nil {
  139. return nil, err
  140. }
  141. b := a[:0]
  142. for _, x := range a {
  143. if x.Name() != "lost+found" { // ext4 always have this dir
  144. b = append(b, x)
  145. }
  146. }
  147. return b, nil
  148. }
  149. // DriverTestCreateEmpty creates an new image and verifies it is empty and the right metadata
  150. func DriverTestCreateEmpty(t *testing.T, drivername string) {
  151. driver := GetDriver(t, drivername)
  152. defer PutDriver(t)
  153. if err := driver.Create("empty", ""); err != nil {
  154. t.Fatal(err)
  155. }
  156. if !driver.Exists("empty") {
  157. t.Fatal("Newly created image doesn't exist")
  158. }
  159. dir, err := driver.Get("empty", "")
  160. if err != nil {
  161. t.Fatal(err)
  162. }
  163. verifyFile(t, dir, 0755|os.ModeDir, 0, 0)
  164. // Verify that the directory is empty
  165. fis, err := readDir(dir)
  166. if err != nil {
  167. t.Fatal(err)
  168. }
  169. if len(fis) != 0 {
  170. t.Fatal("New directory not empty")
  171. }
  172. driver.Put("empty")
  173. if err := driver.Remove("empty"); err != nil {
  174. t.Fatal(err)
  175. }
  176. }
  177. func createBase(t *testing.T, driver graphdriver.Driver, name string) {
  178. // We need to be able to set any perms
  179. oldmask := syscall.Umask(0)
  180. defer syscall.Umask(oldmask)
  181. if err := driver.Create(name, ""); err != nil {
  182. t.Fatal(err)
  183. }
  184. dir, err := driver.Get(name, "")
  185. if err != nil {
  186. t.Fatal(err)
  187. }
  188. defer driver.Put(name)
  189. subdir := path.Join(dir, "a subdir")
  190. if err := os.Mkdir(subdir, 0705|os.ModeSticky); err != nil {
  191. t.Fatal(err)
  192. }
  193. if err := os.Chown(subdir, 1, 2); err != nil {
  194. t.Fatal(err)
  195. }
  196. file := path.Join(dir, "a file")
  197. if err := ioutil.WriteFile(file, []byte("Some data"), 0222|os.ModeSetuid); err != nil {
  198. t.Fatal(err)
  199. }
  200. }
  201. func verifyBase(t *testing.T, driver graphdriver.Driver, name string) {
  202. dir, err := driver.Get(name, "")
  203. if err != nil {
  204. t.Fatal(err)
  205. }
  206. defer driver.Put(name)
  207. subdir := path.Join(dir, "a subdir")
  208. verifyFile(t, subdir, 0705|os.ModeDir|os.ModeSticky, 1, 2)
  209. file := path.Join(dir, "a file")
  210. verifyFile(t, file, 0222|os.ModeSetuid, 0, 0)
  211. fis, err := readDir(dir)
  212. if err != nil {
  213. t.Fatal(err)
  214. }
  215. if len(fis) != 2 {
  216. t.Fatal("Unexpected files in base image")
  217. }
  218. }
  219. // DriverTestCreateBase create a base driver and verify.
  220. func DriverTestCreateBase(t *testing.T, drivername string) {
  221. driver := GetDriver(t, drivername)
  222. defer PutDriver(t)
  223. createBase(t, driver, "Base")
  224. verifyBase(t, driver, "Base")
  225. if err := driver.Remove("Base"); err != nil {
  226. t.Fatal(err)
  227. }
  228. }
  229. // DriverTestCreateSnap Create a driver and snap and verify.
  230. func DriverTestCreateSnap(t *testing.T, drivername string) {
  231. driver := GetDriver(t, drivername)
  232. defer PutDriver(t)
  233. createBase(t, driver, "Base")
  234. if err := driver.Create("Snap", "Base"); err != nil {
  235. t.Fatal(err)
  236. }
  237. verifyBase(t, driver, "Snap")
  238. if err := driver.Remove("Snap"); err != nil {
  239. t.Fatal(err)
  240. }
  241. if err := driver.Remove("Base"); err != nil {
  242. t.Fatal(err)
  243. }
  244. }