diff --git a/.envrc b/.envrc index 5a6fcecd9d5..e01698201b9 100644 --- a/.envrc +++ b/.envrc @@ -57,3 +57,6 @@ export INTEGRATION_DYNAMIC_BACKENDS_POOLSIZE=3 export AWS_REGION="eu-west-1" export AWS_ACCESS_KEY_ID="dummykey" export AWS_SECRET_ACCESS_KEY="dummysecret" + +# integration test suite timeout +export TEST_TIMEOUT_SECONDS=2 diff --git a/changelog.d/2-features/WPB-5241 b/changelog.d/2-features/WPB-5241 new file mode 100644 index 00000000000..9ebf1d1e11d --- /dev/null +++ b/changelog.d/2-features/WPB-5241 @@ -0,0 +1 @@ +add a uniform timeout to the integration test-suite set by the environment variable TEST_TIMEOUT_SECONDS with a default of 10 seconds if the variable isn't set diff --git a/integration/test/MLS/Util.hs b/integration/test/MLS/Util.hs index 10dbd41724a..8e3f850ad0e 100644 --- a/integration/test/MLS/Util.hs +++ b/integration/test/MLS/Util.hs @@ -544,7 +544,7 @@ consumingMessages mp = Codensity $ \k -> do -- each new user and wait for its join event when (mls.protocol == MLSProtocolMLS) $ traverse_ - (awaitMatch 10 isMemberJoinNotif) + (awaitMatch isMemberJoinNotif) ( flip Map.restrictKeys newUsers . Map.mapKeys ((.user) . fst) . Map.fromList @@ -564,7 +564,7 @@ consumingMessages mp = Codensity $ \k -> do consumeMessage :: HasCallStack => ClientIdentity -> Maybe MessagePackage -> WebSocket -> App Value consumeMessage cid mmp ws = do mls <- getMLSState - notif <- awaitMatch 10 isNewMLSMessageNotif ws + notif <- awaitMatch isNewMLSMessageNotif ws event <- notif %. "payload.0" for_ mmp $ \mp -> do @@ -623,7 +623,7 @@ sendAndConsumeCommitBundle mp = do consumeWelcome :: HasCallStack => ClientIdentity -> MessagePackage -> WebSocket -> App () consumeWelcome cid mp ws = do mls <- getMLSState - notif <- awaitMatch 10 isWelcomeNotif ws + notif <- awaitMatch isWelcomeNotif ws event <- notif %. "payload.0" shouldMatch (eventSubConv event) (fromMaybe A.Null mls.convId) diff --git a/integration/test/Notifications.hs b/integration/test/Notifications.hs index 58edd2ec733..861191fce93 100644 --- a/integration/test/Notifications.hs +++ b/integration/test/Notifications.hs @@ -3,6 +3,7 @@ module Notifications where import API.Gundeck import Control.Monad.Extra +import Control.Monad.Reader (asks) import Testlib.Prelude import UnliftIO.Concurrent @@ -11,14 +12,13 @@ awaitNotifications :: user -> client -> Maybe String -> - -- | Timeout in seconds - Int -> -- | Max no. of notifications Int -> -- | Selection function. Should not throw any exceptions (Value -> App Bool) -> App [Value] -awaitNotifications user client since0 tSecs n selector = +awaitNotifications user client since0 n selector = do + tSecs <- asks timeOutSeconds assertAwaitResult =<< go tSecs since0 (AwaitResult False n [] []) where go 0 _ res = pure res @@ -52,12 +52,11 @@ awaitNotification :: user -> client -> Maybe lastNotifId -> - Int -> (Value -> App Bool) -> App Value -awaitNotification user client lastNotifId tSecs selector = do +awaitNotification user client lastNotifId selector = do since0 <- mapM objId lastNotifId - head <$> awaitNotifications user client since0 tSecs 1 selector + head <$> awaitNotifications user client since0 1 selector isDeleteUserNotif :: MakesValue a => a -> App Bool isDeleteUserNotif n = @@ -130,7 +129,6 @@ assertLeaveNotification fromUser conv user client leaver = user client noValue - 2 ( allPreds [ isConvLeaveNotif, isNotifConv conv, diff --git a/integration/test/Test/AccessUpdate.hs b/integration/test/Test/AccessUpdate.hs index c2ed1964e16..c2e6674c015 100644 --- a/integration/test/Test/AccessUpdate.hs +++ b/integration/test/Test/AccessUpdate.hs @@ -115,7 +115,7 @@ testAccessUpdateWithRemotes = do withWebSockets [alice, bob, charlie] $ \wss -> do void $ updateAccess alice conv update >>= getJSON 200 for_ wss $ \ws -> do - notif <- awaitMatch 10 isConvAccessUpdateNotif ws + notif <- awaitMatch isConvAccessUpdateNotif ws notif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv notif %. "payload.0.qualified_from" `shouldMatch` objQidObject alice notif %. "payload.0.data.access" `shouldMatch` update_access_value diff --git a/integration/test/Test/Conversation.hs b/integration/test/Test/Conversation.hs index 4973b171599..d9564dfe3c5 100644 --- a/integration/test/Test/Conversation.hs +++ b/integration/test/Test/Conversation.hs @@ -326,7 +326,7 @@ testAddUnreachableUserFromFederatingBackend = do conv <- postConversation alice (defProteus {qualifiedUsers = [bob, charlie]}) >>= getJSON 201 - forM_ wss $ awaitMatch 5 isMemberJoinNotif + forM_ wss $ awaitMatch isMemberJoinNotif pure conv chadId <- chad %. "qualified_id" pure (alice, chadId, conv) @@ -505,10 +505,10 @@ testSynchroniseUserRemovalNotification = do bindResponse (removeMember alice conv charlie) $ \resp -> resp.status `shouldMatchInt` 200 runCodensity (startDynamicBackend dynBackend mempty) $ \_ -> do - nameNotif <- awaitNotification charlie client noValue 2 isConvNameChangeNotif + nameNotif <- awaitNotification charlie client noValue isConvNameChangeNotif nameNotif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv nameNotif %. "payload.0.data.name" `shouldMatch` newConvName - leaveNotif <- awaitNotification charlie client noValue 2 isConvLeaveNotif + leaveNotif <- awaitNotification charlie client noValue isConvLeaveNotif leaveNotif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv testConvRenaming :: HasCallStack => App () @@ -521,7 +521,7 @@ testConvRenaming = do withWebSockets [alice, bob] $ \wss -> do for_ wss $ \ws -> do void $ changeConversationName alice conv newConvName >>= getBody 200 - nameNotif <- awaitMatch 10 isConvNameChangeNotif ws + nameNotif <- awaitMatch isConvNameChangeNotif ws nameNotif %. "payload.0.data.name" `shouldMatch` newConvName nameNotif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv @@ -534,7 +534,7 @@ testReceiptModeWithRemotesOk = do withWebSockets [alice, bob] $ \wss -> do void $ updateReceiptMode alice conv (43 :: Int) >>= getBody 200 for_ wss $ \ws -> do - notif <- awaitMatch 10 isReceiptModeUpdateNotif ws + notif <- awaitMatch isReceiptModeUpdateNotif ws notif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv notif %. "payload.0.qualified_from" `shouldMatch` objQidObject alice notif %. "payload.0.data.receipt_mode" `shouldMatchInt` 43 @@ -550,7 +550,7 @@ testReceiptModeWithRemotesUnreachable = do >>= getJSON 201 withWebSocket alice $ \ws -> do void $ updateReceiptMode alice conv (43 :: Int) >>= getBody 200 - notif <- awaitMatch 10 isReceiptModeUpdateNotif ws + notif <- awaitMatch isReceiptModeUpdateNotif ws notif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv notif %. "payload.0.qualified_from" `shouldMatch` objQidObject alice notif %. "payload.0.data.receipt_mode" `shouldMatchInt` 43 @@ -608,7 +608,7 @@ testDeleteRemoteMemberRemoteUnreachable = do void $ withWebSockets [alice, bob] $ \wss -> do void $ removeMember alice conv bob >>= getBody 200 for wss $ \ws -> do - leaveNotif <- awaitMatch 10 isConvLeaveNotif ws + leaveNotif <- awaitMatch isConvLeaveNotif ws leaveNotif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv leaveNotif %. "payload.0.qualified_from" `shouldMatch` objQidObject alice leaveNotif %. "payload.0.data.qualified_user_ids.0" `shouldMatch` objQidObject bob @@ -629,7 +629,7 @@ testDeleteTeamConversationWithRemoteMembers = do void $ withWebSockets [alice, bob] $ \wss -> do void $ deleteTeamConversation team conv alice >>= getBody 200 for wss $ \ws -> do - notif <- awaitMatch 10 isConvDeleteNotif ws + notif <- awaitMatch isConvDeleteNotif ws notif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv notif %. "payload.0.qualified_from" `shouldMatch` objQidObject alice @@ -654,10 +654,10 @@ testDeleteTeamConversationWithUnreachableRemoteMembers = do pure (bob, bobClient) withWebSocket alice $ \ws -> do void $ deleteTeamConversation team conv alice >>= getBody 200 - notif <- awaitMatch 10 isConvDeleteNotif ws + notif <- awaitMatch isConvDeleteNotif ws assertNotification notif void $ runCodensity (startDynamicBackend dynBackend mempty) $ \_ -> do - notif <- awaitNotification bob bobClient noValue 2 isConvDeleteNotif + notif <- awaitNotification bob bobClient noValue isConvDeleteNotif assertNotification notif testLeaveConversationSuccess :: HasCallStack => App () @@ -705,7 +705,7 @@ testOnUserDeletedConversations = do void $ withWebSocket alex $ \ws -> do void $ deleteUser bob >>= getBody 200 - n <- awaitMatch 10 isConvLeaveNotif ws + n <- awaitMatch isConvLeaveNotif ws n %. "payload.0.qualified_from" `shouldMatch` bobId n %. "payload.0.qualified_conversation" `shouldMatch` (mainConvBefore %. "qualified_id") @@ -732,7 +732,7 @@ testUpdateConversationByRemoteAdmin = do void $ updateRole alice bob "wire_admin" (conv %. "qualified_id") >>= getBody 200 void $ withWebSockets [alice, bob, charlie] $ \wss -> do void $ updateReceiptMode bob conv (41 :: Int) >>= getBody 200 - for_ wss $ \ws -> awaitMatch 10 isReceiptModeUpdateNotif ws + for_ wss $ \ws -> awaitMatch isReceiptModeUpdateNotif ws testGuestCreatesConversation :: HasCallStack => App () testGuestCreatesConversation = do diff --git a/integration/test/Test/Demo.hs b/integration/test/Test/Demo.hs index 3e73c8be4e9..102d6dc0f59 100644 --- a/integration/test/Test/Demo.hs +++ b/integration/test/Test/Demo.hs @@ -185,7 +185,7 @@ testWebSockets = do user <- randomUser OwnDomain def withWebSocket user $ \ws -> do client <- BrigP.addClient user def >>= getJSON 201 - n <- awaitMatch 3 (\n -> nPayload n %. "type" `isEqual` "user.client-add") ws + n <- awaitMatch (\n -> nPayload n %. "type" `isEqual` "user.client-add") ws nPayload n %. "client.id" `shouldMatch` (client %. "id") testMultipleBackends :: App () diff --git a/integration/test/Test/Federation.hs b/integration/test/Test/Federation.hs index ba584b67bcc..e1960f73f63 100644 --- a/integration/test/Test/Federation.hs +++ b/integration/test/Test/Federation.hs @@ -103,18 +103,18 @@ testNotificationsForOfflineBackends = do isDelUserLeaveUpConvNotif = allPreds [isConvLeaveNotif, isNotifConv upBackendConv, isNotifForUser delUser] do - newMsgNotif <- awaitMatch 10 isNewMessageNotif ws + newMsgNotif <- awaitMatch isNewMessageNotif ws newMsgNotif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject upBackendConv newMsgNotif %. "payload.0.data.text" `shouldMatchBase64` "success message for other user" - void $ awaitMatch 10 isOtherUser2LeaveUpConvNotif ws - void $ awaitMatch 10 isDelUserLeaveUpConvNotif ws + void $ awaitMatch isOtherUser2LeaveUpConvNotif ws + void $ awaitMatch isDelUserLeaveUpConvNotif ws - delUserDeletedNotif <- nPayload $ awaitMatch 10 isDeleteUserNotif ws + delUserDeletedNotif <- nPayload $ awaitMatch isDeleteUserNotif ws objQid delUserDeletedNotif `shouldMatch` objQid delUser runCodensity (startDynamicBackend downBackend mempty) $ \_ -> do - newMsgNotif <- awaitNotification downUser1 downClient1 noValue 5 isNewMessageNotif + newMsgNotif <- awaitNotification downUser1 downClient1 noValue isNewMessageNotif newMsgNotif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject upBackendConv newMsgNotif %. "payload.0.data.text" `shouldMatchBase64` "success message for down user" @@ -124,11 +124,11 @@ testNotificationsForOfflineBackends = do isNotifConv downBackendConv, isNotifForUser delUser ] - void $ awaitNotification downUser1 downClient1 (Just newMsgNotif) 5 isDelUserLeaveDownConvNotif + void $ awaitNotification downUser1 downClient1 (Just newMsgNotif) isDelUserLeaveDownConvNotif -- FUTUREWORK: Uncomment after fixing this bug: https://wearezeta.atlassian.net/browse/WPB-3664 -- void $ awaitNotification downUser1 downClient1 (Just newMsgNotif) 1 isOtherUser2LeaveUpConvNotif -- void $ awaitNotification otherUser otherClient (Just newMsgNotif) 1 isDelUserLeaveDownConvNotif - delUserDeletedNotif <- nPayload $ awaitNotification downUser1 downClient1 (Just newMsgNotif) 5 isDeleteUserNotif + delUserDeletedNotif <- nPayload $ awaitNotification downUser1 downClient1 (Just newMsgNotif) isDeleteUserNotif objQid delUserDeletedNotif `shouldMatch` objQid delUser diff --git a/integration/test/Test/MLS.hs b/integration/test/Test/MLS.hs index cbf41adcf0d..6c58081fbc1 100644 --- a/integration/test/Test/MLS.hs +++ b/integration/test/Test/MLS.hs @@ -27,11 +27,10 @@ testSendMessageNoReturnToSender = do void . bindResponse (postMLSMessage mp.sender mp.message) $ \resp -> do resp.status `shouldMatchInt` 201 for_ wss $ \ws -> do - n <- awaitMatch 3 (\n -> nPayload n %. "type" `isEqual` "conversation.mls-message-add") ws + n <- awaitMatch (\n -> nPayload n %. "type" `isEqual` "conversation.mls-message-add") ws nPayload n %. "data" `shouldMatch` T.decodeUtf8 (Base64.encode mp.message) expectFailure (const $ pure ()) $ awaitMatch - 3 ( \n -> liftM2 (&&) @@ -93,7 +92,7 @@ testMixedProtocolUpgrade secondDomain = do modifyMLSState $ \mls -> mls {protocol = MLSProtocolMixed} for_ websockets $ \ws -> do - n <- awaitMatch 3 (\value -> nPayload value %. "type" `isEqual` "conversation.protocol-update") ws + n <- awaitMatch (\value -> nPayload value %. "type" `isEqual` "conversation.protocol-update") ws nPayload n %. "data.protocol" `shouldMatch` "mixed" bindResponse (getConversation alice qcnv) $ \resp -> do @@ -145,7 +144,7 @@ testMixedProtocolAddUsers secondDomain = do mp <- createAddCommit alice1 [bob] welcome <- assertJust "should have welcome" mp.welcome void $ sendAndConsumeCommitBundle mp - n <- awaitMatch 3 (\n -> nPayload n %. "type" `isEqual` "conversation.mls-welcome") ws + n <- awaitMatch (\n -> nPayload n %. "type" `isEqual` "conversation.mls-welcome") ws nPayload n %. "data" `shouldMatch` T.decodeUtf8 (Base64.encode welcome) testMixedProtocolUserLeaves :: HasCallStack => Domain -> App () @@ -177,7 +176,7 @@ testMixedProtocolUserLeaves secondDomain = do bindResponse (removeConversationMember bob qcnv) $ \resp -> resp.status `shouldMatchInt` 200 - n <- awaitMatch 3 (\n -> nPayload n %. "type" `isEqual` "conversation.mls-message-add") ws + n <- awaitMatch (\n -> nPayload n %. "type" `isEqual` "conversation.mls-message-add") ws msg <- asByteString (nPayload n %. "data") >>= showMessage alice1 let leafIndexBob = 1 @@ -293,7 +292,7 @@ testMLSProtocolUpgrade secondDomain = do -- charlie is added to the group void $ uploadNewKeyPackage charlie1 void $ createAddCommit alice1 [charlie] >>= sendAndConsumeCommitBundle - awaitMatch 10 isNewMLSMessageNotif ws + awaitMatch isNewMLSMessageNotif ws supportMLS alice bindResponse (putConversationProtocol bob conv "mls") $ \resp -> do @@ -310,7 +309,7 @@ testMLSProtocolUpgrade secondDomain = do resp.status `shouldMatchInt` 200 modifyMLSState $ \mls -> mls {protocol = MLSProtocolMLS} for_ wss $ \ws -> do - n <- awaitMatch 3 isNewMLSMessageNotif ws + n <- awaitMatch isNewMLSMessageNotif ws msg <- asByteString (nPayload n %. "data") >>= showMessage alice1 let leafIndexCharlie = 2 msg %. "message.content.body.Proposal.Remove.removed" `shouldMatchInt` leafIndexCharlie @@ -377,7 +376,7 @@ testRemoteRemoveClient = do withWebSocket alice $ \wsAlice -> do void $ deleteClient bob bob1.client >>= getBody 200 let predicate n = nPayload n %. "type" `isEqual` "conversation.mls-message-add" - n <- awaitMatch 5 predicate wsAlice + n <- awaitMatch predicate wsAlice shouldMatch (nPayload n %. "conversation") (objId conv) shouldMatch (nPayload n %. "from") (objId bob) @@ -527,7 +526,7 @@ testLocalWelcome = do es <- sendAndConsumeCommitBundle commit let isWelcome n = nPayload n %. "type" `isEqual` "conversation.mls-welcome" - n <- awaitMatch 5 isWelcome wsBob + n <- awaitMatch isWelcome wsBob shouldMatch (nPayload n %. "conversation") (objId qcnv) shouldMatch (nPayload n %. "from") (objId alice) diff --git a/integration/test/Test/MLS/Message.hs b/integration/test/Test/MLS/Message.hs index f4bfef3e587..3a7c2efc213 100644 --- a/integration/test/Test/MLS/Message.hs +++ b/integration/test/Test/MLS/Message.hs @@ -45,15 +45,15 @@ testApplicationMessage = do withWebSockets [alice, alex, bob, betty] $ \wss -> do -- alice adds all other users (including her own client) void $ createAddCommit alice1 [alice, alex, bob, betty] >>= sendAndConsumeCommitBundle - traverse_ (awaitMatch 10 isMemberJoinNotif) wss + traverse_ (awaitMatch isMemberJoinNotif) wss -- alex sends a message void $ createApplicationMessage alex1 "hello" >>= sendAndConsumeMessage - traverse_ (awaitMatch 10 isNewMLSMessageNotif) wss + traverse_ (awaitMatch isNewMLSMessageNotif) wss -- bob sends a message void $ createApplicationMessage bob1 "hey" >>= sendAndConsumeMessage - traverse_ (awaitMatch 10 isNewMLSMessageNotif) wss + traverse_ (awaitMatch isNewMLSMessageNotif) wss testAppMessageSomeReachable :: HasCallStack => App () testAppMessageSomeReachable = do @@ -67,7 +67,7 @@ testAppMessageSomeReachable = do void $ createNewGroup alice1 void $ withWebSocket charlie $ \ws -> do void $ createAddCommit alice1 [bob, charlie] >>= sendAndConsumeCommitBundle - awaitMatch 10 isMemberJoinNotif ws + awaitMatch isMemberJoinNotif ws pure alice1 -- charlie isn't able to receive this message, so we make sure we can post it @@ -88,7 +88,7 @@ testMessageNotifications bobDomain = do void $ withWebSocket bob $ \ws -> do void $ createAddCommit alice1 [alice, bob] >>= sendAndConsumeCommitBundle - awaitMatch 10 isMemberJoinNotif ws + awaitMatch isMemberJoinNotif ws let get (opts :: GetNotifications) = do notifs <- getNotifications bob opts {size = Just 10000} >>= getJSON 200 @@ -100,7 +100,7 @@ testMessageNotifications bobDomain = do void $ withWebSocket bob $ \ws -> do void $ createApplicationMessage alice1 "hi bob" >>= sendAndConsumeMessage - awaitMatch 10 isNewMLSMessageNotif ws + awaitMatch isNewMLSMessageNotif ws get def `shouldMatchInt` (numNotifs + 1) get def {client = Just bobClient} `shouldMatchInt` (numNotifsClient + 1) @@ -114,10 +114,10 @@ testMultipleMessages = do withWebSockets [bob] $ \wss -> do void $ createAddCommit alice1 [bob] >>= sendAndConsumeCommitBundle - traverse_ (awaitMatch 10 isMemberJoinNotif) wss + traverse_ (awaitMatch isMemberJoinNotif) wss void $ createApplicationMessage alice1 "hello" >>= sendAndConsumeMessage - traverse_ (awaitMatch 10 isNewMLSMessageNotif) wss + traverse_ (awaitMatch isNewMLSMessageNotif) wss void $ createApplicationMessage alice1 "world" >>= sendAndConsumeMessage - traverse_ (awaitMatch 10 isNewMLSMessageNotif) wss + traverse_ (awaitMatch isNewMLSMessageNotif) wss diff --git a/integration/test/Test/MLS/One2One.hs b/integration/test/Test/MLS/One2One.hs index c8935b6cb5c..2252ab344e5 100644 --- a/integration/test/Test/MLS/One2One.hs +++ b/integration/test/Test/MLS/One2One.hs @@ -100,14 +100,14 @@ testMLSOne2One scenario = do void $ sendAndConsumeCommitBundle commit let isWelcome n = nPayload n %. "type" `isEqual` "conversation.mls-welcome" - n <- awaitMatch 3 isWelcome ws + n <- awaitMatch isWelcome ws nPayload n %. "data" `shouldMatch` B8.unpack (Base64.encode (fold commit.welcome)) - void $ awaitMatch 3 isMemberJoinNotif ws + void $ awaitMatch isMemberJoinNotif ws withWebSocket bob1 $ \ws -> do mp <- createApplicationMessage alice1 "hello, world" void $ sendAndConsumeMessage mp let isMessage n = nPayload n %. "type" `isEqual` "conversation.mls-message-add" - n <- awaitMatch 3 isMessage ws + n <- awaitMatch isMessage ws nPayload n %. "data" `shouldMatch` B8.unpack (Base64.encode mp.message) diff --git a/integration/test/Test/MLS/SubConversation.hs b/integration/test/Test/MLS/SubConversation.hs index 4ce961bab03..c66af611187 100644 --- a/integration/test/Test/MLS/SubConversation.hs +++ b/integration/test/Test/MLS/SubConversation.hs @@ -60,7 +60,7 @@ testDeleteParentOfSubConv secondDomain = do withWebSocket bob $ \ws -> do void . bindResponse (deleteTeamConv tid qcnv alice) $ \resp -> do resp.status `shouldMatchInt` 200 - void $ awaitMatch 3 isConvDeleteNotif ws + void $ awaitMatch isConvDeleteNotif ws -- bob fails to send a message to the subconversation do @@ -115,7 +115,7 @@ testLeaveSubConv variant = do withWebSockets [bob, charlie] $ \wss -> do void $ createAddCommit alice1 [bob, charlie] >>= sendAndConsumeCommitBundle - traverse_ (awaitMatch 10 isMemberJoinNotif) wss + traverse_ (awaitMatch isMemberJoinNotif) wss createSubConv bob1 "conference" void $ createExternalCommit alice1 Nothing >>= sendAndConsumeCommitBundle @@ -140,11 +140,11 @@ testLeaveSubConv variant = do withWebSockets (tail others) $ \wss -> do -- a member commits the pending proposal void $ createPendingProposalCommit (head others) >>= sendAndConsumeCommitBundle - traverse_ (awaitMatch 10 isNewMLSMessageNotif) wss + traverse_ (awaitMatch isNewMLSMessageNotif) wss -- send an application message void $ createApplicationMessage (head others) "good riddance" >>= sendAndConsumeMessage - traverse_ (awaitMatch 10 isNewMLSMessageNotif) wss + traverse_ (awaitMatch isNewMLSMessageNotif) wss -- check that only 3 clients are left in the subconv do diff --git a/integration/test/Test/MLS/Unreachable.hs b/integration/test/Test/MLS/Unreachable.hs index 2989cddc750..9ac4e31f387 100644 --- a/integration/test/Test/MLS/Unreachable.hs +++ b/integration/test/Test/MLS/Unreachable.hs @@ -38,7 +38,7 @@ testAddUsersSomeReachable = do void $ createNewGroup alice1 void $ withWebSocket bob $ \ws -> do void $ createAddCommit alice1 [bob] >>= sendAndConsumeCommitBundle - awaitMatch 10 isMemberJoinNotif ws + awaitMatch isMemberJoinNotif ws mp <- createAddCommit alice1 [charlie] pure (mp, thirdDomain) @@ -62,7 +62,7 @@ testAddUserWithUnreachableRemoteUsers = do void $ createNewGroup alice1 void $ withWebSocket charlie $ \ws -> do void $ createAddCommit alice1 [charlie] >>= sendAndConsumeCommitBundle - awaitMatch 10 isMemberJoinNotif ws + awaitMatch isMemberJoinNotif ws pure (alice1, bob, brad, chris) [bob1, brad1] <- traverse (createMLSClient def) [bob, brad] @@ -103,7 +103,7 @@ testAddUnreachableUserFromFederatingBackend = do void $ createNewGroup alice1 withWebSockets [bob, charlie] $ \wss -> do void $ createAddCommit alice1 [bob, charlie] >>= sendAndConsumeCommitBundle - forM_ wss $ awaitMatch 5 isMemberJoinNotif + forM_ wss $ awaitMatch isMemberJoinNotif createAddCommit alice1 [chad] bindResponse (postMLSCommitBundle mp.sender (mkBundle mp)) $ \resp -> do diff --git a/integration/test/Test/MessageTimer.hs b/integration/test/Test/MessageTimer.hs index 7a8aff06c87..9e2e38d4a66 100644 --- a/integration/test/Test/MessageTimer.hs +++ b/integration/test/Test/MessageTimer.hs @@ -33,7 +33,7 @@ testMessageTimerChangeWithRemotes = do withWebSockets [alice, bob] $ \wss -> do void $ updateMessageTimer alice conv 1000 >>= getBody 200 for_ wss $ \ws -> do - notif <- awaitMatch 10 isConvMsgTimerUpdateNotif ws + notif <- awaitMatch isConvMsgTimerUpdateNotif ws notif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv notif %. "payload.0.qualified_from" `shouldMatch` objQidObject alice @@ -48,6 +48,6 @@ testMessageTimerChangeWithUnreachableRemotes = do postConversation alice (defProteus {qualifiedUsers = [bob]}) >>= getJSON 201 withWebSocket alice $ \ws -> do void $ updateMessageTimer alice conv 1000 >>= getBody 200 - notif <- awaitMatch 10 isConvMsgTimerUpdateNotif ws + notif <- awaitMatch isConvMsgTimerUpdateNotif ws notif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv notif %. "payload.0.qualified_from" `shouldMatch` objQidObject alice diff --git a/integration/test/Test/Roles.hs b/integration/test/Test/Roles.hs index 1fde4b95c4b..34ccaff2eba 100644 --- a/integration/test/Test/Roles.hs +++ b/integration/test/Test/Roles.hs @@ -41,7 +41,7 @@ testRoleUpdateWithRemotesOk = do resp.json %. "members.others.0.qualified_id" `shouldMatch` objQidObject charlie resp.json %. "members.others.0.conversation_role" `shouldMatch` "wire_admin" for_ wss $ \ws -> do - notif <- awaitMatch 10 isMemberUpdateNotif ws + notif <- awaitMatch isMemberUpdateNotif ws notif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv notif %. "payload.0.qualified_from" `shouldMatch` objQidObject bob @@ -61,6 +61,6 @@ testRoleUpdateWithRemotesUnreachable = do void $ updateRole bob charlie adminRole conv >>= getBody 200 for_ wss $ \ws -> do - notif <- awaitMatch 10 isMemberUpdateNotif ws + notif <- awaitMatch isMemberUpdateNotif ws notif %. "payload.0.qualified_conversation" `shouldMatch` objQidObject conv notif %. "payload.0.qualified_from" `shouldMatch` objQidObject bob diff --git a/integration/test/Testlib/Cannon.hs b/integration/test/Testlib/Cannon.hs index 4fefd3dfe3f..eb30cd74c5b 100644 --- a/integration/test/Testlib/Cannon.hs +++ b/integration/test/Testlib/Cannon.hs @@ -47,6 +47,7 @@ import Control.Monad import Control.Monad.Catch hiding (bracket) import Control.Monad.Catch qualified as Catch import Control.Monad.IO.Class +import Control.Monad.Reader (asks) import Control.Monad.STM import Data.Aeson (Value (..), decodeStrict') import Data.ByteString (ByteString) @@ -291,13 +292,11 @@ awaitNMatchesResult :: HasCallStack => -- | Number of matches Int -> - -- | Timeout in seconds - Int -> -- | Selection function. Exceptions are *not* caught. (Value -> App Bool) -> WebSocket -> App AwaitResult -awaitNMatchesResult nExpected tSecs checkMatch ws = go nExpected [] [] +awaitNMatchesResult nExpected checkMatch ws = go nExpected [] [] where go 0 nonMatches matches = do refill nonMatches @@ -309,6 +308,7 @@ awaitNMatchesResult nExpected tSecs checkMatch ws = go nExpected [] [] nonMatches = reverse nonMatches } go nLeft nonMatches matches = do + tSecs <- asks timeOutSeconds mEvent <- awaitAnyEvent tSecs ws case mEvent of Just event -> @@ -332,15 +332,14 @@ awaitAtLeastNMatchesResult :: HasCallStack => -- | Minimum number of matches Int -> - -- | Timeout in seconds - Int -> -- | Selection function. Exceptions are *not* caught. (Value -> App Bool) -> WebSocket -> App AwaitAtLeastResult -awaitAtLeastNMatchesResult nExpected tSecs checkMatch ws = go 0 [] [] +awaitAtLeastNMatchesResult nExpected checkMatch ws = go 0 [] [] where go nSeen nonMatches matches = do + tSecs <- asks timeOutSeconds mEvent <- awaitAnyEvent tSecs ws case mEvent of Just event -> @@ -367,15 +366,14 @@ awaitNToMMatchesResult :: Int -> -- | Maximum number of matches Int -> - -- | Timeout in seconds - Int -> -- | Selection function. Exceptions are *not* caught. (Value -> App Bool) -> WebSocket -> App AwaitAtLeastResult -awaitNToMMatchesResult nMin nMax tSecs checkMatch ws = go 0 [] [] +awaitNToMMatchesResult nMin nMax checkMatch ws = go 0 [] [] where go nSeen nonMatches matches = do + tSecs <- asks timeOutSeconds mEvent <- awaitAnyEvent tSecs ws case mEvent of Just event -> @@ -400,14 +398,12 @@ awaitNMatches :: HasCallStack => -- | Number of matches Int -> - -- | Timeout in seconds - Int -> -- | Selection function. Should not throw any exceptions (Value -> App Bool) -> WebSocket -> App [Value] -awaitNMatches nExpected tSecs checkMatch ws = do - res <- awaitNMatchesResult nExpected tSecs checkMatch ws +awaitNMatches nExpected checkMatch ws = do + res <- awaitNMatchesResult nExpected checkMatch ws assertAwaitResult res assertAwaitResult :: HasCallStack => AwaitResult -> App [Value] @@ -423,14 +419,12 @@ awaitAtLeastNMatches :: HasCallStack => -- | Minumum number of matches Int -> - -- | Timeout in seconds - Int -> -- | Selection function. Should not throw any exceptions (Value -> App Bool) -> WebSocket -> App [Value] -awaitAtLeastNMatches nExpected tSecs checkMatch ws = do - res <- awaitAtLeastNMatchesResult nExpected tSecs checkMatch ws +awaitAtLeastNMatches nExpected checkMatch ws = do + res <- awaitAtLeastNMatchesResult nExpected checkMatch ws if res.success then pure res.matches else do @@ -444,14 +438,12 @@ awaitNToMMatches :: Int -> -- | Maximum Number of matches Int -> - -- | Timeout in seconds - Int -> -- | Selection function. Should not throw any exceptions (Value -> App Bool) -> WebSocket -> App [Value] -awaitNToMMatches nMin nMax tSecs checkMatch ws = do - res <- awaitNToMMatchesResult nMin nMax tSecs checkMatch ws +awaitNToMMatches nMin nMax checkMatch ws = do + res <- awaitNToMMatchesResult nMin nMax checkMatch ws if res.success then pure res.matches else do @@ -461,13 +453,11 @@ awaitNToMMatches nMin nMax tSecs checkMatch ws = do awaitMatch :: HasCallStack => - -- | Timeout in seconds - Int -> -- | Selection function. Should not throw any exceptions (Value -> App Bool) -> WebSocket -> App Value -awaitMatch tSecs checkMatch ws = head <$> awaitNMatches 1 tSecs checkMatch ws +awaitMatch checkMatch ws = head <$> awaitNMatches 1 checkMatch ws nPayload :: MakesValue a => a -> App Value nPayload event = do diff --git a/integration/test/Testlib/Env.hs b/integration/test/Testlib/Env.hs index 4a9b680be80..6f82c901c7b 100644 --- a/integration/test/Testlib/Env.hs +++ b/integration/test/Testlib/Env.hs @@ -9,11 +9,13 @@ import Data.Function ((&)) import Data.Functor import Data.IORef import Data.Map qualified as Map +import Data.Maybe (fromMaybe) import Data.Set (Set) import Data.Set qualified as Set import Data.Yaml qualified as Yaml import Database.CQL.IO qualified as Cassandra import Network.HTTP.Client qualified as HTTP +import System.Environment (lookupEnv) import System.Exit import System.FilePath import System.IO @@ -21,6 +23,7 @@ import System.IO.Temp import Testlib.Prekeys import Testlib.ResourcePool import Testlib.Types +import Text.Read (readMaybe) import Prelude serviceHostPort :: ServiceMap -> Service -> HostPort @@ -64,6 +67,9 @@ mkGlobalEnv cfgFile = do intConfig.rabbitmq cassClient tempDir <- Codensity $ withSystemTempDirectory "test" + timeOutSeconds <- + liftIO $ + fromMaybe 10 . (readMaybe @Int =<<) <$> (lookupEnv "TEST_TIMEOUT_SECONDS") pure GlobalEnv { gServiceMap = @@ -80,7 +86,8 @@ mkGlobalEnv cfgFile = do gRemovalKeyPath = error "Uninitialised removal key path", gBackendResourcePool = resourcePool, gRabbitMQConfig = intConfig.rabbitmq, - gTempDir = tempDir + gTempDir = tempDir, + gTimeOutSeconds = timeOutSeconds } mkEnv :: GlobalEnv -> Codensity IO Env @@ -103,7 +110,8 @@ mkEnv ge = do lastPrekeys = lpks, mls = mls, resourcePool = ge.gBackendResourcePool, - rabbitMQConfig = ge.gRabbitMQConfig + rabbitMQConfig = ge.gRabbitMQConfig, + timeOutSeconds = ge.gTimeOutSeconds } destroy :: IORef (Set BackendResource) -> BackendResource -> IO () diff --git a/integration/test/Testlib/Types.hs b/integration/test/Testlib/Types.hs index 557c5d327d4..c88ac445f6c 100644 --- a/integration/test/Testlib/Types.hs +++ b/integration/test/Testlib/Types.hs @@ -107,7 +107,8 @@ data GlobalEnv = GlobalEnv gRemovalKeyPath :: FilePath, gBackendResourcePool :: ResourcePool BackendResource, gRabbitMQConfig :: RabbitMQConfig, - gTempDir :: FilePath + gTempDir :: FilePath, + gTimeOutSeconds :: Int } data IntegrationConfig = IntegrationConfig @@ -181,7 +182,8 @@ data Env = Env lastPrekeys :: IORef [String], mls :: IORef MLSState, resourcePool :: ResourcePool BackendResource, - rabbitMQConfig :: RabbitMQConfig + rabbitMQConfig :: RabbitMQConfig, + timeOutSeconds :: Int } data Response = Response