Compare commits
2 Commits
b33fa10677
...
51472e9951
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51472e9951 | ||
|
|
6bbd55111c |
@@ -2134,3 +2134,64 @@
|
||||
- `internal/routing`
|
||||
- `internal/store/sqlite`
|
||||
- `internal/overlay`
|
||||
|
||||
## 2026-05-30 已补齐 routing / sqlite / overlay 的低覆盖热点分支
|
||||
|
||||
**目标**:在全部 `watch -> core` 升级完成后,不再继续调阈值,而是直接补已记录的低覆盖热点分支,降低“虽然过线但边角不稳”的风险
|
||||
|
||||
**本次补测点**:
|
||||
|
||||
- `internal/routing`
|
||||
- `RedisStickyStore.ClearRouteFailure`
|
||||
- `RedisStickyStore.ClearCooldown`
|
||||
- `AsyncLogWriter.Flush` 的 close 后路径
|
||||
- `internal/store/sqlite`
|
||||
- `SyncProviderAccountsFromLatestImportBatches`
|
||||
- 多 provider latest reconcilable batch 同步路径
|
||||
- `internal/overlay`
|
||||
- `applyPatchFile` invalid patch 错误路径
|
||||
- `Apply` existing output dir 错误路径
|
||||
- `copyFile` missing source 错误路径
|
||||
|
||||
**验证结果**:
|
||||
|
||||
- 定向测试:
|
||||
- `go test ./internal/routing ./internal/store/sqlite ./internal/overlay -count=1` => `ok`
|
||||
- 定向覆盖率:
|
||||
- `go test -coverprofile=/tmp/routing-hotspots.cover ./internal/routing` => `75.5%`
|
||||
- `go test -coverprofile=/tmp/sqlite-hotspots.cover ./internal/store/sqlite` => `76.4%`
|
||||
- `go test -coverprofile=/tmp/overlay-hotspots.cover ./internal/overlay` => `75.4%`
|
||||
- 热点函数回读:
|
||||
- `internal/routing`
|
||||
- `Flush = 71.4%`
|
||||
- `ClearRouteFailure = 75.0%`
|
||||
- `ClearCooldown = 75.0%`
|
||||
- `internal/overlay`
|
||||
- `Apply = 70.6%`
|
||||
- `applyPatchFile = 90.0%`
|
||||
- `copyFile = 76.9%`
|
||||
- `internal/store/sqlite`
|
||||
- `SyncProviderAccountsFromLatestImportBatches = 66.7%`
|
||||
- 全量门禁:
|
||||
- `gofmt -l .` => clean
|
||||
- `go vet ./...` => `ok`
|
||||
- `go test -cover ./internal/...` => `ok`
|
||||
- `go test ./tests/integration/... -count=1` => `ok`
|
||||
- `bash ./scripts/test/verify_quality_gates.sh` => `PASS`
|
||||
|
||||
**覆盖率变化**:
|
||||
|
||||
- `internal/routing`
|
||||
- 本轮前:`73.1%`
|
||||
- 本轮后:`75.5%`
|
||||
- `internal/store/sqlite`
|
||||
- 本轮前:`76.1%`
|
||||
- 本轮后:`76.4%`
|
||||
- `internal/overlay`
|
||||
- 本轮前:`71.6%`
|
||||
- 本轮后:`75.4%`
|
||||
|
||||
**结论**:
|
||||
|
||||
- 这轮已经把此前执行板里明确记录的三组低覆盖热点分支补掉了一批
|
||||
- 当前质量治理不再只是“包级过线”,而是开始向关键边界分支收口
|
||||
|
||||
@@ -151,6 +151,19 @@ func TestApplyPatchFileRejectsMissingPatch(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyPatchFileRejectsInvalidPatch(t *testing.T) {
|
||||
outputDir := t.TempDir()
|
||||
patchPath := filepath.Join(t.TempDir(), "invalid.patch")
|
||||
if err := os.WriteFile(patchPath, []byte("not a patch\n"), 0o644); err != nil {
|
||||
t.Fatalf("WriteFile() error = %v", err)
|
||||
}
|
||||
|
||||
err := applyPatchFile(context.Background(), outputDir, patchPath)
|
||||
if err == nil {
|
||||
t.Fatal("applyPatchFile() error = nil, want invalid patch failure")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteMetadataIncludesSourceDirAndOverlays(t *testing.T) {
|
||||
metadataPath := filepath.Join(t.TempDir(), metadataFileName)
|
||||
overlays := []pack.HostOverlay{{OverlayID: "sample", PatchPath: "overlays/sample.patch"}}
|
||||
@@ -208,3 +221,31 @@ func TestCopyTreeSkipsGitAndPreservesSymlink(t *testing.T) {
|
||||
t.Fatalf("symlink target = %q, want backend/hello.txt", target)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyRejectsExistingOutputDir(t *testing.T) {
|
||||
sourceDir := t.TempDir()
|
||||
if err := os.MkdirAll(filepath.Join(sourceDir, "backend"), 0o755); err != nil {
|
||||
t.Fatalf("MkdirAll() error = %v", err)
|
||||
}
|
||||
outputDir := filepath.Join(t.TempDir(), "existing-output")
|
||||
if err := os.MkdirAll(outputDir, 0o755); err != nil {
|
||||
t.Fatalf("MkdirAll(outputDir) error = %v", err)
|
||||
}
|
||||
|
||||
_, err := Apply(context.Background(), ApplyRequest{
|
||||
PackDir: t.TempDir(),
|
||||
SourceDir: sourceDir,
|
||||
OutputDir: outputDir,
|
||||
Overlays: []pack.HostOverlay{{OverlayID: "sample", PatchPath: "overlays/sample.patch"}},
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "already exists") {
|
||||
t.Fatalf("Apply() error = %v, want existing output rejection", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCopyFileRejectsMissingSource(t *testing.T) {
|
||||
err := copyFile(filepath.Join(t.TempDir(), "missing.txt"), filepath.Join(t.TempDir(), "target.txt"), 0o644)
|
||||
if err == nil {
|
||||
t.Fatal("copyFile() error = nil, want missing source failure")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +162,22 @@ func TestAsyncLogWriterFlushesQueuedEvents(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAsyncLogWriterFlushAfterCloseReturnsNil(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
writer := NewAsyncLogWriter(&recordingRouteLogSink{}, AsyncLogWriterOptions{
|
||||
QueueSize: 1,
|
||||
FlushInterval: time.Hour,
|
||||
MaxBatchSize: 1,
|
||||
})
|
||||
if err := writer.Close(); err != nil {
|
||||
t.Fatalf("Close() error = %v", err)
|
||||
}
|
||||
if err := writer.Flush(context.Background()); err != nil {
|
||||
t.Fatalf("Flush() after close error = %v, want nil", err)
|
||||
}
|
||||
}
|
||||
|
||||
type failingRouteLogSink struct {
|
||||
appendCalls int
|
||||
}
|
||||
|
||||
@@ -181,6 +181,18 @@ func TestRedisStickyStoreRoundTripWithFakeServer(t *testing.T) {
|
||||
if state, ok, err := store.GetCooldown(ctx, "asxs"); err != nil || !ok || state.Reason != "degraded" {
|
||||
t.Fatalf("GetCooldown() = (%+v, %v, %v), want reason degraded", state, ok, err)
|
||||
}
|
||||
if err := store.ClearRouteFailure(ctx, "asxs"); err != nil {
|
||||
t.Fatalf("ClearRouteFailure() error = %v", err)
|
||||
}
|
||||
if _, ok, err := store.GetRouteFailure(ctx, "asxs"); err != nil || ok {
|
||||
t.Fatalf("GetRouteFailure() after clear = (ok=%v, err=%v), want false nil", ok, err)
|
||||
}
|
||||
if err := store.ClearCooldown(ctx, "asxs"); err != nil {
|
||||
t.Fatalf("ClearCooldown() error = %v", err)
|
||||
}
|
||||
if _, ok, err := store.GetCooldown(ctx, "asxs"); err != nil || ok {
|
||||
t.Fatalf("GetCooldown() after clear = (ok=%v, err=%v), want false nil", ok, err)
|
||||
}
|
||||
if err := store.Delete(ctx, key); err != nil {
|
||||
t.Fatalf("Delete() error = %v", err)
|
||||
}
|
||||
|
||||
@@ -561,3 +561,86 @@ func TestSyncProviderAccountsFromImportBatchPromotesSingleReadyGatewayAccount(t
|
||||
t.Fatalf("LastProbeStatus = %q, want gateway_ready", account.LastProbeStatus)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncProviderAccountsFromLatestImportBatchesSyncsEachLatestReconcilableBatch(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
store := openTestDBWithFK(t)
|
||||
ctx := context.Background()
|
||||
hostID := createTestHost(t, store)
|
||||
packID := createTestPack(t, store)
|
||||
providerAID, err := store.Providers().Create(ctx, Provider{
|
||||
PackID: packID,
|
||||
ProviderID: "provider-a",
|
||||
DisplayName: "Provider A",
|
||||
BaseURL: "https://api.provider-a.example/v1",
|
||||
Platform: "openai",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Providers().Create(provider-a) error = %v", err)
|
||||
}
|
||||
providerBID, err := store.Providers().Create(ctx, Provider{
|
||||
PackID: packID,
|
||||
ProviderID: "provider-b",
|
||||
DisplayName: "Provider B",
|
||||
BaseURL: "https://api.provider-b.example/v1",
|
||||
Platform: "openai",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Providers().Create(provider-b) error = %v", err)
|
||||
}
|
||||
|
||||
createBatchWithAccount := func(providerID int64, accountID, keyFingerprint string) {
|
||||
t.Helper()
|
||||
batchID, err := store.ImportBatches().Create(ctx, ImportBatch{
|
||||
HostID: hostID,
|
||||
PackID: packID,
|
||||
ProviderID: providerID,
|
||||
Mode: "strict",
|
||||
BatchStatus: "succeeded",
|
||||
AccessStatus: "subscription_ready",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("ImportBatches().Create(%s) error = %v", accountID, err)
|
||||
}
|
||||
if _, err := store.ImportBatchItems().Create(ctx, ImportBatchItem{
|
||||
BatchID: batchID,
|
||||
KeyFingerprint: keyFingerprint,
|
||||
AccountStatus: "passed",
|
||||
ProbeSummaryJSON: `{"account_id":"` + accountID + `","probe_status":"passed"}`,
|
||||
}); err != nil {
|
||||
t.Fatalf("ImportBatchItems().Create(%s) error = %v", accountID, err)
|
||||
}
|
||||
for _, resource := range []ManagedResource{
|
||||
{BatchID: batchID, HostID: hostID, ResourceType: "group", HostResourceID: "group-" + accountID, ResourceName: "Group " + accountID},
|
||||
{BatchID: batchID, HostID: hostID, ResourceType: "account", HostResourceID: accountID, ResourceName: "Account " + accountID},
|
||||
} {
|
||||
if _, err := store.ManagedResources().Create(ctx, resource); err != nil {
|
||||
t.Fatalf("ManagedResources().Create(%s/%s) error = %v", accountID, resource.ResourceType, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createBatchWithAccount(providerAID, "account-a1", "sha256:a1")
|
||||
createBatchWithAccount(providerBID, "account-b1", "sha256:b1")
|
||||
|
||||
if err := SyncProviderAccountsFromLatestImportBatches(ctx, store); err != nil {
|
||||
t.Fatalf("SyncProviderAccountsFromLatestImportBatches() error = %v", err)
|
||||
}
|
||||
|
||||
accountA, err := store.ProviderAccounts().GetByHostIDAndAccountID(ctx, hostID, "account-a1")
|
||||
if err != nil {
|
||||
t.Fatalf("ProviderAccounts().GetByHostIDAndAccountID(account-a1) error = %v", err)
|
||||
}
|
||||
if accountA.AccountStatus != ProviderAccountStatusActive || accountA.KeyFingerprint != "sha256:a1" {
|
||||
t.Fatalf("account-a1 = %+v, want active sha256:a1", accountA)
|
||||
}
|
||||
|
||||
accountB, err := store.ProviderAccounts().GetByHostIDAndAccountID(ctx, hostID, "account-b1")
|
||||
if err != nil {
|
||||
t.Fatalf("ProviderAccounts().GetByHostIDAndAccountID(account-b1) error = %v", err)
|
||||
}
|
||||
if accountB.AccountStatus != ProviderAccountStatusActive || accountB.KeyFingerprint != "sha256:b1" {
|
||||
t.Fatalf("account-b1 = %+v, want active sha256:b1", accountB)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user