package api //nolint:revive import ( "fmt" "net/http" "testing" "time" "github.com/bluenviron/mediamtx/internal/conf" "github.com/bluenviron/mediamtx/internal/defs" "github.com/bluenviron/mediamtx/internal/servers/srt" "github.com/bluenviron/mediamtx/internal/test" "github.com/google/uuid" "github.com/stretchr/testify/require" ) type testSRTServer struct { conns map[uuid.UUID]*defs.APISRTConn } func (s *testSRTServer) APIConnsList() (*defs.APISRTConnList, error) { items := make([]*defs.APISRTConn, 0, len(s.conns)) for _, conn := range s.conns { items = append(items, conn) } return &defs.APISRTConnList{Items: items}, nil } func (s *testSRTServer) APIConnsGet(id uuid.UUID) (*defs.APISRTConn, error) { conn, ok := s.conns[id] if !ok { return nil, srt.ErrConnNotFound } return conn, nil } func (s *testSRTServer) APIConnsKick(id uuid.UUID) error { _, ok := s.conns[id] if !ok { return srt.ErrConnNotFound } return nil } func TestSRTConnsList(t *testing.T) { id1 := uuid.New() id2 := uuid.New() now := time.Now() srtServer := &testSRTServer{ conns: map[uuid.UUID]*defs.APISRTConn{ id1: { ID: id1, Created: now, RemoteAddr: "192.168.1.1:5000", State: defs.APISRTConnStatePublish, Path: "stream1", Query: "token=abc", PacketsSent: 1000, PacketsReceived: 2000, PacketsSentUnique: 950, PacketsReceivedUnique: 1950, BytesReceived: 100000, BytesSent: 200000, MsRTT: 10.5, MbpsSendRate: 5.2, MbpsReceiveRate: 4.8, }, id2: { ID: id2, Created: now.Add(time.Minute), RemoteAddr: "192.168.1.2:5001", State: defs.APISRTConnStateRead, Path: "stream2", Query: "", PacketsSent: 500, PacketsReceived: 1500, PacketsSentUnique: 480, PacketsReceivedUnique: 1470, BytesReceived: 50000, BytesSent: 150000, MsRTT: 15.2, MbpsSendRate: 3.5, MbpsReceiveRate: 3.2, }, }, } api := API{ Address: "localhost:9997", ReadTimeout: conf.Duration(10 * time.Second), WriteTimeout: conf.Duration(10 * time.Second), AuthManager: test.NilAuthManager, SRTServer: srtServer, Parent: &testParent{}, } err := api.Initialize() require.NoError(t, err) defer api.Close() tr := &http.Transport{} defer tr.CloseIdleConnections() hc := &http.Client{Transport: tr} var out defs.APISRTConnList httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/srtconns/list", nil, &out) require.Equal(t, 2, out.ItemCount) require.Equal(t, 1, out.PageCount) require.Len(t, out.Items, 2) } func TestSRTConnsGet(t *testing.T) { id := uuid.New() now := time.Now() srtServer := &testSRTServer{ conns: map[uuid.UUID]*defs.APISRTConn{ id: { ID: id, Created: now, RemoteAddr: "192.168.1.100:5000", State: defs.APISRTConnStatePublish, Path: "mystream", Query: "key=value", PacketsSent: 10000, PacketsReceived: 20000, PacketsSentUnique: 9900, PacketsReceivedUnique: 19800, PacketsSendLoss: 50, PacketsReceivedLoss: 100, PacketsRetrans: 60, PacketsReceivedRetrans: 80, PacketsSentACK: 500, PacketsReceivedACK: 600, PacketsSentNAK: 10, PacketsReceivedNAK: 15, PacketsSentKM: 2, PacketsReceivedKM: 2, UsSndDuration: 1000000, PacketsReceivedBelated: 5, PacketsSendDrop: 3, PacketsReceivedDrop: 4, PacketsReceivedUndecrypt: 0, BytesReceived: 999999, BytesSent: 888888, BytesSentUnique: 880000, BytesReceivedUnique: 990000, BytesReceivedLoss: 5000, BytesRetrans: 3000, BytesReceivedRetrans: 4000, BytesReceivedBelated: 200, BytesSendDrop: 150, BytesReceivedDrop: 180, BytesReceivedUndecrypt: 0, UsPacketsSendPeriod: 1000.5, PacketsFlowWindow: 8192, PacketsFlightSize: 256, MsRTT: 25.5, MbpsSendRate: 10.5, MbpsReceiveRate: 9.8, MbpsLinkCapacity: 100.0, BytesAvailSendBuf: 65536, BytesAvailReceiveBuf: 131072, MbpsMaxBW: 50.0, ByteMSS: 1500, PacketsSendBuf: 128, BytesSendBuf: 192000, MsSendBuf: 1000, MsSendTsbPdDelay: 120, PacketsReceiveBuf: 256, BytesReceiveBuf: 384000, MsReceiveBuf: 2000, MsReceiveTsbPdDelay: 120, PacketsReorderTolerance: 10, PacketsReceivedAvgBelatedTime: 50, PacketsSendLossRate: 0.5, PacketsReceivedLossRate: 0.6, }, }, } api := API{ Address: "localhost:9997", ReadTimeout: conf.Duration(10 * time.Second), WriteTimeout: conf.Duration(10 * time.Second), AuthManager: test.NilAuthManager, SRTServer: srtServer, Parent: &testParent{}, } err := api.Initialize() require.NoError(t, err) defer api.Close() tr := &http.Transport{} defer tr.CloseIdleConnections() hc := &http.Client{Transport: tr} var out defs.APISRTConn httpRequest(t, hc, http.MethodGet, fmt.Sprintf("http://localhost:9997/v3/srtconns/get/%s", id), nil, &out) require.Equal(t, id, out.ID) require.Equal(t, "192.168.1.100:5000", out.RemoteAddr) require.Equal(t, defs.APISRTConnStatePublish, out.State) require.Equal(t, "mystream", out.Path) require.Equal(t, uint64(999999), out.BytesReceived) require.Equal(t, uint64(888888), out.BytesSent) require.Equal(t, 25.5, out.MsRTT) require.Equal(t, 10.5, out.MbpsSendRate) require.Equal(t, 9.8, out.MbpsReceiveRate) } func TestSRTConnsKick(t *testing.T) { id := uuid.New() now := time.Now() srtServer := &testSRTServer{ conns: map[uuid.UUID]*defs.APISRTConn{ id: { ID: id, Created: now, RemoteAddr: "192.168.1.100:5000", State: defs.APISRTConnStatePublish, Path: "mystream", Query: "", PacketsSent: 1000, PacketsReceived: 2000, PacketsSentUnique: 950, PacketsReceivedUnique: 1950, BytesReceived: 100000, BytesSent: 200000, MsRTT: 10.5, MbpsSendRate: 5.2, MbpsReceiveRate: 4.8, }, }, } api := API{ Address: "localhost:9997", ReadTimeout: conf.Duration(10 * time.Second), WriteTimeout: conf.Duration(10 * time.Second), AuthManager: test.NilAuthManager, SRTServer: srtServer, Parent: &testParent{}, } err := api.Initialize() require.NoError(t, err) defer api.Close() tr := &http.Transport{} defer tr.CloseIdleConnections() hc := &http.Client{Transport: tr} httpRequest(t, hc, http.MethodPost, fmt.Sprintf("http://localhost:9997/v3/srtconns/kick/%s", id), nil, nil) }