github.com/moby/docker@v26.1.3+incompatible/pkg/fileutils/fileutils_test.go (about)

     1  package fileutils // import "github.com/docker/docker/pkg/fileutils"
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"os"
     7  	"path"
     8  	"path/filepath"
     9  	"runtime"
    10  	"strings"
    11  	"testing"
    12  )
    13  
    14  // CopyFile with invalid src
    15  func TestCopyFileWithInvalidSrc(t *testing.T) {
    16  	tempDir := t.TempDir()
    17  	bytes, err := CopyFile(filepath.Join(tempDir, "/invalid/file/path"), path.Join(t.TempDir(), "dest"))
    18  	if err == nil {
    19  		t.Error("Should have fail to copy an invalid src file")
    20  	}
    21  	if !errors.Is(err, os.ErrNotExist) {
    22  		t.Errorf("Expected an os.ErrNotExist, got: %v", err)
    23  	}
    24  	if bytes != 0 {
    25  		t.Errorf("Should have written 0 bytes, got: %d", bytes)
    26  	}
    27  }
    28  
    29  // CopyFile with invalid dest
    30  func TestCopyFileWithInvalidDest(t *testing.T) {
    31  	tempFolder := t.TempDir()
    32  	src := path.Join(tempFolder, "file")
    33  	err := os.WriteFile(src, []byte("content"), 0o740)
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  	bytes, err := CopyFile(src, path.Join(tempFolder, "/invalid/dest/path"))
    38  	if err == nil {
    39  		t.Error("Should have fail to copy an invalid src file")
    40  	}
    41  	if !errors.Is(err, os.ErrNotExist) {
    42  		t.Errorf("Expected an os.ErrNotExist, got: %v", err)
    43  	}
    44  	if bytes != 0 {
    45  		t.Errorf("Should have written 0 bytes, got: %d", bytes)
    46  	}
    47  }
    48  
    49  // CopyFile with same src and dest
    50  func TestCopyFileWithSameSrcAndDest(t *testing.T) {
    51  	file := path.Join(t.TempDir(), "file")
    52  	err := os.WriteFile(file, []byte("content"), 0o740)
    53  	if err != nil {
    54  		t.Fatal(err)
    55  	}
    56  	bytes, err := CopyFile(file, file)
    57  	if err != nil {
    58  		t.Fatal(err)
    59  	}
    60  	if bytes != 0 {
    61  		t.Fatal("Should have written 0 bytes as it is the same file.")
    62  	}
    63  }
    64  
    65  // CopyFile with same src and dest but path is different and not clean
    66  func TestCopyFileWithSameSrcAndDestWithPathNameDifferent(t *testing.T) {
    67  	testFolder := path.Join(t.TempDir(), "test")
    68  	err := os.Mkdir(testFolder, 0o740)
    69  	if err != nil {
    70  		t.Fatal(err)
    71  	}
    72  	file := path.Join(testFolder, "file")
    73  	sameFile := testFolder + "/../test/file"
    74  	err = os.WriteFile(file, []byte("content"), 0o740)
    75  	if err != nil {
    76  		t.Fatal(err)
    77  	}
    78  	bytes, err := CopyFile(file, sameFile)
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	if bytes != 0 {
    83  		t.Fatal("Should have written 0 bytes as it is the same file.")
    84  	}
    85  }
    86  
    87  func TestCopyFile(t *testing.T) {
    88  	tempFolder := t.TempDir()
    89  	src := path.Join(tempFolder, "src")
    90  	dest := path.Join(tempFolder, "dest")
    91  	err := os.WriteFile(src, []byte("content"), 0o777)
    92  	if err != nil {
    93  		t.Error(err)
    94  	}
    95  	err = os.WriteFile(dest, []byte("destContent"), 0o777)
    96  	if err != nil {
    97  		t.Error(err)
    98  	}
    99  	bytes, err := CopyFile(src, dest)
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  	if bytes != 7 {
   104  		t.Fatalf("Should have written %d bytes but wrote %d", 7, bytes)
   105  	}
   106  	actual, err := os.ReadFile(dest)
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  	if string(actual) != "content" {
   111  		t.Fatalf("Dest content was '%s', expected '%s'", string(actual), "content")
   112  	}
   113  }
   114  
   115  // Reading a symlink to a directory must return the directory
   116  func TestReadSymlinkedDirectoryExistingDirectory(t *testing.T) {
   117  	// TODO Windows: Port this test
   118  	if runtime.GOOS == "windows" {
   119  		t.Skip("Needs porting to Windows")
   120  	}
   121  
   122  	// On macOS, tmp itself is symlinked, so resolve this one upfront;
   123  	// see https://github.com/golang/go/issues/56259
   124  	tmpDir, err := filepath.EvalSymlinks(t.TempDir())
   125  	if err != nil {
   126  		t.Fatal(err)
   127  	}
   128  
   129  	srcPath := filepath.Join(tmpDir, "/testReadSymlinkToExistingDirectory")
   130  	dstPath := filepath.Join(tmpDir, "/dirLinkTest")
   131  	if err = os.Mkdir(srcPath, 0o777); err != nil {
   132  		t.Errorf("failed to create directory: %s", err)
   133  	}
   134  
   135  	if err = os.Symlink(srcPath, dstPath); err != nil {
   136  		t.Errorf("failed to create symlink: %s", err)
   137  	}
   138  
   139  	var symlinkedPath string
   140  	if symlinkedPath, err = ReadSymlinkedDirectory(dstPath); err != nil {
   141  		t.Fatalf("failed to read symlink to directory: %s", err)
   142  	}
   143  
   144  	if symlinkedPath != srcPath {
   145  		t.Fatalf("symlink returned unexpected directory: %s", symlinkedPath)
   146  	}
   147  
   148  	if err = os.Remove(srcPath); err != nil {
   149  		t.Errorf("failed to remove temporary directory: %s", err)
   150  	}
   151  
   152  	if err = os.Remove(dstPath); err != nil {
   153  		t.Errorf("failed to remove symlink: %s", err)
   154  	}
   155  }
   156  
   157  // Reading a non-existing symlink must fail
   158  func TestReadSymlinkedDirectoryNonExistingSymlink(t *testing.T) {
   159  	tmpDir := t.TempDir()
   160  	symLinkedPath, err := ReadSymlinkedDirectory(path.Join(tmpDir, "/Non/ExistingPath"))
   161  	if err == nil {
   162  		t.Errorf("error expected for non-existing symlink")
   163  	}
   164  	if !errors.Is(err, os.ErrNotExist) {
   165  		t.Errorf("Expected an os.ErrNotExist, got: %v", err)
   166  	}
   167  	if symLinkedPath != "" {
   168  		t.Fatalf("expected empty path, but '%s' was returned", symLinkedPath)
   169  	}
   170  }
   171  
   172  // Reading a symlink to a file must fail
   173  func TestReadSymlinkedDirectoryToFile(t *testing.T) {
   174  	// TODO Windows: Port this test
   175  	if runtime.GOOS == "windows" {
   176  		t.Skip("Needs porting to Windows")
   177  	}
   178  	var err error
   179  	var file *os.File
   180  
   181  	// #nosec G303
   182  	if file, err = os.Create("/tmp/testReadSymlinkToFile"); err != nil {
   183  		t.Fatalf("failed to create file: %s", err)
   184  	}
   185  
   186  	_ = file.Close()
   187  
   188  	if err = os.Symlink("/tmp/testReadSymlinkToFile", "/tmp/fileLinkTest"); err != nil {
   189  		t.Errorf("failed to create symlink: %s", err)
   190  	}
   191  
   192  	symlinkedPath, err := ReadSymlinkedDirectory("/tmp/fileLinkTest")
   193  	if err == nil {
   194  		t.Errorf("ReadSymlinkedDirectory on a symlink to a file should've failed")
   195  	}
   196  	if !strings.HasPrefix(err.Error(), "canonical path points to a file") {
   197  		t.Errorf("unexpected error: %v", err)
   198  	}
   199  
   200  	if symlinkedPath != "" {
   201  		t.Errorf("path should've been empty: %s", symlinkedPath)
   202  	}
   203  
   204  	if err = os.Remove("/tmp/testReadSymlinkToFile"); err != nil {
   205  		t.Errorf("failed to remove file: %s", err)
   206  	}
   207  
   208  	if err = os.Remove("/tmp/fileLinkTest"); err != nil {
   209  		t.Errorf("failed to remove symlink: %s", err)
   210  	}
   211  }
   212  
   213  func TestCreateIfNotExistsDir(t *testing.T) {
   214  	folderToCreate := filepath.Join(t.TempDir(), "tocreate")
   215  
   216  	if err := CreateIfNotExists(folderToCreate, true); err != nil {
   217  		t.Fatal(err)
   218  	}
   219  	fileinfo, err := os.Stat(folderToCreate)
   220  	if err != nil {
   221  		t.Fatalf("Should have create a folder, got %v", err)
   222  	}
   223  
   224  	if !fileinfo.IsDir() {
   225  		t.Errorf("Should have been a dir, seems it's not")
   226  	}
   227  }
   228  
   229  func TestCreateIfNotExistsFile(t *testing.T) {
   230  	fileToCreate := filepath.Join(t.TempDir(), "file/to/create")
   231  
   232  	if err := CreateIfNotExists(fileToCreate, false); err != nil {
   233  		t.Error(err)
   234  	}
   235  	fileinfo, err := os.Stat(fileToCreate)
   236  	if err != nil {
   237  		t.Fatalf("Should have create a file, got %v", err)
   238  	}
   239  
   240  	if fileinfo.IsDir() {
   241  		t.Errorf("Should have been a file, seems it's not")
   242  	}
   243  }
   244  
   245  func BenchmarkGetTotalUsedFds(b *testing.B) {
   246  	ctx := context.Background()
   247  	b.ReportAllocs()
   248  	for i := 0; i < b.N; i++ {
   249  		_ = GetTotalUsedFds(ctx)
   250  	}
   251  }