From cde3ee53a9aac32f0ea108879018dc9f640c7e36 Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Thu, 29 Jan 2026 16:31:03 +0100 Subject: [PATCH] Add mock ServerHub implementation. --- grpc/test/server.go | 49 +++++++++++++++++++++++++ grpc/test/server_test.go | 79 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/grpc/test/server.go b/grpc/test/server.go index fd1ba21..ef67170 100644 --- a/grpc/test/server.go +++ b/grpc/test/server.go @@ -22,7 +22,10 @@ package test import ( + "context" + "errors" "net" + "net/url" "strconv" "testing" @@ -30,9 +33,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/strukturag/nextcloud-spreed-signaling/api" "github.com/strukturag/nextcloud-spreed-signaling/grpc" "github.com/strukturag/nextcloud-spreed-signaling/log" logtest "github.com/strukturag/nextcloud-spreed-signaling/log/test" + "github.com/strukturag/nextcloud-spreed-signaling/sfu" + "github.com/strukturag/nextcloud-spreed-signaling/talk" "github.com/strukturag/nextcloud-spreed-signaling/test" ) @@ -71,3 +77,46 @@ func NewServerForTest(t *testing.T) (server *grpc.Server, addr string) { config := goconf.NewConfigFile() return NewServerForTestWithConfig(t, config) } + +type MockHub struct { +} + +func (h *MockHub) GetSessionIdByResumeId(resumeId api.PrivateSessionId) api.PublicSessionId { + return "" +} + +func (h *MockHub) GetSessionIdByRoomSessionId(roomSessionId api.RoomSessionId) (api.PublicSessionId, error) { + return "", errors.New("not implemented") +} + +func (h *MockHub) IsSessionIdInCall(sessionId api.PublicSessionId, roomId string, backendUrl string) (bool, bool) { + return false, false +} + +func (h *MockHub) DisconnectSessionByRoomSessionId(sessionId api.PublicSessionId, roomSessionId api.RoomSessionId, reason string) { +} + +func (h *MockHub) GetBackend(u *url.URL) *talk.Backend { + return nil +} + +func (h *MockHub) GetInternalSessions(roomId string, backend *talk.Backend) ([]*grpc.InternalSessionData, []*grpc.VirtualSessionData, bool) { + return nil, nil, false +} + +func (h *MockHub) GetTransientEntries(roomId string, backend *talk.Backend) (api.TransientDataEntries, bool) { + return nil, false +} + +func (h *MockHub) GetPublisherIdForSessionId(ctx context.Context, sessionId api.PublicSessionId, streamType sfu.StreamType) (*grpc.GetPublisherIdReply, error) { + return nil, errors.New("not implemented") +} + +func (h *MockHub) ProxySession(request grpc.RpcSessions_ProxySessionServer) error { + return errors.New("not implemented") +} + +var ( + // Compile-time check that MockHub implements the interface. + _ grpc.ServerHub = &MockHub{} +) diff --git a/grpc/test/server_test.go b/grpc/test/server_test.go index bd5e871..323334e 100644 --- a/grpc/test/server_test.go +++ b/grpc/test/server_test.go @@ -22,12 +22,43 @@ package test import ( + "errors" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/strukturag/nextcloud-spreed-signaling/geoip" + "github.com/strukturag/nextcloud-spreed-signaling/grpc" + "github.com/strukturag/nextcloud-spreed-signaling/sfu" + "github.com/strukturag/nextcloud-spreed-signaling/talk" ) +type emptyReceiver struct { +} + +func (r *emptyReceiver) RemoteAddr() string { + return "127.0.0.1" +} + +func (r *emptyReceiver) Country() geoip.Country { + return "DE" +} + +func (r *emptyReceiver) UserAgent() string { + return "testing" +} + +func (r *emptyReceiver) OnProxyMessage(message *grpc.ServerSessionMessage) error { + return errors.New("not implemented") +} + +func (r *emptyReceiver) OnProxyClose(err error) { + // Ignore +} + func TestServer(t *testing.T) { t.Parallel() @@ -37,15 +68,63 @@ func TestServer(t *testing.T) { serverId := "the-test-server-id" server, addr := NewServerForTest(t) server.SetServerId(serverId) + hub := &MockHub{} + server.SetHub(hub) clients, _ := NewClientsForTest(t, addr, nil) require.NoError(clients.WaitForInitialized(t.Context())) + backend := talk.NewCompatBackend(nil) + for _, client := range clients.GetClients() { if id, version, err := client.GetServerId(t.Context()); assert.NoError(err) { assert.Equal(serverId, id) assert.NotEmpty(version) } + + reply, err := client.LookupResumeId(t.Context(), "resume-id") + assert.ErrorIs(err, grpc.ErrNoSuchResumeId) + assert.Nil(reply) + + id, err := client.LookupSessionId(t.Context(), "session-id", "") + if s, ok := status.FromError(err); assert.True(ok) { + assert.Equal(codes.Unknown, s.Code()) + assert.Equal("not implemented", s.Message()) + } + assert.Empty(id) + + if incall, err := client.IsSessionInCall(t.Context(), "session-id", "room-id", ""); assert.NoError(err) { + assert.False(incall) + } + + if internal, virtual, err := client.GetInternalSessions(t.Context(), "room-id", nil); assert.NoError(err) { + assert.Empty(internal) + assert.Empty(virtual) + } + + publisherId, proxyUrl, ip, connToken, publisherToken, err := client.GetPublisherId(t.Context(), "session-id", sfu.StreamTypeVideo) + if s, ok := status.FromError(err); assert.True(ok) { + assert.Equal(codes.Unknown, s.Code()) + assert.Equal("not implemented", s.Message()) + } + assert.Empty(publisherId) + assert.Empty(proxyUrl) + assert.Empty(ip) + assert.Empty(connToken) + assert.Empty(publisherToken) + + if count, err := client.GetSessionCount(t.Context(), ""); assert.NoError(err) { + assert.EqualValues(0, count) + } + + if data, err := client.GetTransientData(t.Context(), "room-id", backend); assert.NoError(err) { + assert.Empty(data) + } + + receiver := &emptyReceiver{} + proxy, err := client.ProxySession(t.Context(), "session-id", receiver) + assert.NoError(err) + assert.NotNil(proxy) } }