refactor: use nginx -s reload instead of systemd
- doc: add comment
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
//go:build linux
|
||||
|
||||
// Package integration_test 包含 yms-daemon 的集成测试,在真实文件系统与进程环境下
|
||||
// 验证原生后端执行器与事务底座的协同行为。相关测试仅在 Linux 平台编译运行。
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
@@ -22,6 +24,9 @@ import (
|
||||
"yms-daemon/internal/transaction"
|
||||
)
|
||||
|
||||
// TestNativeBackendExecutorIntegration 在临时目录中搭建完整的原生后端发布流程,
|
||||
// 验证执行器能把传入的 JAR 制品安装到发布存储、更新槽位软链接并触发 systemd 单元启动,
|
||||
// 且事务状态与事件能正确持久化到数据库。
|
||||
func TestNativeBackendExecutorIntegration(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
root := t.TempDir()
|
||||
@@ -141,19 +146,28 @@ func TestNativeBackendExecutorIntegration(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// integrationIdentity 根据内容计算文件的 SHA256 摘要与大小,返回用于发布存储校验的文件身份。
|
||||
func integrationIdentity(content []byte) filestore.Identity {
|
||||
digest := sha256.Sum256(content)
|
||||
return filestore.Identity{Size: int64(len(content)), SHA256: hex.EncodeToString(digest[:])}
|
||||
}
|
||||
|
||||
// integrationUnitManager systemd.Manager 接口的内存实现,用于在集成测试中模拟 systemd 单元,
|
||||
// 记录启动与停止调用并跟踪单元状态变化。
|
||||
type integrationUnitManager struct {
|
||||
mu sync.Mutex
|
||||
unit systemd.Unit
|
||||
startCalls int
|
||||
stopCalls int
|
||||
// mu 保护以下所有字段的并发访问。
|
||||
mu sync.Mutex
|
||||
// unit 当前模拟的 systemd 单元状态。
|
||||
unit systemd.Unit
|
||||
// startCalls 统计 Start 被调用的次数。
|
||||
startCalls int
|
||||
// stopCalls 统计 Stop 被调用的次数。
|
||||
stopCalls int
|
||||
// startedName 记录最近一次 Start 的单元名。
|
||||
startedName string
|
||||
}
|
||||
|
||||
// Inspect 返回指定名称的模拟单元状态;名称不匹配时返回 ErrUnitNotFound。
|
||||
func (m *integrationUnitManager) Inspect(_ context.Context, name string) (systemd.Unit, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
@@ -163,6 +177,8 @@ func (m *integrationUnitManager) Inspect(_ context.Context, name string) (system
|
||||
return m.unit, nil
|
||||
}
|
||||
|
||||
// Start 模拟启动指定单元:累计调用次数、记录单元名并把状态更新为 active/running;
|
||||
// 名称不匹配时返回 ErrUnitNotFound。
|
||||
func (m *integrationUnitManager) Start(_ context.Context, name string) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
@@ -176,6 +192,8 @@ func (m *integrationUnitManager) Start(_ context.Context, name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop 模拟停止指定单元:累计调用次数并把状态更新为 inactive/dead;
|
||||
// 名称不匹配时返回 ErrUnitNotFound。
|
||||
func (m *integrationUnitManager) Stop(_ context.Context, name string) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
@@ -188,8 +206,10 @@ func (m *integrationUnitManager) Stop(_ context.Context, name string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// integrationRoundTripFunc 一个可替换的 HTTP 传输实现,用于拦截健康检查请求并返回固定响应。
|
||||
type integrationRoundTripFunc func(*http.Request) (*http.Response, error)
|
||||
|
||||
// RoundTrip 校验请求地址是否为预期的健康检查端点,然后委托给底层函数生成响应。
|
||||
func (f integrationRoundTripFunc) RoundTrip(request *http.Request) (*http.Response, error) {
|
||||
if request.URL.String() != "http://127.0.0.1:8081/yms/actuator/health" {
|
||||
return nil, errors.New("unexpected native backend health endpoint: " + request.URL.String())
|
||||
@@ -197,4 +217,5 @@ func (f integrationRoundTripFunc) RoundTrip(request *http.Request) (*http.Respon
|
||||
return f(request)
|
||||
}
|
||||
|
||||
// 编译期断言 integrationUnitManager 实现了 systemd.Manager 接口。
|
||||
var _ systemd.Manager = (*integrationUnitManager)(nil)
|
||||
|
||||
@@ -14,11 +14,16 @@ import (
|
||||
"yms-daemon/internal/transaction"
|
||||
)
|
||||
|
||||
// 锁辅助进程通过环境变量传递模式与锁路径,用于在独立进程中验证 flock 的互斥语义。
|
||||
const (
|
||||
// lockHelperModeEnvironment 传递锁辅助进程运行模式的环境变量名。
|
||||
lockHelperModeEnvironment = "YMS_DAEMON_INTEGRATION_LOCK_HELPER_MODE"
|
||||
// lockHelperPathEnvironment 传递锁文件路径的环境变量名。
|
||||
lockHelperPathEnvironment = "YMS_DAEMON_INTEGRATION_LOCK_HELPER_PATH"
|
||||
lockHelperExpectBlocked = "EXPECT_BLOCKED"
|
||||
lockHelperExpectAcquired = "EXPECT_ACQUIRED"
|
||||
// lockHelperExpectBlocked 表示期望锁辅助进程因锁被占用而加锁失败。
|
||||
lockHelperExpectBlocked = "EXPECT_BLOCKED"
|
||||
// lockHelperExpectAcquired 表示期望锁辅助进程在锁释放后成功加锁。
|
||||
lockHelperExpectAcquired = "EXPECT_ACQUIRED"
|
||||
)
|
||||
|
||||
// TestTransactionKernelIntegration 使用真实子进程、flock 和 SQLite 文件验证事务底座。
|
||||
@@ -142,6 +147,8 @@ func TestTransactionKernelLockHelper(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// runLockHelper 启动一个独立的锁辅助测试进程,通过环境变量传入模式与锁路径,
|
||||
// 并校验该进程按预期成功退出。
|
||||
func runLockHelper(t *testing.T, mode, lockPath string) {
|
||||
t.Helper()
|
||||
command := exec.Command(os.Args[0], "-test.run=^TestTransactionKernelLockHelper$", "-test.v")
|
||||
@@ -156,6 +163,8 @@ func runLockHelper(t *testing.T, mode, lockPath string) {
|
||||
t.Logf("lock helper mode %s passed", mode)
|
||||
}
|
||||
|
||||
// assertStateEvents 校验事务事件流与给定的状态迁移序列一致:事件数量应为迁移数加一,
|
||||
// 首条为事务创建事件,其后每条状态变更事件的前后状态与序列号递增关系均需匹配,最终状态为 Committed。
|
||||
func assertStateEvents(t *testing.T, events []transaction.Event, transitions []transaction.State) {
|
||||
t.Helper()
|
||||
if len(events) != len(transitions)+1 {
|
||||
|
||||
Reference in New Issue
Block a user