forked from matrix-org/sliding-sync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbench_test.go
101 lines (95 loc) · 3.47 KB
/
bench_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package syncv3
import (
"encoding/json"
"fmt"
"testing"
"time"
"github.com/matrix-org/sliding-sync/sync2"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils"
"github.com/rs/zerolog"
)
// The purpose of this benchmark is to ensure that sync v3 responds quickly regardless of how many
// rooms the user has on their account. The first initial sync to fetch the rooms are ignored for
// the purposes of the benchmark, only subsequent requests are taken into account. We expect this
// value to grow slowly (searching more rows in a database, looping more elements in an array) but
// this should not grow so quickly that it impacts performance or else something has gone terribly
// wrong.
func BenchmarkNumRooms(b *testing.B) {
testutils.Quiet = true
for _, numRooms := range []int{100, 200, 400, 800} {
n := numRooms
b.Run(fmt.Sprintf("num_rooms_%d", n), func(b *testing.B) {
benchNumV2Rooms(n, b)
})
}
}
func benchNumV2Rooms(numRooms int, b *testing.B) {
// setup code
boolFalse := false
pqString := testutils.PrepareDBConnectionString()
v2 := runTestV2Server(b)
v3 := runTestServer(b, v2, pqString)
zerolog.SetGlobalLevel(zerolog.Disabled)
defer v2.close()
defer v3.close()
allRooms := make([]roomEvents, numRooms)
for i := 0; i < len(allRooms); i++ {
ts := time.Now().Add(time.Duration(i) * time.Minute)
roomName := fmt.Sprintf("My Room %d", i)
allRooms[i] = roomEvents{
roomID: fmt.Sprintf("!benchNumV2Rooms_%d:localhost", i),
name: roomName,
events: append(createRoomState(b, alice, ts), []json.RawMessage{
testutils.NewStateEvent(b, "m.room.name", "", alice, map[string]interface{}{"name": roomName}, testutils.WithTimestamp(ts.Add(3*time.Second))),
testutils.NewEvent(b, "m.room.message", alice, map[string]interface{}{"body": "A"}, testutils.WithTimestamp(ts.Add(4*time.Second))),
testutils.NewEvent(b, "m.room.message", alice, map[string]interface{}{"body": "B"}, testutils.WithTimestamp(ts.Add(5*time.Second))),
testutils.NewEvent(b, "m.room.message", alice, map[string]interface{}{"body": "C"}, testutils.WithTimestamp(ts.Add(6*time.Second))),
}...),
}
}
v2.addAccount(b, alice, aliceToken)
v2.queueResponse(alice, sync2.SyncResponse{
Rooms: sync2.SyncRoomsResponse{
Join: v2JoinTimeline(allRooms...),
},
})
// do the initial request
v3.mustDoV3Request(b, aliceToken, sync3.Request{
Lists: map[string]sync3.RequestList{
"a": {
Ranges: sync3.SliceRanges{
[2]int64{0, 20}, // first few rooms
},
RoomSubscription: sync3.RoomSubscription{
TimelineLimit: 3,
},
}},
})
b.ResetTimer() // don't count setup code
// these should all take roughly the same amount of time, regardless of the value of `numRooms`
for n := 0; n < b.N; n++ {
v3.mustDoV3Request(b, aliceToken, sync3.Request{
Lists: map[string]sync3.RequestList{
"a": {
// always use a fixed range else we will scale O(n) with the number of rooms
Ranges: sync3.SliceRanges{
[2]int64{0, 20}, // first few rooms
},
// include a filter to ensure we loop over rooms
Filters: &sync3.RequestFilters{
IsEncrypted: &boolFalse,
},
// include a few required state events to force us to query the database
// include a few timeline events to force us to query the database
RoomSubscription: sync3.RoomSubscription{
TimelineLimit: 3,
RequiredState: [][2]string{
{"m.room.create", ""},
{"m.room.member", alice},
},
},
}},
})
}
}