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  }