47 lines
1.7 KiB
Go
47 lines
1.7 KiB
Go
package local_event
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
|
|
"git.ilapage.cn/ila/yovision/Sense/server/app/sense/outbox"
|
|
)
|
|
|
|
func TestCreateWithOutboxCommitsAndRollsBackAtomically(t *testing.T) {
|
|
db, err := gorm.Open(sqlite.Open("file:"+uuid.NewString()+"?mode=memory&cache=shared"), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sqlDB, _ := db.DB()
|
|
sqlDB.SetMaxOpenConns(1)
|
|
if err = db.AutoMigrate(&EventCandidate{}, &outbox.Message{}, &outbox.DeliveryRecord{}, &outbox.Attempt{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
now := time.Date(2026, 8, 28, 10, 0, 0, 0, time.UTC)
|
|
candidate := EventCandidate{ID: uuid.NewString(), OccurredAt: now, SourceRef: "SEN-CAM-01", RuleRef: "rule-1", RuleName: "区域闯入", CandidateState: CandidateStateCandidate, EvidenceState: EvidenceStatePending, RetainUntil: now.Add(24 * time.Hour)}
|
|
if err = CreateWithOutbox(context.Background(), db, candidate, map[string]interface{}{"eventId": candidate.ID}, now); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var candidates, messages int64
|
|
db.Model(&EventCandidate{}).Count(&candidates)
|
|
db.Model(&outbox.Message{}).Count(&messages)
|
|
if candidates != 1 || messages != 1 {
|
|
t.Fatalf("candidates=%d messages=%d", candidates, messages)
|
|
}
|
|
duplicate := candidate
|
|
duplicate.ID = candidate.ID
|
|
if err = CreateWithOutbox(context.Background(), db, duplicate, map[string]interface{}{"eventId": duplicate.ID}, now); err == nil {
|
|
t.Fatal("expected duplicate transaction failure")
|
|
}
|
|
db.Model(&EventCandidate{}).Count(&candidates)
|
|
db.Model(&outbox.Message{}).Count(&messages)
|
|
if candidates != 1 || messages != 1 {
|
|
t.Fatalf("atomic rollback failed candidates=%d messages=%d", candidates, messages)
|
|
}
|
|
}
|