mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-31 13:22:46 +00:00
Begin adding syncapi component tests (#2442)
* Add very basic syncapi tests * Add a way to inject jetstream messages * implement add_state_ids * bugfixes * Unbreak tests * Remove now un-needed API call * Linting
This commit is contained in:
parent
a443d1e5f3
commit
236b16aa6c
9 changed files with 337 additions and 11 deletions
|
@ -65,11 +65,13 @@ func NewRequestPool(
|
|||
userAPI userapi.SyncUserAPI, keyAPI keyapi.SyncKeyAPI,
|
||||
rsAPI roomserverAPI.SyncRoomserverAPI,
|
||||
streams *streams.Streams, notifier *notifier.Notifier,
|
||||
producer PresencePublisher,
|
||||
producer PresencePublisher, enableMetrics bool,
|
||||
) *RequestPool {
|
||||
prometheus.MustRegister(
|
||||
activeSyncRequests, waitingSyncRequests,
|
||||
)
|
||||
if enableMetrics {
|
||||
prometheus.MustRegister(
|
||||
activeSyncRequests, waitingSyncRequests,
|
||||
)
|
||||
}
|
||||
rp := &RequestPool{
|
||||
db: db,
|
||||
cfg: cfg,
|
||||
|
|
|
@ -65,7 +65,7 @@ func AddPublicRoutes(
|
|||
JetStream: js,
|
||||
}
|
||||
|
||||
requestPool := sync.NewRequestPool(syncDB, cfg, userAPI, keyAPI, rsAPI, streams, notifier, federationPresenceProducer)
|
||||
requestPool := sync.NewRequestPool(syncDB, cfg, userAPI, keyAPI, rsAPI, streams, notifier, federationPresenceProducer, base.EnableMetrics)
|
||||
|
||||
userAPIStreamEventProducer := &producers.UserAPIStreamEventProducer{
|
||||
JetStream: js,
|
||||
|
|
162
syncapi/syncapi_test.go
Normal file
162
syncapi/syncapi_test.go
Normal file
|
@ -0,0 +1,162 @@
|
|||
package syncapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
keyapi "github.com/matrix-org/dendrite/keyserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
rsapi "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||
"github.com/matrix-org/dendrite/syncapi/types"
|
||||
"github.com/matrix-org/dendrite/test"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/nats-io/nats.go"
|
||||
)
|
||||
|
||||
type syncRoomserverAPI struct {
|
||||
rsapi.SyncRoomserverAPI
|
||||
rooms []*test.Room
|
||||
}
|
||||
|
||||
func (s *syncRoomserverAPI) QueryLatestEventsAndState(ctx context.Context, req *rsapi.QueryLatestEventsAndStateRequest, res *rsapi.QueryLatestEventsAndStateResponse) error {
|
||||
var room *test.Room
|
||||
for _, r := range s.rooms {
|
||||
if r.ID == req.RoomID {
|
||||
room = r
|
||||
break
|
||||
}
|
||||
}
|
||||
if room == nil {
|
||||
res.RoomExists = false
|
||||
return nil
|
||||
}
|
||||
res.RoomVersion = room.Version
|
||||
return nil // TODO: return state
|
||||
}
|
||||
|
||||
type syncUserAPI struct {
|
||||
userapi.SyncUserAPI
|
||||
accounts []userapi.Device
|
||||
}
|
||||
|
||||
func (s *syncUserAPI) QueryAccessToken(ctx context.Context, req *userapi.QueryAccessTokenRequest, res *userapi.QueryAccessTokenResponse) error {
|
||||
for _, acc := range s.accounts {
|
||||
if acc.AccessToken == req.AccessToken {
|
||||
res.Device = &acc
|
||||
return nil
|
||||
}
|
||||
}
|
||||
res.Err = "unknown user"
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *syncUserAPI) PerformLastSeenUpdate(ctx context.Context, req *userapi.PerformLastSeenUpdateRequest, res *userapi.PerformLastSeenUpdateResponse) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type syncKeyAPI struct {
|
||||
keyapi.KeyInternalAPI
|
||||
}
|
||||
|
||||
func TestSyncAPI(t *testing.T) {
|
||||
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
|
||||
testSync(t, dbType)
|
||||
})
|
||||
}
|
||||
|
||||
func testSync(t *testing.T, dbType test.DBType) {
|
||||
user := test.NewUser()
|
||||
room := test.NewRoom(t, user)
|
||||
alice := userapi.Device{
|
||||
ID: "ALICEID",
|
||||
UserID: user.ID,
|
||||
AccessToken: "ALICE_BEARER_TOKEN",
|
||||
DisplayName: "Alice",
|
||||
AccountType: userapi.AccountTypeUser,
|
||||
}
|
||||
|
||||
base, close := test.CreateBaseDendrite(t, dbType)
|
||||
defer close()
|
||||
|
||||
jsctx, _ := base.NATS.Prepare(base.ProcessContext, &base.Cfg.Global.JetStream)
|
||||
defer jetstream.DeleteAllStreams(jsctx, &base.Cfg.Global.JetStream)
|
||||
var msgs []*nats.Msg
|
||||
for _, ev := range room.Events() {
|
||||
var addsStateIDs []string
|
||||
if ev.StateKey() != nil {
|
||||
addsStateIDs = append(addsStateIDs, ev.EventID())
|
||||
}
|
||||
msgs = append(msgs, test.NewOutputEventMsg(t, base, room.ID, api.OutputEvent{
|
||||
Type: rsapi.OutputTypeNewRoomEvent,
|
||||
NewRoomEvent: &rsapi.OutputNewRoomEvent{
|
||||
Event: ev,
|
||||
AddsStateEventIDs: addsStateIDs,
|
||||
},
|
||||
}))
|
||||
}
|
||||
AddPublicRoutes(base, &syncUserAPI{accounts: []userapi.Device{alice}}, &syncRoomserverAPI{rooms: []*test.Room{room}}, &syncKeyAPI{})
|
||||
test.MustPublishMsgs(t, jsctx, msgs...)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
req *http.Request
|
||||
wantCode int
|
||||
wantJoinedRooms []string
|
||||
}{
|
||||
{
|
||||
name: "missing access token",
|
||||
req: test.NewRequest(t, "GET", "/_matrix/client/v3/sync", test.WithQueryParams(map[string]string{
|
||||
"timeout": "0",
|
||||
})),
|
||||
wantCode: 401,
|
||||
},
|
||||
{
|
||||
name: "unknown access token",
|
||||
req: test.NewRequest(t, "GET", "/_matrix/client/v3/sync", test.WithQueryParams(map[string]string{
|
||||
"access_token": "foo",
|
||||
"timeout": "0",
|
||||
})),
|
||||
wantCode: 401,
|
||||
},
|
||||
{
|
||||
name: "valid access token",
|
||||
req: test.NewRequest(t, "GET", "/_matrix/client/v3/sync", test.WithQueryParams(map[string]string{
|
||||
"access_token": alice.AccessToken,
|
||||
"timeout": "0",
|
||||
})),
|
||||
wantCode: 200,
|
||||
wantJoinedRooms: []string{room.ID},
|
||||
},
|
||||
}
|
||||
// TODO: find a better way
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
for _, tc := range testCases {
|
||||
w := httptest.NewRecorder()
|
||||
base.PublicClientAPIMux.ServeHTTP(w, tc.req)
|
||||
if w.Code != tc.wantCode {
|
||||
t.Fatalf("%s: got HTTP %d want %d", tc.name, w.Code, tc.wantCode)
|
||||
}
|
||||
if tc.wantJoinedRooms != nil {
|
||||
var res types.Response
|
||||
if err := json.NewDecoder(w.Body).Decode(&res); err != nil {
|
||||
t.Fatalf("%s: failed to decode response body: %s", tc.name, err)
|
||||
}
|
||||
if len(res.Rooms.Join) != len(tc.wantJoinedRooms) {
|
||||
t.Errorf("%s: got %v joined rooms, want %v.\nResponse: %+v", tc.name, len(res.Rooms.Join), len(tc.wantJoinedRooms), res)
|
||||
}
|
||||
t.Logf("res: %+v", res.Rooms.Join[room.ID])
|
||||
|
||||
gotEventIDs := make([]string, len(res.Rooms.Join[room.ID].Timeline.Events))
|
||||
for i, ev := range res.Rooms.Join[room.ID].Timeline.Events {
|
||||
gotEventIDs[i] = ev.EventID
|
||||
}
|
||||
test.AssertEventIDsEqual(t, gotEventIDs, room.Events())
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue