发布 0.3.0:恢复 Chat 接口并增强云端事件通知
This commit is contained in:
@@ -55,7 +55,7 @@ func newTenantDeleteEnv(t *testing.T, client oci.Client) (*OciConfigService, *Ta
|
||||
}
|
||||
configs := NewOciConfigService(db, cipher, client)
|
||||
tasks := NewTaskService(db, configs, nil, nil)
|
||||
configs.SetTenantCleanupDeps(tasks, nil)
|
||||
configs.SetTenantCleanupDeps(tasks)
|
||||
return configs, tasks, db
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ func migrateTenantDeleteModels(t *testing.T, db *gorm.DB) {
|
||||
err := db.AutoMigrate(
|
||||
&model.OciConfig{}, &model.Task{}, &model.TaskLog{}, &model.Setting{},
|
||||
&model.CheckSnapshot{}, &model.CostSnapshot{}, &model.RegionCache{}, &model.CompartmentCache{},
|
||||
&model.LogEvent{}, &model.AlertRule{}, &model.AlertRuleHit{},
|
||||
&model.LogEvent{},
|
||||
&model.AiChannel{}, &model.AiModelCache{}, &model.AiCallLog{}, &model.AiContentLog{},
|
||||
&model.Proxy{}, &model.AiKey{}, &model.SystemLog{},
|
||||
)
|
||||
@@ -162,19 +162,9 @@ func seedTenantEvents(t *testing.T, db *gorm.DB, target, other uint) {
|
||||
t.Helper()
|
||||
targetEvent := model.LogEvent{OciConfigID: target, MessageID: "target-event"}
|
||||
otherEvent := model.LogEvent{OciConfigID: other, MessageID: "other-event"}
|
||||
targetRule := model.AlertRule{Name: "target-rule", OciConfigID: target}
|
||||
globalRule := model.AlertRule{Name: "global-rule", OciConfigID: 0}
|
||||
for _, value := range []any{&targetEvent, &otherEvent, &targetRule, &globalRule} {
|
||||
for _, value := range []any{&targetEvent, &otherEvent} {
|
||||
mustCreate(t, db, value)
|
||||
}
|
||||
hits := []model.AlertRuleHit{
|
||||
{RuleID: targetRule.ID, LogEventID: otherEvent.ID},
|
||||
{RuleID: globalRule.ID, LogEventID: targetEvent.ID},
|
||||
{RuleID: globalRule.ID, LogEventID: otherEvent.ID},
|
||||
}
|
||||
for i := range hits {
|
||||
mustCreate(t, db, &hits[i])
|
||||
}
|
||||
}
|
||||
|
||||
func seedTenantAI(t *testing.T, db *gorm.DB, target, other uint) {
|
||||
@@ -202,7 +192,7 @@ func assertTenantRowsGone(t *testing.T, db *gorm.DB, id uint) {
|
||||
rows := []any{
|
||||
&model.OciConfig{}, &model.CheckSnapshot{}, &model.CostSnapshot{},
|
||||
&model.RegionCache{}, &model.CompartmentCache{}, &model.LogEvent{},
|
||||
&model.AlertRule{}, &model.AiChannel{},
|
||||
&model.AiChannel{},
|
||||
}
|
||||
for _, value := range rows {
|
||||
column := "oci_config_id"
|
||||
@@ -212,7 +202,6 @@ func assertTenantRowsGone(t *testing.T, db *gorm.DB, id uint) {
|
||||
assertCount(t, db, value, column+" = ?", []any{id}, 0)
|
||||
}
|
||||
assertCount(t, db, &model.Setting{}, "key = ?", []any{secretKey(id)}, 0)
|
||||
assertCount(t, db, &model.AlertRuleHit{}, "", nil, 1)
|
||||
assertCount(t, db, &model.AiModelCache{}, "", nil, 1)
|
||||
assertCount(t, db, &model.AiCallLog{}, "", nil, 1)
|
||||
assertCount(t, db, &model.AiContentLog{}, "", nil, 1)
|
||||
@@ -248,31 +237,10 @@ func assertRemainingIndirectRows(t *testing.T, db *gorm.DB, otherID uint) {
|
||||
t.Fatalf("load other AI call: %v", err)
|
||||
}
|
||||
assertCount(t, db, &model.AiContentLog{}, "call_log_id = ?", []any{call.ID}, 1)
|
||||
assertRemainingAlertHit(t, db, otherID)
|
||||
}
|
||||
|
||||
func assertRemainingAlertHit(t *testing.T, db *gorm.DB, otherID uint) {
|
||||
t.Helper()
|
||||
var hit model.AlertRuleHit
|
||||
if err := db.First(&hit).Error; err != nil {
|
||||
t.Fatalf("load remaining alert hit: %v", err)
|
||||
}
|
||||
var rule model.AlertRule
|
||||
var event model.LogEvent
|
||||
if err := db.First(&rule, hit.RuleID).Error; err != nil {
|
||||
t.Fatalf("load remaining rule: %v", err)
|
||||
}
|
||||
if err := db.First(&event, hit.LogEventID).Error; err != nil {
|
||||
t.Fatalf("load remaining event: %v", err)
|
||||
}
|
||||
if rule.OciConfigID != 0 || event.OciConfigID != otherID {
|
||||
t.Errorf("remaining hit = rule cfg %d/event cfg %d, want global/other", rule.OciConfigID, event.OciConfigID)
|
||||
}
|
||||
}
|
||||
|
||||
func assertRetainedGlobals(t *testing.T, db *gorm.DB) {
|
||||
t.Helper()
|
||||
assertCount(t, db, &model.AlertRule{}, "oci_config_id = 0", nil, 1)
|
||||
assertCount(t, db, &model.Proxy{}, "", nil, 1)
|
||||
assertCount(t, db, &model.AiKey{}, "", nil, 1)
|
||||
assertCount(t, db, &model.SystemLog{}, "", nil, 1)
|
||||
@@ -629,35 +597,6 @@ func TestDeleteTenantSkipsCorruptTaskPayload(t *testing.T) {
|
||||
assertCount(t, db, &model.OciConfig{}, "id = ?", []any{target.ID}, 0)
|
||||
}
|
||||
|
||||
func TestDeleteTenantEventsAffectedRules(t *testing.T) {
|
||||
_, _, db := newTenantDeleteEnv(t, &fakeClient{})
|
||||
target, other := seedDeleteTenants(t, db)
|
||||
seedTenantEvents(t, db, target.ID, other.ID)
|
||||
|
||||
// 规则 ID 须在删除前取:target-rule 会随租户一并删除
|
||||
var targetRule, globalRule model.AlertRule
|
||||
db.Where("name = ?", "target-rule").First(&targetRule)
|
||||
db.Where("name = ?", "global-rule").First(&globalRule)
|
||||
|
||||
result := &tenantDeleteResult{}
|
||||
err := db.Transaction(func(tx *gorm.DB) error {
|
||||
return deleteTenantEvents(tx, target.ID, result)
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("deleteTenantEvents: %v", err)
|
||||
}
|
||||
// target-rule 属本租户,global-rule 的命中引用了本租户事件:都应回收冷却
|
||||
got := map[uint]bool{}
|
||||
for _, id := range result.alertRuleIDs {
|
||||
got[id] = true
|
||||
}
|
||||
if len(got) != 2 || !got[targetRule.ID] || !got[globalRule.ID] {
|
||||
t.Errorf("alertRuleIDs = %v, want 含 target-rule(%d) 与 global-rule(%d)", result.alertRuleIDs, targetRule.ID, globalRule.ID)
|
||||
}
|
||||
// 仅保留 global-rule × other-event 一条命中
|
||||
assertCount(t, db, &model.AlertRuleHit{}, "", nil, 1)
|
||||
}
|
||||
|
||||
func TestDeleteTenantManyEventsNoVarLimit(t *testing.T) {
|
||||
// 回归:事件数超 SQLite 绑定变量上限(32766)时删除仍成功(旧实现 IN 展开必失败)
|
||||
configs, _, db := newTenantDeleteEnv(t, &fakeClient{})
|
||||
|
||||
Reference in New Issue
Block a user