mirror of
https://github.com/1f349/dendrite.git
synced 2024-11-08 18:16:59 +00:00
cbdc601f1b
Move create room logic over to roomserver.
238 lines
6.4 KiB
Go
238 lines
6.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/Masterminds/semver/v3"
|
|
"github.com/matrix-org/gomatrix"
|
|
"github.com/matrix-org/gomatrixserverlib"
|
|
"github.com/matrix-org/gomatrixserverlib/spec"
|
|
)
|
|
|
|
const userPassword = "this_is_a_long_password"
|
|
|
|
type user struct {
|
|
userID string
|
|
localpart string
|
|
client *gomatrix.Client
|
|
}
|
|
|
|
// runTests performs the following operations:
|
|
// - register alice and bob with branch name muxed into the localpart
|
|
// - create a DM room for the 2 users and exchange messages
|
|
// - create/join a public #global room and exchange messages
|
|
func runTests(baseURL string, v *semver.Version) error {
|
|
branchName, _ := versionToBranchAndBinary(v)
|
|
// register 2 users
|
|
users := []user{
|
|
{
|
|
localpart: "alice" + branchName,
|
|
},
|
|
{
|
|
localpart: "bob" + branchName,
|
|
},
|
|
}
|
|
for i, u := range users {
|
|
client, err := gomatrix.NewClient(baseURL, "", "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
resp, err := client.RegisterDummy(&gomatrix.ReqRegister{
|
|
Username: strings.ToLower(u.localpart),
|
|
Password: userPassword,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to register %s: %s", u.localpart, err)
|
|
}
|
|
client, err = gomatrix.NewClient(baseURL, resp.UserID, resp.AccessToken)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
users[i].client = client
|
|
users[i].userID = resp.UserID
|
|
}
|
|
|
|
// create DM room, join it and exchange messages
|
|
createRoomResp, err := users[0].client.CreateRoom(&gomatrix.ReqCreateRoom{
|
|
Preset: spec.PresetTrustedPrivateChat,
|
|
Invite: []string{users[1].userID},
|
|
IsDirect: true,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create DM room: %s", err)
|
|
}
|
|
dmRoomID := createRoomResp.RoomID
|
|
if _, err = users[1].client.JoinRoom(dmRoomID, "", nil); err != nil {
|
|
return fmt.Errorf("failed to join DM room: %s", err)
|
|
}
|
|
msgs := []struct {
|
|
client *gomatrix.Client
|
|
text string
|
|
}{
|
|
{
|
|
client: users[0].client, text: "1: " + branchName,
|
|
},
|
|
{
|
|
client: users[1].client, text: "2: " + branchName,
|
|
},
|
|
{
|
|
client: users[0].client, text: "3: " + branchName,
|
|
},
|
|
{
|
|
client: users[1].client, text: "4: " + branchName,
|
|
},
|
|
}
|
|
wantEventIDs := make(map[string]struct{}, 8)
|
|
for _, msg := range msgs {
|
|
var resp *gomatrix.RespSendEvent
|
|
resp, err = msg.client.SendText(dmRoomID, msg.text)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to send text in dm room: %s", err)
|
|
}
|
|
wantEventIDs[resp.EventID] = struct{}{}
|
|
}
|
|
|
|
// attempt to create/join the shared public room
|
|
publicRoomID := ""
|
|
createRoomResp, err = users[0].client.CreateRoom(&gomatrix.ReqCreateRoom{
|
|
RoomAliasName: "global",
|
|
Preset: spec.PresetPublicChat,
|
|
})
|
|
if err != nil { // this is okay and expected if the room already exists and the aliases clash
|
|
// try to join it
|
|
_, domain, err2 := gomatrixserverlib.SplitID('@', users[0].userID)
|
|
if err2 != nil {
|
|
return fmt.Errorf("failed to split user ID: %s, %s", users[0].userID, err2)
|
|
}
|
|
joinRoomResp, err2 := users[0].client.JoinRoom(fmt.Sprintf("#global:%s", domain), "", nil)
|
|
if err2 != nil {
|
|
return fmt.Errorf("alice failed to join public room: %s", err2)
|
|
}
|
|
publicRoomID = joinRoomResp.RoomID
|
|
} else {
|
|
publicRoomID = createRoomResp.RoomID
|
|
}
|
|
if _, err = users[1].client.JoinRoom(publicRoomID, "", nil); err != nil {
|
|
return fmt.Errorf("bob failed to join public room: %s", err)
|
|
}
|
|
// send messages
|
|
for _, msg := range msgs {
|
|
resp, err := msg.client.SendText(publicRoomID, "public "+msg.text)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to send text in public room: %s", err)
|
|
}
|
|
wantEventIDs[resp.EventID] = struct{}{}
|
|
}
|
|
|
|
// Sync until we have all expected messages
|
|
doneCh := make(chan struct{})
|
|
go func() {
|
|
syncClient := users[0].client
|
|
since := ""
|
|
for len(wantEventIDs) > 0 {
|
|
select {
|
|
case <-doneCh:
|
|
return
|
|
default:
|
|
}
|
|
syncResp, err := syncClient.SyncRequest(1000, since, "1", false, "")
|
|
if err != nil {
|
|
continue
|
|
}
|
|
for _, room := range syncResp.Rooms.Join {
|
|
for _, ev := range room.Timeline.Events {
|
|
if ev.Type != "m.room.message" {
|
|
continue
|
|
}
|
|
delete(wantEventIDs, ev.ID)
|
|
}
|
|
}
|
|
since = syncResp.NextBatch
|
|
}
|
|
close(doneCh)
|
|
}()
|
|
|
|
select {
|
|
case <-time.After(time.Second * 10):
|
|
close(doneCh)
|
|
return fmt.Errorf("failed to receive all expected messages: %+v", wantEventIDs)
|
|
case <-doneCh:
|
|
}
|
|
|
|
log.Printf("OK! rooms(public=%s, dm=%s) users(%s, %s)\n", publicRoomID, dmRoomID, users[0].userID, users[1].userID)
|
|
return nil
|
|
}
|
|
|
|
// verifyTestsRan checks that the HS has the right rooms/messages
|
|
func verifyTestsRan(baseURL string, versions []*semver.Version) error {
|
|
log.Println("Verifying tests....")
|
|
// check we can login as all users
|
|
var resp *gomatrix.RespLogin
|
|
for _, version := range versions {
|
|
client, err := gomatrix.NewClient(baseURL, "", "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
branchName, _ := versionToBranchAndBinary(version)
|
|
userLocalparts := []string{
|
|
"alice" + branchName,
|
|
"bob" + branchName,
|
|
}
|
|
for _, userLocalpart := range userLocalparts {
|
|
resp, err = client.Login(&gomatrix.ReqLogin{
|
|
Type: "m.login.password",
|
|
User: strings.ToLower(userLocalpart),
|
|
Password: userPassword,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to login as %s: %s", userLocalpart, err)
|
|
}
|
|
if resp.AccessToken == "" {
|
|
return fmt.Errorf("failed to login, bad response: %+v", resp)
|
|
}
|
|
}
|
|
}
|
|
log.Println(" accounts exist: OK")
|
|
client, err := gomatrix.NewClient(baseURL, resp.UserID, resp.AccessToken)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, domain, err := gomatrixserverlib.SplitID('@', client.UserID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
u := client.BuildURL("directory", "room", fmt.Sprintf("#global:%s", domain))
|
|
r := struct {
|
|
RoomID string `json:"room_id"`
|
|
}{}
|
|
err = client.MakeRequest("GET", u, nil, &r)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to /directory: %s", err)
|
|
}
|
|
if r.RoomID == "" {
|
|
return fmt.Errorf("/directory lookup returned no room ID")
|
|
}
|
|
log.Println(" public room exists: OK")
|
|
|
|
history, err := client.Messages(r.RoomID, client.Store.LoadNextBatch(client.UserID), "", 'b', 100)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get /messages: %s", err)
|
|
}
|
|
// we expect 4 messages per version
|
|
msgCount := 0
|
|
for _, ev := range history.Chunk {
|
|
if ev.Type == "m.room.message" {
|
|
msgCount += 1
|
|
}
|
|
}
|
|
wantMsgCount := len(versions) * 4
|
|
if msgCount != wantMsgCount {
|
|
return fmt.Errorf("got %d messages in global room, want %d", msgCount, wantMsgCount)
|
|
}
|
|
log.Println(" messages exist: OK")
|
|
return nil
|
|
}
|