github.com/vrothberg/storage@v1.12.13/drivers/aufs/aufs_test.go (about)

     1  // +build linux
     2  
     3  package aufs
     4  
     5  import (
     6  	"crypto/sha256"
     7  	"encoding/hex"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"os"
    11  	"path"
    12  	"path/filepath"
    13  	"sync"
    14  	"testing"
    15  
    16  	"github.com/containers/storage/drivers"
    17  	"github.com/containers/storage/drivers/graphtest"
    18  	"github.com/containers/storage/pkg/archive"
    19  	"github.com/containers/storage/pkg/reexec"
    20  	"github.com/containers/storage/pkg/stringid"
    21  	"github.com/pkg/errors"
    22  	"github.com/stretchr/testify/assert"
    23  	"github.com/stretchr/testify/require"
    24  )
    25  
    26  var (
    27  	tmpOuter = path.Join(os.TempDir(), "aufs-tests")
    28  	tmp      = path.Join(tmpOuter, "aufs")
    29  )
    30  
    31  func init() {
    32  	reexec.Init()
    33  }
    34  
    35  func testInit(dir string, t testing.TB) graphdriver.Driver {
    36  	d, err := Init(dir, graphdriver.Options{})
    37  	if err != nil {
    38  		if errors.Cause(err) == graphdriver.ErrNotSupported {
    39  			t.Skip(err)
    40  		} else {
    41  			t.Fatal(err)
    42  		}
    43  	}
    44  	return d
    45  }
    46  
    47  func driverGet(d *Driver, id string, mntLabel string) (string, error) {
    48  	options := graphdriver.MountOpts{
    49  		MountLabel: mntLabel,
    50  	}
    51  	return d.Get(id, options)
    52  }
    53  
    54  func newDriver(t testing.TB) *Driver {
    55  	if err := os.MkdirAll(tmp, 0755); err != nil {
    56  		t.Fatal(err)
    57  	}
    58  
    59  	d := testInit(tmp, t)
    60  	return d.(*Driver)
    61  }
    62  
    63  func TestNewDriver(t *testing.T) {
    64  	if err := os.MkdirAll(tmp, 0755); err != nil {
    65  		t.Fatal(err)
    66  	}
    67  
    68  	d := testInit(tmp, t)
    69  	defer os.RemoveAll(tmp)
    70  	if d == nil {
    71  		t.Fatal("Driver should not be nil")
    72  	}
    73  }
    74  
    75  func TestAufsString(t *testing.T) {
    76  	d := newDriver(t)
    77  	defer os.RemoveAll(tmp)
    78  
    79  	if d.String() != "aufs" {
    80  		t.Fatalf("Expected aufs got %s", d.String())
    81  	}
    82  }
    83  
    84  func TestCreateDirStructure(t *testing.T) {
    85  	newDriver(t)
    86  	defer os.RemoveAll(tmp)
    87  
    88  	paths := []string{
    89  		"mnt",
    90  		"layers",
    91  		"diff",
    92  	}
    93  
    94  	for _, p := range paths {
    95  		if _, err := os.Stat(path.Join(tmp, p)); err != nil {
    96  			t.Fatal(err)
    97  		}
    98  	}
    99  }
   100  
   101  // We should be able to create two drivers with the same dir structure
   102  func TestNewDriverFromExistingDir(t *testing.T) {
   103  	if err := os.MkdirAll(tmp, 0755); err != nil {
   104  		t.Fatal(err)
   105  	}
   106  
   107  	testInit(tmp, t)
   108  	testInit(tmp, t)
   109  	os.RemoveAll(tmp)
   110  }
   111  
   112  func TestCreateNewDir(t *testing.T) {
   113  	d := newDriver(t)
   114  	defer os.RemoveAll(tmp)
   115  
   116  	if err := d.Create("1", "", nil); err != nil {
   117  		t.Fatal(err)
   118  	}
   119  }
   120  
   121  func TestCreateNewDirStructure(t *testing.T) {
   122  	d := newDriver(t)
   123  	defer os.RemoveAll(tmp)
   124  
   125  	if err := d.Create("1", "", nil); err != nil {
   126  		t.Fatal(err)
   127  	}
   128  
   129  	paths := []string{
   130  		"mnt",
   131  		"diff",
   132  		"layers",
   133  	}
   134  
   135  	for _, p := range paths {
   136  		if _, err := os.Stat(path.Join(tmp, p, "1")); err != nil {
   137  			t.Fatal(err)
   138  		}
   139  	}
   140  }
   141  
   142  func TestRemoveImage(t *testing.T) {
   143  	d := newDriver(t)
   144  	defer os.RemoveAll(tmp)
   145  
   146  	if err := d.Create("1", "", nil); err != nil {
   147  		t.Fatal(err)
   148  	}
   149  
   150  	if err := d.Remove("1"); err != nil {
   151  		t.Fatal(err)
   152  	}
   153  
   154  	paths := []string{
   155  		"mnt",
   156  		"diff",
   157  		"layers",
   158  	}
   159  
   160  	for _, p := range paths {
   161  		if _, err := os.Stat(path.Join(tmp, p, "1")); err == nil {
   162  			t.Fatalf("Error should not be nil because dirs with id 1 should be deleted: %s", p)
   163  		}
   164  		if _, err := os.Stat(path.Join(tmp, p, "1-removing")); err == nil {
   165  			t.Fatalf("Error should not be nil because dirs with id 1-removing should be deleted: %s", p)
   166  		}
   167  	}
   168  }
   169  
   170  func TestGetWithoutParent(t *testing.T) {
   171  	d := newDriver(t)
   172  	defer os.RemoveAll(tmp)
   173  
   174  	if err := d.Create("1", "", nil); err != nil {
   175  		t.Fatal(err)
   176  	}
   177  
   178  	diffPath, err := d.Get("1", graphdriver.MountOpts{})
   179  	if err != nil {
   180  		t.Fatal(err)
   181  	}
   182  	expected := path.Join(tmp, "diff", "1")
   183  	if diffPath != expected {
   184  		t.Fatalf("Expected path %s got %s", expected, diffPath)
   185  	}
   186  }
   187  
   188  func TestCleanupWithNoDirs(t *testing.T) {
   189  	d := newDriver(t)
   190  	defer os.RemoveAll(tmp)
   191  
   192  	err := d.Cleanup()
   193  	assert.NoError(t, err)
   194  }
   195  
   196  func TestCleanupWithDir(t *testing.T) {
   197  	d := newDriver(t)
   198  	defer os.RemoveAll(tmp)
   199  
   200  	if err := d.Create("1", "", nil); err != nil {
   201  		t.Fatal(err)
   202  	}
   203  
   204  	if err := d.Cleanup(); err != nil {
   205  		t.Fatal(err)
   206  	}
   207  }
   208  
   209  func TestMountedFalseResponse(t *testing.T) {
   210  	d := newDriver(t)
   211  	defer os.RemoveAll(tmp)
   212  
   213  	err := d.Create("1", "", nil)
   214  	require.NoError(t, err)
   215  
   216  	response, err := d.mounted(d.getDiffPath("1"))
   217  	require.NoError(t, err)
   218  	assert.False(t, response)
   219  }
   220  
   221  func TestMountedTrueResponse(t *testing.T) {
   222  	d := newDriver(t)
   223  	defer os.RemoveAll(tmp)
   224  	defer d.Cleanup()
   225  
   226  	err := d.Create("1", "", nil)
   227  	require.NoError(t, err)
   228  	err = d.Create("2", "1", nil)
   229  	require.NoError(t, err)
   230  
   231  	_, err = d.Get("2", graphdriver.MountOpts{})
   232  	require.NoError(t, err)
   233  
   234  	response, err := d.mounted(d.pathCache["2"])
   235  	require.NoError(t, err)
   236  	assert.True(t, response)
   237  }
   238  
   239  func TestMountWithParent(t *testing.T) {
   240  	d := newDriver(t)
   241  	defer os.RemoveAll(tmp)
   242  
   243  	if err := d.Create("1", "", nil); err != nil {
   244  		t.Fatal(err)
   245  	}
   246  	if err := d.Create("2", "1", nil); err != nil {
   247  		t.Fatal(err)
   248  	}
   249  
   250  	defer func() {
   251  		if err := d.Cleanup(); err != nil {
   252  			t.Fatal(err)
   253  		}
   254  	}()
   255  
   256  	mntPath, err := d.Get("2", graphdriver.MountOpts{})
   257  	if err != nil {
   258  		t.Fatal(err)
   259  	}
   260  	if mntPath == "" {
   261  		t.Fatal("mntPath should not be nil")
   262  	}
   263  
   264  	expected := path.Join(tmp, "mnt", "2")
   265  	if mntPath != expected {
   266  		t.Fatalf("Expected %s got %s", expected, mntPath)
   267  	}
   268  }
   269  
   270  func TestRemoveMountedDir(t *testing.T) {
   271  	d := newDriver(t)
   272  	defer os.RemoveAll(tmp)
   273  
   274  	if err := d.Create("1", "", nil); err != nil {
   275  		t.Fatal(err)
   276  	}
   277  	if err := d.Create("2", "1", nil); err != nil {
   278  		t.Fatal(err)
   279  	}
   280  
   281  	defer func() {
   282  		if err := d.Cleanup(); err != nil {
   283  			t.Fatal(err)
   284  		}
   285  	}()
   286  
   287  	mntPath, err := d.Get("2", graphdriver.MountOpts{})
   288  	if err != nil {
   289  		t.Fatal(err)
   290  	}
   291  	if mntPath == "" {
   292  		t.Fatal("mntPath should not be empty")
   293  	}
   294  
   295  	mounted, err := d.mounted(d.pathCache["2"])
   296  	if err != nil {
   297  		t.Fatal(err)
   298  	}
   299  
   300  	if !mounted {
   301  		t.Fatal("Dir id 2 should be mounted")
   302  	}
   303  
   304  	if err := d.Remove("2"); err != nil {
   305  		t.Fatal(err)
   306  	}
   307  }
   308  
   309  func TestCreateWithInvalidParent(t *testing.T) {
   310  	d := newDriver(t)
   311  	defer os.RemoveAll(tmp)
   312  
   313  	if err := d.Create("1", "storage", nil); err == nil {
   314  		t.Fatal("Error should not be nil with parent does not exist")
   315  	}
   316  }
   317  
   318  func TestGetDiff(t *testing.T) {
   319  	d := newDriver(t)
   320  	defer os.RemoveAll(tmp)
   321  
   322  	if err := d.CreateReadWrite("1", "", nil); err != nil {
   323  		t.Fatal(err)
   324  	}
   325  
   326  	diffPath, err := driverGet(d, "1", "")
   327  	if err != nil {
   328  		t.Fatal(err)
   329  	}
   330  
   331  	// Add a file to the diff path with a fixed size
   332  	size := int64(1024)
   333  
   334  	f, err := os.Create(path.Join(diffPath, "test_file"))
   335  	if err != nil {
   336  		t.Fatal(err)
   337  	}
   338  	if err := f.Truncate(size); err != nil {
   339  		t.Fatal(err)
   340  	}
   341  	f.Close()
   342  
   343  	a, err := d.Diff("1", nil, "", nil, "")
   344  	if err != nil {
   345  		t.Fatal(err)
   346  	}
   347  	if a == nil {
   348  		t.Fatal("Archive should not be nil")
   349  	}
   350  }
   351  
   352  func TestChanges(t *testing.T) {
   353  	d := newDriver(t)
   354  	defer os.RemoveAll(tmp)
   355  
   356  	if err := d.Create("1", "", nil); err != nil {
   357  		t.Fatal(err)
   358  	}
   359  
   360  	if err := d.CreateReadWrite("2", "1", nil); err != nil {
   361  		t.Fatal(err)
   362  	}
   363  
   364  	defer func() {
   365  		if err := d.Cleanup(); err != nil {
   366  			t.Fatal(err)
   367  		}
   368  	}()
   369  
   370  	mntPoint, err := driverGet(d, "2", "")
   371  	if err != nil {
   372  		t.Fatal(err)
   373  	}
   374  
   375  	// Create a file to save in the mountpoint
   376  	f, err := os.Create(path.Join(mntPoint, "test.txt"))
   377  	if err != nil {
   378  		t.Fatal(err)
   379  	}
   380  
   381  	if _, err := f.WriteString("testline"); err != nil {
   382  		t.Fatal(err)
   383  	}
   384  	if err := f.Close(); err != nil {
   385  		t.Fatal(err)
   386  	}
   387  
   388  	changes, err := d.Changes("2", nil, "", nil, "")
   389  	if err != nil {
   390  		t.Fatal(err)
   391  	}
   392  	if len(changes) != 1 {
   393  		t.Fatalf("Dir 2 should have one change from parent got %d", len(changes))
   394  	}
   395  	change := changes[0]
   396  
   397  	expectedPath := "/test.txt"
   398  	if change.Path != expectedPath {
   399  		t.Fatalf("Expected path %s got %s", expectedPath, change.Path)
   400  	}
   401  
   402  	if change.Kind != archive.ChangeAdd {
   403  		t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind)
   404  	}
   405  
   406  	if err := d.CreateReadWrite("3", "2", nil); err != nil {
   407  		t.Fatal(err)
   408  	}
   409  	mntPoint, err = driverGet(d, "3", "")
   410  	if err != nil {
   411  		t.Fatal(err)
   412  	}
   413  
   414  	// Create a file to save in the mountpoint
   415  	f, err = os.Create(path.Join(mntPoint, "test2.txt"))
   416  	if err != nil {
   417  		t.Fatal(err)
   418  	}
   419  
   420  	if _, err := f.WriteString("testline"); err != nil {
   421  		t.Fatal(err)
   422  	}
   423  	if err := f.Close(); err != nil {
   424  		t.Fatal(err)
   425  	}
   426  
   427  	changes, err = d.Changes("3", nil, "2", nil, "")
   428  	if err != nil {
   429  		t.Fatal(err)
   430  	}
   431  
   432  	if len(changes) != 1 {
   433  		t.Fatalf("Dir 2 should have one change from parent got %d", len(changes))
   434  	}
   435  	change = changes[0]
   436  
   437  	expectedPath = "/test2.txt"
   438  	if change.Path != expectedPath {
   439  		t.Fatalf("Expected path %s got %s", expectedPath, change.Path)
   440  	}
   441  
   442  	if change.Kind != archive.ChangeAdd {
   443  		t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind)
   444  	}
   445  }
   446  
   447  func TestDiffSize(t *testing.T) {
   448  	d := newDriver(t)
   449  	defer os.RemoveAll(tmp)
   450  
   451  	if err := d.CreateReadWrite("1", "", nil); err != nil {
   452  		t.Fatal(err)
   453  	}
   454  
   455  	diffPath, err := driverGet(d, "1", "")
   456  	if err != nil {
   457  		t.Fatal(err)
   458  	}
   459  
   460  	// Add a file to the diff path with a fixed size
   461  	size := int64(1024)
   462  
   463  	f, err := os.Create(path.Join(diffPath, "test_file"))
   464  	if err != nil {
   465  		t.Fatal(err)
   466  	}
   467  	if err := f.Truncate(size); err != nil {
   468  		t.Fatal(err)
   469  	}
   470  	s, err := f.Stat()
   471  	if err != nil {
   472  		t.Fatal(err)
   473  	}
   474  	size = s.Size()
   475  	if err := f.Close(); err != nil {
   476  		t.Fatal(err)
   477  	}
   478  
   479  	diffSize, err := d.DiffSize("1", nil, "", nil, "")
   480  	if err != nil {
   481  		t.Fatal(err)
   482  	}
   483  	if diffSize != size {
   484  		t.Fatalf("Expected size to be %d got %d", size, diffSize)
   485  	}
   486  }
   487  
   488  func TestChildDiffSize(t *testing.T) {
   489  	d := newDriver(t)
   490  	defer os.RemoveAll(tmp)
   491  	defer d.Cleanup()
   492  
   493  	if err := d.CreateReadWrite("1", "", nil); err != nil {
   494  		t.Fatal(err)
   495  	}
   496  
   497  	diffPath, err := driverGet(d, "1", "")
   498  	if err != nil {
   499  		t.Fatal(err)
   500  	}
   501  
   502  	// Add a file to the diff path with a fixed size
   503  	size := int64(1024)
   504  
   505  	f, err := os.Create(path.Join(diffPath, "test_file"))
   506  	if err != nil {
   507  		t.Fatal(err)
   508  	}
   509  	if err := f.Truncate(size); err != nil {
   510  		t.Fatal(err)
   511  	}
   512  	s, err := f.Stat()
   513  	if err != nil {
   514  		t.Fatal(err)
   515  	}
   516  	size = s.Size()
   517  	if err := f.Close(); err != nil {
   518  		t.Fatal(err)
   519  	}
   520  
   521  	diffSize, err := d.DiffSize("1", nil, "", nil, "")
   522  	if err != nil {
   523  		t.Fatal(err)
   524  	}
   525  	if diffSize != size {
   526  		t.Fatalf("Expected size to be %d got %d", size, diffSize)
   527  	}
   528  
   529  	if err := d.Create("2", "1", nil); err != nil {
   530  		t.Fatal(err)
   531  	}
   532  
   533  	diffSize, err = d.DiffSize("2", nil, "1", nil, "")
   534  	if err != nil {
   535  		t.Fatal(err)
   536  	}
   537  	// The diff size for the child should be zero
   538  	if diffSize != 0 {
   539  		t.Fatalf("Expected size to be %d got %d", 0, diffSize)
   540  	}
   541  }
   542  
   543  func TestExists(t *testing.T) {
   544  	d := newDriver(t)
   545  	defer os.RemoveAll(tmp)
   546  	defer d.Cleanup()
   547  
   548  	if err := d.Create("1", "", nil); err != nil {
   549  		t.Fatal(err)
   550  	}
   551  
   552  	if d.Exists("none") {
   553  		t.Fatal("id none should not exist in the driver")
   554  	}
   555  
   556  	if !d.Exists("1") {
   557  		t.Fatal("id 1 should exist in the driver")
   558  	}
   559  }
   560  
   561  func TestStatus(t *testing.T) {
   562  	d := newDriver(t)
   563  	defer os.RemoveAll(tmp)
   564  	defer d.Cleanup()
   565  
   566  	if err := d.Create("1", "", nil); err != nil {
   567  		t.Fatal(err)
   568  	}
   569  
   570  	status := d.Status()
   571  	assert.Len(t, status, 4)
   572  
   573  	rootDir := status[0]
   574  	dirs := status[2]
   575  	if rootDir[0] != "Root Dir" {
   576  		t.Fatalf("Expected Root Dir got %s", rootDir[0])
   577  	}
   578  	if rootDir[1] != d.rootPath() {
   579  		t.Fatalf("Expected %s got %s", d.rootPath(), rootDir[1])
   580  	}
   581  	if dirs[0] != "Dirs" {
   582  		t.Fatalf("Expected Dirs got %s", dirs[0])
   583  	}
   584  	if dirs[1] != "1" {
   585  		t.Fatalf("Expected 1 got %s", dirs[1])
   586  	}
   587  }
   588  
   589  func TestApplyDiff(t *testing.T) {
   590  	d := newDriver(t)
   591  	defer os.RemoveAll(tmp)
   592  	defer d.Cleanup()
   593  
   594  	if err := d.CreateReadWrite("1", "", nil); err != nil {
   595  		t.Fatal(err)
   596  	}
   597  
   598  	diffPath, err := driverGet(d, "1", "")
   599  	if err != nil {
   600  		t.Fatal(err)
   601  	}
   602  
   603  	// Add a file to the diff path with a fixed size
   604  	size := int64(1024)
   605  
   606  	f, err := os.Create(path.Join(diffPath, "test_file"))
   607  	if err != nil {
   608  		t.Fatal(err)
   609  	}
   610  	if err := f.Truncate(size); err != nil {
   611  		t.Fatal(err)
   612  	}
   613  	f.Close()
   614  
   615  	diff, err := d.Diff("1", nil, "", nil, "")
   616  	if err != nil {
   617  		t.Fatal(err)
   618  	}
   619  
   620  	if err := d.Create("2", "", nil); err != nil {
   621  		t.Fatal(err)
   622  	}
   623  	if err := d.Create("3", "2", nil); err != nil {
   624  		t.Fatal(err)
   625  	}
   626  
   627  	if err := d.applyDiff("3", nil, diff); err != nil {
   628  		t.Fatal(err)
   629  	}
   630  
   631  	// Ensure that the file is in the mount point for id 3
   632  
   633  	mountPoint, err := driverGet(d, "3", "")
   634  	if err != nil {
   635  		t.Fatal(err)
   636  	}
   637  	if _, err := os.Stat(path.Join(mountPoint, "test_file")); err != nil {
   638  		t.Fatal(err)
   639  	}
   640  }
   641  
   642  func hash(c string) string {
   643  	h := sha256.New()
   644  	fmt.Fprint(h, c)
   645  	return hex.EncodeToString(h.Sum(nil))
   646  }
   647  
   648  func testMountMoreThan42Layers(t *testing.T, mountPath string) {
   649  	if err := os.MkdirAll(mountPath, 0755); err != nil {
   650  		t.Fatal(err)
   651  	}
   652  
   653  	defer os.RemoveAll(mountPath)
   654  	d := testInit(mountPath, t).(*Driver)
   655  	defer d.Cleanup()
   656  	var last string
   657  	var expected int
   658  
   659  	for i := 1; i < 127; i++ {
   660  		expected++
   661  		var (
   662  			parent  = fmt.Sprintf("%d", i-1)
   663  			current = fmt.Sprintf("%d", i)
   664  		)
   665  
   666  		if parent == "0" {
   667  			parent = ""
   668  		} else {
   669  			parent = hash(parent)
   670  		}
   671  		current = hash(current)
   672  
   673  		err := d.CreateReadWrite(current, parent, nil)
   674  		require.NoError(t, err, "current layer %d", i)
   675  
   676  		point, err := driverGet(d, current, "")
   677  		require.NoError(t, err, "current layer %d", i)
   678  
   679  		f, err := os.Create(path.Join(point, current))
   680  		require.NoError(t, err, "current layer %d", i)
   681  		f.Close()
   682  
   683  		if i%10 == 0 {
   684  			err := os.Remove(path.Join(point, parent))
   685  			require.NoError(t, err, "current layer %d", i)
   686  			expected--
   687  		}
   688  		last = current
   689  	}
   690  
   691  	// Perform the actual mount for the top most image
   692  	point, err := driverGet(d, last, "")
   693  	require.NoError(t, err)
   694  	files, err := ioutil.ReadDir(point)
   695  	require.NoError(t, err)
   696  	assert.Len(t, files, expected)
   697  }
   698  
   699  func TestMountMoreThan42Layers(t *testing.T) {
   700  	defer os.RemoveAll(tmpOuter)
   701  	testMountMoreThan42Layers(t, tmp)
   702  }
   703  
   704  func TestMountMoreThan42LayersMatchingPathLength(t *testing.T) {
   705  	defer os.RemoveAll(tmpOuter)
   706  	zeroes := "0"
   707  	for {
   708  		// This finds a mount path so that when combined into aufs mount options
   709  		// 4096 byte boundary would be in between the paths or in permission
   710  		// section. For '/tmp' it will use '/tmp/aufs-tests/00000000/aufs'
   711  		mountPath := path.Join(tmpOuter, zeroes, "aufs")
   712  		pathLength := 77 + len(mountPath)
   713  
   714  		if mod := 4095 % pathLength; mod == 0 || mod > pathLength-2 {
   715  			t.Logf("Using path: %s", mountPath)
   716  			testMountMoreThan42Layers(t, mountPath)
   717  			return
   718  		}
   719  		zeroes += "0"
   720  	}
   721  }
   722  
   723  func BenchmarkConcurrentAccess(b *testing.B) {
   724  	b.StopTimer()
   725  	b.ResetTimer()
   726  
   727  	d := newDriver(b)
   728  	defer os.RemoveAll(tmp)
   729  	defer d.Cleanup()
   730  
   731  	numConcurrent := 256
   732  	// create a bunch of ids
   733  	var ids []string
   734  	for i := 0; i < numConcurrent; i++ {
   735  		ids = append(ids, stringid.GenerateNonCryptoID())
   736  	}
   737  
   738  	if err := d.Create(ids[0], "", nil); err != nil {
   739  		b.Fatal(err)
   740  	}
   741  
   742  	if err := d.Create(ids[1], ids[0], nil); err != nil {
   743  		b.Fatal(err)
   744  	}
   745  
   746  	parent := ids[1]
   747  	ids = append(ids[2:])
   748  
   749  	chErr := make(chan error, numConcurrent)
   750  	var outerGroup sync.WaitGroup
   751  	outerGroup.Add(len(ids))
   752  	b.StartTimer()
   753  
   754  	// here's the actual bench
   755  	for _, id := range ids {
   756  		go func(id string) {
   757  			defer outerGroup.Done()
   758  			if err := d.Create(id, parent, nil); err != nil {
   759  				b.Logf("Create %s failed", id)
   760  				chErr <- err
   761  				return
   762  			}
   763  			var innerGroup sync.WaitGroup
   764  			for i := 0; i < b.N; i++ {
   765  				innerGroup.Add(1)
   766  				go func() {
   767  					d.Get(id, graphdriver.MountOpts{})
   768  					d.Put(id)
   769  					innerGroup.Done()
   770  				}()
   771  			}
   772  			innerGroup.Wait()
   773  			d.Remove(id)
   774  		}(id)
   775  	}
   776  
   777  	outerGroup.Wait()
   778  	b.StopTimer()
   779  	close(chErr)
   780  	for err := range chErr {
   781  		if err != nil {
   782  			b.Log(err)
   783  			b.Fail()
   784  		}
   785  	}
   786  }
   787  
   788  func TestInitStaleCleanup(t *testing.T) {
   789  	if err := os.MkdirAll(tmp, 0755); err != nil {
   790  		t.Fatal(err)
   791  	}
   792  	defer os.RemoveAll(tmp)
   793  
   794  	for _, d := range []string{"diff", "mnt"} {
   795  		if err := os.MkdirAll(filepath.Join(tmp, d, "123-removing"), 0755); err != nil {
   796  			t.Fatal(err)
   797  		}
   798  	}
   799  
   800  	testInit(tmp, t)
   801  	for _, d := range []string{"diff", "mnt"} {
   802  		if _, err := os.Stat(filepath.Join(tmp, d, "123-removing")); err == nil {
   803  			t.Fatal("cleanup failed")
   804  		}
   805  	}
   806  }
   807  
   808  func TestAufsCreateEmpty(t *testing.T) {
   809  	graphtest.DriverTestCreateEmpty(t, "aufs")
   810  }
   811  
   812  func TestAufsCreateBase(t *testing.T) {
   813  	graphtest.DriverTestCreateBase(t, "aufs")
   814  }
   815  
   816  func TestAufsCreateSnap(t *testing.T) {
   817  	graphtest.DriverTestCreateSnap(t, "aufs")
   818  }
   819  
   820  func TestAufsCreateFromTemplate(t *testing.T) {
   821  	graphtest.DriverTestCreateFromTemplate(t, "aufs")
   822  }
   823  
   824  func TestAufsEcho(t *testing.T) {
   825  	graphtest.DriverTestEcho(t, "aufs")
   826  }