Compare commits

...

2 Commits

Author SHA1 Message Date
phamnazage-jpg
d9216d5712 docs(testing): record narrow branch coverage follow-up 2026-05-30 18:28:03 +08:00
phamnazage-jpg
f895eb9035 test(quality): cover sqlite redis and overlay edge branches 2026-05-30 18:28:03 +08:00
7 changed files with 439 additions and 0 deletions

View File

@@ -2195,3 +2195,85 @@
- 这轮已经把此前执行板里明确记录的三组低覆盖热点分支补掉了一批
- 当前质量治理不再只是“包级过线”,而是开始向关键边界分支收口
## 2026-05-30 已继续补齐 sqlite Upsert / redis RESP / overlay IO 的窄分支
**目标**:在上一轮热点补测之后,继续收口仍然低覆盖的窄分支,优先覆盖 `repo Upsert` 的默认值/trim 路径、`sticky_redis` 的异常 RESP 路径,以及 `overlay` 更细的文件系统异常
**本次新增测试点**
- `internal/store/sqlite`
- `ProvidersRepo.Upsert`
- trim 输入
- `ManifestJSON / DefaultModelsJSON / GroupTemplateJSON / ChannelTemplateJSON / PlanTemplateJSON / ImportOptionsJSON` 默认值
- `PacksRepo.Upsert`
- trim 输入
- `ManifestJSON` 默认值
- `ImportRunItemsRepo.Upsert`
- `defaultJSON` 路径
- nullable / trim 字段回读
- `normalizeProviderAccountBindingState`
- `assigned / unassigned / conflict / invalid` 归一化
- `internal/routing`
- `RedisStickyStore.open`
- `AUTH` 错误返回
- `SELECT` unexpected response
- `RedisStickyStore.getJSON`
- `GET` unexpected response
- `RedisStickyStore.setJSON`
- `SET` unexpected response
- `internal/overlay`
- `Apply`
- `source dir` 实际是文件时拒绝
- `copyFile`
- target parent 路径被普通文件阻塞时失败
**验证结果**
- 定向测试:
- `go test ./internal/routing ./internal/store/sqlite ./internal/overlay -count=1` => `ok`
- 定向覆盖率:
- `go test -coverprofile=/tmp/routing-redis-hotspots.cover ./internal/routing` => `77.1%`
- `go test -coverprofile=/tmp/sqlite-upsert-hotspots.cover ./internal/store/sqlite` => `76.5%`
- `go test -coverprofile=/tmp/overlay-io-hotspots.cover ./internal/overlay` => `76.9%`
- 热点函数回读:
- `internal/routing`
- `open = 69.0%`
- `getJSON = 76.9%`
- `setJSON = 70.0%`
- `internal/store/sqlite`
- `normalizeProviderAccountBindingState = 100.0%`
- `ProvidersRepo.Upsert = 52.0%`
- `PacksRepo.Upsert = 54.5%`
- `ImportRunItemsRepo.Upsert = 54.2%`
- `internal/overlay`
- `Apply = 72.5%`
- `copyFile = 84.6%`
- 全量门禁:
- `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`
- 当前沙箱下 `httptest` 监听端口会被限制,统一门禁脚本已在 unrestricted 环境重跑确认真实结果
**覆盖率变化**
- `internal/routing`
- 本轮前:`75.5%`
- 本轮后:`77.1%`
- `internal/store/sqlite`
- 本轮前:`76.4%`
- 本轮后:`76.5%`
- `internal/overlay`
- 本轮前:`75.4%`
- 本轮后:`76.9%`
**结论**
- `routing` 的 Redis 异常响应路径已经明显收口,包级覆盖率继续抬升
- `overlay` 的 IO 异常分支继续前进,`copyFile``Apply` 的风险点比上一轮更稳
- `sqlite` 的包级提升有限,但 `Upsert` 默认值/trim 和 `binding_state` 规范化已被显式锁定
- 剩余最值得继续补的点,已经缩成:
- `ProvidersRepo.Upsert / PacksRepo.Upsert / ImportRunItemsRepo.Upsert` 更细的分支回读
- `RedisStickyStore.open` 的剩余异常路径

