dendrite/syncapi/sync/requestpool_test.go
Brian Meek de78eab63a
Add race testing to tests, and fix a few small race conditions in the tests (#2587)
* Add race testing to tests, and fix a few small race conditions in the tests

* Enable run-sytest on MacOS

* Remove deadlock detecting mutex, per code review feedback

* Remove autoformatting related changes and a closure that is not needed

* Adjust to importing nats client as 'natsclient'

Signed-off-by: Brian Meek <brian@hntlabs.com>

* Clarify the use of gooseMutex to proect goose internal state

Signed-off-by: Brian Meek <brian@hntlabs.com>

* Remove no longer needed mutex for guarding goose

Signed-off-by: Brian Meek <brian@hntlabs.com>
2022-08-05 09:19:33 +01:00

143 lines
3.3 KiB
Go

package sync
import (
"context"
"sync"
"testing"
"time"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/syncapi/types"
"github.com/matrix-org/gomatrixserverlib"
)
type dummyPublisher struct {
lock sync.Mutex
count int
}
func (d *dummyPublisher) SendPresence(userID string, presence types.Presence, statusMsg *string) error {
d.lock.Lock()
defer d.lock.Unlock()
d.count++
return nil
}
type dummyDB struct{}
func (d dummyDB) UpdatePresence(ctx context.Context, userID string, presence types.Presence, statusMsg *string, lastActiveTS gomatrixserverlib.Timestamp, fromSync bool) (types.StreamPosition, error) {
return 0, nil
}
func (d dummyDB) GetPresence(ctx context.Context, userID string) (*types.PresenceInternal, error) {
return &types.PresenceInternal{}, nil
}
func (d dummyDB) PresenceAfter(ctx context.Context, after types.StreamPosition, filter gomatrixserverlib.EventFilter) (map[string]*types.PresenceInternal, error) {
return map[string]*types.PresenceInternal{}, nil
}
func (d dummyDB) MaxStreamPositionForPresence(ctx context.Context) (types.StreamPosition, error) {
return 0, nil
}
type dummyConsumer struct{}
func (d dummyConsumer) EmitPresence(ctx context.Context, userID string, presence types.Presence, statusMsg *string, ts gomatrixserverlib.Timestamp, fromSync bool) {
}
func TestRequestPool_updatePresence(t *testing.T) {
type args struct {
presence string
userID string
sleep time.Duration
}
publisher := &dummyPublisher{}
consumer := &dummyConsumer{}
syncMap := sync.Map{}
tests := []struct {
name string
args args
wantIncrease bool
}{
{
name: "new presence is published",
wantIncrease: true,
args: args{
userID: "dummy",
},
},
{
name: "presence not published, no change",
args: args{
userID: "dummy",
},
},
{
name: "new presence is published dummy2",
wantIncrease: true,
args: args{
userID: "dummy2",
presence: "online",
},
},
{
name: "different presence is published dummy2",
wantIncrease: true,
args: args{
userID: "dummy2",
presence: "unavailable",
},
},
{
name: "same presence is not published dummy2",
args: args{
userID: "dummy2",
presence: "unavailable",
sleep: time.Millisecond * 150,
},
},
{
name: "same presence is published after being deleted",
wantIncrease: true,
args: args{
userID: "dummy2",
presence: "unavailable",
},
},
}
rp := &RequestPool{
presence: &syncMap,
producer: publisher,
consumer: consumer,
cfg: &config.SyncAPI{
Matrix: &config.Global{
JetStream: config.JetStream{
TopicPrefix: "Dendrite",
},
Presence: config.PresenceOptions{
EnableInbound: true,
EnableOutbound: true,
},
},
},
}
db := dummyDB{}
go rp.cleanPresence(db, time.Millisecond*50)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
publisher.lock.Lock()
beforeCount := publisher.count
publisher.lock.Unlock()
rp.updatePresence(db, tt.args.presence, tt.args.userID)
publisher.lock.Lock()
if tt.wantIncrease && publisher.count <= beforeCount {
t.Fatalf("expected count to increase: %d <= %d", publisher.count, beforeCount)
}
publisher.lock.Unlock()
time.Sleep(tt.args.sleep)
})
}
}