webrtc: add 409 single-publisher enforcement test and SetMetrics/PublisherCount tests (issues #22, #26)
This commit is contained in:
parent
498aaefa0f
commit
278ebaa087
1 changed files with 66 additions and 1 deletions
|
|
@ -7,6 +7,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
corewebrtc "github.com/datarhei/core/v16/core/webrtc"
|
||||
)
|
||||
|
||||
// TestWHIPHandler_Publish_404WhenNoIngest verifies POST /whip/:id returns
|
||||
|
|
@ -81,6 +83,52 @@ func TestWHIPHandler_Publish_400OnNonSDP(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestWHIPHandler_Publish_409OnSecondPublisher verifies that attempting to
|
||||
// publish a second time on the same stream while a publisher is already
|
||||
// active returns 409 Conflict, not 201, and does not increment the counter.
|
||||
func TestWHIPHandler_Publish_409OnSecondPublisher(t *testing.T) {
|
||||
sub := newTestSubsystem(t)
|
||||
sub.mu.Lock()
|
||||
sub.whipIngests["probe"] = &ingestStream{id: "probe", videoPort: 5104, audioPort: 5105}
|
||||
sub.mu.Unlock()
|
||||
|
||||
h := NewWHIPHandler(sub, 0)
|
||||
|
||||
// Inject a fake active publisher directly into the handler's index.
|
||||
// We use a nil *IngestPeer because the 409 check only tests map length
|
||||
// and never dereferences the peer pointer.
|
||||
h.mu.Lock()
|
||||
h.ingestByStream["probe"] = map[string]*corewebrtc.IngestPeer{
|
||||
"existing-rid": nil,
|
||||
}
|
||||
h.ingestStream["existing-rid"] = "probe"
|
||||
h.mu.Unlock()
|
||||
|
||||
// Verify initial count is 0 (the fake was injected, not published).
|
||||
if c := h.PublisherCount(); c != 0 {
|
||||
t.Fatalf("expected initial count 0, got %d", c)
|
||||
}
|
||||
|
||||
e := echo.New()
|
||||
req := httptest.NewRequest(http.MethodPost, "/whip/probe",
|
||||
strings.NewReader("v=0\r\nm=video 0 RTP/AVP 96\r\n"))
|
||||
rec := httptest.NewRecorder()
|
||||
ctx := e.NewContext(req, rec)
|
||||
ctx.SetParamNames("id")
|
||||
ctx.SetParamValues("probe")
|
||||
|
||||
if err := h.Publish(ctx); err != nil {
|
||||
t.Fatalf("Publish returned error: %v", err)
|
||||
}
|
||||
if rec.Code != http.StatusConflict {
|
||||
t.Fatalf("expected 409, got %d: %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
// Count must not have incremented on the rejected request.
|
||||
if c := h.PublisherCount(); c != 0 {
|
||||
t.Errorf("expected count still 0 after 409, got %d", c)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWHIPHandler_Unpublish_204WhenUnknown verifies DELETE returns 204
|
||||
// even for unknown resource ids — idempotent per the WHIP spec.
|
||||
func TestWHIPHandler_Unpublish_204WhenUnknown(t *testing.T) {
|
||||
|
|
@ -192,9 +240,26 @@ func TestWHIPHandler_Preflight_ExposesLinkHeader(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestWHIPHandler_SetMetrics_DoesNotPanic verifies that SetMetrics accepts
|
||||
// a nil argument without panicking (nil-safe guard for wiring code).
|
||||
func TestWHIPHandler_SetMetrics_DoesNotPanic(t *testing.T) {
|
||||
h := NewWHIPHandler(newTestSubsystem(t), 0)
|
||||
// nil metrics is explicitly allowed — recordRequest guards on h.met == nil.
|
||||
h.SetMetrics(nil)
|
||||
}
|
||||
|
||||
// TestWHIPHandler_PublisherCount_ZeroOnEmpty verifies that a freshly
|
||||
// constructed handler reports 0 active publishers.
|
||||
func TestWHIPHandler_PublisherCount_ZeroOnEmpty(t *testing.T) {
|
||||
h := NewWHIPHandler(newTestSubsystem(t), 0)
|
||||
if n := h.PublisherCount(); n != 0 {
|
||||
t.Errorf("expected 0 publishers on empty handler, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWHIPHandler_Publish_CORSHeadersPresent verifies that every Publish
|
||||
// response (even a 404) carries the CORS headers required for cross-origin
|
||||
// browser-based publishers (e.g., a browser-based OBS alternative).
|
||||
// browser-based publishers.
|
||||
func TestWHIPHandler_Publish_CORSHeadersPresent(t *testing.T) {
|
||||
h := NewWHIPHandler(newTestSubsystem(t), 0)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue