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  }