Files
mediamtx/internal/api/api_paths_test.go
T
98ab3009ea support forwarding streams natively (#5558)
It is now possible to define forward destinations for each path configuration. For each destination, the server will create a client that will forward the stream to the intended destination. Supported protocols are RTSP, RTMP, SRT. API and metrics have also been improved to allow monitoring the new forwarding system.

---------

Co-authored-by: aler9 <46489434+aler9@users.noreply.github.com>
2026-08-04 21:57:15 +02:00

160 lines
4.6 KiB
Go

package api //nolint:revive
import (
"net/http"
"testing"
"time"
"github.com/google/uuid"
"github.com/bluenviron/mediamtx/internal/conf"
"github.com/bluenviron/mediamtx/internal/defs"
"github.com/bluenviron/mediamtx/internal/formatlabel"
"github.com/bluenviron/mediamtx/internal/test"
"github.com/stretchr/testify/require"
)
type testPathManager struct {
paths map[string]*defs.APIPath
}
func (m *testPathManager) APIPathsList() (*defs.APIPathList, error) {
items := make([]defs.APIPath, 0, len(m.paths))
for _, path := range m.paths {
items = append(items, *path)
}
return &defs.APIPathList{Items: items}, nil
}
func (m *testPathManager) APIPathsGet(name string) (*defs.APIPath, error) {
path, ok := m.paths[name]
if !ok {
return nil, conf.ErrPathNotFound
}
return path, nil
}
func (*testPathManager) APIForwardDestList(string) (*defs.APIForwardDestList, error) {
return &defs.APIForwardDestList{}, nil
}
func (*testPathManager) APIForwardDestGet(string, uuid.UUID) (*defs.APIForwardDest, error) {
return nil, conf.ErrPathNotFound
}
func TestPathsList(t *testing.T) {
now := time.Now()
pathManager := &testPathManager{
paths: map[string]*defs.APIPath{
"test1": {
Name: "test1",
ConfName: "test1",
Source: &defs.APIPathSource{Type: defs.APIPathSourceTypeRTSPSession, ID: "pub1"},
Ready: true,
ReadyTime: &now,
Tracks: []defs.APIPathTrackCodec{formatlabel.H264, formatlabel.Opus},
InboundBytes: 1000,
OutboundBytes: 2000,
InboundFramesInError: 3,
BytesReceived: 1000,
BytesSent: 2000,
Readers: []defs.APIPathReader{
{Type: defs.APIPathReaderTypeRTSPSession, ID: "reader1"},
},
},
"test2": {
Name: "test2",
ConfName: "test2",
Ready: false,
Tracks: []defs.APIPathTrackCodec{},
InboundBytes: 500,
OutboundBytes: 100,
InboundFramesInError: 1,
BytesReceived: 500,
BytesSent: 100,
Readers: []defs.APIPathReader{},
},
},
}
api := API{
Address: "localhost:9997",
ReadTimeout: conf.Duration(10 * time.Second),
WriteTimeout: conf.Duration(10 * time.Second),
AuthManager: test.NilAuthManager,
PathManager: pathManager,
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.APIPathList
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/paths/list", nil, &out)
require.Equal(t, 2, out.ItemCount)
require.Equal(t, 1, out.PageCount)
require.Len(t, out.Items, 2)
}
func TestPathsGet(t *testing.T) {
now := time.Now()
pathManager := &testPathManager{
paths: map[string]*defs.APIPath{
"mystream": {
Name: "mystream",
ConfName: "mystream",
Source: &defs.APIPathSource{Type: defs.APIPathSourceTypeRTSPSession, ID: "session123"},
Ready: true,
ReadyTime: &now,
Tracks: []defs.APIPathTrackCodec{formatlabel.H264, formatlabel.Opus},
InboundBytes: 123456,
OutboundBytes: 789012,
InboundFramesInError: 12,
BytesReceived: 123456,
BytesSent: 789012,
Readers: []defs.APIPathReader{
{Type: defs.APIPathReaderTypeHLSSession, ID: "session6123"},
{Type: defs.APIPathReaderTypeWebRTCSession, ID: "session456"},
},
},
},
}
api := API{
Address: "localhost:9997",
ReadTimeout: conf.Duration(10 * time.Second),
WriteTimeout: conf.Duration(10 * time.Second),
AuthManager: test.NilAuthManager,
PathManager: pathManager,
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.APIPath
httpRequest(t, hc, http.MethodGet, "http://localhost:9997/v3/paths/get/mystream", nil, &out)
require.Equal(t, "mystream", out.Name)
require.Equal(t, "mystream", out.ConfName)
require.True(t, out.Ready)
require.NotNil(t, out.Source)
require.Equal(t, defs.APIPathSourceTypeRTSPSession, out.Source.Type)
require.Len(t, out.Tracks, 2)
require.Len(t, out.Readers, 2)
require.Equal(t, uint64(123456), out.InboundBytes)
require.Equal(t, uint64(789012), out.OutboundBytes)
require.Equal(t, uint64(12), out.InboundFramesInError)
require.Equal(t, uint64(123456), out.BytesReceived)
require.Equal(t, uint64(789012), out.BytesSent)
}