View File

@@ -243,9 +243,41 @@ func TestApplyRejectsExistingOutputDir(t *testing.T) {
}
}
func TestApplyRejectsSourceFile(t *testing.T) {
sourceDir := filepath.Join(t.TempDir(), "source.txt")
if err := os.WriteFile(sourceDir, []byte("not a dir"), 0o644); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}
_, err := Apply(context.Background(), ApplyRequest{
PackDir: t.TempDir(),
SourceDir: sourceDir,
Overlays: []pack.HostOverlay{{OverlayID: "sample", PatchPath: "overlays/sample.patch"}},
})
if err == nil || !strings.Contains(err.Error(), "must be a directory") {
t.Fatalf("Apply() error = %v, want source dir 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")
}
}
func TestCopyFileRejectsTargetParentThatIsAFile(t *testing.T) {
parentFile := filepath.Join(t.TempDir(), "parent-file")
if err := os.WriteFile(parentFile, []byte("block mkdir"), 0o644); err != nil {
t.Fatalf("WriteFile(parentFile) error = %v", err)
}
sourcePath := filepath.Join(t.TempDir(), "source.txt")
if err := os.WriteFile(sourcePath, []byte("hello"), 0o644); err != nil {
t.Fatalf("WriteFile(sourcePath) error = %v", err)
}
err := copyFile(sourcePath, filepath.Join(parentFile, "nested", "target.txt"), 0o644)
if err == nil {
t.Fatal("copyFile() error = nil, want parent path mkdir failure")
}
}

View File

@@ -436,6 +436,91 @@ func TestRedisStickyStoreRequiresAddr(t *testing.T) {
}
}
func TestRedisStickyStoreOpenRejectsAuthError(t *testing.T) {
t.Parallel()
server := newScriptedRedisServer(t, func(conn net.Conn, reader *bufio.Reader) {
command, err := readRESPArray(reader)
if err != nil {
return
}
if len(command) > 0 && strings.ToUpper(command[0]) == "AUTH" {
_, _ = io.WriteString(conn, "-ERR invalid password\r\n")
}
})
defer server.Close()
store := &RedisStickyStore{cfg: RedisConfig{Addr: server.Addr(), Password: "secret"}}
_, _, err := store.open(context.Background())
if err == nil || !strings.Contains(err.Error(), "redis AUTH read") {
t.Fatalf("open() error = %v, want auth read failure", err)
}
}
func TestRedisStickyStoreOpenRejectsSelectUnexpectedResponse(t *testing.T) {
t.Parallel()
server := newScriptedRedisServer(t, func(conn net.Conn, reader *bufio.Reader) {
command, err := readRESPArray(reader)
if err != nil {
return
}
if len(command) > 0 && strings.ToUpper(command[0]) == "AUTH" {
_, _ = io.WriteString(conn, "+OK\r\n")
}
command, err = readRESPArray(reader)
if err != nil {
return
}
if len(command) > 0 && strings.ToUpper(command[0]) == "SELECT" {
_, _ = io.WriteString(conn, ":1\r\n")
}
})
defer server.Close()
store := &RedisStickyStore{cfg: RedisConfig{Addr: server.Addr(), Password: "secret", DB: 2}}
_, _, err := store.open(context.Background())
if err == nil || !strings.Contains(err.Error(), "redis SELECT unexpected response") {
t.Fatalf("open() error = %v, want select unexpected response", err)
}
}
func TestRedisStickyStoreGetJSONRejectsUnexpectedResponse(t *testing.T) {
t.Parallel()
server := newScriptedRedisServer(t, func(conn net.Conn, reader *bufio.Reader) {
if _, err := readRESPArray(reader); err != nil {
return
}
_, _ = io.WriteString(conn, "+OK\r\n")
})
defer server.Close()
store := &RedisStickyStore{cfg: RedisConfig{Addr: server.Addr()}}
_, _, err := store.getJSON(context.Background(), "sticky-key")
if err == nil || !strings.Contains(err.Error(), "unexpected response") {
t.Fatalf("getJSON() error = %v, want unexpected response", err)
}
}
func TestRedisStickyStoreSetJSONRejectsUnexpectedResponse(t *testing.T) {
t.Parallel()
server := newScriptedRedisServer(t, func(conn net.Conn, reader *bufio.Reader) {
if _, err := readRESPArray(reader); err != nil {
return
}
_, _ = io.WriteString(conn, ":1\r\n")
})
defer server.Close()
store := &RedisStickyStore{cfg: RedisConfig{Addr: server.Addr()}}
err := store.setJSON(context.Background(), "sticky-key", map[string]string{"route_id": "asxs"}, time.Second)
if err == nil || !strings.Contains(err.Error(), "unexpected response") {
t.Fatalf("setJSON() error = %v, want unexpected response", err)
}
}
func TestNormalizeRuntimeBackend(t *testing.T) {
t.Parallel()
@@ -470,3 +555,35 @@ func TestRedisStickyStoreFixturePathExists(t *testing.T) {
t.Fatal("temp dir base should not be empty")
}
}
type scriptedRedisServer struct {
listener net.Listener
handler func(net.Conn, *bufio.Reader)
}
func newScriptedRedisServer(t *testing.T, handler func(net.Conn, *bufio.Reader)) *scriptedRedisServer {
t.Helper()
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("net.Listen() error = %v", err)
}
server := &scriptedRedisServer{listener: ln, handler: handler}
go func() {
conn, err := ln.Accept()
if err != nil {
return
}
defer conn.Close()
handler(conn, bufio.NewReader(conn))
}()
return server
}
func (s *scriptedRedisServer) Addr() string {
return s.listener.Addr().String()
}
func (s *scriptedRedisServer) Close() {
_ = s.listener.Close()
}

