Skip to content

Commit 10fee65

Browse files
Lock /createRoom calls (matrix-org#800)
* Lock /createRoom calls To reduce the chance of multiple rooms being made in the same millisecond which makes v12 rooms unhappy as it causes the same room ID to be generated. * Update client/client.go Co-authored-by: Eric Eastwood <erice@element.io> --------- Co-authored-by: Eric Eastwood <erice@element.io>
1 parent 091cbf5 commit 10fee65

2 files changed

Lines changed: 42 additions & 9 deletions

File tree

client/client.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"net/url"
1616
"strconv"
1717
"strings"
18+
"sync"
1819
"sync/atomic"
1920
"time"
2021

@@ -48,6 +49,19 @@ type retryUntilParams struct {
4849
// See functions starting with `With...` in this package for more info.
4950
type RequestOpt func(req *http.Request)
5051

52+
type CSAPIOpts struct {
53+
UserID string
54+
AccessToken string
55+
DeviceID string
56+
Password string // if provided
57+
BaseURL string
58+
Client *http.Client
59+
// how long are we willing to wait for MustSyncUntil.... calls
60+
SyncUntilTimeout time.Duration
61+
// True to enable verbose logging
62+
Debug bool
63+
}
64+
5165
type CSAPI struct {
5266
UserID string
5367
AccessToken string
@@ -60,7 +74,22 @@ type CSAPI struct {
6074
// True to enable verbose logging
6175
Debug bool
6276

63-
txnID int64
77+
txnID int64
78+
createRoomMutex *sync.Mutex
79+
}
80+
81+
func NewCSAPI(opts CSAPIOpts) *CSAPI {
82+
return &CSAPI{
83+
UserID: opts.UserID,
84+
AccessToken: opts.AccessToken,
85+
DeviceID: opts.DeviceID,
86+
Password: opts.Password,
87+
BaseURL: opts.BaseURL,
88+
Client: opts.Client,
89+
SyncUntilTimeout: opts.SyncUntilTimeout,
90+
Debug: opts.Debug,
91+
createRoomMutex: &sync.Mutex{},
92+
}
6493
}
6594

6695
// CreateMedia creates an MXC URI for asynchronous media uploads.
@@ -137,6 +166,10 @@ func (c *CSAPI) MustCreateRoom(t ct.TestLike, reqBody map[string]interface{}) st
137166
// CreateRoom creates a room with an optional HTTP request body.
138167
func (c *CSAPI) CreateRoom(t ct.TestLike, body map[string]interface{}) *http.Response {
139168
t.Helper()
169+
// Ensure we don't call /createRoom from the same user in parallel, else we might try to make
170+
// 2 rooms in the same millisecond (same `origin_server_ts`), causing v12 rooms to get the same room ID thus failing the test.
171+
c.createRoomMutex.Lock()
172+
defer c.createRoomMutex.Unlock()
140173
return c.Do(t, "POST", []string{"_matrix", "client", "v3", "createRoom"}, WithJSONBody(t, body))
141174
}
142175

internal/docker/deployment.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,13 @@ func (d *Deployment) Register(t ct.TestLike, hsName string, opts helpers.Registr
105105
ct.Fatalf(t, "Deployment.Register - HS name '%s' not found", hsName)
106106
return nil
107107
}
108-
client := &client.CSAPI{
108+
client := client.NewCSAPI(client.CSAPIOpts{
109109
BaseURL: dep.BaseURL,
110110
Client: client.NewLoggedClient(t, hsName, nil),
111111
SyncUntilTimeout: 5 * time.Second,
112112
Debug: d.Deployer.debugLogging,
113113
Password: opts.Password,
114-
}
114+
})
115115
// Appending a slice is not thread-safe. Protect the write with a mutex.
116116
dep.CSAPIClientsMutex.Lock()
117117
dep.CSAPIClients = append(dep.CSAPIClients, client)
@@ -155,13 +155,13 @@ func (d *Deployment) Login(t ct.TestLike, hsName string, existing *client.CSAPI,
155155
if err != nil {
156156
ct.Fatalf(t, "Deployment.Login: existing CSAPI client has invalid user ID '%s', cannot login as this user: %s", existing.UserID, err)
157157
}
158-
c := &client.CSAPI{
158+
c := client.NewCSAPI(client.CSAPIOpts{
159159
BaseURL: dep.BaseURL,
160160
Client: client.NewLoggedClient(t, hsName, nil),
161161
SyncUntilTimeout: 5 * time.Second,
162162
Debug: d.Deployer.debugLogging,
163163
Password: existing.Password,
164-
}
164+
})
165165
if opts.Password != "" {
166166
c.Password = opts.Password
167167
}
@@ -197,12 +197,12 @@ func (d *Deployment) UnauthenticatedClient(t ct.TestLike, hsName string) *client
197197
ct.Fatalf(t, "Deployment.Client - HS name '%s' not found", hsName)
198198
return nil
199199
}
200-
client := &client.CSAPI{
200+
client := client.NewCSAPI(client.CSAPIOpts{
201201
BaseURL: dep.BaseURL,
202202
Client: client.NewLoggedClient(t, hsName, nil),
203203
SyncUntilTimeout: 5 * time.Second,
204204
Debug: d.Deployer.debugLogging,
205-
}
205+
})
206206
// Appending a slice is not thread-safe. Protect the write with a mutex.
207207
dep.CSAPIClientsMutex.Lock()
208208
dep.CSAPIClients = append(dep.CSAPIClients, client)
@@ -230,15 +230,15 @@ func (d *Deployment) AppServiceUser(t ct.TestLike, hsName, appServiceUserID stri
230230
if deviceID == "" && appServiceUserID != "" {
231231
t.Logf("WARNING: Deployment.Client - HS name '%s' - user ID '%s' - deviceID not found", hsName, appServiceUserID)
232232
}
233-
client := &client.CSAPI{
233+
client := client.NewCSAPI(client.CSAPIOpts{
234234
UserID: appServiceUserID,
235235
AccessToken: token,
236236
DeviceID: deviceID,
237237
BaseURL: dep.BaseURL,
238238
Client: client.NewLoggedClient(t, hsName, nil),
239239
SyncUntilTimeout: 5 * time.Second,
240240
Debug: d.Deployer.debugLogging,
241-
}
241+
})
242242
// Appending a slice is not thread-safe. Protect the write with a mutex.
243243
dep.CSAPIClientsMutex.Lock()
244244
dep.CSAPIClients = append(dep.CSAPIClients, client)

0 commit comments

Comments
 (0)