refactor(supply-api): reduce runtime aggregation density
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
# Supply API Runtime Layered Surfaces Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** 把 `Runtime` 自身继续降噪为“外部资源句柄 + 业务启动视图”两层结构,进一步压低 `Runtime` 顶层字段密度。
|
||||
|
||||
**Architecture:** 保留 `BuildRuntime`、`Runtime.BuildServer`、`Runtime.StartBackgroundWorkers` 等对外接口不变,但把 `Runtime` 顶层的 `db/redis/api/auth/tuning/serverConfig/env/logger` 等字段收进更有语义的聚合体。具体做法是新增 `runtimeExternalResources` 和 `runtimeStartupViews`,其中启动视图再分为 HTTP 与 background 两支;现有 `runtimeHTTPView`/`runtimeBackgroundView` builder 改为从分层后的 `Runtime` 聚合中派生。
|
||||
|
||||
**Tech Stack:** Go, Go test
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 为 Runtime 引入分层聚合
|
||||
|
||||
**Files:**
|
||||
- Modify: `supply-api/internal/app/runtime.go`
|
||||
- Modify: `supply-api/internal/app/runtime_test.go`
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
```go
|
||||
func TestBuildRuntime_GroupsResourcesAndStartupViews(t *testing.T) {
|
||||
runtime, err := buildRuntimeWithFactory(...)
|
||||
if err != nil {
|
||||
t.Fatalf("expected runtime build to succeed: %v", err)
|
||||
}
|
||||
if runtime.startupViews.http.env != "dev" {
|
||||
t.Fatal("expected http startup view env")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `cd "supply-api" && go test ./internal/app -run 'TestBuildRuntime_GroupsResourcesAndStartupViews' -v`
|
||||
Expected: FAIL,因为新聚合字段尚不存在
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
|
||||
```go
|
||||
type runtimeExternalResources struct { ... }
|
||||
type runtimeStartupViews struct { ... }
|
||||
type runtimeHTTPStartupView struct { ... }
|
||||
type runtimeBackgroundStartupView struct { ... }
|
||||
type Runtime struct { resources runtimeExternalResources; startupViews runtimeStartupViews }
|
||||
```
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `cd "supply-api" && go test ./internal/app -run 'TestBuildRuntime_GroupsResourcesAndStartupViews' -v`
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add supply-api/internal/app/runtime.go supply-api/internal/app/runtime_test.go
|
||||
git commit -m "refactor(supply-api): layer runtime resources and startup views"
|
||||
```
|
||||
|
||||
### Task 2: 改造现有 HTTP/background view builder 读取分层 Runtime
|
||||
|
||||
**Files:**
|
||||
- Modify: `supply-api/internal/app/runtime.go`
|
||||
- Modify: `supply-api/internal/app/background.go`
|
||||
- Modify: `supply-api/internal/app/runtime_test.go`
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
```go
|
||||
func TestBuildRuntimeHTTPView_MapsLayeredRuntimeFields(t *testing.T) {
|
||||
view, err := buildRuntimeHTTPView(runtime)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if view.supplyAPI == nil {
|
||||
t.Fatal("expected supply api")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `cd "supply-api" && go test ./internal/app -run 'Test(BuildRuntimeHTTPView_MapsHTTPFields|BuildRuntimeBackgroundView_MapsBackgroundFields|AdaptRuntimeToBuildServerOptions_MapsRuntimeFields)' -v`
|
||||
Expected: FAIL,旧 builder 仍读取旧顶层字段
|
||||
|
||||
**Step 3: Write minimal implementation**
|
||||
|
||||
```go
|
||||
func resolveRuntimeHealthChecks(runtime *Runtime) runtimeHealthChecks { ... } // 改为读取 runtime.resources
|
||||
func buildRuntimeHTTPView(runtime *Runtime) (runtimeHTTPView, error) { ... } // 改为读取 runtime.startupViews.http
|
||||
func buildRuntimeBackgroundView(runtime *Runtime) (runtimeBackgroundView, error) { ... } // 改为读取 runtime.startupViews.background + runtime.resources
|
||||
```
|
||||
|
||||
**Step 4: Run test to verify it passes**
|
||||
|
||||
Run: `cd "supply-api" && go test ./internal/app -run 'Test(BuildRuntimeHTTPView_MapsHTTPFields|BuildRuntimeBackgroundView_MapsBackgroundFields|AdaptRuntimeToBuildServerOptions_MapsRuntimeFields)' -v`
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add supply-api/internal/app/runtime.go supply-api/internal/app/background.go supply-api/internal/app/runtime_test.go
|
||||
git commit -m "refactor(supply-api): route runtime views through layered surfaces"
|
||||
```
|
||||
|
||||
### Task 3: 回归验证与收尾
|
||||
|
||||
**Files:**
|
||||
- Modify: `supply-api/internal/app/runtime.go`
|
||||
- Modify: `supply-api/internal/app/background.go`
|
||||
- Verify: `supply-api/internal/app/runtime_test.go`
|
||||
|
||||
**Step 1: Run focused tests**
|
||||
|
||||
Run: `cd "supply-api" && go test ./internal/app -run 'Test(BuildRuntime_GroupsResourcesAndStartupViews|BuildRuntimeHTTPView_.*|BuildRuntimeBackgroundView_.*|AdaptRuntime(ToBuildServerOptions|HTTPViewToBuildServerOptions)_.*|Runtime_StartBackgroundWorkers_.*|BuildRuntime_.*)' -v`
|
||||
Expected: PASS
|
||||
|
||||
**Step 2: Run package regression**
|
||||
|
||||
Run: `cd "supply-api" && go test ./internal/app ./cmd/supply-api ./internal/httpapi`
|
||||
Expected: PASS
|
||||
|
||||
**Step 3: Run e2e tests**
|
||||
|
||||
Run: `cd "supply-api" && go test -tags=e2e ./e2e`
|
||||
Expected: PASS
|
||||
|
||||
**Step 4: Run repo exit verification**
|
||||
|
||||
Run: `bash "scripts/ci/repo_integrity_check.sh"`
|
||||
Expected: PASS
|
||||
|
||||
**Step 5: Check formatting**
|
||||
|
||||
Run: `git diff --check`
|
||||
Expected: no output
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add docs/plans/2026-04-16-supply-api-runtime-layered-surfaces-plan.md supply-api/internal/app/runtime.go supply-api/internal/app/background.go supply-api/internal/app/runtime_test.go
|
||||
git commit -m "refactor(supply-api): reduce runtime aggregation density"
|
||||
```
|
||||
@@ -79,17 +79,17 @@ func buildRuntimeBackgroundView(runtime *Runtime) (runtimeBackgroundView, error)
|
||||
if runtime == nil {
|
||||
return runtimeBackgroundView{}, errors.New("runtime is required")
|
||||
}
|
||||
if runtime.logger == nil {
|
||||
if runtime.startupViews.background.logger == nil {
|
||||
return runtimeBackgroundView{}, errors.New("runtime logger is required")
|
||||
}
|
||||
|
||||
view := runtimeBackgroundView{
|
||||
env: runtime.env,
|
||||
logger: runtime.logger,
|
||||
tuning: runtime.tuning,
|
||||
db: runtime.db,
|
||||
redisCache: runtime.redisCache,
|
||||
revocationSubscriber: runtime.revocationSubscriber,
|
||||
env: runtime.startupViews.background.env,
|
||||
logger: runtime.startupViews.background.logger,
|
||||
tuning: runtime.startupViews.background.tuning,
|
||||
db: runtime.resources.db,
|
||||
redisCache: runtime.resources.redisCache,
|
||||
revocationSubscriber: runtime.startupViews.background.revocationSubscriber,
|
||||
}
|
||||
if view.tuning.outboxStreamName == "" {
|
||||
view.tuning = defaultRuntimeTuning()
|
||||
|
||||
@@ -41,24 +41,41 @@ type runtimeTuning struct {
|
||||
|
||||
// Runtime 聚合 HTTP 启动和后台任务启动所需的运行时依赖。
|
||||
type Runtime struct {
|
||||
env string
|
||||
logger logging.Logger
|
||||
now func() time.Time
|
||||
tuning runtimeTuning
|
||||
serverConfig config.ServerConfig
|
||||
db *repository.DB
|
||||
redisCache *cache.RedisCache
|
||||
supplyAPI *httpapi.SupplyAPI
|
||||
alertAPI *httpapi.AlertAPI
|
||||
authMiddleware *middleware.AuthMiddleware
|
||||
rateLimitConfig *middleware.RateLimitConfig
|
||||
revocationSubscriber revocationSubscriber
|
||||
resources runtimeExternalResources
|
||||
startupViews runtimeStartupViews
|
||||
}
|
||||
|
||||
type revocationSubscriber interface {
|
||||
StartRevocationSubscriber(ctx context.Context) error
|
||||
}
|
||||
|
||||
type runtimeExternalResources struct {
|
||||
db *repository.DB
|
||||
redisCache *cache.RedisCache
|
||||
}
|
||||
|
||||
type runtimeHTTPStartupView struct {
|
||||
env string
|
||||
logger logging.Logger
|
||||
serverConfig config.ServerConfig
|
||||
supplyAPI *httpapi.SupplyAPI
|
||||
alertAPI *httpapi.AlertAPI
|
||||
authMiddleware *middleware.AuthMiddleware
|
||||
rateLimitConfig *middleware.RateLimitConfig
|
||||
}
|
||||
|
||||
type runtimeBackgroundStartupView struct {
|
||||
env string
|
||||
logger logging.Logger
|
||||
tuning runtimeTuning
|
||||
revocationSubscriber revocationSubscriber
|
||||
}
|
||||
|
||||
type runtimeStartupViews struct {
|
||||
http runtimeHTTPStartupView
|
||||
background runtimeBackgroundStartupView
|
||||
}
|
||||
|
||||
type runtimeFactory struct {
|
||||
newDB func(ctx context.Context, cfg config.DatabaseConfig) (*repository.DB, error)
|
||||
newRedisCache func(cfg config.RedisConfig) (*cache.RedisCache, error)
|
||||
@@ -173,18 +190,27 @@ func buildRuntimeWithFactory(opts RuntimeOptions, factory runtimeFactory) (*Runt
|
||||
}
|
||||
|
||||
return &Runtime{
|
||||
env: env,
|
||||
logger: opts.Logger,
|
||||
now: now,
|
||||
tuning: tuning,
|
||||
serverConfig: normalizeServerConfig(opts.Config.Server),
|
||||
db: db,
|
||||
redisCache: redisCache,
|
||||
supplyAPI: apiBundle.supplyAPI,
|
||||
alertAPI: apiBundle.alertAPI,
|
||||
authMiddleware: securityBundle.authMiddleware,
|
||||
rateLimitConfig: apiBundle.rateLimitConfig,
|
||||
revocationSubscriber: securityBundle.revocationSubscriber,
|
||||
resources: runtimeExternalResources{
|
||||
db: db,
|
||||
redisCache: redisCache,
|
||||
},
|
||||
startupViews: runtimeStartupViews{
|
||||
http: runtimeHTTPStartupView{
|
||||
env: env,
|
||||
logger: opts.Logger,
|
||||
serverConfig: normalizeServerConfig(opts.Config.Server),
|
||||
supplyAPI: apiBundle.supplyAPI,
|
||||
alertAPI: apiBundle.alertAPI,
|
||||
authMiddleware: securityBundle.authMiddleware,
|
||||
rateLimitConfig: apiBundle.rateLimitConfig,
|
||||
},
|
||||
background: runtimeBackgroundStartupView{
|
||||
env: env,
|
||||
logger: opts.Logger,
|
||||
tuning: tuning,
|
||||
revocationSubscriber: securityBundle.revocationSubscriber,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -361,11 +387,11 @@ func resolveRuntimeHealthChecks(runtime *Runtime) runtimeHealthChecks {
|
||||
if runtime == nil {
|
||||
return checks
|
||||
}
|
||||
if runtime.db != nil {
|
||||
checks.DBHealthCheck = runtime.db.HealthCheck
|
||||
if runtime.resources.db != nil {
|
||||
checks.DBHealthCheck = runtime.resources.db.HealthCheck
|
||||
}
|
||||
if runtime.redisCache != nil {
|
||||
checks.RedisHealthCheck = runtime.redisCache.HealthCheck
|
||||
if runtime.resources.redisCache != nil {
|
||||
checks.RedisHealthCheck = runtime.resources.redisCache.HealthCheck
|
||||
}
|
||||
return checks
|
||||
}
|
||||
@@ -376,13 +402,13 @@ func buildRuntimeHTTPView(runtime *Runtime) (runtimeHTTPView, error) {
|
||||
}
|
||||
|
||||
return runtimeHTTPView{
|
||||
env: runtime.env,
|
||||
logger: runtime.logger,
|
||||
serverConfig: runtime.serverConfig,
|
||||
supplyAPI: runtime.supplyAPI,
|
||||
alertAPI: runtime.alertAPI,
|
||||
authMiddleware: runtime.authMiddleware,
|
||||
rateLimitConfig: runtime.rateLimitConfig,
|
||||
env: runtime.startupViews.http.env,
|
||||
logger: runtime.startupViews.http.logger,
|
||||
serverConfig: runtime.startupViews.http.serverConfig,
|
||||
supplyAPI: runtime.startupViews.http.supplyAPI,
|
||||
alertAPI: runtime.startupViews.http.alertAPI,
|
||||
authMiddleware: runtime.startupViews.http.authMiddleware,
|
||||
rateLimitConfig: runtime.startupViews.http.rateLimitConfig,
|
||||
healthChecks: resolveRuntimeHealthChecks(runtime),
|
||||
}, nil
|
||||
}
|
||||
@@ -414,11 +440,11 @@ func (r *Runtime) Close() {
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
if r.redisCache != nil {
|
||||
_ = r.redisCache.Close()
|
||||
if r.resources.redisCache != nil {
|
||||
_ = r.resources.redisCache.Close()
|
||||
}
|
||||
if r.db != nil {
|
||||
r.db.Close()
|
||||
if r.resources.db != nil {
|
||||
r.resources.db.Close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,7 +453,7 @@ func (r *Runtime) ShutdownTimeout() time.Duration {
|
||||
if r == nil {
|
||||
return 0
|
||||
}
|
||||
return r.serverConfig.ShutdownTimeout
|
||||
return r.startupViews.http.serverConfig.ShutdownTimeout
|
||||
}
|
||||
|
||||
func ResolveEnv(env string) (string, error) {
|
||||
|
||||
@@ -243,19 +243,19 @@ func TestBuildRuntime_DevFallsBackToInMemoryDependencies(t *testing.T) {
|
||||
if runtime == nil {
|
||||
t.Fatal("expected runtime")
|
||||
}
|
||||
if runtime.db != nil {
|
||||
if runtime.resources.db != nil {
|
||||
t.Fatal("expected nil db after dev fallback")
|
||||
}
|
||||
if runtime.redisCache != nil {
|
||||
if runtime.resources.redisCache != nil {
|
||||
t.Fatal("expected nil redis cache after dev fallback")
|
||||
}
|
||||
if runtime.supplyAPI == nil || runtime.alertAPI == nil {
|
||||
if runtime.startupViews.http.supplyAPI == nil || runtime.startupViews.http.alertAPI == nil {
|
||||
t.Fatal("expected apis to be initialized")
|
||||
}
|
||||
if runtime.authMiddleware == nil {
|
||||
if runtime.startupViews.http.authMiddleware == nil {
|
||||
t.Fatal("expected auth middleware to be initialized")
|
||||
}
|
||||
if runtime.rateLimitConfig == nil {
|
||||
if runtime.startupViews.http.rateLimitConfig == nil {
|
||||
t.Fatal("expected rate limit config to be initialized")
|
||||
}
|
||||
}
|
||||
@@ -283,8 +283,8 @@ func TestBuildRuntime_NormalizesServerConfigDefaults(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("expected runtime build to succeed, got %v", err)
|
||||
}
|
||||
if runtime.serverConfig.Addr != ":18082" {
|
||||
t.Fatalf("unexpected addr: %s", runtime.serverConfig.Addr)
|
||||
if runtime.startupViews.http.serverConfig.Addr != ":18082" {
|
||||
t.Fatalf("unexpected addr: %s", runtime.startupViews.http.serverConfig.Addr)
|
||||
}
|
||||
if runtime.ShutdownTimeout() != 5*time.Second {
|
||||
t.Fatalf("unexpected shutdown timeout: %s", runtime.ShutdownTimeout())
|
||||
@@ -311,20 +311,20 @@ func TestBuildRuntime_SeedsDefaultTuning(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("expected runtime build to succeed, got %v", err)
|
||||
}
|
||||
if runtime.tuning.outboxStreamName != "supply:outbox:stream" {
|
||||
t.Fatalf("unexpected outbox stream: %s", runtime.tuning.outboxStreamName)
|
||||
if runtime.startupViews.background.tuning.outboxStreamName != "supply:outbox:stream" {
|
||||
t.Fatalf("unexpected outbox stream: %s", runtime.startupViews.background.tuning.outboxStreamName)
|
||||
}
|
||||
if runtime.tuning.outboxConsumerGroup != "outbox-processor" {
|
||||
t.Fatalf("unexpected outbox group: %s", runtime.tuning.outboxConsumerGroup)
|
||||
if runtime.startupViews.background.tuning.outboxConsumerGroup != "outbox-processor" {
|
||||
t.Fatalf("unexpected outbox group: %s", runtime.startupViews.background.tuning.outboxConsumerGroup)
|
||||
}
|
||||
if runtime.tuning.idempotencyTTL != 24*time.Hour {
|
||||
t.Fatalf("unexpected idempotency ttl: %s", runtime.tuning.idempotencyTTL)
|
||||
if runtime.startupViews.background.tuning.idempotencyTTL != 24*time.Hour {
|
||||
t.Fatalf("unexpected idempotency ttl: %s", runtime.startupViews.background.tuning.idempotencyTTL)
|
||||
}
|
||||
if runtime.tuning.partitionMaintenanceInterval != time.Hour {
|
||||
t.Fatalf("unexpected partition maintenance interval: %s", runtime.tuning.partitionMaintenanceInterval)
|
||||
if runtime.startupViews.background.tuning.partitionMaintenanceInterval != time.Hour {
|
||||
t.Fatalf("unexpected partition maintenance interval: %s", runtime.startupViews.background.tuning.partitionMaintenanceInterval)
|
||||
}
|
||||
if runtime.tuning.compensationCheckInterval != 5*time.Minute {
|
||||
t.Fatalf("unexpected compensation interval: %s", runtime.tuning.compensationCheckInterval)
|
||||
if runtime.startupViews.background.tuning.compensationCheckInterval != 5*time.Minute {
|
||||
t.Fatalf("unexpected compensation interval: %s", runtime.startupViews.background.tuning.compensationCheckInterval)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,6 +355,49 @@ func TestBuildRuntime_DevFallbackLogsWarnings(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildRuntime_GroupsResourcesAndStartupViews(t *testing.T) {
|
||||
runtime, err := buildRuntimeWithFactory(RuntimeOptions{
|
||||
Env: "dev",
|
||||
Config: testRuntimeConfig(),
|
||||
Logger: testLogger{},
|
||||
InitContext: context.Background(),
|
||||
Now: func() time.Time {
|
||||
return time.Unix(1712800000, 0).UTC()
|
||||
},
|
||||
}, runtimeFactory{
|
||||
newDB: func(context.Context, config.DatabaseConfig) (*repository.DB, error) {
|
||||
return nil, errors.New("db down")
|
||||
},
|
||||
newRedisCache: func(config.RedisConfig) (*cache.RedisCache, error) {
|
||||
return nil, errors.New("redis down")
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("expected runtime build to succeed, got %v", err)
|
||||
}
|
||||
if runtime.startupViews.http.env != "dev" {
|
||||
t.Fatalf("unexpected http env: %s", runtime.startupViews.http.env)
|
||||
}
|
||||
if runtime.startupViews.background.env != "dev" {
|
||||
t.Fatalf("unexpected background env: %s", runtime.startupViews.background.env)
|
||||
}
|
||||
if runtime.resources.db != nil {
|
||||
t.Fatal("expected nil db resource after dev fallback")
|
||||
}
|
||||
if runtime.resources.redisCache != nil {
|
||||
t.Fatal("expected nil redis resource after dev fallback")
|
||||
}
|
||||
if runtime.startupViews.http.supplyAPI == nil || runtime.startupViews.http.alertAPI == nil {
|
||||
t.Fatal("expected http startup view apis to be initialized")
|
||||
}
|
||||
if runtime.startupViews.http.authMiddleware == nil {
|
||||
t.Fatal("expected http startup view auth middleware")
|
||||
}
|
||||
if runtime.startupViews.background.tuning.outboxStreamName != "supply:outbox:stream" {
|
||||
t.Fatalf("unexpected background outbox stream: %s", runtime.startupViews.background.tuning.outboxStreamName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveRuntimeHealthChecks_OmitsUnavailableDependencies(t *testing.T) {
|
||||
checks := resolveRuntimeHealthChecks(&Runtime{})
|
||||
if checks.DBHealthCheck != nil {
|
||||
@@ -367,8 +410,10 @@ func TestResolveRuntimeHealthChecks_OmitsUnavailableDependencies(t *testing.T) {
|
||||
|
||||
func TestResolveRuntimeHealthChecks_ExposesAvailableDependencies(t *testing.T) {
|
||||
checks := resolveRuntimeHealthChecks(&Runtime{
|
||||
db: &repository.DB{},
|
||||
redisCache: &cache.RedisCache{},
|
||||
resources: runtimeExternalResources{
|
||||
db: &repository.DB{},
|
||||
redisCache: &cache.RedisCache{},
|
||||
},
|
||||
})
|
||||
if checks.DBHealthCheck == nil {
|
||||
t.Fatal("expected db health check")
|
||||
@@ -394,15 +439,21 @@ func TestBuildRuntimeHTTPView_MapsHTTPFields(t *testing.T) {
|
||||
rateLimitConfig := &middleware.RateLimitConfig{Enabled: true}
|
||||
|
||||
view, err := buildRuntimeHTTPView(&Runtime{
|
||||
env: "staging",
|
||||
logger: testLogger{},
|
||||
serverConfig: config.ServerConfig{Addr: ":19090"},
|
||||
supplyAPI: supplyAPI,
|
||||
alertAPI: alertAPI,
|
||||
authMiddleware: authMiddleware,
|
||||
rateLimitConfig: rateLimitConfig,
|
||||
db: &repository.DB{},
|
||||
redisCache: &cache.RedisCache{},
|
||||
resources: runtimeExternalResources{
|
||||
db: &repository.DB{},
|
||||
redisCache: &cache.RedisCache{},
|
||||
},
|
||||
startupViews: runtimeStartupViews{
|
||||
http: runtimeHTTPStartupView{
|
||||
env: "staging",
|
||||
logger: testLogger{},
|
||||
serverConfig: config.ServerConfig{Addr: ":19090"},
|
||||
supplyAPI: supplyAPI,
|
||||
alertAPI: alertAPI,
|
||||
authMiddleware: authMiddleware,
|
||||
rateLimitConfig: rateLimitConfig,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("expected view build to succeed, got %v", err)
|
||||
@@ -449,15 +500,21 @@ func TestAdaptRuntimeToBuildServerOptions_MapsRuntimeFields(t *testing.T) {
|
||||
rateLimitConfig := &middleware.RateLimitConfig{Enabled: true}
|
||||
|
||||
opts, err := adaptRuntimeToBuildServerOptions(&Runtime{
|
||||
env: "staging",
|
||||
logger: testLogger{},
|
||||
serverConfig: config.ServerConfig{Addr: ":19090"},
|
||||
supplyAPI: supplyAPI,
|
||||
alertAPI: alertAPI,
|
||||
authMiddleware: authMiddleware,
|
||||
rateLimitConfig: rateLimitConfig,
|
||||
db: &repository.DB{},
|
||||
redisCache: &cache.RedisCache{},
|
||||
resources: runtimeExternalResources{
|
||||
db: &repository.DB{},
|
||||
redisCache: &cache.RedisCache{},
|
||||
},
|
||||
startupViews: runtimeStartupViews{
|
||||
http: runtimeHTTPStartupView{
|
||||
env: "staging",
|
||||
logger: testLogger{},
|
||||
serverConfig: config.ServerConfig{Addr: ":19090"},
|
||||
supplyAPI: supplyAPI,
|
||||
alertAPI: alertAPI,
|
||||
authMiddleware: authMiddleware,
|
||||
rateLimitConfig: rateLimitConfig,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("expected adapter to succeed, got %v", err)
|
||||
@@ -544,12 +601,18 @@ func TestBuildRuntimeBackgroundView_MapsBackgroundFields(t *testing.T) {
|
||||
subscriber := stubRevocationSubscriber{}
|
||||
|
||||
view, err := buildRuntimeBackgroundView(&Runtime{
|
||||
env: "prod",
|
||||
logger: testLogger{},
|
||||
tuning: defaultRuntimeTuning(),
|
||||
db: &repository.DB{},
|
||||
redisCache: &cache.RedisCache{},
|
||||
revocationSubscriber: subscriber,
|
||||
resources: runtimeExternalResources{
|
||||
db: &repository.DB{},
|
||||
redisCache: &cache.RedisCache{},
|
||||
},
|
||||
startupViews: runtimeStartupViews{
|
||||
background: runtimeBackgroundStartupView{
|
||||
env: "prod",
|
||||
logger: testLogger{},
|
||||
tuning: defaultRuntimeTuning(),
|
||||
revocationSubscriber: subscriber,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("expected background view build to succeed, got %v", err)
|
||||
@@ -578,8 +641,12 @@ func TestRuntime_StartBackgroundWorkers_WithoutDatabaseIsNoop(t *testing.T) {
|
||||
var outboxRepoCalled bool
|
||||
|
||||
err := startBackgroundWorkersWithFactory(context.Background(), context.Background(), &Runtime{
|
||||
env: "dev",
|
||||
logger: testLogger{},
|
||||
startupViews: runtimeStartupViews{
|
||||
background: runtimeBackgroundStartupView{
|
||||
env: "dev",
|
||||
logger: testLogger{},
|
||||
},
|
||||
},
|
||||
}, backgroundFactory{
|
||||
newOutboxRepository: func(*repository.DB) outboxRepository {
|
||||
outboxRepoCalled = true
|
||||
@@ -596,9 +663,15 @@ func TestRuntime_StartBackgroundWorkers_WithoutDatabaseIsNoop(t *testing.T) {
|
||||
|
||||
func TestRuntime_StartBackgroundWorkers_ProdRequiresOutboxBroker(t *testing.T) {
|
||||
err := startBackgroundWorkersWithFactory(context.Background(), context.Background(), &Runtime{
|
||||
env: "prod",
|
||||
logger: testLogger{},
|
||||
db: &repository.DB{},
|
||||
resources: runtimeExternalResources{
|
||||
db: &repository.DB{},
|
||||
},
|
||||
startupViews: runtimeStartupViews{
|
||||
background: runtimeBackgroundStartupView{
|
||||
env: "prod",
|
||||
logger: testLogger{},
|
||||
},
|
||||
},
|
||||
}, backgroundFactory{
|
||||
newOutboxRepository: func(*repository.DB) outboxRepository {
|
||||
return stubOutboxRepository{}
|
||||
@@ -641,10 +714,16 @@ func TestRuntime_StartBackgroundWorkers_UsesDefaultCompensationInterval(t *testi
|
||||
var gotInterval time.Duration
|
||||
|
||||
err := startBackgroundWorkersWithFactory(context.Background(), context.Background(), &Runtime{
|
||||
env: "dev",
|
||||
logger: testLogger{},
|
||||
db: &repository.DB{},
|
||||
tuning: defaultRuntimeTuning(),
|
||||
resources: runtimeExternalResources{
|
||||
db: &repository.DB{},
|
||||
},
|
||||
startupViews: runtimeStartupViews{
|
||||
background: runtimeBackgroundStartupView{
|
||||
env: "dev",
|
||||
logger: testLogger{},
|
||||
tuning: defaultRuntimeTuning(),
|
||||
},
|
||||
},
|
||||
}, backgroundFactory{
|
||||
newOutboxRepository: func(*repository.DB) outboxRepository {
|
||||
return stubOutboxRepository{}
|
||||
@@ -720,10 +799,16 @@ func TestRuntime_StartBackgroundWorkers_DevMissingOutboxBrokerLogsWarning(t *tes
|
||||
logger := &captureLogger{}
|
||||
|
||||
err := startBackgroundWorkersWithFactory(context.Background(), context.Background(), &Runtime{
|
||||
env: "dev",
|
||||
logger: logger,
|
||||
db: &repository.DB{},
|
||||
tuning: defaultRuntimeTuning(),
|
||||
resources: runtimeExternalResources{
|
||||
db: &repository.DB{},
|
||||
},
|
||||
startupViews: runtimeStartupViews{
|
||||
background: runtimeBackgroundStartupView{
|
||||
env: "dev",
|
||||
logger: logger,
|
||||
tuning: defaultRuntimeTuning(),
|
||||
},
|
||||
},
|
||||
}, backgroundFactory{
|
||||
newOutboxRepository: func(*repository.DB) outboxRepository {
|
||||
return stubOutboxRepository{}
|
||||
|
||||
Reference in New Issue
Block a user