github.com/rumpl/bof@v23.0.0-rc.2+incompatible/daemon/graphdriver/aufs/aufs_test.go (about)

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