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