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