test: use clientmanager to logout fakeapi

This commit is contained in:
James Houlahan
2020-04-20 12:26:11 +02:00
parent 99635cd56d
commit e027aa5fae
5 changed files with 68 additions and 36 deletions

View File

@ -65,6 +65,8 @@ type Bridge struct {
lock sync.RWMutex lock sync.RWMutex
cancel chan struct{}
userAgentClientName string userAgentClientName string
userAgentClientVersion string userAgentClientVersion string
userAgentOS string userAgentOS string
@ -92,6 +94,7 @@ func New(
storeCache: store.NewCache(config.GetIMAPCachePath()), storeCache: store.NewCache(config.GetIMAPCachePath()),
idleUpdates: make(chan interface{}), idleUpdates: make(chan interface{}),
lock: sync.RWMutex{}, lock: sync.RWMutex{},
cancel: make(chan struct{}),
} }
// Allow DoH before starting bridge if the user has previously set this setting. // Allow DoH before starting bridge if the user has previously set this setting.
@ -110,6 +113,8 @@ func New(
b.watchAPIAuths() b.watchAPIAuths()
}() }()
go b.heartbeat()
if b.credStorer == nil { if b.credStorer == nil {
log.Error("Bridge has no credentials store") log.Error("Bridge has no credentials store")
} else if err := b.loadUsersFromCredentialsStore(); err != nil { } else if err := b.loadUsersFromCredentialsStore(); err != nil {
@ -120,23 +125,29 @@ func New(
b.SendMetric(metrics.New(metrics.Setup, metrics.FirstStart, metrics.Label(version))) b.SendMetric(metrics.New(metrics.Setup, metrics.FirstStart, metrics.Label(version)))
} }
go b.heartbeat()
return b return b
} }
// heartbeat sends a heartbeat signal once a day. // heartbeat sends a heartbeat signal once a day.
func (b *Bridge) heartbeat() { func (b *Bridge) heartbeat() {
for range time.NewTicker(1 * time.Hour).C { ticker := time.NewTicker(1 * time.Minute)
next, err := strconv.ParseInt(b.pref.Get(preferences.NextHeartbeatKey), 10, 64)
if err != nil { for {
continue select {
} case <-ticker.C:
nextTime := time.Unix(next, 0) next, err := strconv.ParseInt(b.pref.Get(preferences.NextHeartbeatKey), 10, 64)
if time.Now().After(nextTime) { if err != nil {
b.SendMetric(metrics.New(metrics.Heartbeat, metrics.Daily, metrics.NoLabel)) continue
nextTime = nextTime.Add(24 * time.Hour) }
b.pref.Set(preferences.NextHeartbeatKey, strconv.FormatInt(nextTime.Unix(), 10)) nextTime := time.Unix(next, 0)
if time.Now().After(nextTime) {
b.SendMetric(metrics.New(metrics.Heartbeat, metrics.Daily, metrics.NoLabel))
nextTime = nextTime.Add(24 * time.Hour)
b.pref.Set(preferences.NextHeartbeatKey, strconv.FormatInt(nextTime.Unix(), 10))
}
case <-b.cancel:
return
} }
} }
} }
@ -171,30 +182,44 @@ func (b *Bridge) loadUsersFromCredentialsStore() (err error) {
func (b *Bridge) watchBridgeOutdated() { func (b *Bridge) watchBridgeOutdated() {
ch := make(chan string) ch := make(chan string)
b.events.Add(events.UpgradeApplicationEvent, ch) b.events.Add(events.UpgradeApplicationEvent, ch)
for range ch {
isApplicationOutdated = true for {
b.closeAllConnections() select {
case <-ch:
isApplicationOutdated = true
b.closeAllConnections()
case <-b.cancel:
return
}
} }
} }
// watchAPIAuths receives auths from the client manager and sends them to the appropriate user. // watchAPIAuths receives auths from the client manager and sends them to the appropriate user.
func (b *Bridge) watchAPIAuths() { func (b *Bridge) watchAPIAuths() {
for auth := range b.clientManager.GetAuthUpdateChannel() { for {
log.Debug("Bridge received auth from ClientManager") select {
case auth := <-b.clientManager.GetAuthUpdateChannel():
log.Debug("Bridge received auth from ClientManager")
user, ok := b.hasUser(auth.UserID) user, ok := b.hasUser(auth.UserID)
if !ok { if !ok {
log.WithField("userID", auth.UserID).Info("User not available for auth update") log.WithField("userID", auth.UserID).Info("User not available for auth update")
continue continue
} }
if auth.Auth != nil { if auth.Auth != nil {
user.updateAuthToken(auth.Auth) user.updateAuthToken(auth.Auth)
} else if err := user.logout(); err != nil { } else if err := user.logout(); err != nil {
log.WithError(err). log.WithError(err).
WithField("userID", auth.UserID). WithField("userID", auth.UserID).
Error("User logout failed while watching API auths") Error("User logout failed while watching API auths")
}
case <-b.cancel:
return
} }
} }
} }
@ -541,6 +566,11 @@ func (b *Bridge) CheckConnection() error {
return b.clientManager.CheckConnection() return b.clientManager.CheckConnection()
} }
// StopWatchers stops all bridge goroutines.
func (b *Bridge) StopWatchers() {
close(b.cancel)
}
func (b *Bridge) updateCurrentUserAgent() { func (b *Bridge) updateCurrentUserAgent() {
UpdateCurrentUserAgent(b.version, b.userAgentOS, b.userAgentClientName, b.userAgentClientVersion) UpdateCurrentUserAgent(b.version, b.userAgentOS, b.userAgentClientName, b.userAgentClientVersion)
} }

