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