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