Files
yms-daemon/internal/hostnginx/controller_test.go
T

116 lines
4.2 KiB
Go
Raw Normal View History

2026-08-16 01:27:30 +08:00
package hostnginx
import (
"context"
"errors"
"os"
"path/filepath"
"slices"
"testing"
)
// TestControllerSwitchesAndReloadsNginx 验证 Switch 能将活动端口切到 8080
// 且实际执行了 nginx -t 与 nginx -s reload 命令。
func TestControllerSwitchesAndReloadsNginx(t *testing.T) {
2026-08-16 01:27:30 +08:00
configPath := writeNginxConfig(t, serverConfiguration)
runner := &recordingRunner{}
controller, err := newController(configPath, "/usr/sbin/nginx", runner)
2026-08-16 01:27:30 +08:00
if err != nil {
t.Fatalf("create host Nginx controller: %v", err)
}
previous, err := controller.Switch(context.Background(), 8080)
if err != nil {
t.Fatalf("switch host Nginx backend: %v", err)
}
if previous.ActivePort != 8081 {
t.Fatalf("unexpected previous port: %d", previous.ActivePort)
}
current, err := controller.Read()
if err != nil || current.ActivePort != 8080 {
t.Fatalf("unexpected current host Nginx configuration: snapshot=%+v err=%v", current, err)
}
wantCalls := [][]string{
{"/usr/sbin/nginx", "-t"},
{"/usr/sbin/nginx", "-s", "reload"},
2026-08-16 01:27:30 +08:00
}
if !slices.EqualFunc(runner.calls, wantCalls, slices.Equal) {
t.Fatalf("unexpected host Nginx commands: %+v", runner.calls)
}
}
// TestControllerRestoresConfigurationWhenValidationFails 验证 nginx -t 校验失败时 Switch 返回错误,
// 并把配置回滚为原始内容,同时执行了校验、回滚校验与回滚重载三次命令。
2026-08-16 01:27:30 +08:00
func TestControllerRestoresConfigurationWhenValidationFails(t *testing.T) {
configPath := writeNginxConfig(t, serverConfiguration)
runner := &recordingRunner{errors: []error{errors.New("nginx test failed"), nil, nil}}
controller, err := newController(configPath, "/usr/sbin/nginx", runner)
2026-08-16 01:27:30 +08:00
if err != nil {
t.Fatalf("create host Nginx controller: %v", err)
}
if _, err := controller.Switch(context.Background(), 8080); err == nil {
t.Fatal("expected host Nginx validation failure")
}
current, err := controller.Read()
if err != nil || current.ActivePort != 8081 || string(current.Content) != serverConfiguration {
t.Fatalf("host Nginx configuration was not restored: snapshot=%+v err=%v", current, err)
}
if len(runner.calls) != 3 {
t.Fatalf("unexpected validation compensation calls: %+v", runner.calls)
}
}
// TestControllerRestoreUsesCompleteSnapshot 验证 Restore 能使用 Switch 返回的完整快照
// 把配置恢复到切换前的原始内容与活动端口。
2026-08-16 01:27:30 +08:00
func TestControllerRestoreUsesCompleteSnapshot(t *testing.T) {
configPath := writeNginxConfig(t, serverConfiguration)
runner := &recordingRunner{}
controller, err := newController(configPath, "/usr/sbin/nginx", runner)
2026-08-16 01:27:30 +08:00
if err != nil {
t.Fatalf("create host Nginx controller: %v", err)
}
previous, err := controller.Switch(context.Background(), 8080)
if err != nil {
t.Fatalf("switch host Nginx backend: %v", err)
}
if err := controller.Restore(context.Background(), previous); err != nil {
t.Fatalf("restore host Nginx backend: %v", err)
}
current, err := controller.Read()
if err != nil || current.ActivePort != 8081 || string(current.Content) != serverConfiguration {
t.Fatalf("unexpected restored configuration: snapshot=%+v err=%v", current, err)
}
}
// writeNginxConfig 将 content 写入临时目录下的 nginx.conf 并返回其绝对路径,
// 供 Controller 测试使用。写入失败会直接终止测试。
2026-08-16 01:27:30 +08:00
func writeNginxConfig(t *testing.T, content string) string {
t.Helper()
path := filepath.Join(t.TempDir(), "nginx.conf")
if err := os.WriteFile(path, []byte(content), 0o640); err != nil {
t.Fatalf("write host Nginx configuration: %v", err)
}
return path
}
// recordingRunner commandRunner 的测试实现,记录每次调用并依次返回预设的错误。
2026-08-16 01:27:30 +08:00
type recordingRunner struct {
// calls 记录每次执行的命令(含参数)序列。
calls [][]string
// errors 依次返回的预设错误,取完后续调用返回 nil。
2026-08-16 01:27:30 +08:00
errors []error
}
// Run 记录本次调用命令,并按 errors 中的顺序返回下一个预设错误。
2026-08-16 01:27:30 +08:00
func (r *recordingRunner) Run(_ context.Context, executable string, arguments ...string) error {
call := append([]string{executable}, arguments...)
r.calls = append(r.calls, call)
if len(r.errors) == 0 {
return nil
}
err := r.errors[0]
r.errors = r.errors[1:]
return err
}