refactor: use nginx -s reload instead of systemd
- doc: add comment
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user