Skip to content

Commit 87283d7

Browse files
battermannfisxMangoIV
authored
WPB-9733 backport flakiness fixes (#4168)
* WPB-5845 guests should not be able to join conversations under legalhold (#3853) * Clean up LH tests (#3830) * Use HasTests to save a few LOC. * Fix/extend client CRUD api. - moved internal add from API.Brig to API.BrigInternal - created API.BrigCommon for data structured needed in both - added public add * Tranlate tests: manually add/delete client. * Fiddle with test case type abstractions. * Remove obsolete test from integration/test/Test/Demo.hs * Unblock release. (#3871) * WIP: [WPB-5687] port flaking LH tests to new integration (#3876) * [fix] use -e flag to abort when `docker-compose` fails * [feat] make `HasTests` easier to use - delegate only the testcase generation to the user - use an OVERLAPPABLE default instance if the type is a Generic Enum - cover more cases - don't use newtype Wrappers wherever possible * [feat] port over flaking Legalhold tests and delete them from galley integration * [feat] minor testlib improvements and additions --------- Co-authored-by: Matthias Fischmann <mf@zerobuzz.net> * wip * fix integration tests --------- Co-authored-by: fisx <mf@zerobuzz.net> Co-authored-by: Mango The Fourth <40720523+MangoIV@users.noreply.github.com>
1 parent b7f50a2 commit 87283d7

File tree

37 files changed

+1263
-1004
lines changed

37 files changed

+1263
-1004
lines changed

.hlint.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- ignore: { name: Avoid lambda using `infix` }
1212
- ignore: { name: Eta reduce }
1313
- ignore: { name: Use section }
14+
- ignore: { name: "Use :" }
1415
- ignore: { name: Use underscore }
1516

1617
# custom rules:

changelog.d/3-bug-fixes/WPB-5845

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Guests should not be added to conversations that are under legalhold

changelog.d/5-internal/WPB-5687

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
port flaking LH tests to new integration and improve the ergonomics of our testing library
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Translate integration tests: manually add / delete LH device

deploy/dockerephemeral/run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
22

3-
set -x
3+
set -xe
44

55
# run.sh should work no matter what is the current directory
66
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

integration/integration.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ library
9090
-- cabal-fmt: expand test
9191
exposed-modules:
9292
API.Brig
93+
API.BrigCommon
9394
API.BrigInternal
9495
API.Cargohold
9596
API.Common

integration/test/API/Brig.hs

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module API.Brig where
22

3+
import API.BrigCommon
34
import API.Common
45
import qualified Data.Aeson as Aeson
56
import qualified Data.ByteString.Base64 as Base64
@@ -130,6 +131,7 @@ getUserByHandle user domain handle = do
130131
joinHttpPath ["users", "by-handle", domainStr, handle]
131132
submit "GET" req
132133

134+
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/get_clients__client_
133135
getClient ::
134136
(HasCallStack, MakesValue user, MakesValue client) =>
135137
user ->
@@ -142,58 +144,23 @@ getClient u cli = do
142144
joinHttpPath ["clients", c]
143145
submit "GET" req
144146

147+
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/delete_self
145148
deleteUser :: (HasCallStack, MakesValue user) => user -> App Response
146149
deleteUser user = do
147150
req <- baseRequest user Brig Versioned "/self"
148151
submit "DELETE" $
149152
req & addJSONObject ["password" .= defPassword]
150153

151-
data AddClient = AddClient
152-
{ ctype :: String,
153-
internal :: Bool,
154-
clabel :: String,
155-
model :: String,
156-
prekeys :: Maybe [Value],
157-
lastPrekey :: Maybe Value,
158-
password :: String,
159-
acapabilities :: Maybe [String]
160-
}
161-
162-
instance Default AddClient where
163-
def =
164-
AddClient
165-
{ ctype = "permanent",
166-
internal = False,
167-
clabel = "Test Device",
168-
model = "Test Model",
169-
prekeys = Nothing,
170-
lastPrekey = Nothing,
171-
password = defPassword,
172-
acapabilities = Just ["legalhold-implicit-consent"]
173-
}
174-
175-
-- | https://staging-nginz-https.zinfra.io/api-internal/swagger-ui/brig/#/brig/post_i_clients__uid_
154+
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/post_clients
176155
addClient ::
177156
(HasCallStack, MakesValue user) =>
178157
user ->
179158
AddClient ->
180159
App Response
181160
addClient user args = do
182-
uid <- objId user
183-
req <- baseRequest user Brig Unversioned $ "/i/clients/" <> uid
184-
pks <- maybe (fmap pure getPrekey) pure args.prekeys
185-
lpk <- maybe getLastPrekey pure args.lastPrekey
186-
submit "POST" $
187-
req
188-
& addJSONObject
189-
[ "prekeys" .= pks,
190-
"lastkey" .= lpk,
191-
"type" .= args.ctype,
192-
"label" .= args.clabel,
193-
"model" .= args.model,
194-
"password" .= args.password,
195-
"capabilities" .= args.acapabilities
196-
]
161+
req <- baseRequest user Brig Versioned $ "/clients"
162+
val <- mkAddClientValue args
163+
submit "POST" $ req & addJSONObject val
197164

198165
data UpdateClient = UpdateClient
199166
{ prekeys :: [Value],
@@ -230,6 +197,7 @@ updateClient cid args = do
230197
<> ["mls_public_keys" .= k | k <- toList args.mlsPublicKeys]
231198
)
232199

200+
-- | https://staging-nginz-https.zinfra.io/v6/api/swagger-ui/#/default/delete_clients__client_
233201
deleteClient ::
234202
(HasCallStack, MakesValue user, MakesValue client) =>
235203
user ->
@@ -354,9 +322,7 @@ uploadKeyPackages cid kps = do
354322
"/mls/key-packages/self/" <> cid.client
355323
submit
356324
"POST"
357-
( req
358-
& addJSONObject ["key_packages" .= map (T.decodeUtf8 . Base64.encode) kps]
359-
)
325+
(req & addJSONObject ["key_packages" .= map (T.decodeUtf8 . Base64.encode) kps])
360326

361327
claimKeyPackagesWithParams :: (MakesValue u, MakesValue v) => Ciphersuite -> u -> v -> [(String, String)] -> App Response
362328
claimKeyPackagesWithParams suite u v params = do
@@ -368,7 +334,7 @@ claimKeyPackagesWithParams suite u v params = do
368334
req
369335
& addQueryParams ([("ciphersuite", suite.code)] <> params)
370336

371-
claimKeyPackages :: (MakesValue u, MakesValue v) => Ciphersuite -> u -> v -> App Response
337+
claimKeyPackages :: (HasCallStack, MakesValue u, MakesValue v) => Ciphersuite -> u -> v -> App Response
372338
claimKeyPackages suite u v = claimKeyPackagesWithParams suite u v []
373339

374340
countKeyPackages :: Ciphersuite -> ClientIdentity -> App Response
@@ -664,3 +630,9 @@ getMultiUserPrekeyBundle :: (HasCallStack, MakesValue caller, ToJSON userClients
664630
getMultiUserPrekeyBundle caller userClients = do
665631
req <- baseRequest caller Brig Versioned $ joinHttpPath ["users", "list-prekeys"]
666632
submit "POST" (addJSON userClients req)
633+
634+
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/post_access
635+
renewToken :: (HasCallStack, MakesValue uid) => uid -> String -> App Response
636+
renewToken caller cookie = do
637+
req <- baseRequest caller Brig Versioned "access"
638+
submit "POST" (addHeader "Cookie" ("zuid=" <> cookie) req)

integration/test/API/BrigCommon.hs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module API.BrigCommon where
2+
3+
import API.Common
4+
import Data.Aeson.Types (Pair)
5+
import Data.Maybe
6+
import Testlib.Prelude as Prelude
7+
8+
data AddClient = AddClient
9+
{ ctype :: String, -- "temporary", "permanent", "legalhold"
10+
internal :: Bool,
11+
clabel :: String,
12+
model :: String,
13+
prekeys :: Maybe [Value],
14+
lastPrekey :: Maybe Value,
15+
password :: String,
16+
acapabilities :: Maybe [String]
17+
}
18+
19+
instance Default AddClient where
20+
def =
21+
AddClient
22+
{ ctype = "permanent",
23+
internal = False,
24+
clabel = "Test Device",
25+
model = "Test Model",
26+
prekeys = Nothing,
27+
lastPrekey = Nothing,
28+
password = defPassword,
29+
acapabilities = Just ["legalhold-implicit-consent"]
30+
}
31+
32+
mkAddClientValue :: AddClient -> App [Pair]
33+
mkAddClientValue args = do
34+
pks <- maybe (fmap pure getPrekey) pure args.prekeys
35+
lpk <- maybe getLastPrekey pure args.lastPrekey
36+
pure
37+
[ "prekeys" .= pks,
38+
"lastkey" .= lpk,
39+
"type" .= args.ctype,
40+
"label" .= args.clabel,
41+
"model" .= args.model,
42+
"password" .= args.password,
43+
"capabilities" .= args.acapabilities
44+
]

integration/test/API/BrigInternal.hs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module API.BrigInternal where
22

3+
import API.BrigCommon
34
import API.Common
45
import qualified Data.Aeson as Aeson
56
import Data.Aeson.Types (Pair)
@@ -223,3 +224,22 @@ getProviderActivationCodeInternal dom email = do
223224
rawBaseRequest d Brig Unversioned $
224225
joinHttpPath ["i", "provider", "activation-code"]
225226
submit "GET" (addQueryParams [("email", email)] req)
227+
228+
-- | https://staging-nginz-https.zinfra.io/api-internal/swagger-ui/brig/#/brig/post_i_clients__uid_
229+
addClient ::
230+
(HasCallStack, MakesValue user) =>
231+
user ->
232+
AddClient ->
233+
App Response
234+
addClient user args = do
235+
uid <- objId user
236+
req <- baseRequest user Brig Unversioned $ "/i/clients/" <> uid
237+
val <- mkAddClientValue args
238+
submit "POST" $ req & addJSONObject val
239+
240+
-- | https://staging-nginz-https.zinfra.io/api-internal/swagger-ui/brig/#/brig/post_i_clients_full
241+
getClientsFull :: (HasCallStack, MakesValue users, MakesValue uid) => uid -> users -> App Response
242+
getClientsFull user users = do
243+
val <- make users
244+
baseRequest user Brig Unversioned do joinHttpPath ["i", "clients", "full"]
245+
>>= submit "POST" . addJSONObject ["users" .= val]

integration/test/API/Galley.hs

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ postProteusMessage user conv msgs = do
243243
convDomain <- objDomain conv
244244
convId <- objId conv
245245
let bytes = Proto.encodeMessage msgs
246-
req <- baseRequest user Galley Versioned ("/conversations/" <> convDomain <> "/" <> convId <> "/proteus/messages")
246+
req <- baseRequest user Galley Versioned (joinHttpPath ["conversations", convDomain, convId, "proteus", "messages"])
247247
submit "POST" (addProtobuf bytes req)
248248

249249
mkProteusRecipient :: (HasCallStack, MakesValue user, MakesValue client) => user -> client -> String -> App Proto.QualifiedUserEntry
@@ -520,23 +520,47 @@ getTeamMembers user tid = do
520520
req <- baseRequest user Galley Versioned (joinHttpPath ["teams", tidStr, "members"])
521521
submit "GET" req
522522

523+
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/get_teams__tid__legalhold__uid_
524+
legalholdUserStatus :: (HasCallStack, MakesValue tid, MakesValue user, MakesValue owner) => tid -> owner -> user -> App Response
525+
legalholdUserStatus tid ownerid user = do
526+
tidS <- asString tid
527+
uid <- objId user
528+
req <- baseRequest ownerid Galley Versioned (joinHttpPath ["teams", tidS, "legalhold", uid])
529+
submit "GET" req
530+
523531
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/post_teams__tid__legalhold_settings
524532
enableLegalHold :: (HasCallStack, MakesValue tid, MakesValue ownerid) => tid -> ownerid -> App Response
525533
enableLegalHold tid ownerid = do
526534
tidStr <- asString tid
527535
req <- baseRequest ownerid Galley Versioned (joinHttpPath ["teams", tidStr, "features", "legalhold"])
528536
submit "PUT" (addJSONObject ["status" .= "enabled", "ttl" .= "unlimited"] req)
529537

530-
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/post_teams__tid__legalhold_settings
531-
postLegalHoldSettings :: (HasCallStack, MakesValue owner, MakesValue tid, MakesValue newService) => owner -> tid -> newService -> App Response
532-
postLegalHoldSettings owner tid newSettings = retrying policy only412 $ \_ -> do
538+
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/delete_teams__tid__legalhold__uid_
539+
disableLegalHold ::
540+
(HasCallStack, MakesValue tid, MakesValue ownerid, MakesValue uid) =>
541+
tid ->
542+
ownerid ->
543+
uid ->
544+
-- | the password for user with $uid$
545+
String ->
546+
App Response
547+
disableLegalHold tid ownerid uid pw = do
533548
tidStr <- asString tid
534-
req <- baseRequest owner Galley Versioned (joinHttpPath ["teams", tidStr, "legalhold", "settings"])
535-
newSettingsObj <- make newSettings
536-
submit "POST" (addJSON newSettingsObj req)
549+
uidStr <- objId uid
550+
req <- baseRequest ownerid Galley Versioned (joinHttpPath ["teams", tidStr, "legalhold", uidStr])
551+
submit "DELETE" (addJSONObject ["password" .= pw] req)
552+
553+
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/post_teams__tid__legalhold_settings
554+
postLegalHoldSettings :: (HasCallStack, MakesValue ownerid, MakesValue tid, MakesValue newService) => tid -> ownerid -> newService -> App Response
555+
postLegalHoldSettings tid owner newSettings =
556+
asks ((* 1_000_000) . timeOutSeconds) >>= \tSecs -> retrying (policy tSecs) only412 $ \_ -> do
557+
tidStr <- asString tid
558+
req <- baseRequest owner Galley Versioned (joinHttpPath ["teams", tidStr, "legalhold", "settings"])
559+
newSettingsObj <- make newSettings
560+
submit "POST" (addJSON newSettingsObj req)
537561
where
538-
policy :: RetryPolicy
539-
policy = limitRetriesByCumulativeDelay 5_000_000 $ exponentialBackoff 50
562+
policy :: Int -> RetryPolicy
563+
policy tSecs = limitRetriesByCumulativeDelay tSecs $ exponentialBackoff 50
540564

541565
only412 :: RetryStatus -> Response -> App Bool
542566
only412 _ resp = pure $ resp.status == 412
@@ -550,10 +574,18 @@ requestLegalHoldDevice tid ownerid uid = do
550574
submit "POST" req
551575

552576
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/put_teams__tid__legalhold__uid__approve
577+
--
578+
-- like approveLegalHoldDevice' but approves for the requesting party
553579
approveLegalHoldDevice :: (HasCallStack, MakesValue tid, MakesValue uid) => tid -> uid -> String -> App Response
554-
approveLegalHoldDevice tid uid pwd = do
580+
approveLegalHoldDevice tid uid = approveLegalHoldDevice' tid uid uid
581+
582+
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/put_teams__tid__legalhold__uid__approve
583+
--
584+
-- useful for testing unauthorized requests
585+
approveLegalHoldDevice' :: (HasCallStack, MakesValue tid, MakesValue uid, MakesValue forUid) => tid -> uid -> forUid -> String -> App Response
586+
approveLegalHoldDevice' tid uid forUid pwd = do
555587
tidStr <- asString tid
556-
uidStr <- asString $ uid %. "id"
588+
uidStr <- asString $ forUid %. "id"
557589
req <- baseRequest uid Galley Versioned (joinHttpPath ["teams", tidStr, "legalhold", uidStr, "approve"])
558590
submit "PUT" (addJSONObject ["password" .= pwd] req)
559591

@@ -590,3 +622,18 @@ getTeamFeature user tid featureName = do
590622
tidStr <- asString tid
591623
req <- baseRequest user Galley Versioned (joinHttpPath ["teams", tidStr, "features", featureName])
592624
submit "GET" req
625+
626+
-- | https://staging-nginz-https.zinfra.io/v5/api/swagger-ui/#/default/put_teams__tid__features_legalhold
627+
putLegalholdStatus ::
628+
(HasCallStack, MakesValue tid, MakesValue usr) =>
629+
tid ->
630+
usr ->
631+
-- | the status to put to
632+
String ->
633+
App Response
634+
putLegalholdStatus tid usr status = do
635+
tidStr <- asString tid
636+
637+
baseRequest usr Galley Versioned (joinHttpPath ["teams", tidStr, "features", "legalhold"])
638+
>>= submit "PUT"
639+
. addJSONObject ["status" .= status, "ttl" .= "unlimited"]

0 commit comments

Comments
 (0)