github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/daemon/graphdriver/graphtest/graphtest_unix.go (about)

     1  // +build linux freebsd
     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, root, options, nil, nil, nil)
    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  
   170  	if err := driver.Create(base, "", "", nil); err != nil {
   171  		t.Fatal(err)
   172  	}
   173  
   174  	content := []byte("test content")
   175  	if err := addFile(driver, base, "testfile.txt", content); err != nil {
   176  		t.Fatal(err)
   177  	}
   178  
   179  	topLayer, err := addManyLayers(driver, base, layerCount)
   180  	if err != nil {
   181  		t.Fatal(err)
   182  	}
   183  
   184  	err = checkManyLayers(driver, topLayer, layerCount)
   185  	if err != nil {
   186  		t.Fatal(err)
   187  	}
   188  
   189  	if err := checkFile(driver, topLayer, "testfile.txt", content); err != nil {
   190  		t.Fatal(err)
   191  	}
   192  }
   193  
   194  // DriverTestDiffApply tests diffing and applying produces the same layer
   195  func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverOptions ...string) {
   196  	driver := GetDriver(t, drivername, driverOptions...)
   197  	defer PutDriver(t)
   198  	base := stringid.GenerateRandomID()
   199  	upper := stringid.GenerateRandomID()
   200  	deleteFile := "file-remove.txt"
   201  	deleteFileContent := []byte("This file should get removed in upper!")
   202  	deleteDir := "var/lib"
   203  
   204  	if err := driver.Create(base, "", "", nil); err != nil {
   205  		t.Fatal(err)
   206  	}
   207  
   208  	if err := addManyFiles(driver, base, fileCount, 3); err != nil {
   209  		t.Fatal(err)
   210  	}
   211  
   212  	if err := addFile(driver, base, deleteFile, deleteFileContent); err != nil {
   213  		t.Fatal(err)
   214  	}
   215  
   216  	if err := addDirectory(driver, base, deleteDir); err != nil {
   217  		t.Fatal(err)
   218  	}
   219  
   220  	if err := driver.Create(upper, base, "", nil); err != nil {
   221  		t.Fatal(err)
   222  	}
   223  
   224  	if err := addManyFiles(driver, upper, fileCount, 6); err != nil {
   225  		t.Fatal(err)
   226  	}
   227  
   228  	if err := removeAll(driver, upper, deleteFile, deleteDir); err != nil {
   229  		t.Fatal(err)
   230  	}
   231  
   232  	diffSize, err := driver.DiffSize(upper, "")
   233  	if err != nil {
   234  		t.Fatal(err)
   235  	}
   236  
   237  	diff := stringid.GenerateRandomID()
   238  	if err := driver.Create(diff, base, "", nil); err != nil {
   239  		t.Fatal(err)
   240  	}
   241  
   242  	if err := checkManyFiles(driver, diff, fileCount, 3); err != nil {
   243  		t.Fatal(err)
   244  	}
   245  
   246  	if err := checkFile(driver, diff, deleteFile, deleteFileContent); err != nil {
   247  		t.Fatal(err)
   248  	}
   249  
   250  	arch, err := driver.Diff(upper, base)
   251  	if err != nil {
   252  		t.Fatal(err)
   253  	}
   254  
   255  	buf := bytes.NewBuffer(nil)
   256  	if _, err := buf.ReadFrom(arch); err != nil {
   257  		t.Fatal(err)
   258  	}
   259  	if err := arch.Close(); err != nil {
   260  		t.Fatal(err)
   261  	}
   262  
   263  	applyDiffSize, err := driver.ApplyDiff(diff, base, bytes.NewReader(buf.Bytes()))
   264  	if err != nil {
   265  		t.Fatal(err)
   266  	}
   267  
   268  	if applyDiffSize != diffSize {
   269  		t.Fatalf("Apply diff size different, got %d, expected %d", applyDiffSize, diffSize)
   270  	}
   271  
   272  	if err := checkManyFiles(driver, diff, fileCount, 6); err != nil {
   273  		t.Fatal(err)
   274  	}
   275  
   276  	if err := checkFileRemoved(driver, diff, deleteFile); err != nil {
   277  		t.Fatal(err)
   278  	}
   279  
   280  	if err := checkFileRemoved(driver, diff, deleteDir); err != nil {
   281  		t.Fatal(err)
   282  	}
   283  }
   284  
   285  // DriverTestChanges tests computed changes on a layer matches changes made
   286  func DriverTestChanges(t testing.TB, drivername string, driverOptions ...string) {
   287  	driver := GetDriver(t, drivername, driverOptions...)
   288  	defer PutDriver(t)
   289  	base := stringid.GenerateRandomID()
   290  	upper := stringid.GenerateRandomID()
   291  
   292  	if err := driver.Create(base, "", "", nil); err != nil {
   293  		t.Fatal(err)
   294  	}
   295  
   296  	if err := addManyFiles(driver, base, 20, 3); err != nil {
   297  		t.Fatal(err)
   298  	}
   299  
   300  	if err := driver.Create(upper, base, "", nil); err != nil {
   301  		t.Fatal(err)
   302  	}
   303  
   304  	expectedChanges, err := changeManyFiles(driver, upper, 20, 6)
   305  	if err != nil {
   306  		t.Fatal(err)
   307  	}
   308  
   309  	changes, err := driver.Changes(upper, base)
   310  	if err != nil {
   311  		t.Fatal(err)
   312  	}
   313  
   314  	if err = checkChanges(expectedChanges, changes); err != nil {
   315  		t.Fatal(err)
   316  	}
   317  }
   318  
   319  func writeRandomFile(path string, size uint64) error {
   320  	buf := make([]int64, size/8)
   321  
   322  	r := rand.NewSource(0)
   323  	for i := range buf {
   324  		buf[i] = r.Int63()
   325  	}
   326  
   327  	// Cast to []byte
   328  	header := *(*reflect.SliceHeader)(unsafe.Pointer(&buf))
   329  	header.Len *= 8
   330  	header.Cap *= 8
   331  	data := *(*[]byte)(unsafe.Pointer(&header))
   332  
   333  	return ioutil.WriteFile(path, data, 0700)
   334  }
   335  
   336  // DriverTestSetQuota Create a driver and test setting quota.
   337  func DriverTestSetQuota(t *testing.T, drivername string) {
   338  	driver := GetDriver(t, drivername)
   339  	defer PutDriver(t)
   340  
   341  	createBase(t, driver, "Base")
   342  	storageOpt := make(map[string]string, 1)
   343  	storageOpt["size"] = "50M"
   344  	if err := driver.Create("zfsTest", "Base", "", storageOpt); err != nil {
   345  		t.Fatal(err)
   346  	}
   347  
   348  	mountPath, err := driver.Get("zfsTest", "")
   349  	if err != nil {
   350  		t.Fatal(err)
   351  	}
   352  
   353  	quota := uint64(50 * units.MiB)
   354  	err = writeRandomFile(path.Join(mountPath, "file"), quota*2)
   355  	if pathError, ok := err.(*os.PathError); ok && pathError.Err != syscall.EDQUOT {
   356  		t.Fatalf("expect write() to fail with %v, got %v", syscall.EDQUOT, err)
   357  	}
   358  
   359  }