github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/daemon/graphdriver/graphtest/graphtest_unix.go (about)

     1  // +build linux freebsd solaris
     2  
     3  package graphtest
     4  
     5  import (
     6  	"bytes"
     7  	"io/ioutil"
     8  	"math/rand"
     9  	"os"
    10  	"path"
    11  	"reflect"
    12  	"syscall"
    13  	"testing"
    14  	"unsafe"
    15  
    16  	"github.com/docker/docker/daemon/graphdriver"
    17  	"github.com/docker/docker/pkg/stringid"
    18  	"github.com/docker/go-units"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  var (
    24  	drv *Driver
    25  )
    26  
    27  // Driver conforms to graphdriver.Driver interface and
    28  // contains information such as root and reference count of the number of clients using it.
    29  // This helps in testing drivers added into the framework.
    30  type Driver struct {
    31  	graphdriver.Driver
    32  	root     string
    33  	refCount int
    34  }
    35  
    36  func newDriver(t testing.TB, name string, options []string) *Driver {
    37  	root, err := ioutil.TempDir("", "docker-graphtest-")
    38  	require.NoError(t, err)
    39  
    40  	require.NoError(t, os.MkdirAll(root, 0755))
    41  	d, err := graphdriver.GetDriver(name, nil, graphdriver.Options{DriverOptions: options, Root: root})
    42  	if err != nil {
    43  		t.Logf("graphdriver: %v\n", err)
    44  		if err == graphdriver.ErrNotSupported || err == graphdriver.ErrPrerequisites || err == graphdriver.ErrIncompatibleFS {
    45  			t.Skipf("Driver %s not supported", name)
    46  		}
    47  		t.Fatal(err)
    48  	}
    49  	return &Driver{d, root, 1}
    50  }
    51  
    52  func cleanup(t testing.TB, d *Driver) {
    53  	if err := drv.Cleanup(); err != nil {
    54  		t.Fatal(err)
    55  	}
    56  	os.RemoveAll(d.root)
    57  }
    58  
    59  // GetDriver create a new driver with given name or return an existing driver with the name updating the reference count.
    60  func GetDriver(t testing.TB, name string, options ...string) graphdriver.Driver {
    61  	if drv == nil {
    62  		drv = newDriver(t, name, options)
    63  	} else {
    64  		drv.refCount++
    65  	}
    66  	return drv
    67  }
    68  
    69  // PutDriver removes the driver if it is no longer used and updates the reference count.
    70  func PutDriver(t testing.TB) {
    71  	if drv == nil {
    72  		t.Skip("No driver to put!")
    73  	}
    74  	drv.refCount--
    75  	if drv.refCount == 0 {
    76  		cleanup(t, drv)
    77  		drv = nil
    78  	}
    79  }
    80  
    81  // DriverTestCreateEmpty creates a new image and verifies it is empty and the right metadata
    82  func DriverTestCreateEmpty(t testing.TB, drivername string, driverOptions ...string) {
    83  	driver := GetDriver(t, drivername, driverOptions...)
    84  	defer PutDriver(t)
    85  
    86  	err := driver.Create("empty", "", nil)
    87  	require.NoError(t, err)
    88  
    89  	defer func() {
    90  		require.NoError(t, driver.Remove("empty"))
    91  	}()
    92  
    93  	if !driver.Exists("empty") {
    94  		t.Fatal("Newly created image doesn't exist")
    95  	}
    96  
    97  	dir, err := driver.Get("empty", "")
    98  	require.NoError(t, err)
    99  
   100  	verifyFile(t, dir, 0755|os.ModeDir, 0, 0)
   101  
   102  	// Verify that the directory is empty
   103  	fis, err := readDir(dir)
   104  	require.NoError(t, err)
   105  	assert.Len(t, fis, 0)
   106  
   107  	driver.Put("empty")
   108  }
   109  
   110  // DriverTestCreateBase create a base driver and verify.
   111  func DriverTestCreateBase(t testing.TB, drivername string, driverOptions ...string) {
   112  	driver := GetDriver(t, drivername, driverOptions...)
   113  	defer PutDriver(t)
   114  
   115  	createBase(t, driver, "Base")
   116  	defer func() {
   117  		require.NoError(t, driver.Remove("Base"))
   118  	}()
   119  	verifyBase(t, driver, "Base")
   120  }
   121  
   122  // DriverTestCreateSnap Create a driver and snap and verify.
   123  func DriverTestCreateSnap(t testing.TB, drivername string, driverOptions ...string) {
   124  	driver := GetDriver(t, drivername, driverOptions...)
   125  	defer PutDriver(t)
   126  
   127  	createBase(t, driver, "Base")
   128  	defer func() {
   129  		require.NoError(t, driver.Remove("Base"))
   130  	}()
   131  
   132  	err := driver.Create("Snap", "Base", nil)
   133  	require.NoError(t, err)
   134  	defer func() {
   135  		require.NoError(t, driver.Remove("Snap"))
   136  	}()
   137  
   138  	verifyBase(t, driver, "Snap")
   139  }
   140  
   141  // DriverTestDeepLayerRead reads a file from a lower layer under a given number of layers
   142  func DriverTestDeepLayerRead(t testing.TB, layerCount int, drivername string, driverOptions ...string) {
   143  	driver := GetDriver(t, drivername, driverOptions...)
   144  	defer PutDriver(t)
   145  
   146  	base := stringid.GenerateRandomID()
   147  	if err := driver.Create(base, "", nil); err != nil {
   148  		t.Fatal(err)
   149  	}
   150  
   151  	content := []byte("test content")
   152  	if err := addFile(driver, base, "testfile.txt", content); err != nil {
   153  		t.Fatal(err)
   154  	}
   155  
   156  	topLayer, err := addManyLayers(driver, base, layerCount)
   157  	if err != nil {
   158  		t.Fatal(err)
   159  	}
   160  
   161  	err = checkManyLayers(driver, topLayer, layerCount)
   162  	if err != nil {
   163  		t.Fatal(err)
   164  	}
   165  
   166  	if err := checkFile(driver, topLayer, "testfile.txt", content); err != nil {
   167  		t.Fatal(err)
   168  	}
   169  }
   170  
   171  // DriverTestDiffApply tests diffing and applying produces the same layer
   172  func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverOptions ...string) {
   173  	driver := GetDriver(t, drivername, driverOptions...)
   174  	defer PutDriver(t)
   175  	base := stringid.GenerateRandomID()
   176  	upper := stringid.GenerateRandomID()
   177  	deleteFile := "file-remove.txt"
   178  	deleteFileContent := []byte("This file should get removed in upper!")
   179  	deleteDir := "var/lib"
   180  
   181  	if err := driver.Create(base, "", nil); err != nil {
   182  		t.Fatal(err)
   183  	}
   184  
   185  	if err := addManyFiles(driver, base, fileCount, 3); err != nil {
   186  		t.Fatal(err)
   187  	}
   188  
   189  	if err := addFile(driver, base, deleteFile, deleteFileContent); err != nil {
   190  		t.Fatal(err)
   191  	}
   192  
   193  	if err := addDirectory(driver, base, deleteDir); err != nil {
   194  		t.Fatal(err)
   195  	}
   196  
   197  	if err := driver.Create(upper, base, nil); err != nil {
   198  		t.Fatal(err)
   199  	}
   200  
   201  	if err := addManyFiles(driver, upper, fileCount, 6); err != nil {
   202  		t.Fatal(err)
   203  	}
   204  
   205  	if err := removeAll(driver, upper, deleteFile, deleteDir); err != nil {
   206  		t.Fatal(err)
   207  	}
   208  
   209  	diffSize, err := driver.DiffSize(upper, "")
   210  	if err != nil {
   211  		t.Fatal(err)
   212  	}
   213  
   214  	diff := stringid.GenerateRandomID()
   215  	if err := driver.Create(diff, base, nil); err != nil {
   216  		t.Fatal(err)
   217  	}
   218  
   219  	if err := checkManyFiles(driver, diff, fileCount, 3); err != nil {
   220  		t.Fatal(err)
   221  	}
   222  
   223  	if err := checkFile(driver, diff, deleteFile, deleteFileContent); err != nil {
   224  		t.Fatal(err)
   225  	}
   226  
   227  	arch, err := driver.Diff(upper, base)
   228  	if err != nil {
   229  		t.Fatal(err)
   230  	}
   231  
   232  	buf := bytes.NewBuffer(nil)
   233  	if _, err := buf.ReadFrom(arch); err != nil {
   234  		t.Fatal(err)
   235  	}
   236  	if err := arch.Close(); err != nil {
   237  		t.Fatal(err)
   238  	}
   239  
   240  	applyDiffSize, err := driver.ApplyDiff(diff, base, bytes.NewReader(buf.Bytes()))
   241  	if err != nil {
   242  		t.Fatal(err)
   243  	}
   244  
   245  	if applyDiffSize != diffSize {
   246  		t.Fatalf("Apply diff size different, got %d, expected %d", applyDiffSize, diffSize)
   247  	}
   248  
   249  	if err := checkManyFiles(driver, diff, fileCount, 6); err != nil {
   250  		t.Fatal(err)
   251  	}
   252  
   253  	if err := checkFileRemoved(driver, diff, deleteFile); err != nil {
   254  		t.Fatal(err)
   255  	}
   256  
   257  	if err := checkFileRemoved(driver, diff, deleteDir); err != nil {
   258  		t.Fatal(err)
   259  	}
   260  }
   261  
   262  // DriverTestChanges tests computed changes on a layer matches changes made
   263  func DriverTestChanges(t testing.TB, drivername string, driverOptions ...string) {
   264  	driver := GetDriver(t, drivername, driverOptions...)
   265  	defer PutDriver(t)
   266  	base := stringid.GenerateRandomID()
   267  	upper := stringid.GenerateRandomID()
   268  	if err := driver.Create(base, "", nil); err != nil {
   269  		t.Fatal(err)
   270  	}
   271  
   272  	if err := addManyFiles(driver, base, 20, 3); err != nil {
   273  		t.Fatal(err)
   274  	}
   275  
   276  	if err := driver.Create(upper, base, nil); err != nil {
   277  		t.Fatal(err)
   278  	}
   279  
   280  	expectedChanges, err := changeManyFiles(driver, upper, 20, 6)
   281  	if err != nil {
   282  		t.Fatal(err)
   283  	}
   284  
   285  	changes, err := driver.Changes(upper, base)
   286  	if err != nil {
   287  		t.Fatal(err)
   288  	}
   289  
   290  	if err = checkChanges(expectedChanges, changes); err != nil {
   291  		t.Fatal(err)
   292  	}
   293  }
   294  
   295  func writeRandomFile(path string, size uint64) error {
   296  	buf := make([]int64, size/8)
   297  
   298  	r := rand.NewSource(0)
   299  	for i := range buf {
   300  		buf[i] = r.Int63()
   301  	}
   302  
   303  	// Cast to []byte
   304  	header := *(*reflect.SliceHeader)(unsafe.Pointer(&buf))
   305  	header.Len *= 8
   306  	header.Cap *= 8
   307  	data := *(*[]byte)(unsafe.Pointer(&header))
   308  
   309  	return ioutil.WriteFile(path, data, 0700)
   310  }
   311  
   312  // DriverTestSetQuota Create a driver and test setting quota.
   313  func DriverTestSetQuota(t *testing.T, drivername string) {
   314  	driver := GetDriver(t, drivername)
   315  	defer PutDriver(t)
   316  
   317  	createBase(t, driver, "Base")
   318  	createOpts := &graphdriver.CreateOpts{}
   319  	createOpts.StorageOpt = make(map[string]string, 1)
   320  	createOpts.StorageOpt["size"] = "50M"
   321  	if err := driver.Create("zfsTest", "Base", createOpts); err != nil {
   322  		t.Fatal(err)
   323  	}
   324  
   325  	mountPath, err := driver.Get("zfsTest", "")
   326  	if err != nil {
   327  		t.Fatal(err)
   328  	}
   329  
   330  	quota := uint64(50 * units.MiB)
   331  	err = writeRandomFile(path.Join(mountPath, "file"), quota*2)
   332  	if pathError, ok := err.(*os.PathError); ok && pathError.Err != syscall.EDQUOT {
   333  		t.Fatalf("expect write() to fail with %v, got %v", syscall.EDQUOT, err)
   334  	}
   335  
   336  }