Smail/backend/utils/runtimepath/layout_test.go
smail 5e7b57d754
Some checks are pending
Security Checks / security (push) Waiting to run
修复配置原子写中断后的启动恢复
2026-09-22 01:09:18 +08:00

81 lines
2.5 KiB
Go

package runtimepath
import (
"os"
"path/filepath"
"runtime"
"testing"
)
func TestCheckReadyRemovesInterruptedAtomicConfigurationTemporaryFiles(t *testing.T) {
root := t.TempDir()
if err := os.Mkdir(filepath.Join(root, "config"), 0700); err != nil {
t.Fatal(err)
}
temporary := filepath.Join(root, "config", ".config.json-0123456789abcdef0123456789abcdef")
if err := os.WriteFile(temporary, []byte("incomplete"), 0600); err != nil {
t.Fatal(err)
}
if err := CheckReady(root); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(temporary); !os.IsNotExist(err) {
t.Fatalf("temporary file still exists: %v", err)
}
}
func TestCheckReadyRejectsAtomicTemporaryDirectory(t *testing.T) {
root := t.TempDir()
configDirectory := filepath.Join(root, "config")
if err := os.Mkdir(configDirectory, 0700); err != nil {
t.Fatal(err)
}
path := filepath.Join(configDirectory, ".config.json-0123456789abcdef0123456789abcdef")
if err := os.Mkdir(path, 0700); err != nil {
t.Fatal(err)
}
if err := CheckReady(root); err == nil {
t.Fatal("expected invalid temporary directory to be rejected")
}
}
func TestCheckReadyRejectsAtomicTemporarySymlink(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("当前 Windows 测试环境通常没有创建符号链接的权限")
}
root := t.TempDir()
configDirectory := filepath.Join(root, "config")
if err := os.Mkdir(configDirectory, 0700); err != nil {
t.Fatal(err)
}
path := filepath.Join(configDirectory, ".config.json-0123456789abcdef0123456789abcdef")
if err := os.Symlink(filepath.Join(configDirectory, "missing"), path); err != nil {
t.Fatal(err)
}
if err := CheckReady(root); err == nil {
t.Fatal("expected invalid temporary symlink to be rejected")
}
}
func TestPlanIgnoresKnownAtomicTemporaryFilesButRejectsUnknownFiles(t *testing.T) {
root := t.TempDir()
configDirectory := filepath.Join(root, "config")
if err := os.Mkdir(configDirectory, 0700); err != nil {
t.Fatal(err)
}
known := filepath.Join(configDirectory, ".smtp.json-0123456789abcdef0123456789abcdef")
if err := os.WriteFile(known, []byte("incomplete"), 0600); err != nil {
t.Fatal(err)
}
if moves, err := Plan(root); err != nil || len(moves) != 0 {
t.Fatalf("known temporary file should be ignored, moves=%v err=%v", moves, err)
}
unknown := filepath.Join(configDirectory, ".not-an-atomic-file")
if err := os.WriteFile(unknown, []byte("unexpected"), 0600); err != nil {
t.Fatal(err)
}
if _, err := Plan(root); err == nil {
t.Fatal("unknown file should be rejected")
}
}