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