Files
go-sip/internal/dispatcher/current_gate_test.go
T

65 lines
2.7 KiB
Go

package dispatcher
import (
"context"
"testing"
"time"
"git.ipao.vip/rogee/go-sip/internal/store"
)
func TestCurrentPreDialWindowChangeReleasesUnusedReservation(t *testing.T) {
controller, originator, _, s := newCurrentExecuteFixture(t)
first := time.Date(2026, 9, 21, 19, 59, 59, 900_000_000, time.FixedZone("Asia/Shanghai", 8*3600))
second := time.Date(2026, 9, 21, 20, 0, 0, 0, time.FixedZone("Asia/Shanghai", 8*3600))
calls := 0
controller.Now = func() time.Time {
calls++
if calls == 1 {
return first
}
return second
}
if err := controller.ProcessExecute(context.Background(), currentExecuteBody(t, "boundary-1", "15003164745")); err != nil {
t.Fatal(err)
}
if len(originator.calls) != 0 {
t.Fatal("dialed after window closed")
}
pending, err := s.ListPendingExecute(controller.DispatcherID)
if err != nil || len(pending) != 1 || pending[0].EventID != "boundary-1" {
t.Fatalf("unused reservation not returned to pending: %+v %v", pending, err)
}
occupied, err := s.TrunkOccupancy(controller.DispatcherID)
if err != nil || occupied["trunk-mock"] != 0 {
t.Fatalf("unused reservation held quota: %+v %v", occupied, err)
}
controller.Now = func() time.Time { return time.Date(2026, 9, 28, 9, 30, 0, 0, time.FixedZone("Asia/Shanghai", 8*3600)) }
if err := controller.ProcessPending(context.Background()); err != nil || len(originator.calls) != 1 {
t.Fatalf("eligible pending call did not resume once: calls=%d err=%v", len(originator.calls), err)
}
}
func TestCurrentFutureIssuedAtNeverDialsEarly(t *testing.T) {
controller, originator, _, s := newCurrentExecuteFixture(t)
controller.Now = func() time.Time { return time.Date(2026, 9, 21, 8, 59, 59, 0, time.FixedZone("Asia/Shanghai", 8*3600)) }
body := currentExecuteBody(t, "future-1", "15003164745")
if err := controller.ProcessExecute(context.Background(), body); err != nil {
t.Fatal(err)
}
if len(originator.calls) != 0 {
t.Fatal("future issued_at dialed early")
}
pending, err := s.ListPendingExecute(controller.DispatcherID)
if err != nil || len(pending) != 1 {
t.Fatalf("future command not durable: %+v %v", pending, err)
}
controller.Now = func() time.Time { return time.Date(2026, 9, 21, 9, 30, 0, 0, time.FixedZone("Asia/Shanghai", 8*3600)) }
if err := controller.ProcessPending(context.Background()); err != nil || len(originator.calls) != 1 {
t.Fatalf("future command did not dispatch after issued_at: %d %v", len(originator.calls), err)
}
if _, _, err := s.RecordExecute(store.CurrentExecuteCommand{DispatcherID: controller.DispatcherID, EventID: "future-1", TenantID: 1001, TaskID: "task-asr", Callee: "15830461047", IssuedAt: "2026-09-21T01:00:00Z"}); err == nil {
t.Fatal("conflicting identity silently accepted")
}
}