初始化仓库
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAtomicWriteFile_Basic(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "test.txt")
|
||||
data := []byte("hello world")
|
||||
|
||||
if err := AtomicWriteFile(path, data, 0644); err != nil {
|
||||
t.Fatalf("AtomicWriteFile: %v", err)
|
||||
}
|
||||
|
||||
got, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile: %v", err)
|
||||
}
|
||||
if string(got) != string(data) {
|
||||
t.Errorf("got %q, want %q", got, data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAtomicWriteFile_Overwrite(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "test.txt")
|
||||
|
||||
if err := AtomicWriteFile(path, []byte("first"), 0644); err != nil {
|
||||
t.Fatalf("first write: %v", err)
|
||||
}
|
||||
if err := AtomicWriteFile(path, []byte("second"), 0644); err != nil {
|
||||
t.Fatalf("second write: %v", err)
|
||||
}
|
||||
|
||||
got, _ := os.ReadFile(path)
|
||||
if string(got) != "second" {
|
||||
t.Errorf("got %q, want %q", got, "second")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAtomicWriteFile_Permissions(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("Unix file permissions not supported on Windows")
|
||||
}
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "test.txt")
|
||||
|
||||
if err := AtomicWriteFile(path, []byte("x"), 0600); err != nil {
|
||||
t.Fatalf("AtomicWriteFile: %v", err)
|
||||
}
|
||||
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Stat: %v", err)
|
||||
}
|
||||
if perm := info.Mode().Perm(); perm != 0600 {
|
||||
t.Errorf("perm = %o, want 0600", perm)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAtomicWriteFile_NoTempLeftOnSuccess(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "test.txt")
|
||||
|
||||
_ = AtomicWriteFile(path, []byte("data"), 0644)
|
||||
|
||||
entries, _ := os.ReadDir(dir)
|
||||
for _, e := range entries {
|
||||
if e.Name() != "test.txt" {
|
||||
t.Errorf("unexpected file left: %s", e.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestAtomicWriteFile_NoTempLeftWhenRenameFails is a regression test for a
|
||||
// `.tmp-*` leak in the rename-failure path. Before the fix, AtomicWriteFile
|
||||
// returned the rename error directly without removing the tmp file it had
|
||||
// just created — so repeated failures would litter the parent directory
|
||||
// with stale `.tmp-*` files and confuse callers that scan that directory
|
||||
// (cron store, session store, etc.).
|
||||
//
|
||||
// We force a rename failure by writing to a path that already exists as a
|
||||
// directory; os.Rename refuses to replace a non-empty directory with a
|
||||
// regular file on every supported platform.
|
||||
func TestAtomicWriteFile_NoTempLeftWhenRenameFails(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
target := filepath.Join(dir, "blocked")
|
||||
if err := os.MkdirAll(target, 0o755); err != nil {
|
||||
t.Fatalf("mkdir target dir: %v", err)
|
||||
}
|
||||
|
||||
if err := AtomicWriteFile(target, []byte("payload"), 0o644); err == nil {
|
||||
t.Fatal("AtomicWriteFile should fail when target is an existing directory")
|
||||
}
|
||||
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDir: %v", err)
|
||||
}
|
||||
for _, e := range entries {
|
||||
if e.Name() != "blocked" {
|
||||
t.Errorf("rename failure left orphan file %q in %s; cleanup is missing", e.Name(), dir)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user