Files
go-sip/internal/asterisk/end_confirmation_test.go
T

76 lines
2.2 KiB
Go

package asterisk
import (
"context"
"errors"
"strings"
"testing"
"time"
"github.com/CyCoreSystems/ari/v5"
)
type delayedTeardownChannel struct {
ari.Channel
reads, hangups int
}
func (c *delayedTeardownChannel) Hangup(key *ari.Key, _ string) error {
if key.ID != "owned-call" {
return errors.New("wrong channel")
}
c.hangups++
return nil
}
func (c *delayedTeardownChannel) Data(key *ari.Key) (*ari.ChannelData, error) {
if key.ID != "owned-call" {
return nil, errors.New("wrong channel")
}
c.reads++
if c.reads < 3 {
return &ari.ChannelData{ID: key.ID}, nil
}
return nil, nativeHTTPStatusError{code: 404}
}
func TestNativeCloseWaitsForExactChannelAsynchronousTeardown(t *testing.T) {
channel := &delayedTeardownChannel{}
call := &NativeCall{verifyEnd: true, outbound: ari.NewChannelHandle(ari.NewKey(ari.ChannelKey, "owned-call"), channel, nil)}
if err := call.Close(); err != nil {
t.Fatal(err)
}
if !call.EndConfirmed() || channel.reads != 3 || channel.hangups != 1 {
t.Fatalf("only the exact channel 404 confirms end; reads=%d hangups=%d confirmed=%v", channel.reads, channel.hangups, call.EndConfirmed())
}
if err := call.Close(); err != nil || channel.hangups != 1 {
t.Fatal("Close must never repeat Hangup")
}
}
func TestNativeEndReadbackKeepsUncertaintyVisible(t *testing.T) {
for _, scenario := range []string{"still-present", "HTTP-error", "transport-error"} {
t.Run(scenario, func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
defer cancel()
reads, err := awaitNativeChannelEnd(ctx, func() error {
switch scenario {
case "HTTP-error":
return nativeHTTPStatusError{code: 503}
case "transport-error":
return errors.New("read unavailable")
}
return nil
})
if err == nil || reads < 1 {
t.Fatalf("missing terminal evidence must fail explicitly: reads=%d error=%v", reads, err)
}
if scenario == "still-present" && (!errors.Is(err, context.DeadlineExceeded) || !strings.Contains(err.Error(), "channel still present")) {
t.Fatalf("deadline must retain pending-channel evidence: %v", err)
}
if scenario != "still-present" && reads != 1 {
t.Fatal("failed read is not silently retried")
}
})
}
}