Skip to content

Commit

Permalink
Prekeys investigation: test (#2694)
Browse files Browse the repository at this point in the history
* log randomPrekey state of things

* Add an integration test to ensure list of prekeys does not become empty.

This test should also run for the dynamoDB case, to ensure our
implementation isn't buggy (it probably isn't, but to check for
regressions)

* add another test for last prekey validation

* Add one more test, fix warning from previous test

* logging on startup: log using info level, not warning

* fixup: expected status code is 201, not 200

* remove commented out code

* changelog

* linter? make format doesn't work; or local/CI don't agree
  • Loading branch information
jschaul authored Jan 23, 2023
1 parent 8c589be commit a0f44f6
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 3 deletions.
1 change: 1 addition & 0 deletions changelog.d/5-internal/pr-2694
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add two integration tests arounds last prekeys
6 changes: 6 additions & 0 deletions libs/wire-api/src/Wire/API/User/Client/Prekey.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module Wire.API.User.Client.Prekey
LastPrekey,
lastPrekey,
unpackLastPrekey,
fakeLastPrekey,
lastPrekeyId,
PrekeyBundle (..),
ClientPrekey (..),
Expand Down Expand Up @@ -101,6 +102,11 @@ lastPrekeyId = PrekeyId maxBound
lastPrekey :: Text -> LastPrekey
lastPrekey = LastPrekey . Prekey lastPrekeyId

-- for tests only
-- This fake last prekey has the wrong prekeyId
fakeLastPrekey :: LastPrekey
fakeLastPrekey = LastPrekey $ Prekey (PrekeyId 7) "pQABAQcCoQBYIDXdN8VlKb5lbgPmoDPLPyqNIEyShG4oT/DlW0peRRZUA6EAoQBYILLf1TIwSB62q69Ojs/X1tzJ+dYHNAw4QbW/7TC5vSZqBPY="

--------------------------------------------------------------------------------
-- PrekeyBundle

Expand Down
8 changes: 6 additions & 2 deletions services/brig/src/Brig/App.hs
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,12 @@ newEnv o = do
SqsQueue q -> SqsQueue <$> AWS.getQueueUrl (aws ^. AWS.amazonkaEnv) q
mSFTEnv <- mapM Calling.mkSFTEnv $ Opt.sft o
prekeyLocalLock <- case Opt.randomPrekeys o of
Just True -> Just <$> newMVar ()
_ -> pure Nothing
Just True -> do
Log.info lgr $ Log.msg (Log.val "randomPrekeys: active")
Just <$> newMVar ()
_ -> do
Log.info lgr $ Log.msg (Log.val "randomPrekeys: not active; using dynamoDB instead.")
pure Nothing
kpLock <- newMVar ()
pure $!
Env
Expand Down
59 changes: 59 additions & 0 deletions services/brig/test/integration/API/User/Client.hs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import Data.Text.Ascii (AsciiChars (validate))
import qualified Data.Vector as Vec
import Imports
import qualified Network.Wai.Utilities.Error as Error
import qualified System.Logger as Log
import Test.QuickCheck (arbitrary, generate)
import Test.Tasty hiding (Timeout)
import Test.Tasty.Cannon hiding (Cannon)
Expand Down Expand Up @@ -103,6 +104,9 @@ tests _cl _at opts p db b c g =
test p "get /clients - 200" $ testListClients b,
test p "get /clients/:client/prekeys - 200" $ testListPrekeyIds b,
test p "post /clients - 400" $ testTooManyClients opts b,
test p "client/prekeys not empty" $ testPrekeysNotEmptyRandomPrekeys opts b,
test p "lastprekeys not bogus" $ testRegularPrekeysCannotBeSentAsLastPrekeys b,
test p "lastprekeys not bogus during update" $ testRegularPrekeysCannotBeSentAsLastPrekeysDuringUpdate b,
test p "delete /clients/:client - 200 (pwd)" $ testRemoveClient True b c,
test p "delete /clients/:client - 200 (no pwd)" $ testRemoveClient False b c,
test p "delete /clients/:client - 400 (short pwd)" $ testRemoveClientShortPwd b,
Expand Down Expand Up @@ -689,6 +693,61 @@ testTooManyClients opts brig = do
const (Just "too-many-clients") === fmap Error.label . responseJsonMaybe
const (Just "application/json") === getHeader "Content-Type"

