github.com/thy00/storage@v1.12.8/drivers/graphtest/graphtest_unix.go (about)

     1  // +build linux freebsd solaris
     2  
     3  package graphtest
     4  
     5  import (
     6  	"bytes"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"math/rand"
    10  	"os"
    11  	"path"
    12  	"path/filepath"
    13  	"reflect"
    14  	"testing"
    15  	"unsafe"
    16  
    17  	"github.com/containers/storage/drivers"
    18  	"github.com/containers/storage/pkg/archive"
    19  	"github.com/containers/storage/pkg/stringid"
    20  	"github.com/docker/go-units"
    21  	"github.com/pkg/errors"
    22  	"github.com/stretchr/testify/assert"
    23  	"github.com/stretchr/testify/require"
    24  	"golang.org/x/sys/unix"
    25  )
    26  
    27  var (
    28  	drv *Driver
    29  )
    30  
    31  // Driver conforms to graphdriver.Driver interface and
    32  // contains information such as root and reference count of the number of clients using it.
    33  // This helps in testing drivers added into the framework.
    34  type Driver struct {
    35  	graphdriver.Driver
    36  	root     string
    37  	refCount int
    38  }
    39  
    40  func newDriver(t testing.TB, name string, options []string) *Driver {
    41  	root, err := ioutil.TempDir("", "storage-graphtest-")
    42  	require.NoError(t, err)
    43  
    44  	require.NoError(t, os.MkdirAll(root, 0755))
    45  	d, err := graphdriver.GetDriver(name, graphdriver.Options{DriverOptions: options, Root: root})
    46  	if err != nil {
    47  		t.Logf("graphdriver: %v\n", err)
    48  		cause := errors.Cause(err)
    49  		if cause == graphdriver.ErrNotSupported || cause == graphdriver.ErrPrerequisites || cause == graphdriver.ErrIncompatibleFS {
    50  			t.Skipf("Driver %s not supported", name)
    51  		}
    52  		t.Fatal(err)
    53  	}
    54  	return &Driver{d, root, 1}
    55  }
    56  
    57  func cleanup(t testing.TB, d *Driver) {
    58  	if err := drv.Cleanup(); err != nil {
    59  		t.Fatal(err)
    60  	}
    61  	os.RemoveAll(d.root)
    62  }
    63  
    64  // GetDriver create a new driver with given name or return an existing driver with the name updating the reference count.
    65  func GetDriver(t testing.TB, name string, options ...string) graphdriver.Driver {
    66  	if drv == nil {
    67  		drv = newDriver(t, name, options)
    68  	} else {
    69  		drv.refCount++
    70  	}
    71  	return drv
    72  }
    73  
    74  // PutDriver removes the driver if it is no longer used and updates the reference count.
    75  func PutDriver(t testing.TB) {
    76  	if drv == nil {
    77  		t.Skip("No driver to put!")
    78  	}
    79  	drv.refCount--
    80  	if drv.refCount == 0 {
    81  		cleanup(t, drv)
    82  		drv = nil
    83  	}
    84  }
    85  
    86  // DriverTestCreateEmpty creates a new image and verifies it is empty and the right metadata
    87  func DriverTestCreateEmpty(t testing.TB, drivername string, driverOptions ...string) {
    88  	driver := GetDriver(t, drivername, driverOptions...)
    89  	defer PutDriver(t)
    90  
    91  	err := driver.Create("empty", "", nil)
    92  	require.NoError(t, err)
    93  
    94  	defer func() {
    95  		require.NoError(t, driver.Remove("empty"))
    96  	}()
    97  
    98  	if !driver.Exists("empty") {
    99  		t.Fatal("Newly created image doesn't exist")
   100  	}
   101  
   102  	dir, err := driver.Get("empty", graphdriver.MountOpts{})
   103  	require.NoError(t, err)
   104  
   105  	verifyFile(t, dir, 0755|os.ModeDir, 0, 0)
   106  
   107  	// Verify that the directory is empty
   108  	fis, err := readDir(dir)
   109  	require.NoError(t, err)
   110  	assert.Len(t, fis, 0)
   111  
   112  	driver.Put("empty")
   113  }
   114  
   115  // DriverTestCreateBase create a base driver and verify.
   116  func DriverTestCreateBase(t testing.TB, drivername string, driverOptions ...string) {
   117  	driver := GetDriver(t, drivername, driverOptions...)
   118  	defer PutDriver(t)
   119  
   120  	createBase(t, driver, "Base")
   121  	defer func() {
   122  		require.NoError(t, driver.Remove("Base"))
   123  	}()
   124  	verifyBase(t, driver, "Base")
   125  }
   126  
   127  // DriverTestCreateSnap Create a driver and snap and verify.
   128  func DriverTestCreateSnap(t testing.TB, drivername string, driverOptions ...string) {
   129  	driver := GetDriver(t, drivername, driverOptions...)
   130  	defer PutDriver(t)
   131  
   132  	createBase(t, driver, "Base")
   133  	defer func() {
   134  		require.NoError(t, driver.Remove("Base"))
   135  	}()
   136  
   137  	err := driver.Create("Snap", "Base", nil)
   138  	require.NoError(t, err)
   139  	defer func() {
   140  		require.NoError(t, driver.Remove("Snap"))
   141  	}()
   142  
   143  	verifyBase(t, driver, "Snap")
   144  }
   145  
   146  // DriverTestCreateFromTemplate Create a driver and template of a snap and verifies its
   147  // contents.
   148  func DriverTestCreateFromTemplate(t testing.TB, drivername string, driverOptions ...string) {
   149  	driver := GetDriver(t, drivername, driverOptions...)
   150  	defer PutDriver(t)
   151  
   152  	createBase(t, driver, "Base")
   153  	defer func() {
   154  		require.NoError(t, driver.Remove("Base"))
   155  	}()
   156  
   157  	err := driver.Create("Snap", "Base", nil)
   158  	require.NoError(t, err)
   159  	defer func() {
   160  		require.NoError(t, driver.Remove("Snap"))
   161  	}()
   162  
   163  	content := []byte("test content")
   164  	if err := addFile(driver, "Snap", "testfile.txt", content); err != nil {
   165  		t.Fatal(err)
   166  	}
   167  
   168  	err = driver.CreateFromTemplate("FromTemplate", "Snap", nil, "Base", nil, nil, true)
   169  	require.NoError(t, err)
   170  	defer func() {
   171  		require.NoError(t, driver.Remove("FromTemplate"))
   172  	}()
   173  
   174  	err = driver.CreateFromTemplate("ROFromTemplate", "Snap", nil, "Base", nil, nil, false)
   175  	require.NoError(t, err)
   176  	defer func() {
   177  		require.NoError(t, driver.Remove("ROFromTemplate"))
   178  	}()
   179  
   180  	noChanges := []archive.Change{}
   181  
   182  	changes, err := driver.Changes("FromTemplate", nil, "Snap", nil, "")
   183  	if err != nil {
   184  		t.Fatal(err)
   185  	}
   186  	if err = checkChanges(noChanges, changes); err != nil {
   187  		t.Fatal(err)
   188  	}
   189  
   190  	changes, err = driver.Changes("ROFromTemplate", nil, "Snap", nil, "")
   191  	if err != nil {
   192  		t.Fatal(err)
   193  	}
   194  	if err = checkChanges(noChanges, changes); err != nil {
   195  		t.Fatal(err)
   196  	}
   197  
   198  	if err := checkFile(driver, "FromTemplate", "testfile.txt", content); err != nil {
   199  		t.Fatal(err)
   200  	}
   201  	if err := checkFile(driver, "ROFromTemplate", "testfile.txt", content); err != nil {
   202  		t.Fatal(err)
   203  	}
   204  	if err := checkFile(driver, "Snap", "testfile.txt", content); err != nil {
   205  		t.Fatal(err)
   206  	}
   207  
   208  	expectedChanges := []archive.Change{{
   209  		Path: "/testfile.txt",
   210  		Kind: archive.ChangeAdd,
   211  	}}
   212  
   213  	changes, err = driver.Changes("Snap", nil, "Base", nil, "")
   214  	if err != nil {
   215  		t.Fatal(err)
   216  	}
   217  	if err = checkChanges(expectedChanges, changes); err != nil {
   218  		t.Fatal(err)
   219  	}
   220  
   221  	changes, err = driver.Changes("FromTemplate", nil, "Base", nil, "")
   222  	if err != nil {
   223  		t.Fatal(err)
   224  	}
   225  	if err = checkChanges(expectedChanges, changes); err != nil {
   226  		t.Fatal(err)
   227  	}
   228  
   229  	changes, err = driver.Changes("ROFromTemplate", nil, "Base", nil, "")
   230  	if err != nil {
   231  		t.Fatal(err)
   232  	}
   233  	if err = checkChanges(expectedChanges, changes); err != nil {
   234  		t.Fatal(err)
   235  	}
   236  
   237  	verifyBase(t, driver, "Base")
   238  }
   239  
   240  // DriverTestDeepLayerRead reads a file from a lower layer under a given number of layers
   241  func DriverTestDeepLayerRead(t testing.TB, layerCount int, drivername string, driverOptions ...string) {
   242  	driver := GetDriver(t, drivername, driverOptions...)
   243  	defer PutDriver(t)
   244  
   245  	base := stringid.GenerateRandomID()
   246  	if err := driver.Create(base, "", nil); err != nil {
   247  		t.Fatal(err)
   248  	}
   249  
   250  	content := []byte("test content")
   251  	if err := addFile(driver, base, "testfile.txt", content); err != nil {
   252  		t.Fatal(err)
   253  	}
   254  
   255  	topLayer, err := addManyLayers(driver, base, layerCount)
   256  	if err != nil {
   257  		t.Fatal(err)
   258  	}
   259  
   260  	err = checkManyLayers(driver, topLayer, layerCount)
   261  	if err != nil {
   262  		t.Fatal(err)
   263  	}
   264  
   265  	if err := checkFile(driver, topLayer, "testfile.txt", content); err != nil {
   266  		t.Fatal(err)
   267  	}
   268  }
   269  
   270  // DriverTestDiffApply tests diffing and applying produces the same layer
   271  func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverOptions ...string) {
   272  	driver := GetDriver(t, drivername, driverOptions...)
   273  	defer PutDriver(t)
   274  	base := stringid.GenerateRandomID()
   275  	upper := stringid.GenerateRandomID()
   276  	deleteFile := "file-remove.txt"
   277  	deleteFileContent := []byte("This file should get removed in upper!")
   278  	deleteDir := "var/lib"
   279  
   280  	if err := driver.Create(base, "", nil); err != nil {
   281  		t.Fatal(err)
   282  	}
   283  
   284  	if err := addManyFiles(driver, base, fileCount, 3); err != nil {
   285  		t.Fatal(err)
   286  	}
   287  
   288  	if err := addFile(driver, base, deleteFile, deleteFileContent); err != nil {
   289  		t.Fatal(err)
   290  	}
   291  
   292  	if err := addDirectory(driver, base, deleteDir); err != nil {
   293  		t.Fatal(err)
   294  	}
   295  
   296  	if err := driver.Create(upper, base, nil); err != nil {
   297  		t.Fatal(err)
   298  	}
   299  
   300  	if err := addManyFiles(driver, upper, fileCount, 6); err != nil {
   301  		t.Fatal(err)
   302  	}
   303  
   304  	if err := removeAll(driver, upper, deleteFile, deleteDir); err != nil {
   305  		t.Fatal(err)
   306  	}
   307  
   308  	diffSize, err := driver.DiffSize(upper, nil, "", nil, "")
   309  	if err != nil {
   310  		t.Fatal(err)
   311  	}
   312  
   313  	diff := stringid.GenerateRandomID()
   314  	if err := driver.Create(diff, base, nil); err != nil {
   315  		t.Fatal(err)
   316  	}
   317  
   318  	if err := checkManyFiles(driver, diff, fileCount, 3); err != nil {
   319  		t.Fatal(err)
   320  	}
   321  
   322  	if err := checkFile(driver, diff, deleteFile, deleteFileContent); err != nil {
   323  		t.Fatal(err)
   324  	}
   325  
   326  	arch, err := driver.Diff(upper, nil, base, nil, "")
   327  	if err != nil {
   328  		t.Fatal(err)
   329  	}
   330  
   331  	buf := bytes.NewBuffer(nil)
   332  	if _, err := buf.ReadFrom(arch); err != nil {
   333  		t.Fatal(err)
   334  	}
   335  	if err := arch.Close(); err != nil {
   336  		t.Fatal(err)
   337  	}
   338  
   339  	applyDiffSize, err := driver.ApplyDiff(diff, nil, base, "", bytes.NewReader(buf.Bytes()))
   340  	if err != nil {
   341  		t.Fatal(err)
   342  	}
   343  
   344  	if applyDiffSize != diffSize {
   345  		t.Fatalf("Apply diff size different, got %d, expected %d", applyDiffSize, diffSize)
   346  	}
   347  
   348  	if err := checkManyFiles(driver, diff, fileCount, 6); err != nil {
   349  		t.Fatal(err)
   350  	}
   351  
   352  	if err := checkFileRemoved(driver, diff, deleteFile); err != nil {
   353  		t.Fatal(err)
   354  	}
   355  
   356  	if err := checkFileRemoved(driver, diff, deleteDir); err != nil {
   357  		t.Fatal(err)
   358  	}
   359  }
   360  
   361  // DriverTestChanges tests computed changes on a layer matches changes made
   362  func DriverTestChanges(t testing.TB, drivername string, driverOptions ...string) {
   363  	driver := GetDriver(t, drivername, driverOptions...)
   364  	defer PutDriver(t)
   365  	base := stringid.GenerateRandomID()
   366  	upper := stringid.GenerateRandomID()
   367  	if err := driver.Create(base, "", nil); err != nil {
   368  		t.Fatal(err)
   369  	}
   370  
   371  	if err := addManyFiles(driver, base, 20, 3); err != nil {
   372  		t.Fatal(err)
   373  	}
   374  
   375  	if err := driver.Create(upper, base, nil); err != nil {
   376  		t.Fatal(err)
   377  	}
   378  
   379  	expectedChanges, err := changeManyFiles(driver, upper, 20, 6)
   380  	if err != nil {
   381  		t.Fatal(err)
   382  	}
   383  
   384  	changes, err := driver.Changes(upper, nil, base, nil, "")
   385  	if err != nil {
   386  		t.Fatal(err)
   387  	}
   388  
   389  	if err = checkChanges(expectedChanges, changes); err != nil {
   390  		t.Fatal(err)
   391  	}
   392  }
   393  
   394  func writeRandomFile(path string, size uint64) error {
   395  	buf := make([]int64, size/8)
   396  
   397  	r := rand.NewSource(0)
   398  	for i := range buf {
   399  		buf[i] = r.Int63()
   400  	}
   401  
   402  	// Cast to []byte
   403  	header := *(*reflect.SliceHeader)(unsafe.Pointer(&buf))
   404  	header.Len *= 8
   405  	header.Cap *= 8
   406  	data := *(*[]byte)(unsafe.Pointer(&header))
   407  
   408  	return ioutil.WriteFile(path, data, 0700)
   409  }
   410  
   411  // DriverTestSetQuota Create a driver and test setting quota.
   412  func DriverTestSetQuota(t *testing.T, drivername string) {
   413  	driver := GetDriver(t, drivername)
   414  	defer PutDriver(t)
   415  
   416  	createBase(t, driver, "Base")
   417  	createOpts := &graphdriver.CreateOpts{}
   418  	createOpts.StorageOpt = make(map[string]string, 1)
   419  	createOpts.StorageOpt["size"] = "50M"
   420  	if err := driver.Create("zfsTest", "Base", createOpts); err != nil {
   421  		t.Fatal(err)
   422  	}
   423  
   424  	mountPath, err := driver.Get("zfsTest", graphdriver.MountOpts{})
   425  	if err != nil {
   426  		t.Fatal(err)
   427  	}
   428  
   429  	quota := uint64(50 * units.MiB)
   430  	err = writeRandomFile(path.Join(mountPath, "file"), quota*2)
   431  	if pathError, ok := err.(*os.PathError); ok && pathError.Err != unix.EDQUOT {
   432  		t.Fatalf("expect write() to fail with %v, got %v", unix.EDQUOT, err)
   433  	}
   434  
   435  }
   436  
   437  // DriverTestEcho tests that we can diff a layer correctly, focusing on trouble spots that NaiveDiff doesn't have
   438  func DriverTestEcho(t testing.TB, drivername string, driverOptions ...string) {
   439  	driver := GetDriver(t, drivername, driverOptions...)
   440  	defer PutDriver(t)
   441  	var err error
   442  	var root string
   443  	components := 10
   444  
   445  	for depth := 0; depth < components; depth++ {
   446  		base := stringid.GenerateRandomID()
   447  		second := stringid.GenerateRandomID()
   448  		third := stringid.GenerateRandomID()
   449  
   450  		if err := driver.Create(base, "", nil); err != nil {
   451  			t.Fatal(err)
   452  		}
   453  
   454  		if root, err = driver.Get(base, graphdriver.MountOpts{}); err != nil {
   455  			t.Fatal(err)
   456  		}
   457  
   458  		paths := []string{}
   459  		path := "/"
   460  		expectedChanges := []archive.Change{}
   461  		for i := 0; i < components-1; i++ {
   462  			path = filepath.Join(path, fmt.Sprintf("subdir%d", i+1))
   463  			paths = append(paths, path)
   464  			if err = os.Mkdir(filepath.Join(root, path), 0700); err != nil {
   465  				t.Fatal(err)
   466  			}
   467  			expectedChanges = append(expectedChanges, archive.Change{Kind: archive.ChangeAdd, Path: path})
   468  		}
   469  		path = filepath.Join(path, "file")
   470  		paths = append(paths, path)
   471  		if err = ioutil.WriteFile(filepath.Join(root, path), randomContent(128, int64(depth)), 0600); err != nil {
   472  			t.Fatal(err)
   473  		}
   474  		expectedChanges = append(expectedChanges, archive.Change{Kind: archive.ChangeAdd, Path: path})
   475  
   476  		changes, err := driver.Changes(base, nil, "", nil, "")
   477  		if err != nil {
   478  			t.Fatal(err)
   479  		}
   480  
   481  		if err = checkChanges(expectedChanges, changes); err != nil {
   482  			t.Fatal(err)
   483  		}
   484  
   485  		if err := driver.Create(second, base, nil); err != nil {
   486  			t.Fatal(err)
   487  		}
   488  
   489  		if root, err = driver.Get(second, graphdriver.MountOpts{}); err != nil {
   490  			t.Fatal(err)
   491  		}
   492  
   493  		if err = os.RemoveAll(filepath.Join(root, paths[depth])); err != nil {
   494  			t.Fatal(err)
   495  		}
   496  		expectedChanges = []archive.Change{}
   497  		for i := 0; i < depth; i++ {
   498  			expectedChanges = append(expectedChanges, archive.Change{Kind: archive.ChangeModify, Path: paths[i]})
   499  		}
   500  		expectedChanges = append(expectedChanges, archive.Change{Kind: archive.ChangeDelete, Path: paths[depth]})
   501  
   502  		changes, err = driver.Changes(second, nil, base, nil, "")
   503  		if err != nil {
   504  			t.Fatal(err)
   505  		}
   506  
   507  		if err = checkChanges(expectedChanges, changes); err != nil {
   508  			t.Fatal(err)
   509  		}
   510  
   511  		if err = driver.Create(third, second, nil); err != nil {
   512  			t.Fatal(err)
   513  		}
   514  
   515  		if root, err = driver.Get(third, graphdriver.MountOpts{}); err != nil {
   516  			t.Fatal(err)
   517  		}
   518  
   519  		expectedChanges = []archive.Change{}
   520  		for i := 0; i < depth; i++ {
   521  			expectedChanges = append(expectedChanges, archive.Change{Kind: archive.ChangeModify, Path: paths[i]})
   522  		}
   523  		for i := depth; i < components-1; i++ {
   524  			if err = os.Mkdir(filepath.Join(root, paths[i]), 0700); err != nil {
   525  				t.Fatal(err)
   526  			}
   527  			expectedChanges = append(expectedChanges, archive.Change{Kind: archive.ChangeAdd, Path: paths[i]})
   528  		}
   529  		if err = ioutil.WriteFile(filepath.Join(root, paths[len(paths)-1]), randomContent(128, int64(depth)), 0600); err != nil {
   530  			t.Fatal(err)
   531  		}
   532  		expectedChanges = append(expectedChanges, archive.Change{Kind: archive.ChangeAdd, Path: paths[len(paths)-1]})
   533  
   534  		changes, err = driver.Changes(third, nil, second, nil, "")
   535  		if err != nil {
   536  			t.Fatal(err)
   537  		}
   538  
   539  		if err = checkChanges(expectedChanges, changes); err != nil {
   540  			t.Fatal(err)
   541  		}
   542  
   543  		err = driver.Put(third)
   544  		if err != nil {
   545  			t.Fatal(err)
   546  		}
   547  		err = driver.Put(second)
   548  		if err != nil {
   549  			t.Fatal(err)
   550  		}
   551  		err = driver.Put(base)
   552  		if err != nil {
   553  			t.Fatal(err)
   554  		}
   555  	}
   556  }