testhelpers.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. //go:build linux && !exclude_disk_quota && cgo
  2. package quota // import "github.com/docker/docker/quota"
  3. import (
  4. "os"
  5. "os/exec"
  6. "testing"
  7. "golang.org/x/sys/unix"
  8. )
  9. const imageSize = 64 * 1024 * 1024
  10. // CanTestQuota - checks if xfs prjquota can be tested
  11. // returns a reason if not
  12. func CanTestQuota() (string, bool) {
  13. if os.Getuid() != 0 {
  14. return "requires mounts", false
  15. }
  16. _, err := exec.LookPath("mkfs.xfs")
  17. if err != nil {
  18. return "mkfs.xfs not found in PATH", false
  19. }
  20. return "", true
  21. }
  22. // PrepareQuotaTestImage - prepares an xfs prjquota test image
  23. // returns the path the the image on success
  24. func PrepareQuotaTestImage(t *testing.T) (string, error) {
  25. mkfs, err := exec.LookPath("mkfs.xfs")
  26. if err != nil {
  27. return "", err
  28. }
  29. // create a sparse image
  30. imageFile, err := os.CreateTemp("", "xfs-image")
  31. if err != nil {
  32. return "", err
  33. }
  34. imageFileName := imageFile.Name()
  35. if _, err = imageFile.Seek(imageSize-1, 0); err != nil {
  36. os.Remove(imageFileName)
  37. return "", err
  38. }
  39. if _, err = imageFile.Write([]byte{0}); err != nil {
  40. os.Remove(imageFileName)
  41. return "", err
  42. }
  43. if err = imageFile.Close(); err != nil {
  44. os.Remove(imageFileName)
  45. return "", err
  46. }
  47. // The reason for disabling these options is sometimes people run with a newer userspace
  48. // than kernelspace
  49. out, err := exec.Command(mkfs, "-m", "crc=0,finobt=0", imageFileName).CombinedOutput()
  50. if len(out) > 0 {
  51. t.Log(string(out))
  52. }
  53. if err != nil {
  54. os.Remove(imageFileName)
  55. return "", err
  56. }
  57. return imageFileName, nil
  58. }
  59. // WrapMountTest - wraps a test function such that it has easy access to a mountPoint and testDir
  60. // with guaranteed prjquota or guaranteed no prjquota support.
  61. func WrapMountTest(imageFileName string, enableQuota bool, testFunc func(t *testing.T, mountPoint, backingFsDev, testDir string)) func(*testing.T) {
  62. return func(t *testing.T) {
  63. mountOptions := "loop"
  64. if enableQuota {
  65. mountOptions = mountOptions + ",prjquota"
  66. }
  67. mountPoint := t.TempDir()
  68. out, err := exec.Command("mount", "-o", mountOptions, imageFileName, mountPoint).CombinedOutput()
  69. if err != nil {
  70. _, err := os.Stat("/proc/fs/xfs")
  71. if os.IsNotExist(err) {
  72. t.Skip("no /proc/fs/xfs")
  73. }
  74. }
  75. if err != nil {
  76. t.Fatalf("assertion failed: error is not nil: %v: mount failed: %s", err, out)
  77. }
  78. defer func() {
  79. if err := unix.Unmount(mountPoint, 0); err != nil {
  80. t.Fatalf("assertion failed: error is not nil: %v", err)
  81. }
  82. }()
  83. backingFsDev, err := makeBackingFsDev(mountPoint)
  84. if err != nil {
  85. t.Fatalf("assertion failed: error is not nil: %v", err)
  86. }
  87. testDir, err := os.MkdirTemp(mountPoint, "per-test")
  88. if err != nil {
  89. t.Fatalf("assertion failed: error is not nil: %v", err)
  90. }
  91. defer os.RemoveAll(testDir)
  92. testFunc(t, mountPoint, backingFsDev, testDir)
  93. }
  94. }
  95. // WrapQuotaTest - wraps a test function such that is has easy and guaranteed access to a quota Control
  96. // instance with a quota test dir under its control.
  97. func WrapQuotaTest(testFunc func(t *testing.T, ctrl *Control, mountPoint, testDir, testSubDir string)) func(t *testing.T, mountPoint, backingFsDev, testDir string) {
  98. return func(t *testing.T, mountPoint, backingFsDev, testDir string) {
  99. ctrl, err := NewControl(testDir)
  100. if err != nil {
  101. t.Fatalf("assertion failed: error is not nil: %v", err)
  102. }
  103. testSubDir, err := os.MkdirTemp(testDir, "quota-test")
  104. if err != nil {
  105. t.Fatalf("assertion failed: error is not nil: %v", err)
  106. }
  107. testFunc(t, ctrl, mountPoint, testDir, testSubDir)
  108. }
  109. }