Files
2026-08-17 10:10:14 +08:00

116 lines
4.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package hostnginx
import (
"context"
"errors"
"os"
"path/filepath"
"slices"
"testing"
)
// TestControllerSwitchesAndReloadsNginx 验证 Switch 能将活动端口切到 8080
// 且实际执行了 nginx -t 与 nginx -s reload 命令。
func TestControllerSwitchesAndReloadsNginx(t *testing.T) {
configPath := writeNginxConfig(t, serverConfiguration)
runner := &recordingRunner{}
controller, err := newController(configPath, "/usr/sbin/nginx", runner)
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"},
}
if !slices.EqualFunc(runner.calls, wantCalls, slices.Equal) {
t.Fatalf("unexpected host Nginx commands: %+v", runner.calls)
}
}
// TestControllerRestoresConfigurationWhenValidationFails 验证 nginx -t 校验失败时 Switch 返回错误,
// 并把配置回滚为原始内容,同时执行了校验、回滚校验与回滚重载三次命令。
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)
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 返回的完整快照
// 把配置恢复到切换前的原始内容与活动端口。
func TestControllerRestoreUsesCompleteSnapshot(t *testing.T) {
configPath := writeNginxConfig(t, serverConfiguration)
runner := &recordingRunner{}
controller, err := newController(configPath, "/usr/sbin/nginx", runner)
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 测试使用。写入失败会直接终止测试。
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 的测试实现,记录每次调用并依次返回预设的错误。
type recordingRunner struct {
// calls 记录每次执行的命令(含参数)序列。
calls [][]string
// errors 依次返回的预设错误,取完后续调用返回 nil。
errors []error
}
// Run 记录本次调用命令,并按 errors 中的顺序返回下一个预设错误。
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
}