Live video on the AT Protocol
1package misttriggers
2
3import (
4 "bytes"
5 "context"
6 "fmt"
7 "net/http"
8 "net/http/httptest"
9 "testing"
10
11 "github.com/stretchr/testify/require"
12 "stream.place/streamplace/pkg/config"
13)
14
15var pushEndPayload = MistTriggerBody(`
16 2596
17 video+c447r0acdmqhhhpb
18 rtmp://rtmp.livepeer.com/live/stream-key?video=maxbps&audio=maxbps
19 rtmp://rtmp.livepeer.com/live/stream-key-2?video=minbps&audio=maxbps
20 [[1688427369,"INFO","Automatically seeking to resume playback","video+c447r0acdmqhhhpb"],[1688427369,"INFO","Track selection changed - resending headers and continuing","video+c447r0acdmqhhhpb"],[1688427369,"FAIL","Opening file '/maxbps' failed: No such file or directory","video+c447r0acdmqhhhpb"],[1688427369,"INFO","Could not parse audio parameter maxbps. Skipping...","video+c447r0acdmqhhhpb"],[1688427372,"INFO","Switching UDP socket from IPv6 to IPv4","video+c447r0acdmqhhhpb"],[1688427377,"INFO","Switching UDP socket from IPv6 to IPv4","video+c447r0acdmqhhhpb"],[1688427382,"INFO","Switching UDP socket from IPv6 to IPv4","video+c447r0acdmqhhhpb"],[1688427387,"INFO","Switching UDP socket from IPv6 to IPv4","video+c447r0acdmqhhhpb"],[1688427389,"INFO","Received signal Terminated (15) from process 2550","video+c447r0acdmqhhhpb"],[1688427389,"INFO","Client handler shutting down, exit reason: signal Terminated (15) from process 2550","video+c447r0acdmqhhhpb"]]
21 {"active_seconds":24,"bytes":2388218,"mediatime":26693,"tracks":[0,1]}
22`)
23
24var pushEndPayloadInvalidLines = MistTriggerBody(`
25 2596
26`)
27
28var pushEndPayloadInvalidNumber = MistTriggerBody(`
29 nope
30 x
31 x
32 x
33 x
34 x
35`)
36
37var pushEndPayloadInvalidJSON = MistTriggerBody(`
38 1234
39 x
40 x
41 x
42 x
43 x
44`)
45
46var badPushEndCases = []MistTriggerBody{
47 pushEndPayloadInvalidLines,
48 pushEndPayloadInvalidNumber,
49 pushEndPayloadInvalidJSON,
50}
51
52func TestItCanParseValidPushEndPayload(t *testing.T) {
53 payload, err := ParsePushEndPayload(pushEndPayload)
54 require.NoError(t, err)
55 require.Equal(t, payload.StreamName, "video+c447r0acdmqhhhpb")
56 require.Equal(t, payload.Destination, "rtmp://rtmp.livepeer.com/live/stream-key?video=maxbps&audio=maxbps")
57 require.Equal(t, payload.ActualDestination, "rtmp://rtmp.livepeer.com/live/stream-key-2?video=minbps&audio=maxbps")
58 require.Equal(t, payload.PushStatus.ActiveSeconds, int64(24))
59 require.Equal(t, payload.PushStatus.Bytes, int64(2388218))
60 require.Equal(t, payload.PushStatus.MediaTime, int64(26693))
61 require.Equal(t, payload.PushStatus.Tracks, []int{0, 1})
62}
63
64func TestItCanRejectInvalidPushEndPayload(t *testing.T) {
65 for _, testCase := range badPushEndCases {
66 _, err := ParsePushEndPayload(testCase)
67 require.Error(t, err)
68 }
69}
70
71func doPushEndRequest(t *testing.T, payload MistTriggerBody, cb func(ctx context.Context, payload *PushEndPayload) error) *httptest.ResponseRecorder {
72 broker := NewTriggerBroker()
73 broker.OnPushEnd(cb)
74 d := NewMistCallbackHandlersCollection(&config.CLI{}, broker)
75 req, err := http.NewRequest("POST", "/trigger", bytes.NewBuffer([]byte(payload)))
76 require.NoError(t, err)
77 rr := httptest.NewRecorder()
78 d.TriggerPushEnd(context.Background(), rr, req, payload)
79 return rr
80}
81
82func TestItCanHandlePushEndRequests(t *testing.T) {
83 rr := doPushEndRequest(t, pushEndPayload, func(ctx context.Context, payload *PushEndPayload) error {
84 require.Equal(t, payload.StreamName, "video+c447r0acdmqhhhpb")
85 return nil
86 })
87 require.Equal(t, rr.Result().StatusCode, 200)
88 require.Equal(t, rr.Body.String(), "")
89}
90
91func TestItRejectsBadPushEndPayloads(t *testing.T) {
92 for _, testCase := range badPushEndCases {
93 rr := doPushEndRequest(t, testCase, func(ctx context.Context, prp *PushEndPayload) error {
94 return nil
95 })
96 require.Equal(t, rr.Result().StatusCode, 400)
97 }
98}
99
100func TestPushEndHandlesFailures(t *testing.T) {
101 rr := doPushEndRequest(t, pushEndPayload, func(ctx context.Context, prp *PushEndPayload) error {
102 return fmt.Errorf("something went wrong")
103 })
104 require.Equal(t, rr.Result().StatusCode, 500)
105}