refactor: use nginx -s reload instead of systemd

- doc: add comment
This commit is contained in:
2026-08-17 10:10:14 +08:00
parent 79f18fcdea
commit f536987a7e
62 changed files with 2216 additions and 598 deletions
@@ -20,6 +20,8 @@ import (
"yms-daemon/internal/transaction"
)
// TestExecutorInstallsJarStartsExactUnitAndReachesSwitching 验证成功路径:安装 JAR、启动精确单元、
// 槽位软链接指向新版本、事务推进到 switching,且重复运行不会再次启动单元。
func TestExecutorInstallsJarStartsExactUnitAndReachesSwitching(t *testing.T) {
ctx := context.Background()
executor, store, releaseStore, units, request, previousTarget := testNativeExecutor(t)
@@ -65,6 +67,8 @@ func TestExecutorInstallsJarStartsExactUnitAndReachesSwitching(t *testing.T) {
}
}
// TestExecutorRollsBackSlotAndStopsUnitWhenHealthFails 验证健康检查失败时:事务回滚、槽位软链接恢复、
// 单元被停止且状态回到非活跃。
func TestExecutorRollsBackSlotAndStopsUnitWhenHealthFails(t *testing.T) {
ctx := context.Background()
executor, store, _, units, request, previousTarget := testNativeExecutor(t)
@@ -96,6 +100,7 @@ func TestExecutorRollsBackSlotAndStopsUnitWhenHealthFails(t *testing.T) {
}
}
// TestExecutorResumesPersistedRollback 验证从持久化的 rolling back 状态恢复补偿:恢复槽位并停止单元。
func TestExecutorResumesPersistedRollback(t *testing.T) {
ctx := context.Background()
executor, store, _, units, request, previousTarget := testNativeExecutor(t)
@@ -134,6 +139,7 @@ func TestExecutorResumesPersistedRollback(t *testing.T) {
}
}
// TestExecutorRollbackRemovesFirstDeploymentSlotLink 验证首次部署(无先前目标)失败时,回滚会移除槽位软链接。
func TestExecutorRollbackRemovesFirstDeploymentSlotLink(t *testing.T) {
ctx := context.Background()
executor, store, _, _, request, _ := testNativeExecutor(t)
@@ -159,6 +165,8 @@ func TestExecutorRollbackRemovesFirstDeploymentSlotLink(t *testing.T) {
}
}
// TestExecutorRecoversRecordedSlotIntentWithoutChangingRequest 验证崩溃恢复:已记录的槽位意图不依赖请求变更,
// 执行器能直接复用并完成后续步骤。
func TestExecutorRecoversRecordedSlotIntentWithoutChangingRequest(t *testing.T) {
ctx := context.Background()
executor, store, releaseStore, units, request, _ := testNativeExecutor(t)
@@ -197,6 +205,7 @@ func TestExecutorRecoversRecordedSlotIntentWithoutChangingRequest(t *testing.T)
}
}
// TestExecutorRejectsChangedRecoveryIntentAndPreservesStartingState 验证请求变更导致步骤冲突时被拒绝,且事务停留在 starting 状态。
func TestExecutorRejectsChangedRecoveryIntentAndPreservesStartingState(t *testing.T) {
ctx := context.Background()
executor, store, _, _, request, _ := testNativeExecutor(t)
@@ -221,6 +230,7 @@ func TestExecutorRejectsChangedRecoveryIntentAndPreservesStartingState(t *testin
}
}
// TestExecutorRejectsActiveUnitBeforeChangingFiles 验证单元已活跃时校验失败:事务进入 failed,且不改动发布存储与槽位软链接。
func TestExecutorRejectsActiveUnitBeforeChangingFiles(t *testing.T) {
ctx := context.Background()
executor, store, releaseStore, units, request, previousTarget := testNativeExecutor(t)
@@ -246,6 +256,7 @@ func TestExecutorRejectsActiveUnitBeforeChangingFiles(t *testing.T) {
}
}
// TestUnitStopOperationAcceptsSystemdFailedAsStopped 验证 unitStopOperation 把 systemd 的 failed 状态视为已停止。
func TestUnitStopOperationAcceptsSystemdFailedAsStopped(t *testing.T) {
units := &fakeUnitManager{unit: systemd.Unit{
Name: "yms-backend@8080.service",
@@ -263,6 +274,8 @@ func TestUnitStopOperationAcceptsSystemdFailedAsStopped(t *testing.T) {
}
}
// testNativeExecutor 构造一套完整且可复用的原生后端测试夹具。
// t 用于失败报告与清理注册。返回执行器、事务存储、发布存储、伪造的单元管理器、请求与先前槽位目标。
func testNativeExecutor(t *testing.T) (*Executor, *transaction.Store, *filestore.Store, *fakeUnitManager, Request, string) {
t.Helper()
store, err := transaction.OpenStore(context.Background(), filepath.Join(t.TempDir(), "transactions.db"))
@@ -320,6 +333,8 @@ func testNativeExecutor(t *testing.T) (*Executor, *transaction.Store, *filestore
return executor, store, releaseStore, units, request, previousTarget
}
// createNativeTransaction 在测试事务存储中创建一条原生后端事务记录。
// t 用于失败报告;store 是事务存储;suffix 用于构造唯一的事务 ID。返回创建的事务记录。
func createNativeTransaction(t *testing.T, store *transaction.Store, suffix string) transaction.Transaction {
t.Helper()
record, _, err := store.CreateTransaction(context.Background(), transaction.CreateRequest{
@@ -334,6 +349,8 @@ func createNativeTransaction(t *testing.T, store *transaction.Store, suffix stri
return record
}
// transitionNativeToPrepared 把事务依次推进到 validating 与 prepared 状态,供测试预置前置步骤。
// t 用于失败报告;store 是事务存储;transactionID 定位事务。
func transitionNativeToPrepared(t *testing.T, store *transaction.Store, transactionID string) {
t.Helper()
ctx := context.Background()
@@ -345,11 +362,14 @@ func transitionNativeToPrepared(t *testing.T, store *transaction.Store, transact
}
}
// testIdentity 根据内容计算文件身份(大小与 SHA-256),用于测试夹具与校验。
// content 文件内容。返回对应的 filestore.Identity。
func testIdentity(content []byte) filestore.Identity {
digest := sha256.Sum256(content)
return filestore.Identity{Size: int64(len(content)), SHA256: hex.EncodeToString(digest[:])}
}
// fakeUnitManager systemd.Manager 的测试替身,记录单元状态与启动/停止调用次数。
type fakeUnitManager struct {
mu sync.Mutex
unit systemd.Unit
@@ -360,6 +380,8 @@ type fakeUnitManager struct {
startedName string
}
// Inspect 返回单元状态:名称不匹配时返回 ErrUnitNotFound。
// 参数 ctx 与 name 用于取消与定位,name 决定返回哪个单元。返回单元状态与错误。
func (m *fakeUnitManager) Inspect(_ context.Context, name string) (systemd.Unit, error) {
m.mu.Lock()
defer m.mu.Unlock()
@@ -369,6 +391,8 @@ func (m *fakeUnitManager) Inspect(_ context.Context, name string) (systemd.Unit,
return m.unit, nil
}
// Start 模拟启动单元:记录调用与名称,成功置为活跃,失败置为 failed 并返回 startErr。
// 参数 ctx 与 name 用于取消与定位,name 决定记录的名称。返回值是启动错误(若配置了 startErr)。
func (m *fakeUnitManager) Start(_ context.Context, name string) error {
m.mu.Lock()
defer m.mu.Unlock()
@@ -384,6 +408,8 @@ func (m *fakeUnitManager) Start(_ context.Context, name string) error {
return nil
}
// Stop 模拟停止单元:记录调用,成功置为非活跃,失败返回 stopErr。
// 参数 ctx 与 name 用于取消与定位。返回值是停止错误(若配置了 stopErr)。
func (m *fakeUnitManager) Stop(context.Context, string) error {
m.mu.Lock()
defer m.mu.Unlock()
@@ -396,6 +422,7 @@ func (m *fakeUnitManager) Stop(context.Context, string) error {
return nil
}
// fakeActuatorChecker actuatorChecker 的测试替身,返回可配置的健康报告与错误。
type fakeActuatorChecker struct {
waitReport healthcheck.ActuatorReport
waitErr error
@@ -404,6 +431,8 @@ type fakeActuatorChecker struct {
checkErr error
}
// Wait 模拟等待健康检查:先执行运行探针,未运行返回 ErrWorkloadStopped,否则返回 waitReport 与 waitErr。
// ctx 用于取消;running 是运行探针。返回值是健康报告与错误。
func (c *fakeActuatorChecker) Wait(ctx context.Context, _ string, _ time.Duration, running healthcheck.RunningProbe) (healthcheck.ActuatorReport, error) {
isRunning, err := running(ctx)
if err != nil {
@@ -415,6 +444,8 @@ func (c *fakeActuatorChecker) Wait(ctx context.Context, _ string, _ time.Duratio
return c.waitReport, c.waitErr
}
// Check 模拟单次健康检查:先执行运行探针,未运行返回 ErrWorkloadStopped,否则返回 checkReport、checkReady 与 checkErr。
// ctx 用于取消;running 是运行探针。返回值是健康报告、就绪标志与错误。
func (c *fakeActuatorChecker) Check(ctx context.Context, _ string, running healthcheck.RunningProbe) (healthcheck.ActuatorReport, bool, error) {
isRunning, err := running(ctx)
if err != nil {
@@ -426,5 +457,6 @@ func (c *fakeActuatorChecker) Check(ctx context.Context, _ string, running healt
return c.checkReport, c.checkReady, c.checkErr
}
// 以下编译期断言确保测试替身实现了相应接口。
var _ systemd.Manager = (*fakeUnitManager)(nil)
var _ actuatorChecker = (*fakeActuatorChecker)(nil)