View File

@ -49,7 +49,10 @@ func (ctx *TestContext) RestartBridge() error {
_ = user.GetStore().Close() _ = user.GetStore().Close()
} }
ctx.bridge.StopWatchers()
ctx.withBridgeInstance() ctx.withBridgeInstance()
return nil return nil
} }

View File

@ -148,10 +148,7 @@ func (api *FakePMAPI) AuthRefresh(token string) (*pmapi.Auth, error) {
} }
func (api *FakePMAPI) Logout() { func (api *FakePMAPI) Logout() {
if err := api.DeleteAuth(); err != nil { api.controller.clientManager.LogoutClient(api.userID)
api.log.WithError(err).Error("delete auth failed during logout")
}
api.ClearData()
} }
func (api *FakePMAPI) IsConnected() bool { func (api *FakePMAPI) IsConnected() bool {
@ -162,8 +159,6 @@ func (api *FakePMAPI) DeleteAuth() error {
if err := api.checkAndRecordCall(DELETE, "/auth", nil); err != nil { if err := api.checkAndRecordCall(DELETE, "/auth", nil); err != nil {
return err return err
} }
// Logout will also emit change to auth channel
api.sendAuth(nil)
api.controller.deleteSession(api.uid) api.controller.deleteSession(api.uid)
return nil return nil
} }

View File

@ -66,7 +66,7 @@ func NewController(cm *pmapi.ClientManager) *Controller {
} }
cm.SetClientConstructor(func(userID string) pmapi.Client { cm.SetClientConstructor(func(userID string) pmapi.Client {
fakeAPI := New(controller) fakeAPI := New(controller, userID)
controller.fakeAPIs = append(controller.fakeAPIs, fakeAPI) controller.fakeAPIs = append(controller.fakeAPIs, fakeAPI)
return fakeAPI return fakeAPI
}) })

View File

@ -29,6 +29,7 @@ var errBadRequest = errors.New("NOT OK: 400 Bad Request")
type FakePMAPI struct { type FakePMAPI struct {
username string username string
userID string
controller *Controller controller *Controller
eventIDGenerator idGenerator eventIDGenerator idGenerator
@ -45,16 +46,19 @@ type FakePMAPI struct {
log *logrus.Entry log *logrus.Entry
} }
func New(controller *Controller) *FakePMAPI { func New(controller *Controller, userID string) *FakePMAPI {
fakePMAPI := &FakePMAPI{ fakePMAPI := &FakePMAPI{
controller: controller, controller: controller,
log: logrus.WithField("pkg", "fakeapi"), log: logrus.WithField("pkg", "fakeapi"),
userID: userID,
} }
fakePMAPI.addEvent(&pmapi.Event{ fakePMAPI.addEvent(&pmapi.Event{
EventID: fakePMAPI.eventIDGenerator.last("event"), EventID: fakePMAPI.eventIDGenerator.last("event"),
Refresh: 0, Refresh: 0,
More: 0, More: 0,
}) })
return fakePMAPI return fakePMAPI
} }