mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-28 17:23:09 -06:00
Finish dendrite upgrade checks
This commit is contained in:
parent
f3d94843b4
commit
8dec89e207
|
|
@ -273,7 +273,7 @@ func buildDendriteImages(httpClient *http.Client, dockerClient *client.Client, b
|
||||||
|
|
||||||
func runImage(dockerClient *client.Client, volumeName, version, imageID string) (csAPIURL, containerID string, err error) {
|
func runImage(dockerClient *client.Client, volumeName, version, imageID string) (csAPIURL, containerID string, err error) {
|
||||||
log.Printf("%s: running image %s\n", version, imageID)
|
log.Printf("%s: running image %s\n", version, imageID)
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
body, err := dockerClient.ContainerCreate(ctx, &container.Config{
|
body, err := dockerClient.ContainerCreate(ctx, &container.Config{
|
||||||
Image: imageID,
|
Image: imageID,
|
||||||
|
|
@ -284,7 +284,7 @@ func runImage(dockerClient *client.Client, volumeName, version, imageID string)
|
||||||
{
|
{
|
||||||
Type: mount.TypeVolume,
|
Type: mount.TypeVolume,
|
||||||
Source: volumeName,
|
Source: volumeName,
|
||||||
Target: "/usr/local/pgsql/data",
|
Target: "/var/lib/postgresql/9.6/main",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, nil, nil, "dendrite_upgrade_test_"+version)
|
}, nil, nil, "dendrite_upgrade_test_"+version)
|
||||||
|
|
@ -346,6 +346,16 @@ func loadAndRunTests(dockerClient *client.Client, volumeName, v string, branchTo
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func verifyTests(dockerClient *client.Client, volumeName string, versions []string, branchToImageID map[string]string) error {
|
||||||
|
lastVer := versions[len(versions)-1]
|
||||||
|
csAPIURL, containerID, err := runImage(dockerClient, volumeName, lastVer, branchToImageID[lastVer])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to run container for branch %v: %v", lastVer, err)
|
||||||
|
}
|
||||||
|
defer destroyContainer(dockerClient, containerID)
|
||||||
|
return verifyTestsRan(csAPIURL, versions)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
httpClient := &http.Client{
|
httpClient := &http.Client{
|
||||||
|
|
@ -375,10 +385,32 @@ func main() {
|
||||||
log.Fatalf("failed to make docker volume: %s", err)
|
log.Fatalf("failed to make docker volume: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failed := false
|
||||||
|
defer func() {
|
||||||
|
perr := recover()
|
||||||
|
log.Println("removing postgres volume")
|
||||||
|
verr := dockerClient.VolumeRemove(context.Background(), volume.Name, true)
|
||||||
|
if perr == nil {
|
||||||
|
perr = verr
|
||||||
|
}
|
||||||
|
if perr != nil {
|
||||||
|
panic(perr)
|
||||||
|
}
|
||||||
|
if failed {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// run through images sequentially
|
// run through images sequentially
|
||||||
for _, v := range versions {
|
for _, v := range versions {
|
||||||
if err = loadAndRunTests(dockerClient, volume.Name, v, branchToImageID); err != nil {
|
if err = loadAndRunTests(dockerClient, volume.Name, v, branchToImageID); err != nil {
|
||||||
log.Fatalf("failed to run tests for %v: %s", v, err)
|
log.Printf("failed to run tests for %v: %s\n", v, err)
|
||||||
|
failed = true
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := verifyTests(dockerClient, volume.Name, versions, branchToImageID); err != nil {
|
||||||
|
log.Printf("failed to verify test results: %s", err)
|
||||||
|
failed = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,189 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"log"
|
||||||
"net/http/httputil"
|
"strings"
|
||||||
"time"
|
|
||||||
|
"github.com/matrix-org/gomatrix"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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, branchName string) error {
|
func runTests(baseURL, branchName string) error {
|
||||||
httpClient := &http.Client{
|
// register 2 users
|
||||||
Timeout: 60 * time.Second,
|
users := []user{
|
||||||
|
{
|
||||||
|
localpart: "alice" + branchName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
localpart: "bob" + branchName,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
err := assertSuccess(httpClient.Post(
|
for i, u := range users {
|
||||||
fmt.Sprintf("%s/_matrix/client/r0/register", baseURL),
|
client, err := gomatrix.NewClient(baseURL, "", "")
|
||||||
"application/json",
|
if err != nil {
|
||||||
bytes.NewBufferString(fmt.Sprintf(`{"username":"%s","password":"%s","auth":{"type":"m.login.dummy"}}`, "alice", "this_is_a_long_password")),
|
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: "trusted_private_chat",
|
||||||
|
Invite: []string{users[1].userID},
|
||||||
|
IsDirect: true,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to /register: %s", err)
|
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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, msg := range msgs {
|
||||||
|
_, err = msg.client.SendText(dmRoomID, msg.text)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to send text in dm room: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// attempt to create/join the shared public room
|
||||||
|
publicRoomID := ""
|
||||||
|
createRoomResp, err = users[0].client.CreateRoom(&gomatrix.ReqCreateRoom{
|
||||||
|
RoomAliasName: "global",
|
||||||
|
Preset: "public_chat",
|
||||||
|
})
|
||||||
|
if err != nil { // this is okay and expected if the room already exists and the aliases clash
|
||||||
|
// try to join it
|
||||||
|
_, domain, err := gomatrixserverlib.SplitID('@', users[0].userID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to split user ID: %s, %s", users[0].userID, err)
|
||||||
|
}
|
||||||
|
joinRoomResp, err := users[0].client.JoinRoom(fmt.Sprintf("#global:%s", domain), "", nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("alice failed to join public room: %s", err)
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
_, err = msg.client.SendText(publicRoomID, "public "+msg.text)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to send text in public room: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Printf("OK! rooms(public=%s, dm=%s) users(%s, %s)\n", publicRoomID, dmRoomID, users[0].userID, users[1].userID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertSuccess(res *http.Response, err error) error {
|
// verifyTestsRan checks that the HS has the right rooms/messages
|
||||||
|
func verifyTestsRan(baseURL string, branchNames []string) error {
|
||||||
|
log.Println("Verifying tests....")
|
||||||
|
// check we can login as all users
|
||||||
|
var resp *gomatrix.RespLogin
|
||||||
|
for _, branchName := range branchNames {
|
||||||
|
client, err := gomatrix.NewClient(baseURL, "", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("response returned error: %s", err)
|
return err
|
||||||
}
|
}
|
||||||
if res.StatusCode != 200 {
|
_, domain, err := gomatrixserverlib.SplitID('@', client.UserID)
|
||||||
return fmt.Errorf("response returned HTTP %d - %s", res.StatusCode, dumpResponse(res))
|
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)
|
||||||
|
}
|
||||||
|
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(branchNames) * 4
|
||||||
|
if msgCount != wantMsgCount {
|
||||||
|
return fmt.Errorf("got %d messages in global room, want %d", msgCount, wantMsgCount)
|
||||||
|
}
|
||||||
|
log.Println(" messages exist: OK")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpResponse(res *http.Response) string {
|
|
||||||
d, _ := httputil.DumpResponse(res, true)
|
|
||||||
return string(d)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue