Other: Get test events before starting bridge to ensure all are captured

This commit is contained in:
James Houlahan
2022-10-13 02:33:20 +02:00
parent ef2dea89b4
commit a4852c1b36
3 changed files with 76 additions and 39 deletions

View File

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
"github.com/ProtonMail/proton-bridge/v2/internal/vault" "github.com/ProtonMail/proton-bridge/v2/internal/vault"
) )
@ -249,9 +250,9 @@ func (s *scenario) bridgeSendsAForcedUpdateEvent() error {
}) })
} }
func try[T any](inCh <-chan T, wait time.Duration, fn func(T) error) error { func try[T any](inCh *queue.QueuedChannel[T], wait time.Duration, fn func(T) error) error {
select { select {
case event := <-inCh: case event := <-inCh.GetChannel():
return fn(event) return fn(event)
case <-time.After(wait): case <-time.After(wait):
@ -259,6 +260,6 @@ func try[T any](inCh <-chan T, wait time.Duration, fn func(T) error) error {
} }
} }
func get[T any](inCh <-chan T, fn func(T) error) error { func get[T any](inCh *queue.QueuedChannel[T], fn func(T) error) error {
return fn(<-inCh) return fn(<-inCh.GetChannel())
} }

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"net/http/cookiejar" "net/http/cookiejar"
"github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/cookies" "github.com/ProtonMail/proton-bridge/v2/internal/cookies"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
@ -52,12 +53,14 @@ func (t *testCtx) startBridge() error {
// Create the bridge. // Create the bridge.
bridge, eventCh, err := bridge.New( bridge, eventCh, err := bridge.New(
// App stuff
t.locator, t.locator,
vault, vault,
t.mocks.Autostarter, t.mocks.Autostarter,
t.mocks.Updater, t.mocks.Updater,
t.version, t.version,
// API stuff
t.api.GetHostURL(), t.api.GetHostURL(),
persister, persister,
useragent.New(), useragent.New(),
@ -65,6 +68,7 @@ func (t *testCtx) startBridge() error {
liteapi.NewDialer(t.netCtl, &tls.Config{InsecureSkipVerify: true}).GetRoundTripper(), liteapi.NewDialer(t.netCtl, &tls.Config{InsecureSkipVerify: true}).GetRoundTripper(),
t.mocks.ProxyCtl, t.mocks.ProxyCtl,
// Logging stuff
false, false,
false, false,
false, false,
@ -73,25 +77,64 @@ func (t *testCtx) startBridge() error {
return err return err
} }
// Create the event channels for use in the test.
t.loginCh = queue.NewQueuedChannel[events.UserLoggedIn](0, 0)
t.logoutCh = queue.NewQueuedChannel[events.UserLoggedOut](0, 0)
t.loadedCh = queue.NewQueuedChannel[events.AllUsersLoaded](0, 0)
t.deletedCh = queue.NewQueuedChannel[events.UserDeleted](0, 0)
t.deauthCh = queue.NewQueuedChannel[events.UserDeauth](0, 0)
t.addrCreatedCh = queue.NewQueuedChannel[events.UserAddressCreated](0, 0)
t.addrDeletedCh = queue.NewQueuedChannel[events.UserAddressDeleted](0, 0)
t.syncStartedCh = queue.NewQueuedChannel[events.SyncStarted](0, 0)
t.syncFinishedCh = queue.NewQueuedChannel[events.SyncFinished](0, 0)
t.forcedUpdateCh = queue.NewQueuedChannel[events.UpdateForced](0, 0)
t.connStatusCh = queue.NewQueuedChannel[events.Event](0, 0)
t.updateCh = queue.NewQueuedChannel[events.Event](0, 0)
// Push the updates to the appropriate channels.
go func() {
for event := range eventCh {
switch event := event.(type) {
case events.UserLoggedIn:
t.loginCh.Enqueue(event)
case events.UserLoggedOut:
t.logoutCh.Enqueue(event)
case events.AllUsersLoaded:
t.loadedCh.Enqueue(event)
case events.UserDeleted:
t.deletedCh.Enqueue(event)
case events.UserDeauth:
t.deauthCh.Enqueue(event)
case events.UserAddressCreated:
t.addrCreatedCh.Enqueue(event)
case events.UserAddressDeleted:
t.addrDeletedCh.Enqueue(event)
case events.SyncStarted:
t.syncStartedCh.Enqueue(event)
case events.SyncFinished:
t.syncFinishedCh.Enqueue(event)
case events.ConnStatusUp:
t.connStatusCh.Enqueue(event)
case events.ConnStatusDown:
t.connStatusCh.Enqueue(event)
case events.UpdateAvailable:
t.updateCh.Enqueue(event)
case events.UpdateNotAvailable:
t.updateCh.Enqueue(event)
case events.UpdateInstalled:
t.updateCh.Enqueue(event)
case events.UpdateForced:
t.forcedUpdateCh.Enqueue(event)
}
}
}()
// Wait for the users to be loaded. // Wait for the users to be loaded.
waitForEvent(eventCh, events.AllUsersLoaded{}) <-t.loadedCh.GetChannel()
// Save the bridge t. // Save the bridge to the context.
t.bridge = bridge t.bridge = bridge
// Connect the event channels.
t.loginCh = chToType[events.Event, events.UserLoggedIn](bridge.GetEvents(events.UserLoggedIn{}))
t.logoutCh = chToType[events.Event, events.UserLoggedOut](bridge.GetEvents(events.UserLoggedOut{}))
t.deletedCh = chToType[events.Event, events.UserDeleted](bridge.GetEvents(events.UserDeleted{}))
t.deauthCh = chToType[events.Event, events.UserDeauth](bridge.GetEvents(events.UserDeauth{}))
t.addrCreatedCh = chToType[events.Event, events.UserAddressCreated](bridge.GetEvents(events.UserAddressCreated{}))
t.addrDeletedCh = chToType[events.Event, events.UserAddressDeleted](bridge.GetEvents(events.UserAddressDeleted{}))
t.syncStartedCh = chToType[events.Event, events.SyncStarted](bridge.GetEvents(events.SyncStarted{}))
t.syncFinishedCh = chToType[events.Event, events.SyncFinished](bridge.GetEvents(events.SyncFinished{}))
t.forcedUpdateCh = chToType[events.Event, events.UpdateForced](bridge.GetEvents(events.UpdateForced{}))
t.connStatusCh, _ = bridge.GetEvents(events.ConnStatusUp{}, events.ConnStatusDown{})
t.updateCh, _ = bridge.GetEvents(events.UpdateAvailable{}, events.UpdateNotAvailable{}, events.UpdateInstalled{}, events.UpdateForced{})
return nil return nil
} }
@ -104,12 +147,3 @@ func (t *testCtx) stopBridge() error {
return nil return nil
} }
func waitForEvent[T any](eventCh <-chan events.Event, wantEvent T) {
for event := range eventCh {
switch event.(type) {
case T:
return
}
}
}

View File

@ -8,6 +8,7 @@ import (
"testing" "testing"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/ProtonMail/gluon/queue"
"github.com/ProtonMail/proton-bridge/v2/internal/bridge" "github.com/ProtonMail/proton-bridge/v2/internal/bridge"
"github.com/ProtonMail/proton-bridge/v2/internal/events" "github.com/ProtonMail/proton-bridge/v2/internal/events"
"github.com/ProtonMail/proton-bridge/v2/internal/locations" "github.com/ProtonMail/proton-bridge/v2/internal/locations"
@ -34,17 +35,18 @@ type testCtx struct {
bridge *bridge.Bridge bridge *bridge.Bridge
// These channels hold events of various types coming from bridge. // These channels hold events of various types coming from bridge.
loginCh <-chan events.UserLoggedIn loginCh *queue.QueuedChannel[events.UserLoggedIn]
logoutCh <-chan events.UserLoggedOut logoutCh *queue.QueuedChannel[events.UserLoggedOut]
deletedCh <-chan events.UserDeleted loadedCh *queue.QueuedChannel[events.AllUsersLoaded]
deauthCh <-chan events.UserDeauth deletedCh *queue.QueuedChannel[events.UserDeleted]
addrCreatedCh <-chan events.UserAddressCreated deauthCh *queue.QueuedChannel[events.UserDeauth]
addrDeletedCh <-chan events.UserAddressDeleted addrCreatedCh *queue.QueuedChannel[events.UserAddressCreated]
syncStartedCh <-chan events.SyncStarted addrDeletedCh *queue.QueuedChannel[events.UserAddressDeleted]
syncFinishedCh <-chan events.SyncFinished syncStartedCh *queue.QueuedChannel[events.SyncStarted]
forcedUpdateCh <-chan events.UpdateForced syncFinishedCh *queue.QueuedChannel[events.SyncFinished]
connStatusCh <-chan events.Event forcedUpdateCh *queue.QueuedChannel[events.UpdateForced]
updateCh <-chan events.Event connStatusCh *queue.QueuedChannel[events.Event]
updateCh *queue.QueuedChannel[events.Event]
// These maps hold expected userIDByName, their primary addresses and bridge passwords. // These maps hold expected userIDByName, their primary addresses and bridge passwords.
userIDByName map[string]string userIDByName map[string]string