-- Ensure that the list of prekeys for a user does not become empty, and the
-- last resort prekey keeps being returned if it's the only key left.
-- Test with featureFlag randomPrekeys=true
testPrekeysNotEmptyRandomPrekeys :: Opt.Opts -> Brig -> Http ()
testPrekeysNotEmptyRandomPrekeys opts brig = do
-- Run the test for randomPrekeys (not dynamoDB locking)
let newOpts = opts {Opt.randomPrekeys = Just True}
ensurePrekeysNotEmpty newOpts brig

ensurePrekeysNotEmpty :: Opt.Opts -> Brig -> Http ()
ensurePrekeysNotEmpty opts brig = withSettingsOverrides opts $ do
lgr <- Log.new Log.defSettings
uid <- userId <$> randomUser brig
-- Create a client with 1 regular prekey and 1 last resort prekey
c <- responseJsonError =<< addClient brig uid (defNewClient PermanentClientType [somePrekeys !! 10] (someLastPrekeys !! 10))
-- Claim the first regular one
_rs1 <- getPreKey brig uid uid (clientId c) <!! const 200 === statusCode
-- Claim again; this should give the last resort one
rs2 <- getPreKey brig uid uid (clientId c) <!! const 200 === statusCode
let pId2 = prekeyId . prekeyData <$> responseJsonMaybe rs2
liftIO $ assertEqual "last prekey rs2" (Just lastPrekeyId) pId2
liftIO $ Log.warn lgr (Log.msg (Log.val "First claim of last resort successful, claim again..."))
-- Claim again; this should (again) give the last resort one
rs3 <- getPreKey brig uid uid (clientId c) <!! const 200 === statusCode
let pId3 = prekeyId . prekeyData <$> responseJsonMaybe rs3
liftIO $ assertEqual "last prekey rs3" (Just lastPrekeyId) pId3

testRegularPrekeysCannotBeSentAsLastPrekeys :: Brig -> Http ()
testRegularPrekeysCannotBeSentAsLastPrekeys brig = do
uid <- userId <$> randomUser brig
-- The parser should reject a normal prekey in the lastPrekey field
addClient brig uid (defNewClient PermanentClientType [head somePrekeys] fakeLastPrekey) !!! const 400 === statusCode

testRegularPrekeysCannotBeSentAsLastPrekeysDuringUpdate :: Brig -> Http ()
testRegularPrekeysCannotBeSentAsLastPrekeysDuringUpdate brig = do
uid <- userId <$> randomUser brig
c <- responseJsonError =<< addClient brig uid (defNewClient PermanentClientType [head somePrekeys] (someLastPrekeys !! 11)) <!! const 201 === statusCode
let newPrekey = somePrekeys !! 2
let update =
defUpdateClient
{ updateClientPrekeys = [newPrekey],
updateClientLastKey = Just fakeLastPrekey,
updateClientLabel = Just "label"
}
-- The parser should reject a normal prekey in the lastPrekey field
put
( brig
. paths ["clients", toByteString' (clientId c)]
. zUser uid
. contentJson
. body (RequestBodyLBS $ encode update)
)
!!! const 400
=== statusCode

-- @END

-- The testRemoveClient test conforms to the following testing standards:
Expand Down
8 changes: 7 additions & 1 deletion services/brig/test/integration/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,13 @@ defNewClientWithVerificationCode mbCode ty pks lpk =
newClientVerificationCode = mbCode
}

getPreKey :: Brig -> UserId -> UserId -> ClientId -> Http ResponseLBS
getPreKey ::
(MonadIO m, MonadCatch m, MonadFail m, MonadHttp m, HasCallStack) =>
Brig ->
UserId ->
UserId ->
ClientId ->
m ResponseLBS
getPreKey brig zusr u c =
get $
apiVersion "v1"
Expand Down

0 comments on commit a0f44f6

Please sign in to comment.