Procházet zdrojové kódy

Merge pull request #44265 from thaJeztah/pkg_system_move_init_step1

pkg/system: cleanup, test-fixes and improvements and minor fixes
Sebastiaan van Stijn před 2 roky
rodič
revize
081c00c7df

+ 28 - 11
pkg/system/chtimes.go

@@ -2,24 +2,41 @@ package system // import "github.com/docker/docker/pkg/system"
 
 import (
 	"os"
+	"syscall"
 	"time"
+	"unsafe"
 )
 
-// Chtimes changes the access time and modified time of a file at the given path
-func Chtimes(name string, atime time.Time, mtime time.Time) error {
-	unixMinTime := time.Unix(0, 0)
-	unixMaxTime := maxTime
+// Used by Chtimes
+var unixEpochTime, unixMaxTime time.Time
 
-	// If the modified time is prior to the Unix Epoch, or after the
-	// end of Unix Time, os.Chtimes has undefined behavior
-	// default to Unix Epoch in this case, just in case
+func init() {
+	unixEpochTime = time.Unix(0, 0)
+	if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
+		// This is a 64 bit timespec
+		// os.Chtimes limits time to the following
+		//
+		// Note that this intentionally sets nsec (not sec), which sets both sec
+		// and nsec internally in time.Unix();
+		// https://github.com/golang/go/blob/go1.19.2/src/time/time.go#L1364-L1380
+		unixMaxTime = time.Unix(0, 1<<63-1)
+	} else {
+		// This is a 32 bit timespec
+		unixMaxTime = time.Unix(1<<31-1, 0)
+	}
+}
 
-	if atime.Before(unixMinTime) || atime.After(unixMaxTime) {
-		atime = unixMinTime
+// Chtimes changes the access time and modified time of a file at the given path.
+// If the modified time is prior to the Unix Epoch (unixMinTime), or after the
+// end of Unix Time (unixEpochTime), os.Chtimes has undefined behavior. In this
+// case, Chtimes defaults to Unix Epoch, just in case.
+func Chtimes(name string, atime time.Time, mtime time.Time) error {
+	if atime.Before(unixEpochTime) || atime.After(unixMaxTime) {
+		atime = unixEpochTime
 	}
 
-	if mtime.Before(unixMinTime) || mtime.After(unixMaxTime) {
-		mtime = unixMinTime
+	if mtime.Before(unixEpochTime) || mtime.After(unixMaxTime) {
+		mtime = unixEpochTime
 	}
 
 	if err := os.Chtimes(name, atime, mtime); err != nil {

+ 89 - 68
pkg/system/chtimes_linux_test.go

@@ -2,88 +2,109 @@ package system // import "github.com/docker/docker/pkg/system"
 
 import (
 	"os"
+	"path/filepath"
 	"syscall"
 	"testing"
 	"time"
 )
 
-// TestChtimesLinux tests Chtimes access time on a tempfile on Linux
-func TestChtimesLinux(t *testing.T) {
-	file, dir := prepareTempFile(t)
-	defer os.RemoveAll(dir)
-
-	beforeUnixEpochTime := time.Unix(0, 0).Add(-100 * time.Second)
-	unixEpochTime := time.Unix(0, 0)
-	afterUnixEpochTime := time.Unix(100, 0)
-	unixMaxTime := maxTime
-
-	// Test both aTime and mTime set to Unix Epoch
-	Chtimes(file, unixEpochTime, unixEpochTime)
-
-	f, err := os.Stat(file)
-	if err != nil {
+// TestChtimesATime tests Chtimes access time on a tempfile.
+func TestChtimesATime(t *testing.T) {
+	file := filepath.Join(t.TempDir(), "exist")
+	if err := os.WriteFile(file, []byte("hello"), 0o644); err != nil {
 		t.Fatal(err)
 	}
 
-	stat := f.Sys().(*syscall.Stat_t)
-	aTime := time.Unix(stat.Atim.Unix())
-	if aTime != unixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
-	}
-
-	// Test aTime before Unix Epoch and mTime set to Unix Epoch
-	Chtimes(file, beforeUnixEpochTime, unixEpochTime)
+	beforeUnixEpochTime := unixEpochTime.Add(-100 * time.Second)
+	afterUnixEpochTime := unixEpochTime.Add(100 * time.Second)
 
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
+	// Test both aTime and mTime set to Unix Epoch
+	t.Run("both aTime and mTime set to Unix Epoch", func(t *testing.T) {
+		if err := Chtimes(file, unixEpochTime, unixEpochTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		stat := f.Sys().(*syscall.Stat_t)
+		aTime := time.Unix(stat.Atim.Unix())
+		if aTime != unixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
+		}
+	})
 
-	stat = f.Sys().(*syscall.Stat_t)
-	aTime = time.Unix(stat.Atim.Unix())
-	if aTime != unixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
-	}
+	// Test aTime before Unix Epoch and mTime set to Unix Epoch
+	t.Run("aTime before Unix Epoch and mTime set to Unix Epoch", func(t *testing.T) {
+		if err := Chtimes(file, beforeUnixEpochTime, unixEpochTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		stat := f.Sys().(*syscall.Stat_t)
+		aTime := time.Unix(stat.Atim.Unix())
+		if aTime != unixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
+		}
+	})
 
 	// Test aTime set to Unix Epoch and mTime before Unix Epoch
-	Chtimes(file, unixEpochTime, beforeUnixEpochTime)
-
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	stat = f.Sys().(*syscall.Stat_t)
-	aTime = time.Unix(stat.Atim.Unix())
-	if aTime != unixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
-	}
+	t.Run("aTime set to Unix Epoch and mTime before Unix Epoch", func(t *testing.T) {
+		if err := Chtimes(file, unixEpochTime, beforeUnixEpochTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		stat := f.Sys().(*syscall.Stat_t)
+		aTime := time.Unix(stat.Atim.Unix())
+		if aTime != unixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
+		}
+	})
 
 	// Test both aTime and mTime set to after Unix Epoch (valid time)
-	Chtimes(file, afterUnixEpochTime, afterUnixEpochTime)
-
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	stat = f.Sys().(*syscall.Stat_t)
-	aTime = time.Unix(stat.Atim.Unix())
-	if aTime != afterUnixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", afterUnixEpochTime, aTime)
-	}
+	t.Run("both aTime and mTime set to after Unix Epoch (valid time)", func(t *testing.T) {
+		if err := Chtimes(file, afterUnixEpochTime, afterUnixEpochTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		stat := f.Sys().(*syscall.Stat_t)
+		aTime := time.Unix(stat.Atim.Unix())
+		if aTime != afterUnixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", afterUnixEpochTime, aTime)
+		}
+	})
 
 	// Test both aTime and mTime set to Unix max time
-	Chtimes(file, unixMaxTime, unixMaxTime)
-
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	stat = f.Sys().(*syscall.Stat_t)
-	aTime = time.Unix(stat.Atim.Unix())
-	if aTime.Truncate(time.Second) != unixMaxTime.Truncate(time.Second) {
-		t.Fatalf("Expected: %s, got: %s", unixMaxTime.Truncate(time.Second), aTime.Truncate(time.Second))
-	}
+	t.Run("both aTime and mTime set to Unix max time", func(t *testing.T) {
+		if err := Chtimes(file, unixMaxTime, unixMaxTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		stat := f.Sys().(*syscall.Stat_t)
+		aTime := time.Unix(stat.Atim.Unix())
+		if aTime.Truncate(time.Second) != unixMaxTime.Truncate(time.Second) {
+			t.Fatalf("Expected: %s, got: %s", unixMaxTime.Truncate(time.Second), aTime.Truncate(time.Second))
+		}
+	})
 }

+ 69 - 62
pkg/system/chtimes_test.go

@@ -7,87 +7,94 @@ import (
 	"time"
 )
 
-// prepareTempFile creates a temporary file in a temporary directory.
-func prepareTempFile(t *testing.T) (string, string) {
-	dir, err := os.MkdirTemp("", "docker-system-test")
-	if err != nil {
+// TestChtimesModTime tests Chtimes on a tempfile. Test only mTime, because
+// aTime is OS dependent.
+func TestChtimesModTime(t *testing.T) {
+	file := filepath.Join(t.TempDir(), "exist")
+	if err := os.WriteFile(file, []byte("hello"), 0o644); err != nil {
 		t.Fatal(err)
 	}
 
-	file := filepath.Join(dir, "exist")
-	if err := os.WriteFile(file, []byte("hello"), 0644); err != nil {
-		t.Fatal(err)
-	}
-	return file, dir
-}
-
-// TestChtimes tests Chtimes on a tempfile. Test only mTime, because aTime is OS dependent
-func TestChtimes(t *testing.T) {
-	file, dir := prepareTempFile(t)
-	defer os.RemoveAll(dir)
-
-	beforeUnixEpochTime := time.Unix(0, 0).Add(-100 * time.Second)
-	unixEpochTime := time.Unix(0, 0)
-	afterUnixEpochTime := time.Unix(100, 0)
-	unixMaxTime := maxTime
+	beforeUnixEpochTime := unixEpochTime.Add(-100 * time.Second)
+	afterUnixEpochTime := unixEpochTime.Add(100 * time.Second)
 
 	// Test both aTime and mTime set to Unix Epoch
-	Chtimes(file, unixEpochTime, unixEpochTime)
+	t.Run("both aTime and mTime set to Unix Epoch", func(t *testing.T) {
+		if err := Chtimes(file, unixEpochTime, unixEpochTime); err != nil {
+			t.Error(err)
+		}
 
-	f, err := os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
 
-	if f.ModTime() != unixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", unixEpochTime, f.ModTime())
-	}
+		if f.ModTime() != unixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", unixEpochTime, f.ModTime())
+		}
+	})
 
 	// Test aTime before Unix Epoch and mTime set to Unix Epoch
-	Chtimes(file, beforeUnixEpochTime, unixEpochTime)
+	t.Run("aTime before Unix Epoch and mTime set to Unix Epoch", func(t *testing.T) {
+		if err := Chtimes(file, beforeUnixEpochTime, unixEpochTime); err != nil {
+			t.Error(err)
+		}
 
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
 
-	if f.ModTime() != unixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", unixEpochTime, f.ModTime())
-	}
+		if f.ModTime() != unixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", unixEpochTime, f.ModTime())
+		}
+	})
 
 	// Test aTime set to Unix Epoch and mTime before Unix Epoch
-	Chtimes(file, unixEpochTime, beforeUnixEpochTime)
+	t.Run("aTime set to Unix Epoch and mTime before Unix Epoch", func(t *testing.T) {
+		if err := Chtimes(file, unixEpochTime, beforeUnixEpochTime); err != nil {
+			t.Error(err)
+		}
 
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
 
-	if f.ModTime() != unixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", unixEpochTime, f.ModTime())
-	}
+		if f.ModTime() != unixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", unixEpochTime, f.ModTime())
+		}
+	})
 
 	// Test both aTime and mTime set to after Unix Epoch (valid time)
