fix(inbounds): apply runtime changes after the DB commit (#5768)

* fix(inbounds): apply runtime changes after commit

* ci: fix staticcheck findings
This commit is contained in:
n0ctal
2026-07-09 01:12:28 +05:00
committed by GitHub
parent f4199353da
commit f431e9cc03
9 changed files with 420 additions and 195 deletions
@@ -16,21 +16,36 @@ import (
// fakeNodeRuntime is a runtime.Runtime stub that counts the per-client dispatch
// calls so a test can assert a bulk op does NOT stream one RPC per client.
type fakeNodeRuntime struct {
addClient atomic.Int32
deleteUser atomic.Int32
deleteClient atomic.Int32
updateUser atomic.Int32
addInbound atomic.Int32
delInbound atomic.Int32
addClient atomic.Int32
deleteClient atomic.Int32
deleteUser atomic.Int32
updateInbound atomic.Int32
updateUser atomic.Int32
}
func (f *fakeNodeRuntime) Name() string { return "fake-node" }
func (f *fakeNodeRuntime) AddInbound(context.Context, *model.Inbound) error { return nil }
func (f *fakeNodeRuntime) DelInbound(context.Context, *model.Inbound) error { return nil }
func (f *fakeNodeRuntime) UpdateInbound(context.Context, *model.Inbound, *model.Inbound) error {
func (f *fakeNodeRuntime) AddInbound(context.Context, *model.Inbound) error {
f.addInbound.Add(1)
return nil
}
func (f *fakeNodeRuntime) DelInbound(context.Context, *model.Inbound) error {
f.delInbound.Add(1)
return nil
}
func (f *fakeNodeRuntime) UpdateInbound(context.Context, *model.Inbound, *model.Inbound) error {
f.updateInbound.Add(1)
return nil
}
func (f *fakeNodeRuntime) AddUser(context.Context, *model.Inbound, map[string]any) error { return nil }
func (f *fakeNodeRuntime) RemoveUser(context.Context, *model.Inbound, string) error { return nil }
func (f *fakeNodeRuntime) RemoveUser(context.Context, *model.Inbound, string) error { return nil }
func (f *fakeNodeRuntime) UpdateUser(context.Context, *model.Inbound, string, model.Client) error {
f.updateUser.Add(1)
return nil
@@ -67,10 +82,13 @@ func setupNodeRuntime(t *testing.T) (int, *fakeNodeRuntime) {
runtime.SetManager(mgr)
t.Cleanup(func() { runtime.SetManager(prev) })
node := &model.Node{Name: "n1", Address: "127.0.0.1", Port: 2096, ApiToken: "tok", Enable: true, Status: "online"}
node := &model.Node{Name: "n1-" + t.Name(), Address: "127.0.0.1", Port: 2096, ApiToken: "tok", Enable: true, Status: "online"}
if err := database.GetDB().Create(node).Error; err != nil {
t.Fatalf("create node: %v", err)
}
t.Cleanup(func() {
_ = database.GetDB().Where("id = ?", node.Id).Delete(&model.Node{}).Error
})
fake := &fakeNodeRuntime{}
mgr.SetRuntimeOverride(node.Id, fake)
return node.Id, fake
@@ -250,3 +268,39 @@ func TestNodeBulk_LargeDeleteFoldsToDirty(t *testing.T) {
t.Fatal("large delete must mark the node dirty")
}
}
func TestDelInbound_NodeSelectedModeDeletesRemoteImmediately(t *testing.T) {
setupBulkDB(t)
nodeID, fake := setupNodeRuntime(t)
if err := database.GetDB().Model(&model.Node{}).Where("id = ?", nodeID).
Updates(map[string]any{
"inbound_sync_mode": "selected",
"inbound_tags": []string{"other-tag"},
}).Error; err != nil {
t.Fatalf("set selected mode: %v", err)
}
ib := nodeInbound(t, nodeID, 30004, makeNodeClients(1))
needRestart, err := (&InboundService{}).DelInbound(ib.Id)
if err != nil {
t.Fatalf("DelInbound: %v", err)
}
if needRestart {
t.Fatal("node-owned delete should not request local restart")
}
if got := fake.delInbound.Load(); got != 1 {
t.Fatalf("node-owned delete streamed %d DelInbound RPCs, want 1", got)
}
var count int64
if err := database.GetDB().Model(&model.Inbound{}).Where("id = ?", ib.Id).Count(&count).Error; err != nil {
t.Fatalf("count inbound: %v", err)
}
if count != 0 {
t.Fatalf("deleted inbound row count = %d, want 0", count)
}
if _, _, dirty, _, err := (&NodeService{}).NodeSyncState(nodeID); err != nil {
t.Fatalf("NodeSyncState: %v", err)
} else if !dirty {
t.Fatal("node-owned delete should still mark the node dirty as reconcile backup")
}
}