Smail/backend/res_init/directories_test.go
smail d6cc81ed87
Some checks are pending
Security Checks / security (push) Waiting to run
分离五项配置与运行数据并实现无损目录迁移
2026-09-08 17:16:09 +08:00

92 lines
2.6 KiB
Go

package res_init
import (
"bytes"
"os"
"path/filepath"
"testing"
"git.pcux.cn/xuans/Smail/config"
)
func TestDirInitUsesRuntimeRoot(t *testing.T) {
root, working := t.TempDir(), t.TempDir()
t.Chdir(working)
previous := config.ROOT_PATH
config.ROOT_PATH = root
t.Cleanup(func() { config.ROOT_PATH = previous })
for i := 0; i < 2; i++ {
if err := dirInit(); err != nil {
t.Fatal(err)
}
for _, name := range []string{"config", "data", "data/dkim", "data/ssl"} {
info, err := os.Stat(filepath.Join(root, name))
if err != nil || !info.IsDir() {
t.Fatalf("运行目录未创建: %s", name)
}
}
}
if _, err := os.Stat(filepath.Join(working, "config")); !os.IsNotExist(err) {
t.Fatal("初始化不应在工作目录创建另一份配置")
}
}
func TestDirInitPreservesExistingFiles(t *testing.T) {
root := t.TempDir()
previous := config.ROOT_PATH
config.ROOT_PATH = root
t.Cleanup(func() { config.ROOT_PATH = previous })
if err := dirInit(); err != nil {
t.Fatal(err)
}
files := []string{"config/config.json", "data/smail.db", "data/credential.key", "data/dkim/dkim.priv", "data/ssl/private.key"}
data := []byte("existing-runtime-fixture")
for _, name := range files {
if err := os.WriteFile(filepath.Join(root, name), data, 0600); err != nil {
t.Fatal(err)
}
}
if err := dirInit(); err != nil {
t.Fatal(err)
}
for _, name := range files {
actual, err := os.ReadFile(filepath.Join(root, name))
if err != nil || !bytes.Equal(actual, data) {
t.Fatalf("初始化改变了已有运行文件: %s", name)
}
}
}
func TestDirInitRejectsFileAsDirectory(t *testing.T) {
root := t.TempDir()
previous := config.ROOT_PATH
config.ROOT_PATH = root
t.Cleanup(func() { config.ROOT_PATH = previous })
if err := os.Mkdir(filepath.Join(root, "data"), 0700); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(root, "data", "dkim"), []byte("blocked"), 0600); err != nil {
t.Fatal(err)
}
if err := dirInit(); err == nil {
t.Fatal("普通文件不能冒充运行目录")
}
}
func TestDirInitRejectsSymlink(t *testing.T) {
root, outside := t.TempDir(), t.TempDir()
previous := config.ROOT_PATH
config.ROOT_PATH = root
t.Cleanup(func() { config.ROOT_PATH = previous })
if err := os.Symlink(outside, filepath.Join(root, "config")); err != nil {
t.Skipf("当前环境无法创建符号链接: %v", err)
}
if err := dirInit(); err == nil {
t.Fatal("运行配置目录不能通过符号链接逃逸")
}
if _, err := os.Stat(filepath.Join(outside, "dkim")); !os.IsNotExist(err) {
t.Fatal("拒绝符号链接前不应写入外部目录")
}
}