-	Chtimes(file, afterUnixEpochTime, afterUnixEpochTime)
+	t.Run("both aTime and mTime set to after Unix Epoch (valid time)", func(t *testing.T) {
+		if err := Chtimes(file, afterUnixEpochTime, afterUnixEpochTime); err != nil {
+			t.Error(err)
+		}
 
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
 
-	if f.ModTime() != afterUnixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", afterUnixEpochTime, f.ModTime())
-	}
+		if f.ModTime() != afterUnixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", afterUnixEpochTime, f.ModTime())
+		}
+	})
 
 	// Test both aTime and mTime set to Unix max time
-	Chtimes(file, unixMaxTime, unixMaxTime)
-
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if f.ModTime().Truncate(time.Second) != unixMaxTime.Truncate(time.Second) {
-		t.Fatalf("Expected: %s, got: %s", unixMaxTime.Truncate(time.Second), f.ModTime().Truncate(time.Second))
-	}
+	t.Run("both aTime and mTime set to Unix max time", func(t *testing.T) {
+		if err := Chtimes(file, unixMaxTime, unixMaxTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		if f.ModTime().Truncate(time.Second) != unixMaxTime.Truncate(time.Second) {
+			t.Fatalf("Expected: %s, got: %s", unixMaxTime.Truncate(time.Second), f.ModTime().Truncate(time.Second))
+		}
+	})
 }

+ 7 - 8
pkg/system/chtimes_windows.go