View File

@@ -281,6 +281,88 @@ func TestImportRunItemsRepoCreateUpdateAndLease(t *testing.T) {
}
}
func TestImportRunItemsRepoUpsertDefaultsOptionalJSONAndNullableFields(t *testing.T) {
t.Parallel()
ctx := context.Background()
store := openTestDB(t)
run := ImportRun{RunID: "run-upsert-defaults", HostID: "host-upsert", Mode: "strict", AccessMode: "subscription", State: "running"}
if err := store.ImportRuns().Create(ctx, run); err != nil {
t.Fatalf("ImportRuns().Create() error = %v", err)
}
if err := store.ImportRunItems().Upsert(ctx, ImportRunItem{
ItemID: "item-upsert-defaults",
RunID: "run-upsert-defaults",
BaseURL: "https://api.example.com/v1",
ProviderID: "provider-upsert",
APIKeyFingerprint: "fp-upsert",
CurrentStage: "confirm",
ConfirmationStatus: "pending",
AccessStatus: "unknown",
MatchedAccountState: "active",
AccountResolution: "created",
ResolvedSmokeModel: " gpt-5.4 ",
LastRetryAt: " ",
NextRetryAt: " ",
LeaseOwner: " worker-upsert ",
LeaseUntil: " 2026-05-23T12:00:00Z ",
LastErrorStage: " confirm ",
LastError: " timeout ",
LegacyProviderID: " legacy-provider ",
}); err != nil {
t.Fatalf("ImportRunItems().Upsert() error = %v", err)
}
got, err := store.ImportRunItems().GetByItemID(ctx, "item-upsert-defaults")
if err != nil {
t.Fatalf("ImportRunItems().GetByItemID() error = %v", err)
}
if got.RequestedModelsJSON != "[]" {
t.Fatalf("RequestedModelsJSON = %q, want []", got.RequestedModelsJSON)
}
if got.RawModelsJSON != "[]" {
t.Fatalf("RawModelsJSON = %q, want []", got.RawModelsJSON)
}
if got.NormalizedModelsJSON != "[]" {
t.Fatalf("NormalizedModelsJSON = %q, want []", got.NormalizedModelsJSON)
}
if got.CanonicalFamiliesJSON != "[]" {
t.Fatalf("CanonicalFamiliesJSON = %q, want []", got.CanonicalFamiliesJSON)
}
if got.RecommendedModelsJSON != "[]" {
t.Fatalf("RecommendedModelsJSON = %q, want []", got.RecommendedModelsJSON)
}
if got.CapabilityProfileJSON != "{}" {
t.Fatalf("CapabilityProfileJSON = %q, want {}", got.CapabilityProfileJSON)
}
if got.AdvisoryMessagesJSON != "[]" {
t.Fatalf("AdvisoryMessagesJSON = %q, want []", got.AdvisoryMessagesJSON)
}
if got.ResolvedSmokeModel != "gpt-5.4" {
t.Fatalf("ResolvedSmokeModel = %q, want gpt-5.4", got.ResolvedSmokeModel)
}
if got.LeaseOwner != "worker-upsert" {
t.Fatalf("LeaseOwner = %q, want worker-upsert", got.LeaseOwner)
}
if got.LeaseUntil != "2026-05-23T12:00:00Z" {
t.Fatalf("LeaseUntil = %q, want trimmed lease_until", got.LeaseUntil)
}
if got.LastErrorStage != "confirm" {
t.Fatalf("LastErrorStage = %q, want confirm", got.LastErrorStage)
}
if got.LastError != "timeout" {
t.Fatalf("LastError = %q, want timeout", got.LastError)
}
if got.LegacyProviderID != "legacy-provider" {
t.Fatalf("LegacyProviderID = %q, want legacy-provider", got.LegacyProviderID)
}
if got.LastRetryAt != "" || got.NextRetryAt != "" {
t.Fatalf("retry timestamps = (%q, %q), want empty strings", got.LastRetryAt, got.NextRetryAt)
}
}
func TestImportRunEventsRepoCreateAndHelpers(t *testing.T) {
t.Parallel()

View File

@@ -113,6 +113,52 @@ func TestPacksRepoUpsertUpdatesExisting(t *testing.T) {
}
}
func TestPacksRepoUpsertTrimsAndDefaultsManifest(t *testing.T) {
store := openTestDB(t)
id, err := store.Packs().Upsert(context.Background(), Pack{
PackID: " upsert-pack-json ",
Version: " 1.2.3 ",
Checksum: " chk-json ",
Vendor: " vendor-a ",
TargetHost: " sub2api ",
MinHostVersion: " 0.1.0 ",
MaxHostVersion: " 0.2.x ",
})
if err != nil {
t.Fatalf("Upsert() error = %v", err)
}
got, err := store.Packs().GetByID(context.Background(), id)
if err != nil {
t.Fatalf("GetByID() error = %v", err)
}
if got.PackID != "upsert-pack-json" {
t.Fatalf("PackID = %q, want upsert-pack-json", got.PackID)
}
if got.Version != "1.2.3" {
t.Fatalf("Version = %q, want 1.2.3", got.Version)
}
if got.Checksum != "chk-json" {
t.Fatalf("Checksum = %q, want chk-json", got.Checksum)
}
if got.Vendor != "vendor-a" {
t.Fatalf("Vendor = %q, want vendor-a", got.Vendor)
}
if got.TargetHost != "sub2api" {
t.Fatalf("TargetHost = %q, want sub2api", got.TargetHost)
}
if got.MinHostVersion != "0.1.0" {
t.Fatalf("MinHostVersion = %q, want 0.1.0", got.MinHostVersion)
}
if got.MaxHostVersion != "0.2.x" {
t.Fatalf("MaxHostVersion = %q, want 0.2.x", got.MaxHostVersion)
}
if got.ManifestJSON != "{}" {
t.Fatalf("ManifestJSON = %q, want {}", got.ManifestJSON)
}
}
func TestPacksRepoValidationErrors(t *testing.T) {
store := openTestDB(t)

View File

@@ -325,6 +325,27 @@ func TestSyncProviderAccountsFromImportBatchPreservesManualDisabledStatus(t *tes
}
}
func TestNormalizeProviderAccountBindingState(t *testing.T) {
t.Parallel()
tests := []struct {
input string
want string
}{
{input: ProviderAccountBindingStateAssigned, want: ProviderAccountBindingStateAssigned},
{input: " " + ProviderAccountBindingStateUnassigned + " ", want: ProviderAccountBindingStateUnassigned},
{input: ProviderAccountBindingStateConflict, want: ProviderAccountBindingStateConflict},
{input: "invalid", want: ""},
{input: " ", want: ""},
}
for _, tt := range tests {
if got := normalizeProviderAccountBindingState(tt.input); got != tt.want {
t.Fatalf("normalizeProviderAccountBindingState(%q) = %q, want %q", tt.input, got, tt.want)
}
}
}
func TestSyncProviderAccountsFromImportBatchInfersRouteFromShadowBinding(t *testing.T) {
t.Parallel()

View File

@@ -170,6 +170,65 @@ func TestProvidersRepoUpsertUpdatesExisting(t *testing.T) {
}
}
func TestProvidersRepoUpsertTrimsAndDefaultsOptionalJSON(t *testing.T) {
store := openTestDB(t)
packID := createTestPack(t, store)
id, err := store.Providers().Upsert(context.Background(), Provider{
PackID: packID,
ProviderID: " upsert-json ",
DisplayName: " Upsert JSON ",
BaseURL: " https://json.example.com/v1 ",
Platform: " openai ",
AccountType: " apikey ",
SmokeTestModel: " gpt-5.4 ",
})
if err != nil {
t.Fatalf("Upsert() error = %v", err)
}
got, err := store.Providers().GetByID(context.Background(), id)
if err != nil {
t.Fatalf("GetByID() error = %v", err)
}
if got.ProviderID != "upsert-json" {
t.Fatalf("ProviderID = %q, want upsert-json", got.ProviderID)
}
if got.DisplayName != "Upsert JSON" {
t.Fatalf("DisplayName = %q, want Upsert JSON", got.DisplayName)
}
if got.BaseURL != "https://json.example.com/v1" {
t.Fatalf("BaseURL = %q, want trimmed base url", got.BaseURL)
}
if got.Platform != "openai" {
t.Fatalf("Platform = %q, want openai", got.Platform)
}
if got.AccountType != "apikey" {
t.Fatalf("AccountType = %q, want apikey", got.AccountType)
}
if got.SmokeTestModel != "gpt-5.4" {
t.Fatalf("SmokeTestModel = %q, want gpt-5.4", got.SmokeTestModel)
}
if got.DefaultModelsJSON != "[]" {
t.Fatalf("DefaultModelsJSON = %q, want []", got.DefaultModelsJSON)
}
if got.GroupTemplateJSON != "{}" {
t.Fatalf("GroupTemplateJSON = %q, want {}", got.GroupTemplateJSON)
}
if got.ChannelTemplateJSON != "{}" {
t.Fatalf("ChannelTemplateJSON = %q, want {}", got.ChannelTemplateJSON)
}
if got.PlanTemplateJSON != "{}" {
t.Fatalf("PlanTemplateJSON = %q, want {}", got.PlanTemplateJSON)
}
if got.ImportOptionsJSON != "{}" {
t.Fatalf("ImportOptionsJSON = %q, want {}", got.ImportOptionsJSON)
}
if got.ManifestJSON != "{}" {
t.Fatalf("ManifestJSON = %q, want {}", got.ManifestJSON)
}
}
func TestProvidersRepoValidationErrors(t *testing.T) {
store := openTestDB(t)
packID := createTestPack(t, store)