This commit is contained in:
parent
a9e1f9e6f8
commit
1945d34894
|
|
@ -0,0 +1,100 @@
|
|||
package data
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMigrateLegacyAuthorityAPIsWithoutDeletedAt(t *testing.T) {
|
||||
db, err := openWithDriver("sqlite", "file:"+t.Name()+"?mode=memory&cache=shared")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = sqlDB.Close() })
|
||||
|
||||
for _, statement := range []string{
|
||||
`CREATE TABLE sys_apis (id integer primary key, path text, method text)`,
|
||||
`CREATE TABLE sys_authority_apis (authority_id integer, api_id integer)`,
|
||||
`INSERT INTO sys_apis (id, path, method) VALUES (1, '/legacy', 'GET')`,
|
||||
`INSERT INTO sys_authority_apis (authority_id, api_id) VALUES (888, 1)`,
|
||||
} {
|
||||
if err = db.Exec(statement).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err = db.AutoMigrate(&casbinRulePO{}, &errorRecordPO{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
legacyError := errorRecordPO{Status: "未解决"}
|
||||
if err = db.Create(&legacyError).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = migrateLegacyAuthorityAPIsToCasbinRules(db); err != nil {
|
||||
t.Fatalf("legacy migration failed without sys_apis.deleted_at: %v", err)
|
||||
}
|
||||
if err = normalizeErrorRecordStatuses(db); err != nil {
|
||||
t.Fatalf("following migration inherited the legacy table alias: %v", err)
|
||||
}
|
||||
|
||||
var count int64
|
||||
if err = db.Model(&casbinRulePO{}).
|
||||
Where("ptype = ? AND v0 = ? AND v1 = ? AND v2 = ?", "p", "888", "/legacy", "GET").
|
||||
Count(&count).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if count != 1 {
|
||||
t.Fatalf("migrated policy count = %d, want 1", count)
|
||||
}
|
||||
if err = db.First(&legacyError, legacyError.ID).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if legacyError.Status != "未处理" {
|
||||
t.Fatalf("normalized status = %q, want 未处理", legacyError.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReconcileRootAuthorityAPIsUsesIndependentQueries(t *testing.T) {
|
||||
db, err := openWithDriver("sqlite", "file:"+t.Name()+"?mode=memory&cache=shared")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = sqlDB.Close() })
|
||||
|
||||
if err = db.AutoMigrate(&authorityPO{}, &apiPO{}, &ignoredAPIPO{}, &casbinRulePO{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = db.Create(&authorityPO{AuthorityID: 888, AuthorityName: "root"}).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = db.Create(&apiPO{Path: "/allowed", Method: "GET"}).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = db.Create(&apiPO{Path: "/ignored", Method: "POST"}).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err = db.Create(&ignoredAPIPO{Path: "/ignored", Method: "POST"}).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Deliberately pass a handle carrying an unrelated model and predicate.
|
||||
// Migration queries must not inherit either state.
|
||||
dirty := db.Model(&authorityPO{}).Where("authority_id = ?", 999)
|
||||
if err = reconcileRootAuthorityAPIs(dirty); err != nil {
|
||||
t.Fatalf("reconcile root policies with dirty DB state: %v", err)
|
||||
}
|
||||
|
||||
var rules []casbinRulePO
|
||||
if err = db.Where("ptype = ? AND v0 = ?", "p", "888").Find(&rules).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(rules) != 1 || rules[0].V1 != "/allowed" || rules[0].V2 != "GET" {
|
||||
t.Fatalf("root rules = %#v, want only GET /allowed", rules)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package worker
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCloseSubscribersClosesEveryAlertStream(t *testing.T) {
|
||||
scheduler := &TaskScheduler{subscribers: map[uint]map[chan []byte]struct{}{}}
|
||||
first := scheduler.Subscribe(1)
|
||||
second := scheduler.Subscribe(1)
|
||||
third := scheduler.Subscribe(2)
|
||||
|
||||
scheduler.closeSubscribers()
|
||||
|
||||
for _, ch := range []chan []byte{first, second, third} {
|
||||
if _, open := <-ch; open {
|
||||
t.Fatal("subscriber channel remains open after scheduler shutdown")
|
||||
}
|
||||
}
|
||||
if len(scheduler.subscribers) != 0 {
|
||||
t.Fatalf("subscriber registry was not cleared: %#v", scheduler.subscribers)
|
||||
}
|
||||
|
||||
// Handlers defer Unsubscribe. It must remain safe after shutdown has already
|
||||
// closed and removed every channel.
|
||||
scheduler.Unsubscribe(1, first)
|
||||
}
|
||||
Loading…
Reference in New Issue