Scert/backend/internal/nginxactivation/reconcile_linux_test.go

88 lines
2.9 KiB
Go

package nginxactivation
import (
"context"
"os"
"path/filepath"
"testing"
"time"
)
func TestRotationReadyAndState(t *testing.T) {
f := newRotationFixture(t)
ctx := context.Background()
state, err := f.rotation.State(ctx)
if err != nil || state.Status != "idle" {
t.Fatalf("空事务状态错误:%+v, %v", state, err)
}
ready, err := f.rotation.Ready(ctx)
if err != nil || ready.LeafHash != leafHash(f.old.pair.Certificate[0]) || ready.Hostname != testHostname || ready.UpstreamAddress != f.upstream.Address {
t.Fatalf("就绪状态错误:%+v, %v", ready, err)
}
if _, err := f.rotation.Stage(ctx, f.candidate.chain, f.candidate.key); err != nil {
t.Fatal(err)
}
if _, err := f.rotation.Ready(ctx); err == nil {
t.Fatal("未决事务不能通过申请前检查")
}
state, err = f.rotation.State(ctx)
if err != nil || state.Status != "staged" || state.CandidateHash != leafHash(f.candidate.pair.Certificate[0]) || state.PreviousHash != ready.LeafHash {
t.Fatalf("候选事务状态错误:%+v, %v", state, err)
}
}
func TestRotationReconcileUsesActualUpstream(t *testing.T) {
for _, scenario := range []string{"old", "candidate", "pending-candidate", "unrelated", "unavailable", "external-include", "wrong-id"} {
t.Run(scenario, func(t *testing.T) {
f := newRotationFixture(t)
ctx := context.Background()
id, err := f.rotation.Stage(ctx, f.candidate.chain, f.candidate.key)
if err != nil {
t.Fatal(err)
}
expected := "committed"
f.upstream.active.Store(&f.candidate.pair)
switch scenario {
case "old":
f.upstream.active.Store(&f.old.pair)
expected = "rolled_back"
case "pending-candidate":
current := f.assertStatus(t, "staged")
current.Status = "pending"
root, err := os.OpenRoot(f.rotation.Directory)
if err != nil {
t.Fatal(err)
}
defer root.Close()
if err := saveTransaction(root, current); err != nil {
t.Fatal(err)
}
case "unrelated":
other := f.authority.issue(t, testHostname, time.Now().Add(-time.Hour), time.Now().Add(72*time.Hour))
f.upstream.active.Store(&other.pair)
case "unavailable":
f.upstream.server.Close()
case "external-include":
writeTestFile(t, filepath.Join(f.rotation.Directory, includeName), []byte("# 外部修改\n"))
case "wrong-id":
id = "00000000000000000000000000000000"
}
state, err := f.rotation.Reconcile(ctx, id)
if scenario == "unrelated" || scenario == "unavailable" || scenario == "external-include" || scenario == "wrong-id" {
if err == nil {
t.Fatal("无法确认的状态不应完成恢复")
}
f.assertStatus(t, "staged")
return
}
if err != nil || state.Status != expected {
t.Fatalf("恢复结果错误:%+v, %v", state, err)
}
f.assertStatus(t, expected)
if _, err := f.rotation.Reconcile(ctx, id); err != nil {
t.Fatal("重复恢复应返回终态", err)
}
})
}
}