mirror of
https://github.com/bluenviron/mediamtx.git
synced 2025-12-20 02:00:05 -08:00
Add keepalive API endpoints that allow streams to be kept active
without real viewers. Keepalives act as synthetic readers that
trigger on-demand publishers and prevent streams from closing when
all real viewers disconnect.
Features:
- POST /v3/paths/keepalive/add/{name} - create keepalive for path
- DELETE /v3/paths/keepalive/remove/{id} - remove keepalive by ID
- GET /v3/paths/keepalive/list - list all active keepalives
- GET /v3/paths/keepalive/get/{id} - get keepalive details
Implementation details:
- Keepalives implement defs.Reader interface
- Full authentication and authorization support
- Ownership tracking - only creator can remove keepalive
- Automatic cleanup when paths are removed
- UUID-based identification
- Asynchronous stream initialization to prevent deadlocks
88 lines
2.1 KiB
Go
88 lines
2.1 KiB
Go
package core
|
|
|
|
import (
|
|
"net"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/bluenviron/mediamtx/internal/defs"
|
|
"github.com/bluenviron/mediamtx/internal/logger"
|
|
)
|
|
|
|
func TestKeepaliveNew(t *testing.T) {
|
|
pathName := "test/path"
|
|
user := "testuser"
|
|
ip := net.ParseIP("192.168.1.1")
|
|
|
|
ka := newKeepalive(pathName, user, ip)
|
|
|
|
require.NotEqual(t, uuid.Nil, ka.id)
|
|
require.Equal(t, pathName, ka.pathName)
|
|
require.Equal(t, user, ka.creatorUser)
|
|
require.Equal(t, ip, ka.creatorIP)
|
|
require.WithinDuration(t, time.Now(), ka.created, 1*time.Second)
|
|
}
|
|
|
|
func TestKeepaliveAPIReaderDescribe(t *testing.T) {
|
|
ka := newKeepalive("test/path", "user", net.ParseIP("192.168.1.1"))
|
|
|
|
desc := ka.APIReaderDescribe()
|
|
|
|
require.Equal(t, "keepalive", desc.Type)
|
|
require.Equal(t, ka.id.String(), desc.ID)
|
|
}
|
|
|
|
func TestKeepaliveClose(t *testing.T) {
|
|
ka := newKeepalive("test/path", "user", net.ParseIP("192.168.1.1"))
|
|
|
|
// test that Close doesn't panic when onClose is nil
|
|
require.NotPanics(t, func() {
|
|
ka.Close()
|
|
})
|
|
|
|
// test that onClose is called
|
|
called := false
|
|
ka.onClose = func() {
|
|
called = true
|
|
}
|
|
ka.Close()
|
|
require.True(t, called)
|
|
}
|
|
|
|
func TestKeepaliveLog(t *testing.T) {
|
|
ka := newKeepalive("test/path", "user", net.ParseIP("192.168.1.1"))
|
|
|
|
// test that Log doesn't panic
|
|
require.NotPanics(t, func() {
|
|
ka.Log(logger.Info, "test message %s", "arg")
|
|
})
|
|
}
|
|
|
|
func TestKeepaliveAPIDescribe(t *testing.T) {
|
|
pathName := "test/path"
|
|
user := "testuser"
|
|
ip := net.ParseIP("192.168.1.1")
|
|
|
|
ka := newKeepalive(pathName, user, ip)
|
|
|
|
apiDesc := ka.apiDescribe()
|
|
|
|
require.Equal(t, ka.id, apiDesc.ID)
|
|
require.Equal(t, pathName, apiDesc.Path)
|
|
require.Equal(t, user, apiDesc.CreatorUser)
|
|
require.Equal(t, ip.String(), apiDesc.CreatorIP)
|
|
require.WithinDuration(t, ka.created, apiDesc.Created, 1*time.Millisecond)
|
|
}
|
|
|
|
func TestKeepaliveImplementsReader(t *testing.T) {
|
|
ka := newKeepalive("test/path", "user", net.ParseIP("192.168.1.1"))
|
|
|
|
// test that keepalive implements defs.Reader interface
|
|
var _ defs.Reader = ka
|
|
|
|
// test that keepalive implements logger.Writer interface
|
|
var _ logger.Writer = ka
|
|
}
|