From 4f098cbdf39790602bbd778ebc48d94dc5aedd32 Mon Sep 17 00:00:00 2001 From: Alessandro Ros Date: Wed, 21 Jun 2023 15:03:02 +0200 Subject: [PATCH] improve tests (#1965) --- internal/core/rtmp_server_test.go | 361 +++++++++++++----------------- internal/core/rtsp_server_test.go | 60 ++--- 2 files changed, 194 insertions(+), 227 deletions(-) diff --git a/internal/core/rtmp_server_test.go b/internal/core/rtmp_server_test.go index 76fa332b..65e3c151 100644 --- a/internal/core/rtmp_server_test.go +++ b/internal/core/rtmp_server_test.go @@ -29,7 +29,7 @@ func TestRTMPServerRunOnConnect(t *testing.T) { require.Equal(t, true, ok) defer p.Close() - u, err := url.Parse("rtmp://127.0.0.1:1935/mystream") + u, err := url.Parse("rtmp://127.0.0.1:1935/teststream") require.NoError(t, err) nconn, err := net.Dial("tcp", u.Host) @@ -47,220 +47,179 @@ func TestRTMPServerRunOnConnect(t *testing.T) { require.Equal(t, "aa\n", string(byts)) } -func TestRTMPServerPublishRead(t *testing.T) { - for _, ca := range []string{"plain", "tls"} { - t.Run(ca, func(t *testing.T) { - var port string - if ca == "plain" { - port = "1935" - - p, ok := newInstance("rtspDisable: yes\n" + - "hlsDisable: yes\n" + - "paths:\n" + - " all:\n") - require.Equal(t, true, ok) - defer p.Close() - } else { - port = "1936" - - serverCertFpath, err := writeTempFile(serverCert) - require.NoError(t, err) - defer os.Remove(serverCertFpath) - - serverKeyFpath, err := writeTempFile(serverKey) - require.NoError(t, err) - defer os.Remove(serverKeyFpath) - - p, ok := newInstance("rtspDisable: yes\n" + - "hlsDisable: yes\n" + - "webrtcDisable: yes\n" + - "rtmpEncryption: \"yes\"\n" + - "rtmpServerCert: " + serverCertFpath + "\n" + - "rtmpServerKey: " + serverKeyFpath + "\n" + - "paths:\n" + - " all:\n") - require.Equal(t, true, ok) - defer p.Close() - } - - u, err := url.Parse("rtmp://127.0.0.1:" + port + "/mystream") - require.NoError(t, err) - - nconn1, err := func() (net.Conn, error) { - if ca == "plain" { - return net.Dial("tcp", u.Host) - } - return tls.Dial("tcp", u.Host, &tls.Config{InsecureSkipVerify: true}) - }() - require.NoError(t, err) - defer nconn1.Close() - conn1 := rtmp.NewConn(nconn1) - - err = conn1.InitializeClient(u, true) - require.NoError(t, err) - - videoTrack := &formats.H264{ - PayloadTyp: 96, - SPS: []byte{ // 1920x1080 baseline - 0x67, 0x42, 0xc0, 0x28, 0xd9, 0x00, 0x78, 0x02, - 0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, - 0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60, 0xc9, 0x20, - }, - PPS: []byte{0x08, 0x06, 0x07, 0x08}, - PacketizationMode: 1, - } - - audioTrack := &formats.MPEG4Audio{ - PayloadTyp: 96, - Config: &mpeg4audio.Config{ - Type: 2, - SampleRate: 44100, - ChannelCount: 2, - }, - SizeLength: 13, - IndexLength: 3, - IndexDeltaLength: 3, - } - - err = conn1.WriteTracks(videoTrack, audioTrack) - require.NoError(t, err) - - time.Sleep(500 * time.Millisecond) - - nconn2, err := func() (net.Conn, error) { - if ca == "plain" { - return net.Dial("tcp", u.Host) - } - return tls.Dial("tcp", u.Host, &tls.Config{InsecureSkipVerify: true}) - }() - require.NoError(t, err) - defer nconn2.Close() - conn2 := rtmp.NewConn(nconn2) - - err = conn2.InitializeClient(u, false) - require.NoError(t, err) - - videoTrack1, audioTrack2, err := conn2.ReadTracks() - require.NoError(t, err) - require.Equal(t, videoTrack, videoTrack1) - require.Equal(t, audioTrack, audioTrack2) - - err = conn1.WriteMessage(&message.Video{ - ChunkStreamID: message.VideoChunkStreamID, - MessageStreamID: 0x1000000, - Codec: message.CodecH264, - IsKeyFrame: true, - Type: message.VideoTypeAU, - Payload: []byte{ - 0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04, // IDR 1 - 0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04, // IDR 2 - }, - }) - require.NoError(t, err) - - msg1, err := conn2.ReadMessage() - require.NoError(t, err) - require.Equal(t, &message.Video{ - ChunkStreamID: message.VideoChunkStreamID, - MessageStreamID: 0x1000000, - Codec: message.CodecH264, - IsKeyFrame: true, - Type: message.VideoTypeAU, - Payload: []byte{ - 0x00, 0x00, 0x00, 0x19, // SPS - 0x67, 0x42, 0xc0, 0x28, 0xd9, 0x00, 0x78, 0x02, - 0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, - 0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60, 0xc9, - 0x20, - 0x00, 0x00, 0x00, 0x04, 0x08, 0x06, 0x07, 0x08, // PPS - 0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04, // IDR 1 - 0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04, // IDR 2 - }, - }, msg1) - }) - } -} - -func TestRTMPServerAuth(t *testing.T) { - for _, ca := range []string{ - "internal", - "external", +func TestRTMPServer(t *testing.T) { + for _, encrypt := range []string{ + "plain", + "tls", } { - t.Run(ca, func(t *testing.T) { - var conf string - if ca == "internal" { - conf = "paths:\n" + - " all:\n" + - " publishUser: testpublisher\n" + - " publishPass: testpass\n" + - " publishIPs: [127.0.0.0/16]\n" + - " readUser: testreader\n" + - " readPass: testpass\n" + - " readIPs: [127.0.0.0/16]\n" - } else { - conf = "externalAuthenticationURL: http://localhost:9120/auth\n" + - "paths:\n" + - " all:\n" - } + for _, auth := range []string{ + "none", + "internal", + "external", + } { + t.Run("encrypt_"+encrypt+"_auth_"+auth, func(t *testing.T) { + var port string + var conf string - p, ok := newInstance(conf) - require.Equal(t, true, ok) - defer p.Close() + if encrypt == "plain" { + port = "1935" - var a *testHTTPAuthenticator - if ca == "external" { - a = newTestHTTPAuthenticator(t, "rtmp", "publish") - } + conf = "rtspDisable: yes\n" + + "hlsDisable: yes\n" + } else { + port = "1936" - u1, err := url.Parse("rtmp://127.0.0.1:1935/teststream?user=testpublisher&pass=testpass¶m=value") - require.NoError(t, err) + serverCertFpath, err := writeTempFile(serverCert) + require.NoError(t, err) + defer os.Remove(serverCertFpath) - nconn1, err := net.Dial("tcp", u1.Host) - require.NoError(t, err) - defer nconn1.Close() - conn1 := rtmp.NewConn(nconn1) + serverKeyFpath, err := writeTempFile(serverKey) + require.NoError(t, err) + defer os.Remove(serverKeyFpath) - err = conn1.InitializeClient(u1, true) - require.NoError(t, err) + conf = "rtspDisable: yes\n" + + "hlsDisable: yes\n" + + "webrtcDisable: yes\n" + + "rtmpEncryption: \"yes\"\n" + + "rtmpServerCert: " + serverCertFpath + "\n" + + "rtmpServerKey: " + serverKeyFpath + "\n" + } - videoTrack := &formats.H264{ - PayloadTyp: 96, - SPS: []byte{ - 0x67, 0x64, 0x00, 0x0c, 0xac, 0x3b, 0x50, 0xb0, - 0x4b, 0x42, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, - 0x00, 0x03, 0x00, 0x3d, 0x08, - }, - PPS: []byte{ - 0x68, 0xee, 0x3c, 0x80, - }, - PacketizationMode: 1, - } + switch auth { + case "none": + conf += "paths:\n" + + " all:\n" - err = conn1.WriteTracks(videoTrack, nil) - require.NoError(t, err) + case "internal": + conf += "paths:\n" + + " all:\n" + + " publishUser: testpublisher\n" + + " publishPass: testpass\n" + + " publishIPs: [127.0.0.0/16]\n" + + " readUser: testreader\n" + + " readPass: testpass\n" + + " readIPs: [127.0.0.0/16]\n" - time.Sleep(500 * time.Millisecond) + case "external": + conf += "externalAuthenticationURL: http://localhost:9120/auth\n" + + "paths:\n" + + " all:\n" + } - if ca == "external" { - a.close() - a = newTestHTTPAuthenticator(t, "rtmp", "read") - defer a.close() - } + p, ok := newInstance(conf) + require.Equal(t, true, ok) + defer p.Close() - u2, err := url.Parse("rtmp://127.0.0.1:1935/teststream?user=testreader&pass=testpass¶m=value") - require.NoError(t, err) + var a *testHTTPAuthenticator + if auth == "external" { + a = newTestHTTPAuthenticator(t, "rtmp", "publish") + } - nconn2, err := net.Dial("tcp", u2.Host) - require.NoError(t, err) - defer nconn2.Close() - conn2 := rtmp.NewConn(nconn2) + u1, err := url.Parse("rtmp://127.0.0.1:" + port + "/teststream?user=testpublisher&pass=testpass¶m=value") + require.NoError(t, err) - err = conn2.InitializeClient(u2, false) - require.NoError(t, err) + nconn1, err := func() (net.Conn, error) { + if encrypt == "plain" { + return net.Dial("tcp", u1.Host) + } + return tls.Dial("tcp", u1.Host, &tls.Config{InsecureSkipVerify: true}) + }() + require.NoError(t, err) + defer nconn1.Close() + conn1 := rtmp.NewConn(nconn1) - _, _, err = conn2.ReadTracks() - require.NoError(t, err) - }) + err = conn1.InitializeClient(u1, true) + require.NoError(t, err) + + videoTrack := &formats.H264{ + PayloadTyp: 96, + SPS: []byte{ // 1920x1080 baseline + 0x67, 0x42, 0xc0, 0x28, 0xd9, 0x00, 0x78, 0x02, + 0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60, 0xc9, 0x20, + }, + PPS: []byte{0x08, 0x06, 0x07, 0x08}, + PacketizationMode: 1, + } + + audioTrack := &formats.MPEG4Audio{ + PayloadTyp: 96, + Config: &mpeg4audio.Config{ + Type: 2, + SampleRate: 44100, + ChannelCount: 2, + }, + SizeLength: 13, + IndexLength: 3, + IndexDeltaLength: 3, + } + + err = conn1.WriteTracks(videoTrack, audioTrack) + require.NoError(t, err) + + time.Sleep(500 * time.Millisecond) + + if auth == "external" { + a.close() + a = newTestHTTPAuthenticator(t, "rtmp", "read") + defer a.close() + } + + u2, err := url.Parse("rtmp://127.0.0.1:" + port + "/teststream?user=testreader&pass=testpass¶m=value") + require.NoError(t, err) + + nconn2, err := func() (net.Conn, error) { + if encrypt == "plain" { + return net.Dial("tcp", u2.Host) + } + return tls.Dial("tcp", u2.Host, &tls.Config{InsecureSkipVerify: true}) + }() + require.NoError(t, err) + defer nconn2.Close() + conn2 := rtmp.NewConn(nconn2) + + err = conn2.InitializeClient(u2, false) + require.NoError(t, err) + + videoTrack1, audioTrack2, err := conn2.ReadTracks() + require.NoError(t, err) + require.Equal(t, videoTrack, videoTrack1) + require.Equal(t, audioTrack, audioTrack2) + + err = conn1.WriteMessage(&message.Video{ + ChunkStreamID: message.VideoChunkStreamID, + MessageStreamID: 0x1000000, + Codec: message.CodecH264, + IsKeyFrame: true, + Type: message.VideoTypeAU, + Payload: []byte{ + 0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04, // IDR 1 + 0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04, // IDR 2 + }, + }) + require.NoError(t, err) + + msg1, err := conn2.ReadMessage() + require.NoError(t, err) + require.Equal(t, &message.Video{ + ChunkStreamID: message.VideoChunkStreamID, + MessageStreamID: 0x1000000, + Codec: message.CodecH264, + IsKeyFrame: true, + Type: message.VideoTypeAU, + Payload: []byte{ + 0x00, 0x00, 0x00, 0x19, // SPS + 0x67, 0x42, 0xc0, 0x28, 0xd9, 0x00, 0x78, 0x02, + 0x27, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x00, 0x03, 0x00, 0xf0, 0x3c, 0x60, 0xc9, + 0x20, + 0x00, 0x00, 0x00, 0x04, 0x08, 0x06, 0x07, 0x08, // PPS + 0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04, // IDR 1 + 0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04, // IDR 2 + }, + }, msg1) + }) + } } } diff --git a/internal/core/rtsp_server_test.go b/internal/core/rtsp_server_test.go index 68bd3bd8..05366406 100644 --- a/internal/core/rtsp_server_test.go +++ b/internal/core/rtsp_server_test.go @@ -40,14 +40,21 @@ func TestRTSPServerRunOnConnect(t *testing.T) { require.Equal(t, "aa\n", string(byts)) } -func TestRTSPServerAuth(t *testing.T) { - for _, ca := range []string{ +func TestRTSPServer(t *testing.T) { + for _, auth := range []string{ + "none", "internal", "external", } { - t.Run(ca, func(t *testing.T) { + t.Run("auth_"+auth, func(t *testing.T) { var conf string - if ca == "internal" { + + switch auth { + case "none": + conf = "paths:\n" + + " all:\n" + + case "internal": conf = "rtmpDisable: yes\n" + "hlsDisable: yes\n" + "webrtcDisable: yes\n" + @@ -59,7 +66,8 @@ func TestRTSPServerAuth(t *testing.T) { " readUser: testreader\n" + " readPass: testpass\n" + " readIPs: [127.0.0.0/16]\n" - } else { + + case "external": conf = "externalAuthenticationURL: http://localhost:9120/auth\n" + "paths:\n" + " all:\n" @@ -70,7 +78,7 @@ func TestRTSPServerAuth(t *testing.T) { defer p.Close() var a *testHTTPAuthenticator - if ca == "external" { + if auth == "external" { a = newTestHTTPAuthenticator(t, "rtsp", "publish") } @@ -84,7 +92,7 @@ func TestRTSPServerAuth(t *testing.T) { require.NoError(t, err) defer source.Close() - if ca == "external" { + if auth == "external" { a.close() a = newTestHTTPAuthenticator(t, "rtsp", "read") defer a.close() @@ -109,29 +117,29 @@ func TestRTSPServerAuth(t *testing.T) { require.NoError(t, err) }) } +} - t.Run("hashed", func(t *testing.T) { - p, ok := newInstance( - "rtmpDisable: yes\n" + - "hlsDisable: yes\n" + - "webrtcDisable: yes\n" + - "paths:\n" + - " all:\n" + - " publishUser: sha256:rl3rgi4NcZkpAEcacZnQ2VuOfJ0FxAqCRaKB/SwdZoQ=\n" + - " publishPass: sha256:E9JJ8stBJ7QM+nV4ZoUCeHk/gU3tPFh/5YieiJp6n2w=\n") - require.Equal(t, true, ok) - defer p.Close() +func TestRTSPServerAuthHashed(t *testing.T) { + p, ok := newInstance( + "rtmpDisable: yes\n" + + "hlsDisable: yes\n" + + "webrtcDisable: yes\n" + + "paths:\n" + + " all:\n" + + " publishUser: sha256:rl3rgi4NcZkpAEcacZnQ2VuOfJ0FxAqCRaKB/SwdZoQ=\n" + + " publishPass: sha256:E9JJ8stBJ7QM+nV4ZoUCeHk/gU3tPFh/5YieiJp6n2w=\n") + require.Equal(t, true, ok) + defer p.Close() - medi := testMediaH264 + medi := testMediaH264 - source := gortsplib.Client{} + source := gortsplib.Client{} - err := source.StartRecording( - "rtsp://testuser:testpass@127.0.0.1:8554/test/stream", - media.Medias{medi}) - require.NoError(t, err) - defer source.Close() - }) + err := source.StartRecording( + "rtsp://testuser:testpass@127.0.0.1:8554/test/stream", + media.Medias{medi}) + require.NoError(t, err) + defer source.Close() } func TestRTSPServerAuthFail(t *testing.T) {