From a731237701927951f7bdc761ee968d01584be1cd Mon Sep 17 00:00:00 2001 From: Jakub Date: Tue, 22 Aug 2023 08:35:46 +0200 Subject: [PATCH] test(GODT-2871): tests for new telemetry logic. --- Makefile | 4 +- internal/bridge/api_default.go | 2 +- internal/bridge/api_qa.go | 2 +- internal/services/telemetry/service.go | 18 +- internal/services/telemetry/service_test.go | 4 +- internal/services/userevents/subscription.go | 2 +- internal/user/user_test.go | 17 -- tests/bdd_test.go | 166 +--------------- tests/bridge_test.go | 12 +- tests/main_test.go | 8 +- tests/steps_test.go | 188 +++++++++++++++++++ tests/types_test.go | 4 +- 12 files changed, 221 insertions(+), 206 deletions(-) create mode 100644 tests/steps_test.go diff --git a/Makefile b/Makefile index 321f9463..50dcc62e 100644 --- a/Makefile +++ b/Makefile @@ -246,7 +246,7 @@ test-race: gofiles test-integration: gofiles mkdir -p coverage/integration go test \ - -v -timeout=60m -p=1 -count=1 \ + -v -timeout=60m -p=1 -count=1 -tags=test_integration \ ${GOCOVERAGE} \ github.com/ProtonMail/proton-bridge/v3/tests \ ${GOCOVERDIR}/integration @@ -261,7 +261,7 @@ test-integration-race: gofiles test-integration-nightly: gofiles mkdir -p coverage/integration go test \ - -v -timeout=90m -p=1 -count=1 \ + -v -timeout=90m -p=1 -count=1 -tags=test_integration \ ${GOCOVERAGE} \ github.com/ProtonMail/proton-bridge/v3/tests \ ${GOCOVERDIR}/integration \ diff --git a/internal/bridge/api_default.go b/internal/bridge/api_default.go index 244543f8..78b882f2 100644 --- a/internal/bridge/api_default.go +++ b/internal/bridge/api_default.go @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Proton Mail Bridge. If not, see . -//go:build !build_qa +//go:build !build_qa && !test_integration package bridge diff --git a/internal/bridge/api_qa.go b/internal/bridge/api_qa.go index 6bdcd6d4..049e0a49 100644 --- a/internal/bridge/api_qa.go +++ b/internal/bridge/api_qa.go @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Proton Mail Bridge. If not, see . -//go:build build_qa +//go:build build_qa || test_integration package bridge diff --git a/internal/services/telemetry/service.go b/internal/services/telemetry/service.go index cc378718..6969c24d 100644 --- a/internal/services/telemetry/service.go +++ b/internal/services/telemetry/service.go @@ -51,7 +51,7 @@ func NewService( settingsGetter SettingsGetter, eventService userevents.Subscribable, ) *Service { - s := &Service{ + return &Service{ cpc: cpc.NewCPC(), log: logrus.WithFields(logrus.Fields{ "user": userID, @@ -66,14 +66,10 @@ func NewService( userID: userID, settingsGetter: settingsGetter, } - - s.initialise() - - return s } -func (s *Service) initialise() { - settings, err := s.settingsGetter.GetUserSettings(context.Background()) +func (s *Service) initialise(ctx context.Context) { + settings, err := s.settingsGetter.GetUserSettings(ctx) if err != nil { logrus.WithError(err).Error("Cannot get telemetry settings, asuming off") s.isInitialised = false @@ -88,6 +84,8 @@ func (s *Service) initialise() { } func (s *Service) Start(ctx context.Context, group *orderedtasks.OrderedCancelGroup) { + s.initialise(ctx) + group.Go(ctx, s.userID, "telemetry-service", s.run) } @@ -118,7 +116,7 @@ func (s *Service) run(ctx context.Context) { case *isTelemetryEnabledReq: s.log.Debug("Received is telemetry enabled request") if !s.isInitialised { - s.initialise() + s.initialise(ctx) } request.Reply(ctx, s.isTelemetryEnabled, nil) @@ -137,8 +135,8 @@ func (s *Service) run(ctx context.Context) { } } -func (s *Service) HandleRefreshEvent(_ context.Context, _ proton.RefreshFlag) error { - s.initialise() +func (s *Service) HandleRefreshEvent(ctx context.Context, _ proton.RefreshFlag) error { + s.initialise(ctx) return nil } diff --git a/internal/services/telemetry/service_test.go b/internal/services/telemetry/service_test.go index 5bcbcabc..f296096b 100644 --- a/internal/services/telemetry/service_test.go +++ b/internal/services/telemetry/service_test.go @@ -78,14 +78,14 @@ func TestService_OnUserSettingsEvent(t *testing.T) { mockSettingsGetter, &userevents.NoOpSubscribable{}, ) - - require.True(t, service.isInitialised) + require.False(t, service.isInitialised) ctx := context.Background() group := orderedtasks.NewOrderedCancelGroup(async.NoopPanicHandler{}) defer group.CancelAndWait() service.Start(ctx, group) + require.True(t, service.isInitialised) require.False(t, service.IsTelemetryEnabled(ctx)) require.NoError(t, service.HandleUserSettingsEvent(context.Background(), &proton.UserSettings{Telemetry: proton.SettingEnabled})) diff --git a/internal/services/userevents/subscription.go b/internal/services/userevents/subscription.go index b25b7b7d..3a43b1e7 100644 --- a/internal/services/userevents/subscription.go +++ b/internal/services/userevents/subscription.go @@ -46,7 +46,7 @@ func (e EventHandler) OnEvent(ctx context.Context, event proton.Event) error { } // Start with user settings because of telemetry. - if event.UserSettings != nil { + if event.UserSettings != nil && e.UserSettingsHandler != nil { if err := e.UserSettingsHandler.HandleUserSettingsEvent(ctx, event.UserSettings); err != nil { return fmt.Errorf("failed to apply user event: %w", err) } diff --git a/internal/user/user_test.go b/internal/user/user_test.go index 5055b939..6169447b 100644 --- a/internal/user/user_test.go +++ b/internal/user/user_test.go @@ -85,23 +85,6 @@ func TestUser_AddressMode(t *testing.T) { }) } -func TestUser_Telemetry(t *testing.T) { - withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *proton.Manager) { - withAccount(t, s, "username", "password", []string{}, func(string, []string) { - withUser(t, ctx, s, m, "username", "password", func(user *User) { - // By default, user should have Telemetry enabled. - telemetry := user.IsTelemetryEnabled(ctx) - require.Equal(t, true, telemetry) - - user.client.Close() - // If telemetry cannot be retrieved it is disabled. - telemetry = user.IsTelemetryEnabled(ctx) - require.Equal(t, false, telemetry) - }) - }) - }) -} - func withAPI(_ testing.TB, ctx context.Context, fn func(context.Context, *server.Server, *proton.Manager)) { //nolint:revive server := server.New() defer server.Close() diff --git a/tests/bdd_test.go b/tests/bdd_test.go index 658acbaf..9402c9f0 100644 --- a/tests/bdd_test.go +++ b/tests/bdd_test.go @@ -97,171 +97,7 @@ func TestFeatures(testingT *testing.T) { return ctx, nil }) - // ==== ENVIRONMENT ==== - ctx.Step(`^it succeeds$`, s.itSucceeds) - ctx.Step(`^it fails$`, s.itFails) - ctx.Step(`^it fails with error "([^"]*)"$`, s.itFailsWithError) - ctx.Step(`^the internet is turned off$`, s.internetIsTurnedOff) - ctx.Step(`^the internet is turned on$`, s.internetIsTurnedOn) - ctx.Step(`^the user agent is "([^"]*)"$`, s.theUserAgentIs) - ctx.Step(`^the header in the "([^"]*)" request to "([^"]*)" has "([^"]*)" set to "([^"]*)"$`, s.theHeaderInTheRequestToHasSetTo) - ctx.Step(`^the body in the "([^"]*)" request to "([^"]*)" is:$`, s.theBodyInTheRequestToIs) - ctx.Step(`^the body in the "([^"]*)" response to "([^"]*)" is:$`, s.theBodyInTheResponseToIs) - ctx.Step(`^the API requires bridge version at least "([^"]*)"$`, s.theAPIRequiresBridgeVersion) - ctx.Step(`^the network port (\d+) is busy$`, s.networkPortIsBusy) - ctx.Step(`^the network port range (\d+)-(\d+) is busy$`, s.networkPortRangeIsBusy) - ctx.Step(`^bridge IMAP port is (\d+)`, s.bridgeIMAPPortIs) - ctx.Step(`^bridge SMTP port is (\d+)`, s.bridgeSMTPPortIs) - // ==== SETUP ==== - ctx.Step(`^there exists an account with username "([^"]*)" and password "([^"]*)"$`, s.thereExistsAnAccountWithUsernameAndPassword) - ctx.Step(`^there exists a disabled account with username "([^"]*)" and password "([^"]*)"$`, s.thereExistsAnAccountWithUsernameAndPasswordWithDisablePrimary) - ctx.Step(`^the account "([^"]*)" has additional address "([^"]*)"$`, s.theAccountHasAdditionalAddress) - ctx.Step(`^the account "([^"]*)" has additional disabled address "([^"]*)"$`, s.theAccountHasAdditionalDisabledAddress) - ctx.Step(`^the account "([^"]*)" has additional address "([^"]*)" without keys$`, s.theAccountHasAdditionalAddressWithoutKeys) - ctx.Step(`^the account "([^"]*)" no longer has additional address "([^"]*)"$`, s.theAccountNoLongerHasAdditionalAddress) - ctx.Step(`^the account "([^"]*)" has (\d+) custom folders$`, s.theAccountHasCustomFolders) - ctx.Step(`^the account "([^"]*)" has (\d+) custom labels$`, s.theAccountHasCustomLabels) - ctx.Step(`^the account "([^"]*)" has the following custom mailboxes:$`, s.theAccountHasTheFollowingCustomMailboxes) - ctx.Step(`^the address "([^"]*)" of account "([^"]*)" has the following messages in "([^"]*)":$`, s.theAddressOfAccountHasTheFollowingMessagesInMailbox) - ctx.Step(`^the address "([^"]*)" of account "([^"]*)" has (\d+) messages in "([^"]*)"$`, s.theAddressOfAccountHasMessagesInMailbox) - ctx.Step(`^the following fields were changed in draft (\d+) for address "([^"]*)" of account "([^"]*)":$`, s.theFollowingFieldsWereChangedInDraftForAddressOfAccount) - ctx.Step(`^draft (\d+) for address "([^"]*)" of account "([^"]*)" was moved to trash$`, s.drafAtIndexWasMovedToTrashForAddressOfAccount) - - // === REPORTER === - ctx.Step(`^test skips reporter checks$`, s.skipReporterChecks) - - // ==== BRIDGE ==== - ctx.Step(`^bridge starts$`, s.bridgeStarts) - ctx.Step(`^bridge restarts$`, s.bridgeRestarts) - ctx.Step(`^bridge stops$`, s.bridgeStops) - ctx.Step(`^bridge is version "([^"]*)" and the latest available version is "([^"]*)" reachable from "([^"]*)"$`, s.bridgeVersionIsAndTheLatestAvailableVersionIsReachableFrom) - ctx.Step(`^the user has disabled automatic updates$`, s.theUserHasDisabledAutomaticUpdates) - ctx.Step(`^the user has disabled automatic start`, s.theUserHasDisabledAutomaticStart) - ctx.Step(`^the user has enabled alternative routing`, s.theUserHasEnabledAlternativeRouting) - ctx.Step(`^the user set IMAP mode to SSL`, s.theUserSetIMAPModeToSSL) - ctx.Step(`^the user set SMTP mode to SSL`, s.theUserSetSMTPModeToSSL) - ctx.Step(`^the user changes the IMAP port to (\d+)$`, s.theUserChangesTheIMAPPortTo) - ctx.Step(`^the user changes the SMTP port to (\d+)$`, s.theUserChangesTheSMTPPortTo) - ctx.Step(`^the user sets the address mode of user "([^"]*)" to "([^"]*)"$`, s.theUserSetsTheAddressModeOfUserTo) - ctx.Step(`^the user changes the default keychain application`, s.theUserChangesTheDefaultKeychainApplication) - ctx.Step(`^the user changes the gluon path$`, s.theUserChangesTheGluonPath) - ctx.Step(`^the user deletes the gluon files$`, s.theUserDeletesTheGluonFiles) - ctx.Step(`^the user deletes the gluon cache$`, s.theUserDeletesTheGluonCache) - ctx.Step(`^the user reports a bug$`, s.theUserReportsABug) - ctx.Step(`^the user hides All Mail$`, s.theUserHidesAllMail) - ctx.Step(`^the user shows All Mail$`, s.theUserShowsAllMail) - ctx.Step(`^the user disables telemetry in bridge settings$`, s.theUserDisablesTelemetryInBridgeSettings) - ctx.Step(`^the user enables telemetry in bridge settings$`, s.theUserEnablesTelemetryInBridgeSettings) - ctx.Step(`^bridge sends a connection up event$`, s.bridgeSendsAConnectionUpEvent) - ctx.Step(`^bridge sends a connection down event$`, s.bridgeSendsAConnectionDownEvent) - ctx.Step(`^bridge sends a deauth event for user "([^"]*)"$`, s.bridgeSendsADeauthEventForUser) - ctx.Step(`^bridge sends an address created event for user "([^"]*)"$`, s.bridgeSendsAnAddressCreatedEventForUser) - ctx.Step(`^bridge sends an address deleted event for user "([^"]*)"$`, s.bridgeSendsAnAddressDeletedEventForUser) - ctx.Step(`^bridge sends sync started and finished events for user "([^"]*)"$`, s.bridgeSendsSyncStartedAndFinishedEventsForUser) - ctx.Step(`^bridge sends an update available event for version "([^"]*)"$`, s.bridgeSendsAnUpdateAvailableEventForVersion) - ctx.Step(`^bridge sends a manual update event for version "([^"]*)"$`, s.bridgeSendsAManualUpdateEventForVersion) - ctx.Step(`^bridge sends an update installed event for version "([^"]*)"$`, s.bridgeSendsAnUpdateInstalledEventForVersion) - ctx.Step(`^bridge sends an update not available event$`, s.bridgeSendsAnUpdateNotAvailableEvent) - ctx.Step(`^bridge sends a forced update event$`, s.bridgeSendsAForcedUpdateEvent) - ctx.Step(`^bridge reports a message with "([^"]*)"$`, s.bridgeReportsMessage) - ctx.Step(`^bridge telemetry feature is enabled$`, s.bridgeTelemetryFeatureEnabled) - ctx.Step(`^bridge telemetry feature is disabled$`, s.bridgeTelemetryFeatureDisabled) - - // ==== FRONTEND ==== - ctx.Step(`^frontend sees that bridge is version "([^"]*)"$`, s.frontendSeesThatBridgeIsVersion) - - // ==== USER ==== - ctx.Step(`^the user logs in with username "([^"]*)" and password "([^"]*)"$`, s.userLogsInWithUsernameAndPassword) - ctx.Step(`^user "([^"]*)" logs out$`, s.userLogsOut) - ctx.Step(`^user "([^"]*)" is deleted$`, s.userIsDeleted) - ctx.Step(`^the auth of user "([^"]*)" is revoked$`, s.theAuthOfUserIsRevoked) - ctx.Step(`^user "([^"]*)" is eventually listed and connected$`, s.userIsEventuallyListedAndConnected) - ctx.Step(`^user "([^"]*)" is listed but not connected$`, s.userIsListedButNotConnected) - ctx.Step(`^user "([^"]*)" is not listed$`, s.userIsNotListed) - ctx.Step(`^user "([^"]*)" finishes syncing$`, s.userFinishesSyncing) - ctx.Step(`^user "([^"]*)" has telemetry set to (\d+)$`, s.userHasTelemetrySetTo) - ctx.Step(`^the bridge password of user "([^"]*)" is changed to "([^"]*)"`, s.bridgePasswordOfUserIsChangedTo) - ctx.Step(`^the bridge password of user "([^"]*)" is equal to "([^"]*)"`, s.bridgePasswordOfUserIsEqualTo) - - // ==== IMAP ==== - ctx.Step(`^user "([^"]*)" connects IMAP client "([^"]*)"$`, s.userConnectsIMAPClient) - ctx.Step(`^user "([^"]*)" connects IMAP client "([^"]*)" on port (\d+)$`, s.userConnectsIMAPClientOnPort) - ctx.Step(`^user "([^"]*)" connects and authenticates IMAP client "([^"]*)"$`, s.userConnectsAndAuthenticatesIMAPClient) - ctx.Step(`^user "([^"]*)" connects and authenticates IMAP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndAuthenticatesIMAPClientWithAddress) - ctx.Step(`^user "([^"]*)" connects and can not authenticate IMAP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndCanNotAuthenticateIMAPClientWithAddress) - ctx.Step(`^IMAP client "([^"]*)" can authenticate$`, s.imapClientCanAuthenticate) - ctx.Step(`^IMAP client "([^"]*)" can authenticate with address "([^"]*)"$`, s.imapClientCanAuthenticateWithAddress) - ctx.Step(`^IMAP client "([^"]*)" cannot authenticate$`, s.imapClientCannotAuthenticate) - ctx.Step(`^IMAP client "([^"]*)" cannot authenticate with address "([^"]*)"$`, s.imapClientCannotAuthenticateWithAddress) - ctx.Step(`^IMAP client "([^"]*)" cannot authenticate with incorrect username$`, s.imapClientCannotAuthenticateWithIncorrectUsername) - ctx.Step(`^IMAP client "([^"]*)" cannot authenticate with incorrect password$`, s.imapClientCannotAuthenticateWithIncorrectPassword) - ctx.Step(`^IMAP client "([^"]*)" closes$`, s.imapClientCloses) - ctx.Step(`^IMAP client "([^"]*)" announces its ID with name "([^"]*)" and version "([^"]*)"$`, s.imapClientAnnouncesItsIDWithNameAndVersion) - ctx.Step(`^IMAP client "([^"]*)" creates "([^"]*)"$`, s.imapClientCreatesMailbox) - ctx.Step(`^IMAP client "([^"]*)" deletes "([^"]*)"$`, s.imapClientDeletesMailbox) - ctx.Step(`^IMAP client "([^"]*)" renames "([^"]*)" to "([^"]*)"$`, s.imapClientRenamesMailboxTo) - ctx.Step(`^IMAP client "([^"]*)" eventually sees the following mailbox info:$`, s.imapClientEventuallySeesTheFollowingMailboxInfo) - ctx.Step(`^IMAP client "([^"]*)" sees the following mailbox info for "([^"]*)":$`, s.imapClientSeesTheFollowingMailboxInfoForMailbox) - ctx.Step(`^IMAP client "([^"]*)" sees "([^"]*)"$`, s.imapClientSeesMailbox) - ctx.Step(`^IMAP client "([^"]*)" does not see "([^"]*)"$`, s.imapClientDoesNotSeeMailbox) - ctx.Step(`^IMAP client "([^"]*)" counts (\d+) mailboxes under "([^"]*)"$`, s.imapClientCountsMailboxesUnder) - ctx.Step(`^IMAP client "([^"]*)" selects "([^"]*)"$`, s.imapClientSelectsMailbox) - ctx.Step(`^IMAP client "([^"]*)" copies the message with subject "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.imapClientCopiesTheMessageWithSubjectFromTo) - ctx.Step(`^IMAP client "([^"]*)" copies all messages from "([^"]*)" to "([^"]*)"$`, s.imapClientCopiesAllMessagesFromTo) - ctx.Step(`^IMAP client "([^"]*)" moves the message with subject "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.imapClientMovesTheMessageWithSubjectFromTo) - ctx.Step(`^IMAP client "([^"]*)" moves all messages from "([^"]*)" to "([^"]*)"$`, s.imapClientMovesAllMessagesFromTo) - ctx.Step(`^IMAP client "([^"]*)" eventually sees the following messages in "([^"]*)":$`, s.imapClientEventuallySeesTheFollowingMessagesInMailbox) - ctx.Step(`^IMAP client "([^"]*)" eventually sees (\d+) messages in "([^"]*)"$`, s.imapClientEventuallySeesMessagesInMailbox) - ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as deleted$`, s.imapClientMarksMessageAsDeleted) - ctx.Step(`^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as deleted$`, s.imapClientMarksTheMessageWithSubjectAsDeleted) - ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as not deleted$`, s.imapClientMarksMessageAsNotDeleted) - ctx.Step(`^IMAP client "([^"]*)" marks all messages as deleted$`, s.imapClientMarksAllMessagesAsDeleted) - ctx.Step(`^IMAP client "([^"]*)" expunges$`, s.imapClientExpunges) - ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as "([^"]*)"$`, s.imapClientMarksMessageAsState) - ctx.Step(`^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as "([^"]*)"$`, s.imapClientMarksTheMessageWithSubjectAsState) - ctx.Step(`^IMAP client "([^"]*)" marks all messages as "([^"]*)"$`, s.imapClientMarksAllMessagesAsState) - ctx.Step(`^IMAP client "([^"]*)" eventually sees that message at row (\d+) has the flag "([^"]*)"$`, s.imapClientSeesThatMessageHasTheFlag) - ctx.Step(`^IMAP client "([^"]*)" eventually sees that message at row (\d+) does not have the flag "([^"]*)"$`, s.imapClientSeesThatMessageDoesNotHaveTheFlag) - ctx.Step(`^IMAP client "([^"]*)" eventually sees that the message with subject "([^"]*)" has the flag "([^"]*)"`, s.imapClientSeesThatTheMessageWithSubjectHasTheFlag) - ctx.Step(`^IMAP client "([^"]*)" eventually sees that the message with subject "([^"]*)" does not have the flag "([^"]*)"`, s.imapClientSeesThatTheMessageWithSubjectDoesNotHaveTheFlag) - ctx.Step(`^IMAP client "([^"]*)" eventually sees that all the messages have the flag "([^"]*)"`, s.imapClientSeesThatAllTheMessagesHaveTheFlag) - ctx.Step(`^IMAP client "([^"]*)" eventually sees that all the messages do not have the flag "([^"]*)"`, s.imapClientSeesThatAllTheMessagesDoNotHaveTheFlag) - ctx.Step(`^IMAP client "([^"]*)" appends the following message to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessageToMailbox) - ctx.Step(`^IMAP client "([^"]*)" appends the following messages to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessagesToMailbox) - ctx.Step(`^IMAP client "([^"]*)" appends "([^"]*)" to "([^"]*)"$`, s.imapClientAppendsToMailbox) - ctx.Step(`^IMAP clients "([^"]*)" and "([^"]*)" move message with subject "([^"]*)" of "([^"]*)" to "([^"]*)" by ([^"]*) ([^"]*) ([^"]*)`, s.imapClientsMoveMessageWithSubjectUserFromToByOrderedOperations) - ctx.Step(`^IMAP client "([^"]*)" sees header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientSeesHeaderInMessageWithSubject) - ctx.Step(`^IMAP client "([^"]*)" does not see header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientDoesNotSeeHeaderInMessageWithSubject) - - // ==== SMTP ==== - ctx.Step(`^user "([^"]*)" connects SMTP client "([^"]*)"$`, s.userConnectsSMTPClient) - ctx.Step(`^user "([^"]*)" connects SMTP client "([^"]*)" on port (\d+)$`, s.userConnectsSMTPClientOnPort) - ctx.Step(`^user "([^"]*)" connects and authenticates SMTP client "([^"]*)"$`, s.userConnectsAndAuthenticatesSMTPClient) - ctx.Step(`^user "([^"]*)" connects and authenticates SMTP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndAuthenticatesSMTPClientWithAddress) - ctx.Step(`^SMTP client "([^"]*)" can authenticate$`, s.smtpClientCanAuthenticate) - ctx.Step(`^SMTP client "([^"]*)" cannot authenticate$`, s.smtpClientCannotAuthenticate) - ctx.Step(`^SMTP client "([^"]*)" cannot authenticate with incorrect username$`, s.smtpClientCannotAuthenticateWithIncorrectUsername) - ctx.Step(`^SMTP client "([^"]*)" cannot authenticate with incorrect password$`, s.smtpClientCannotAuthenticateWithIncorrectPassword) - ctx.Step(`^SMTP client "([^"]*)" sends MAIL FROM "([^"]*)"$`, s.smtpClientSendsMailFrom) - ctx.Step(`^SMTP client "([^"]*)" sends RCPT TO "([^"]*)"$`, s.smtpClientSendsRcptTo) - ctx.Step(`^SMTP client "([^"]*)" sends DATA:$`, s.smtpClientSendsData) - ctx.Step(`^SMTP client "([^"]*)" sends RSET$`, s.smtpClientSendsReset) - ctx.Step(`^SMTP client "([^"]*)" sends the following message from "([^"]*)" to "([^"]*)":$`, s.smtpClientSendsTheFollowingMessageFromTo) - ctx.Step(`^SMTP client "([^"]*)" sends the following EML "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.smtpClientSendsTheFollowingEmlFromTo) - ctx.Step(`^SMTP client "([^"]*)" logs out$`, s.smtpClientLogsOut) - - // ==== TELEMETRY ==== - ctx.Step(`^bridge eventually sends the following heartbeat:$`, s.bridgeEventuallySendsTheFollowingHeartbeat) - ctx.Step(`^bridge needs to send heartbeat`, s.bridgeNeedsToSendHeartbeat) - ctx.Step(`^bridge do not need to send heartbeat`, s.bridgeDoNotNeedToSendHeartbeat) - ctx.Step(`^heartbeat is not whitelisted`, s.heartbeatIsNotwhitelisted) - ctx.Step(`^config status file exist for user "([^"]*)"$`, s.configStatusFileExistForUser) - ctx.Step(`^config status is pending for user "([^"]*)"$`, s.configStatusIsPendingForUser) - ctx.Step(`^config status is pending with failure for user "([^"]*)"$`, s.configStatusIsPendingWithFailureForUser) - ctx.Step(`^config status succeed for user "([^"]*)"$`, s.configStatusSucceedForUser) - ctx.Step(`^config status event "([^"]*)" is eventually send (\d+) time`, s.configStatusEventIsEventuallySendXTime) - ctx.Step(`^config status event "([^"]*)" is not send more than (\d+) time`, s.configStatusEventIsNotSendMoreThanXTime) - ctx.Step(`^force config status progress to be sent for user"([^"]*)"$`, s.forceConfigStatusProgressToBeSentForUser) + s.steps(ctx) }, Options: &godog.Options{ Format: "pretty", diff --git a/tests/bridge_test.go b/tests/bridge_test.go index 2be4aece..df346e08 100644 --- a/tests/bridge_test.go +++ b/tests/bridge_test.go @@ -320,11 +320,13 @@ func (s *scenario) bridgeTelemetryFeatureDisabled() error { } func (s *scenario) checkTelemetry(expect bool) error { - res := s.t.bridge.IsTelemetryAvailable(context.Background()) - if res != expect { - return fmt.Errorf("expected telemetry feature %v but got %v ", expect, res) - } - return nil + return eventually(func() error { + res := s.t.bridge.IsTelemetryAvailable(context.Background()) + if res != expect { + return fmt.Errorf("expected telemetry feature %v but got %v ", expect, res) + } + return nil + }) } func (s *scenario) theUserHidesAllMail() error { diff --git a/tests/main_test.go b/tests/main_test.go index e568f9fa..4bf3e1e6 100644 --- a/tests/main_test.go +++ b/tests/main_test.go @@ -26,7 +26,13 @@ import ( ) func TestMain(m *testing.M) { - if level := os.Getenv("FEATURE_TEST_LOG_LEVEL"); level != "" { + level := os.Getenv("FEATURE_TEST_LOG_LEVEL") + + if os.Getenv("BRIDGE_API_DEBUG") != "" { + level = "trace" + } + + if level != "" { if parsed, err := logrus.ParseLevel(level); err == nil { logrus.SetLevel(parsed) } diff --git a/tests/steps_test.go b/tests/steps_test.go new file mode 100644 index 00000000..98269da3 --- /dev/null +++ b/tests/steps_test.go @@ -0,0 +1,188 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge.Bridge. +// +// Proton Mail 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. +// +// Proton Mail 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 Proton Mail Bridge. If not, see . + +package tests + +import "github.com/cucumber/godog" + +func (s *scenario) steps(ctx *godog.ScenarioContext) { + // ==== ENVIRONMENT ==== + ctx.Step(`^it succeeds$`, s.itSucceeds) + ctx.Step(`^it fails$`, s.itFails) + ctx.Step(`^it fails with error "([^"]*)"$`, s.itFailsWithError) + ctx.Step(`^the internet is turned off$`, s.internetIsTurnedOff) + ctx.Step(`^the internet is turned on$`, s.internetIsTurnedOn) + ctx.Step(`^the user agent is "([^"]*)"$`, s.theUserAgentIs) + ctx.Step(`^the header in the "([^"]*)" request to "([^"]*)" has "([^"]*)" set to "([^"]*)"$`, s.theHeaderInTheRequestToHasSetTo) + ctx.Step(`^the body in the "([^"]*)" request to "([^"]*)" is:$`, s.theBodyInTheRequestToIs) + ctx.Step(`^the body in the "([^"]*)" response to "([^"]*)" is:$`, s.theBodyInTheResponseToIs) + ctx.Step(`^the API requires bridge version at least "([^"]*)"$`, s.theAPIRequiresBridgeVersion) + ctx.Step(`^the network port (\d+) is busy$`, s.networkPortIsBusy) + ctx.Step(`^the network port range (\d+)-(\d+) is busy$`, s.networkPortRangeIsBusy) + ctx.Step(`^bridge IMAP port is (\d+)`, s.bridgeIMAPPortIs) + ctx.Step(`^bridge SMTP port is (\d+)`, s.bridgeSMTPPortIs) + // ==== SETUP ==== + ctx.Step(`^there exists an account with username "([^"]*)" and password "([^"]*)"$`, s.thereExistsAnAccountWithUsernameAndPassword) + ctx.Step(`^there exists a disabled account with username "([^"]*)" and password "([^"]*)"$`, s.thereExistsAnAccountWithUsernameAndPasswordWithDisablePrimary) + ctx.Step(`^the account "([^"]*)" has additional address "([^"]*)"$`, s.theAccountHasAdditionalAddress) + ctx.Step(`^the account "([^"]*)" has additional disabled address "([^"]*)"$`, s.theAccountHasAdditionalDisabledAddress) + ctx.Step(`^the account "([^"]*)" has additional address "([^"]*)" without keys$`, s.theAccountHasAdditionalAddressWithoutKeys) + ctx.Step(`^the account "([^"]*)" no longer has additional address "([^"]*)"$`, s.theAccountNoLongerHasAdditionalAddress) + ctx.Step(`^the account "([^"]*)" has (\d+) custom folders$`, s.theAccountHasCustomFolders) + ctx.Step(`^the account "([^"]*)" has (\d+) custom labels$`, s.theAccountHasCustomLabels) + ctx.Step(`^the account "([^"]*)" has the following custom mailboxes:$`, s.theAccountHasTheFollowingCustomMailboxes) + ctx.Step(`^the address "([^"]*)" of account "([^"]*)" has the following messages in "([^"]*)":$`, s.theAddressOfAccountHasTheFollowingMessagesInMailbox) + ctx.Step(`^the address "([^"]*)" of account "([^"]*)" has (\d+) messages in "([^"]*)"$`, s.theAddressOfAccountHasMessagesInMailbox) + ctx.Step(`^the following fields were changed in draft (\d+) for address "([^"]*)" of account "([^"]*)":$`, s.theFollowingFieldsWereChangedInDraftForAddressOfAccount) + ctx.Step(`^draft (\d+) for address "([^"]*)" of account "([^"]*)" was moved to trash$`, s.drafAtIndexWasMovedToTrashForAddressOfAccount) + + // === REPORTER === + ctx.Step(`^test skips reporter checks$`, s.skipReporterChecks) + + // ==== BRIDGE ==== + ctx.Step(`^bridge starts$`, s.bridgeStarts) + ctx.Step(`^bridge restarts$`, s.bridgeRestarts) + ctx.Step(`^bridge stops$`, s.bridgeStops) + ctx.Step(`^bridge is version "([^"]*)" and the latest available version is "([^"]*)" reachable from "([^"]*)"$`, s.bridgeVersionIsAndTheLatestAvailableVersionIsReachableFrom) + ctx.Step(`^the user has disabled automatic updates$`, s.theUserHasDisabledAutomaticUpdates) + ctx.Step(`^the user has disabled automatic start`, s.theUserHasDisabledAutomaticStart) + ctx.Step(`^the user has enabled alternative routing`, s.theUserHasEnabledAlternativeRouting) + ctx.Step(`^the user set IMAP mode to SSL`, s.theUserSetIMAPModeToSSL) + ctx.Step(`^the user set SMTP mode to SSL`, s.theUserSetSMTPModeToSSL) + ctx.Step(`^the user changes the IMAP port to (\d+)$`, s.theUserChangesTheIMAPPortTo) + ctx.Step(`^the user changes the SMTP port to (\d+)$`, s.theUserChangesTheSMTPPortTo) + ctx.Step(`^the user sets the address mode of user "([^"]*)" to "([^"]*)"$`, s.theUserSetsTheAddressModeOfUserTo) + ctx.Step(`^the user changes the default keychain application`, s.theUserChangesTheDefaultKeychainApplication) + ctx.Step(`^the user changes the gluon path$`, s.theUserChangesTheGluonPath) + ctx.Step(`^the user deletes the gluon files$`, s.theUserDeletesTheGluonFiles) + ctx.Step(`^the user deletes the gluon cache$`, s.theUserDeletesTheGluonCache) + ctx.Step(`^the user reports a bug$`, s.theUserReportsABug) + ctx.Step(`^the user hides All Mail$`, s.theUserHidesAllMail) + ctx.Step(`^the user shows All Mail$`, s.theUserShowsAllMail) + ctx.Step(`^the user disables telemetry in bridge settings$`, s.theUserDisablesTelemetryInBridgeSettings) + ctx.Step(`^the user enables telemetry in bridge settings$`, s.theUserEnablesTelemetryInBridgeSettings) + ctx.Step(`^bridge sends a connection up event$`, s.bridgeSendsAConnectionUpEvent) + ctx.Step(`^bridge sends a connection down event$`, s.bridgeSendsAConnectionDownEvent) + ctx.Step(`^bridge sends a deauth event for user "([^"]*)"$`, s.bridgeSendsADeauthEventForUser) + ctx.Step(`^bridge sends an address created event for user "([^"]*)"$`, s.bridgeSendsAnAddressCreatedEventForUser) + ctx.Step(`^bridge sends an address deleted event for user "([^"]*)"$`, s.bridgeSendsAnAddressDeletedEventForUser) + ctx.Step(`^bridge sends sync started and finished events for user "([^"]*)"$`, s.bridgeSendsSyncStartedAndFinishedEventsForUser) + ctx.Step(`^bridge sends an update available event for version "([^"]*)"$`, s.bridgeSendsAnUpdateAvailableEventForVersion) + ctx.Step(`^bridge sends a manual update event for version "([^"]*)"$`, s.bridgeSendsAManualUpdateEventForVersion) + ctx.Step(`^bridge sends an update installed event for version "([^"]*)"$`, s.bridgeSendsAnUpdateInstalledEventForVersion) + ctx.Step(`^bridge sends an update not available event$`, s.bridgeSendsAnUpdateNotAvailableEvent) + ctx.Step(`^bridge sends a forced update event$`, s.bridgeSendsAForcedUpdateEvent) + ctx.Step(`^bridge reports a message with "([^"]*)"$`, s.bridgeReportsMessage) + ctx.Step(`^bridge telemetry feature is enabled$`, s.bridgeTelemetryFeatureEnabled) + ctx.Step(`^bridge telemetry feature is disabled$`, s.bridgeTelemetryFeatureDisabled) + + // ==== FRONTEND ==== + ctx.Step(`^frontend sees that bridge is version "([^"]*)"$`, s.frontendSeesThatBridgeIsVersion) + + // ==== USER ==== + ctx.Step(`^the user logs in with username "([^"]*)" and password "([^"]*)"$`, s.userLogsInWithUsernameAndPassword) + ctx.Step(`^user "([^"]*)" logs out$`, s.userLogsOut) + ctx.Step(`^user "([^"]*)" is deleted$`, s.userIsDeleted) + ctx.Step(`^the auth of user "([^"]*)" is revoked$`, s.theAuthOfUserIsRevoked) + ctx.Step(`^user "([^"]*)" is eventually listed and connected$`, s.userIsEventuallyListedAndConnected) + ctx.Step(`^user "([^"]*)" is listed but not connected$`, s.userIsListedButNotConnected) + ctx.Step(`^user "([^"]*)" is not listed$`, s.userIsNotListed) + ctx.Step(`^user "([^"]*)" finishes syncing$`, s.userFinishesSyncing) + ctx.Step(`^user "([^"]*)" has telemetry set to (\d+)$`, s.userHasTelemetrySetTo) + ctx.Step(`^the bridge password of user "([^"]*)" is changed to "([^"]*)"`, s.bridgePasswordOfUserIsChangedTo) + ctx.Step(`^the bridge password of user "([^"]*)" is equal to "([^"]*)"`, s.bridgePasswordOfUserIsEqualTo) + + // ==== IMAP ==== + ctx.Step(`^user "([^"]*)" connects IMAP client "([^"]*)"$`, s.userConnectsIMAPClient) + ctx.Step(`^user "([^"]*)" connects IMAP client "([^"]*)" on port (\d+)$`, s.userConnectsIMAPClientOnPort) + ctx.Step(`^user "([^"]*)" connects and authenticates IMAP client "([^"]*)"$`, s.userConnectsAndAuthenticatesIMAPClient) + ctx.Step(`^user "([^"]*)" connects and authenticates IMAP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndAuthenticatesIMAPClientWithAddress) + ctx.Step(`^user "([^"]*)" connects and can not authenticate IMAP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndCanNotAuthenticateIMAPClientWithAddress) + ctx.Step(`^IMAP client "([^"]*)" can authenticate$`, s.imapClientCanAuthenticate) + ctx.Step(`^IMAP client "([^"]*)" can authenticate with address "([^"]*)"$`, s.imapClientCanAuthenticateWithAddress) + ctx.Step(`^IMAP client "([^"]*)" cannot authenticate$`, s.imapClientCannotAuthenticate) + ctx.Step(`^IMAP client "([^"]*)" cannot authenticate with address "([^"]*)"$`, s.imapClientCannotAuthenticateWithAddress) + ctx.Step(`^IMAP client "([^"]*)" cannot authenticate with incorrect username$`, s.imapClientCannotAuthenticateWithIncorrectUsername) + ctx.Step(`^IMAP client "([^"]*)" cannot authenticate with incorrect password$`, s.imapClientCannotAuthenticateWithIncorrectPassword) + ctx.Step(`^IMAP client "([^"]*)" closes$`, s.imapClientCloses) + ctx.Step(`^IMAP client "([^"]*)" announces its ID with name "([^"]*)" and version "([^"]*)"$`, s.imapClientAnnouncesItsIDWithNameAndVersion) + ctx.Step(`^IMAP client "([^"]*)" creates "([^"]*)"$`, s.imapClientCreatesMailbox) + ctx.Step(`^IMAP client "([^"]*)" deletes "([^"]*)"$`, s.imapClientDeletesMailbox) + ctx.Step(`^IMAP client "([^"]*)" renames "([^"]*)" to "([^"]*)"$`, s.imapClientRenamesMailboxTo) + ctx.Step(`^IMAP client "([^"]*)" eventually sees the following mailbox info:$`, s.imapClientEventuallySeesTheFollowingMailboxInfo) + ctx.Step(`^IMAP client "([^"]*)" sees the following mailbox info for "([^"]*)":$`, s.imapClientSeesTheFollowingMailboxInfoForMailbox) + ctx.Step(`^IMAP client "([^"]*)" sees "([^"]*)"$`, s.imapClientSeesMailbox) + ctx.Step(`^IMAP client "([^"]*)" does not see "([^"]*)"$`, s.imapClientDoesNotSeeMailbox) + ctx.Step(`^IMAP client "([^"]*)" counts (\d+) mailboxes under "([^"]*)"$`, s.imapClientCountsMailboxesUnder) + ctx.Step(`^IMAP client "([^"]*)" selects "([^"]*)"$`, s.imapClientSelectsMailbox) + ctx.Step(`^IMAP client "([^"]*)" copies the message with subject "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.imapClientCopiesTheMessageWithSubjectFromTo) + ctx.Step(`^IMAP client "([^"]*)" copies all messages from "([^"]*)" to "([^"]*)"$`, s.imapClientCopiesAllMessagesFromTo) + ctx.Step(`^IMAP client "([^"]*)" moves the message with subject "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.imapClientMovesTheMessageWithSubjectFromTo) + ctx.Step(`^IMAP client "([^"]*)" moves all messages from "([^"]*)" to "([^"]*)"$`, s.imapClientMovesAllMessagesFromTo) + ctx.Step(`^IMAP client "([^"]*)" eventually sees the following messages in "([^"]*)":$`, s.imapClientEventuallySeesTheFollowingMessagesInMailbox) + ctx.Step(`^IMAP client "([^"]*)" eventually sees (\d+) messages in "([^"]*)"$`, s.imapClientEventuallySeesMessagesInMailbox) + ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as deleted$`, s.imapClientMarksMessageAsDeleted) + ctx.Step(`^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as deleted$`, s.imapClientMarksTheMessageWithSubjectAsDeleted) + ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as not deleted$`, s.imapClientMarksMessageAsNotDeleted) + ctx.Step(`^IMAP client "([^"]*)" marks all messages as deleted$`, s.imapClientMarksAllMessagesAsDeleted) + ctx.Step(`^IMAP client "([^"]*)" expunges$`, s.imapClientExpunges) + ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as "([^"]*)"$`, s.imapClientMarksMessageAsState) + ctx.Step(`^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as "([^"]*)"$`, s.imapClientMarksTheMessageWithSubjectAsState) + ctx.Step(`^IMAP client "([^"]*)" marks all messages as "([^"]*)"$`, s.imapClientMarksAllMessagesAsState) + ctx.Step(`^IMAP client "([^"]*)" eventually sees that message at row (\d+) has the flag "([^"]*)"$`, s.imapClientSeesThatMessageHasTheFlag) + ctx.Step(`^IMAP client "([^"]*)" eventually sees that message at row (\d+) does not have the flag "([^"]*)"$`, s.imapClientSeesThatMessageDoesNotHaveTheFlag) + ctx.Step(`^IMAP client "([^"]*)" eventually sees that the message with subject "([^"]*)" has the flag "([^"]*)"`, s.imapClientSeesThatTheMessageWithSubjectHasTheFlag) + ctx.Step(`^IMAP client "([^"]*)" eventually sees that the message with subject "([^"]*)" does not have the flag "([^"]*)"`, s.imapClientSeesThatTheMessageWithSubjectDoesNotHaveTheFlag) + ctx.Step(`^IMAP client "([^"]*)" eventually sees that all the messages have the flag "([^"]*)"`, s.imapClientSeesThatAllTheMessagesHaveTheFlag) + ctx.Step(`^IMAP client "([^"]*)" eventually sees that all the messages do not have the flag "([^"]*)"`, s.imapClientSeesThatAllTheMessagesDoNotHaveTheFlag) + ctx.Step(`^IMAP client "([^"]*)" appends the following message to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessageToMailbox) + ctx.Step(`^IMAP client "([^"]*)" appends the following messages to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessagesToMailbox) + ctx.Step(`^IMAP client "([^"]*)" appends "([^"]*)" to "([^"]*)"$`, s.imapClientAppendsToMailbox) + ctx.Step(`^IMAP clients "([^"]*)" and "([^"]*)" move message with subject "([^"]*)" of "([^"]*)" to "([^"]*)" by ([^"]*) ([^"]*) ([^"]*)`, s.imapClientsMoveMessageWithSubjectUserFromToByOrderedOperations) + ctx.Step(`^IMAP client "([^"]*)" sees header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientSeesHeaderInMessageWithSubject) + ctx.Step(`^IMAP client "([^"]*)" does not see header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientDoesNotSeeHeaderInMessageWithSubject) + + // ==== SMTP ==== + ctx.Step(`^user "([^"]*)" connects SMTP client "([^"]*)"$`, s.userConnectsSMTPClient) + ctx.Step(`^user "([^"]*)" connects SMTP client "([^"]*)" on port (\d+)$`, s.userConnectsSMTPClientOnPort) + ctx.Step(`^user "([^"]*)" connects and authenticates SMTP client "([^"]*)"$`, s.userConnectsAndAuthenticatesSMTPClient) + ctx.Step(`^user "([^"]*)" connects and authenticates SMTP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndAuthenticatesSMTPClientWithAddress) + ctx.Step(`^SMTP client "([^"]*)" can authenticate$`, s.smtpClientCanAuthenticate) + ctx.Step(`^SMTP client "([^"]*)" cannot authenticate$`, s.smtpClientCannotAuthenticate) + ctx.Step(`^SMTP client "([^"]*)" cannot authenticate with incorrect username$`, s.smtpClientCannotAuthenticateWithIncorrectUsername) + ctx.Step(`^SMTP client "([^"]*)" cannot authenticate with incorrect password$`, s.smtpClientCannotAuthenticateWithIncorrectPassword) + ctx.Step(`^SMTP client "([^"]*)" sends MAIL FROM "([^"]*)"$`, s.smtpClientSendsMailFrom) + ctx.Step(`^SMTP client "([^"]*)" sends RCPT TO "([^"]*)"$`, s.smtpClientSendsRcptTo) + ctx.Step(`^SMTP client "([^"]*)" sends DATA:$`, s.smtpClientSendsData) + ctx.Step(`^SMTP client "([^"]*)" sends RSET$`, s.smtpClientSendsReset) + ctx.Step(`^SMTP client "([^"]*)" sends the following message from "([^"]*)" to "([^"]*)":$`, s.smtpClientSendsTheFollowingMessageFromTo) + ctx.Step(`^SMTP client "([^"]*)" sends the following EML "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.smtpClientSendsTheFollowingEmlFromTo) + ctx.Step(`^SMTP client "([^"]*)" logs out$`, s.smtpClientLogsOut) + + // ==== TELEMETRY ==== + ctx.Step(`^bridge eventually sends the following heartbeat:$`, s.bridgeEventuallySendsTheFollowingHeartbeat) + ctx.Step(`^bridge needs to send heartbeat`, s.bridgeNeedsToSendHeartbeat) + ctx.Step(`^bridge do not need to send heartbeat`, s.bridgeDoNotNeedToSendHeartbeat) + ctx.Step(`^heartbeat is not whitelisted`, s.heartbeatIsNotwhitelisted) + ctx.Step(`^config status file exist for user "([^"]*)"$`, s.configStatusFileExistForUser) + ctx.Step(`^config status is pending for user "([^"]*)"$`, s.configStatusIsPendingForUser) + ctx.Step(`^config status is pending with failure for user "([^"]*)"$`, s.configStatusIsPendingWithFailureForUser) + ctx.Step(`^config status succeed for user "([^"]*)"$`, s.configStatusSucceedForUser) + ctx.Step(`^config status event "([^"]*)" is eventually send (\d+) time`, s.configStatusEventIsEventuallySendXTime) + ctx.Step(`^config status event "([^"]*)" is not send more than (\d+) time`, s.configStatusEventIsNotSendMoreThanXTime) + ctx.Step(`^force config status progress to be sent for user"([^"]*)"$`, s.forceConfigStatusProgressToBeSentForUser) +} diff --git a/tests/types_test.go b/tests/types_test.go index 183637d6..e654635d 100644 --- a/tests/types_test.go +++ b/tests/types_test.go @@ -214,6 +214,7 @@ func matchMailboxes(have, want []Mailbox) error { func eventually(condition func() error) error { ch := make(chan error, 1) + var lastErr error var timerDuration = 30 * time.Second // Extend to 5min for live API. @@ -230,7 +231,7 @@ func eventually(condition func() error) error { for tick := ticker.C; ; { select { case <-timer.C: - return fmt.Errorf("timed out") + return fmt.Errorf("timed out: %w", lastErr) case <-tick: tick = nil @@ -242,6 +243,7 @@ func eventually(condition func() error) error { return nil } + lastErr = err tick = ticker.C } }