github.com/wozhu6104/docker@v20.10.10+incompatible/quota/testhelpers.go (about)

     1  // +build linux,!exclude_disk_quota,cgo
     2  
     3  package quota // import "github.com/docker/docker/quota"
     4  
     5  import (
     6  	"io/ioutil"
     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 := ioutil.TempFile("", "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 := ioutil.TempDir(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 := ioutil.TempDir(testDir, "quota-test")
   119  		assert.NilError(t, err)
   120  		testFunc(t, ctrl, mountPoint, testDir, testSubDir)
   121  	}
   122  }