From 59075f2e264bc5e9283fa5346a95388825cbf47a Mon Sep 17 00:00:00 2001 From: Jakub Date: Fri, 19 Nov 2021 09:40:57 +0100 Subject: [PATCH] GODT-1409 Wait in GetEvents during message preparation for live API. --- test/context/context.go | 3 +++ test/context/pmapi_controller.go | 2 ++ test/fakeapi/controller_control.go | 6 ++++++ test/liveapi/events.go | 26 ++++++++++++++++++++++++++ test/liveapi/persistent_clients.go | 14 ++++++++++++++ test/store_setup_test.go | 14 ++++++++++++++ 6 files changed, 65 insertions(+) create mode 100644 test/liveapi/events.go diff --git a/test/context/context.go b/test/context/context.go index 0778bebf..2008f4fd 100644 --- a/test/context/context.go +++ b/test/context/context.go @@ -177,3 +177,6 @@ func (ctx *TestContext) SetLastError(err error) { func (ctx *TestContext) GetLastError() error { return ctx.lastError } + +func (ctx *TestContext) MessagePreparationStarted() { ctx.pmapiController.LockEvents() } +func (ctx *TestContext) MessagePreparationFinished() { ctx.pmapiController.UnlockEvents() } diff --git a/test/context/pmapi_controller.go b/test/context/pmapi_controller.go index 315b281b..de65a6d3 100644 --- a/test/context/pmapi_controller.go +++ b/test/context/pmapi_controller.go @@ -42,6 +42,8 @@ type PMAPIController interface { WasCalled(method, path string, expectedRequest []byte) bool WasCalledRegex(methodRegex, pathRegex string, expectedRequest []byte) (bool, error) GetCalls(method, path string) [][]byte + LockEvents() + UnlockEvents() } func newPMAPIController(app string, listener listener.Listener) (PMAPIController, pmapi.Manager) { diff --git a/test/fakeapi/controller_control.go b/test/fakeapi/controller_control.go index 8e853b65..4a372366 100644 --- a/test/fakeapi/controller_control.go +++ b/test/fakeapi/controller_control.go @@ -197,3 +197,9 @@ func (ctl *Controller) GetAuthClient(username string) pmapi.Client { return nil } + +// LockEvents doesn't needs to be implemented for fakeAPI. +func (ctl *Controller) LockEvents() {} + +// UnlockEvents doesn't needs to be implemented for fakeAPI. +func (ctl *Controller) UnlockEvents() {} diff --git a/test/liveapi/events.go b/test/liveapi/events.go new file mode 100644 index 00000000..c6b6ba19 --- /dev/null +++ b/test/liveapi/events.go @@ -0,0 +1,26 @@ +// Copyright (c) 2021 Proton Technologies AG +// +// This file is part of ProtonMail Bridge.Bridge. +// +// ProtonMail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ProtonMail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with ProtonMail Bridge. If not, see . + +package liveapi + +func (ctl *Controller) LockEvents() { + persistentClients.eventsPaused.Add(1) +} + +func (ctl *Controller) UnlockEvents() { + persistentClients.eventsPaused.Done() +} diff --git a/test/liveapi/persistent_clients.go b/test/liveapi/persistent_clients.go index 46538995..bb6e4350 100644 --- a/test/liveapi/persistent_clients.go +++ b/test/liveapi/persistent_clients.go @@ -22,6 +22,7 @@ import ( "fmt" "math/rand" "os" + "sync" "github.com/ProtonMail/go-srp" "github.com/ProtonMail/proton-bridge/internal/constants" @@ -47,6 +48,8 @@ var persistentClients = struct { manager pmapi.Manager byName map[string]clientAuthGetter saltByName map[string]string + + eventsPaused sync.WaitGroup }{} type persistentClient struct { @@ -69,6 +72,17 @@ func (pc *persistentClient) AuthSalt(_ context.Context) (string, error) { return persistentClients.saltByName[pc.username], nil } +// GetEvent needs to wait for preparation to finish. Otherwise messages will be +// in wrong order and test will fail. +func (pc *persistentClient) GetEvent(ctx context.Context, eventID string) (*pmapi.Event, error) { + persistentClients.eventsPaused.Wait() + normalClient, ok := persistentClients.byName[pc.username].(pmapi.Client) + if !ok { + return nil, errors.New("cannot convert to normal client") + } + return normalClient.GetEvent(ctx, eventID) +} + func SetupPersistentClients() { app := os.Getenv("TEST_APP") diff --git a/test/store_setup_test.go b/test/store_setup_test.go index 4db566da..d03dd4a1 100644 --- a/test/store_setup_test.go +++ b/test/store_setup_test.go @@ -75,6 +75,13 @@ func thereAreMessagesInMailboxesForUser(mailboxNames, bddUserID string, messages } func thereAreMessagesInMailboxesForAddressOfUser(mailboxNames, bddAddressID, bddUserID string, messages *godog.Table) error { + // It is needed to prevent event processing before syncing these message + // otherwise the seqID and UID will be in reverse order. The + // synchronization add newest message first, the eventloop adds the oldest + // message first. + ctx.MessagePreparationStarted() + defer ctx.MessagePreparationFinished() + account := ctx.GetTestAccountWithAddress(bddUserID, bddAddressID) if account == nil { return godog.ErrPending @@ -263,6 +270,13 @@ func processMailboxStructureDataTable(structure *godog.Table, callback func(stri } func thereAreSomeMessagesInMailboxesForAddressOfUser(numberOfMessages int, mailboxNames, bddAddressID, bddUserID string) error { + // It is needed to prevent event processing before syncing these message + // otherwise the seqID and UID will be in reverse order. The + // synchronization add newest message first, the eventloop adds the oldest + // message first. + ctx.MessagePreparationStarted() + defer ctx.MessagePreparationFinished() + account := ctx.GetTestAccountWithAddress(bddUserID, bddAddressID) if account == nil { return godog.ErrPending