@@ -9,18 +9,17 @@ import (
 // setCTime will set the create time on a file. On Windows, this requires
 // calling SetFileTime and explicitly including the create time.
 func setCTime(path string, ctime time.Time) error {
-	ctimespec := windows.NsecToTimespec(ctime.UnixNano())
-	pathp, e := windows.UTF16PtrFromString(path)
-	if e != nil {
-		return e
+	pathp, err := windows.UTF16PtrFromString(path)
+	if err != nil {
+		return err
 	}
-	h, e := windows.CreateFile(pathp,
+	h, err := windows.CreateFile(pathp,
 		windows.FILE_WRITE_ATTRIBUTES, windows.FILE_SHARE_WRITE, nil,
 		windows.OPEN_EXISTING, windows.FILE_FLAG_BACKUP_SEMANTICS, 0)
-	if e != nil {
-		return e
+	if err != nil {
+		return err
 	}
 	defer windows.Close(h)
-	c := windows.NsecToFiletime(windows.TimespecToNsec(ctimespec))
+	c := windows.NsecToFiletime(ctime.UnixNano())
 	return windows.SetFileTime(h, &c, nil, nil)
 }

+ 84 - 63
pkg/system/chtimes_windows_test.go

@@ -5,83 +5,104 @@ package system // import "github.com/docker/docker/pkg/system"
 
 import (
 	"os"
+	"path/filepath"
 	"syscall"
 	"testing"
 	"time"
 )
 
-// TestChtimesWindows tests Chtimes access time on a tempfile on Windows
-func TestChtimesWindows(t *testing.T) {
-	file, dir := prepareTempFile(t)
-	defer os.RemoveAll(dir)
-
-	beforeUnixEpochTime := time.Unix(0, 0).Add(-100 * time.Second)
-	unixEpochTime := time.Unix(0, 0)
-	afterUnixEpochTime := time.Unix(100, 0)
-	unixMaxTime := maxTime
-
-	// Test both aTime and mTime set to Unix Epoch
-	Chtimes(file, unixEpochTime, unixEpochTime)
-
-	f, err := os.Stat(file)
-	if err != nil {
+// TestChtimesATimeWindows tests Chtimes access time on a tempfile on Windows.
+func TestChtimesATimeWindows(t *testing.T) {
+	file := filepath.Join(t.TempDir(), "exist")
+	if err := os.WriteFile(file, []byte("hello"), 0o644); err != nil {
 		t.Fatal(err)
 	}
 
-	aTime := time.Unix(0, f.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
-	if aTime != unixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
-	}
-
-	// Test aTime before Unix Epoch and mTime set to Unix Epoch
-	Chtimes(file, beforeUnixEpochTime, unixEpochTime)
+	beforeUnixEpochTime := unixEpochTime.Add(-100 * time.Second)
+	afterUnixEpochTime := unixEpochTime.Add(100 * time.Second)
 
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
+	// Test both aTime and mTime set to Unix Epoch
+	t.Run("both aTime and mTime set to Unix Epoch", func(t *testing.T) {
+		if err := Chtimes(file, unixEpochTime, unixEpochTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		aTime := time.Unix(0, f.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
+		if aTime != unixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
+		}
+	})
 
-	aTime = time.Unix(0, f.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
-	if aTime != unixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
-	}
+	// Test aTime before Unix Epoch and mTime set to Unix Epoch
+	t.Run("aTime before Unix Epoch and mTime set to Unix Epoch", func(t *testing.T) {
+		if err := Chtimes(file, beforeUnixEpochTime, unixEpochTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		aTime := time.Unix(0, f.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
+		if aTime != unixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
+		}
+	})
 
 	// Test aTime set to Unix Epoch and mTime before Unix Epoch
-	Chtimes(file, unixEpochTime, beforeUnixEpochTime)
-
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	aTime = time.Unix(0, f.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
-	if aTime != unixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
-	}
+	t.Run("aTime set to Unix Epoch and mTime before Unix Epoch", func(t *testing.T) {
+		if err := Chtimes(file, unixEpochTime, beforeUnixEpochTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		aTime := time.Unix(0, f.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
+		if aTime != unixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", unixEpochTime, aTime)
+		}
+	})
 
 	// Test both aTime and mTime set to after Unix Epoch (valid time)
-	Chtimes(file, afterUnixEpochTime, afterUnixEpochTime)
-
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	aTime = time.Unix(0, f.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
-	if aTime != afterUnixEpochTime {
-		t.Fatalf("Expected: %s, got: %s", afterUnixEpochTime, aTime)
-	}
+	t.Run("both aTime and mTime set to after Unix Epoch (valid time)", func(t *testing.T) {
+		if err := Chtimes(file, afterUnixEpochTime, afterUnixEpochTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		aTime := time.Unix(0, f.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
+		if aTime != afterUnixEpochTime {
+			t.Fatalf("Expected: %s, got: %s", afterUnixEpochTime, aTime)
+		}
+	})
 
 	// Test both aTime and mTime set to Unix max time
-	Chtimes(file, unixMaxTime, unixMaxTime)
-
-	f, err = os.Stat(file)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	aTime = time.Unix(0, f.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
-	if aTime.Truncate(time.Second) != unixMaxTime.Truncate(time.Second) {
-		t.Fatalf("Expected: %s, got: %s", unixMaxTime.Truncate(time.Second), aTime.Truncate(time.Second))
-	}
+	t.Run("both aTime and mTime set to Unix max time", func(t *testing.T) {
+		if err := Chtimes(file, unixMaxTime, unixMaxTime); err != nil {
+			t.Error(err)
+		}
+
+		f, err := os.Stat(file)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		aTime := time.Unix(0, f.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
+		if aTime.Truncate(time.Second) != unixMaxTime.Truncate(time.Second) {
+			t.Fatalf("Expected: %s, got: %s", unixMaxTime.Truncate(time.Second), aTime.Truncate(time.Second))
+		}
+	})
 }

+ 0 - 22
pkg/system/init.go

@@ -1,22 +0,0 @@
-package system // import "github.com/docker/docker/pkg/system"
-
-import (
-	"syscall"
-	"time"
-	"unsafe"
-)
-
-// Used by chtimes
-var maxTime time.Time
-
-func init() {
-	// chtimes initialization
-	if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
-		// This is a 64 bit timespec
-		// os.Chtimes limits time to the following
-		maxTime = time.Unix(0, 1<<63-1)
-	} else {
-		// This is a 32 bit timespec
-		maxTime = time.Unix(1<<31-1, 0)
-	}
-}

+ 7 - 3
pkg/system/lstat_unix_test.go

@@ -5,13 +5,17 @@ package system // import "github.com/docker/docker/pkg/system"
 
 import (
 	"os"
+	"path/filepath"
 	"testing"
 )
 
 // TestLstat tests Lstat for existing and non existing files
 func TestLstat(t *testing.T) {
-	file, invalid, _, dir := prepareFiles(t)
-	defer os.RemoveAll(dir)
+	tmpDir := t.TempDir()
+	file := filepath.Join(tmpDir, "exist")
+	if err := os.WriteFile(file, []byte("hello"), 0o644); err != nil {
+		t.Fatal(err)
+	}
 
 	statFile, err := Lstat(file)
 	if err != nil {
@@ -21,7 +25,7 @@ func TestLstat(t *testing.T) {
 		t.Fatal("returned empty stat for existing file")
 	}
 
-	statInvalid, err := Lstat(invalid)
+	statInvalid, err := Lstat(filepath.Join(tmpDir, "nosuchfile"))
 	if err == nil {
 		t.Fatal("did not return error for non-existing file")
 	}

+ 5 - 2
pkg/system/stat_unix_test.go

@@ -5,6 +5,7 @@ package system // import "github.com/docker/docker/pkg/system"
 
 import (
 	"os"
+	"path/filepath"
 	"syscall"
 	"testing"
 
@@ -13,8 +14,10 @@ import (
 
 // TestFromStatT tests fromStatT for a tempfile
 func TestFromStatT(t *testing.T) {
-	file, _, _, dir := prepareFiles(t)
-	defer os.RemoveAll(dir)
+	file := filepath.Join(t.TempDir(), "exist")
+	if err := os.WriteFile(file, []byte("hello"), 0o644); err != nil {
+		t.Fatal(err)
+	}
 
 	stat := &syscall.Stat_t{}
 	err := syscall.Lstat(file, stat)

+ 9 - 13
pkg/system/utimes_unix_test.go

@@ -11,30 +11,26 @@ import (
 )
 
 // prepareFiles creates files for testing in the temp directory
-func prepareFiles(t *testing.T) (string, string, string, string) {
-	dir, err := os.MkdirTemp("", "docker-system-test")
-	if err != nil {
-		t.Fatal(err)
-	}
+func prepareFiles(t *testing.T) (file, invalid, symlink string) {
+	t.Helper()
+	dir := t.TempDir()
 
-	file := filepath.Join(dir, "exist")
-	if err := os.WriteFile(file, []byte("hello"), 0644); err != nil {
+	file = filepath.Join(dir, "exist")
+	if err := os.WriteFile(file, []byte("hello"), 0o644); err != nil {
 		t.Fatal(err)
 	}
 
-	invalid := filepath.Join(dir, "doesnt-exist")
-
-	symlink := filepath.Join(dir, "symlink")
+	invalid = filepath.Join(dir, "doesnt-exist")
+	symlink = filepath.Join(dir, "symlink")
 	if err := os.Symlink(file, symlink); err != nil {
 		t.Fatal(err)
 	}
 
-	return file, invalid, symlink, dir
+	return file, invalid, symlink
 }
 
 func TestLUtimesNano(t *testing.T) {
-	file, invalid, symlink, dir := prepareFiles(t)
-	defer os.RemoveAll(dir)
+	file, invalid, symlink := prepareFiles(t)
 
 	before, err := os.Stat(file)
 	if err != nil {