package repository import ( "testing" "lokistack/models" ) // 回归:nextSequence / 去重逻辑。 // // 线上事故:logSources 漏在 sequences 重建之外,NextID 每次重启从 1 开始, // 导致两个数据源都是 id=1 → 前端数据源下拉两个 option value 相同, // 选中后 sourceId 不变,界面表现为"无法切换数据源"。 func TestDedupeLogSourceIDs(t *testing.T) { db := &JsonDB{ sequences: map[string]uint{"logSources": 1}, LogSources: []models.LogSource{ {ID: 1, Name: "loki-pre", IsDefault: true}, {ID: 1, Name: "host-verify-loki"}, // 重复 ID }, LogPolicyGroups: []models.LogPolicyGroup{ {ID: 1, Name: "g1", SourceID: 1}, }, } db.dedupeLogSourceIDs() if len(db.LogSources) != 2 { t.Fatalf("数据源数量变化了:%d", len(db.LogSources)) } ids := map[uint]string{} for _, s := range db.LogSources { if _, dup := ids[s.ID]; dup { t.Fatalf("仍然存在重复 ID %d", s.ID) } ids[s.ID] = s.Name } if ids[1] != "loki-pre" { t.Fatalf("第一个数据源应保留 ID=1,实际 %v", ids) } // 被重排的那个必须拿到新号 if _, ok := ids[2]; !ok { t.Fatalf("重复项应被重排为 ID=2,实际 %v", ids) } // 策略组仍指向保留下来的那个 if db.LogPolicyGroups[0].SourceID != 1 { t.Fatalf("策略组引用被误改:%d", db.LogPolicyGroups[0].SourceID) } // 计数器必须已提升,防止紧接着创建又撞号 if db.sequences["logSources"] < 2 { t.Fatalf("sequences 未提升:%d", db.sequences["logSources"]) } } // 只有一个数据源时不应被改动 func TestDedupeLogSourceIDsNoop(t *testing.T) { db := &JsonDB{ sequences: map[string]uint{"logSources": 1}, LogSources: []models.LogSource{{ID: 1, Name: "only"}}, } db.dedupeLogSourceIDs() if len(db.LogSources) != 1 || db.LogSources[0].ID != 1 { t.Fatalf("单数据源不应被改动:%+v", db.LogSources) } } // 多个默认数据源只保留第一个 func TestDedupeKeepsSingleDefault(t *testing.T) { db := &JsonDB{ sequences: map[string]uint{"logSources": 2}, LogSources: []models.LogSource{ {ID: 1, Name: "a", IsDefault: true}, {ID: 2, Name: "b", IsDefault: true}, }, } db.dedupeLogSourceIDs() if !db.LogSources[0].IsDefault { t.Fatal("第一个应保持默认") } if db.LogSources[1].IsDefault { t.Fatal("第二个不应再是默认") } }