65 lines
2.7 KiB
Go
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")
|
|
}
|
|
}
|