86 lines
3.5 KiB
Go
86 lines
3.5 KiB
Go
package callruntime
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/CyCoreSystems/ari/v5"
|
|
)
|
|
|
|
type eventSubscription struct{ events chan ari.Event }
|
|
|
|
func (s eventSubscription) Events() <-chan ari.Event { return s.events }
|
|
func (s eventSubscription) Cancel() {}
|
|
func events(values ...ari.Event) eventSubscription {
|
|
s := eventSubscription{make(chan ari.Event, len(values))}
|
|
for _, event := range values {
|
|
s.events <- event
|
|
}
|
|
close(s.events)
|
|
return s
|
|
}
|
|
|
|
func TestWaitForAnswerUsesOnlyTargetChannel(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
event ari.Event
|
|
wantError string
|
|
}{
|
|
{name: "stasis", event: &ari.StasisStart{EventData: ari.EventData{Type: "StasisStart"}, Channel: ari.ChannelData{ID: "call"}}},
|
|
{name: "up", event: &ari.ChannelStateChange{EventData: ari.EventData{Type: "ChannelStateChange"}, Channel: ari.ChannelData{ID: "call", State: "Up"}}},
|
|
{name: "hangup", event: &ari.ChannelHangupRequest{EventData: ari.EventData{Type: "ChannelHangupRequest"}, Channel: ari.ChannelData{ID: "call", State: "Down"}, Cause: 17}, wantError: "cause=17"},
|
|
{name: "destroyed", event: &ari.ChannelDestroyed{EventData: ari.EventData{Type: "ChannelDestroyed"}, Channel: ari.ChannelData{ID: "call"}}, wantError: "ended before StasisStart"},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
other := &ari.StasisStart{EventData: ari.EventData{Type: "StasisStart"}, Channel: ari.ChannelData{ID: "another-call"}}
|
|
err := waitForStasisStart(context.Background(), events(nil, other, tc.event), "call", time.Second)
|
|
if tc.wantError == "" && err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if tc.wantError != "" && (err == nil || !strings.Contains(err.Error(), tc.wantError)) {
|
|
t.Fatalf("unexpected answer result: %v", err)
|
|
}
|
|
})
|
|
}
|
|
if err := waitForStasisStart(context.Background(), events(), "call", time.Second); err == nil || !strings.Contains(err.Error(), "subscription closed") {
|
|
t.Fatal("closed subscription accepted")
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel()
|
|
if err := waitForStasisStart(ctx, eventSubscription{make(chan ari.Event)}, "call", time.Second); !errors.Is(err, context.Canceled) {
|
|
t.Fatalf("cancellation lost: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestLifecycleCancellationIsScopedToChannel(t *testing.T) {
|
|
for _, kind := range []string{"ChannelHangupRequest", "ChannelDestroyed"} {
|
|
t.Run(kind, func(t *testing.T) {
|
|
var event ari.Event
|
|
if kind == "ChannelDestroyed" {
|
|
event = &ari.ChannelDestroyed{EventData: ari.EventData{Type: kind}, Channel: ari.ChannelData{ID: "call"}}
|
|
} else {
|
|
event = &ari.ChannelHangupRequest{EventData: ari.EventData{Type: kind}, Channel: ari.ChannelData{ID: "call"}}
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
other := &ari.ChannelDestroyed{EventData: ari.EventData{Type: "ChannelDestroyed"}, Channel: ari.ChannelData{ID: "other"}}
|
|
watchChannelLifecycle(ctx, events(other, event), "call", cancel)
|
|
if !errors.Is(ctx.Err(), context.Canceled) {
|
|
t.Fatal("matching hangup failed to cancel")
|
|
}
|
|
})
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
watchChannelLifecycle(ctx, events(&ari.ChannelDestroyed{EventData: ari.EventData{Type: "ChannelDestroyed"}, Channel: ari.ChannelData{ID: "other"}}), "call", cancel)
|
|
if ctx.Err() != nil {
|
|
t.Fatal("another call ended this call")
|
|
}
|
|
watchChannelLifecycle(ctx, events(nil), "call", cancel)
|
|
cancel()
|
|
watchChannelLifecycle(ctx, eventSubscription{make(chan ari.Event)}, "call", cancel)
|
|
}
|