Files
simplexmq/tests/CoreTests/CryptoFileTests.hs
Evgeny af9ca59e51 smp server: optimize concurrency and memory usage, refactor (#1544)
* smp server: optimize concurrency and memory usage, refactor

* hide clients IntMap

* reduce STM contention

* comment

* version

* correct stats for subscriptions

* version

* comment

* remove subscribed clients from map

* version

* optimze, refactor

* version

* debug test

* enable all tests

* remove test logs

* retry failed tests with debug logging

* increase test timeout

* sync between tests
2025-05-23 12:52:18 +01:00

106 lines
3.5 KiB
Haskell

{-# LANGUAGE OverloadedStrings #-}
module CoreTests.CryptoFileTests (cryptoFileTests) where
import AgentTests.FunctionalAPITests (runRight_)
import Control.Concurrent.STM
import Control.Monad.Except
import Control.Monad.IO.Class
import Crypto.Random (ChaChaDRG)
import qualified Data.ByteString.Lazy as LB
import GHC.IO.IOMode (IOMode (..))
import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Crypto.File (CryptoFile (..), FTCryptoError (..))
import qualified Simplex.Messaging.Crypto.File as CF
import System.Directory (getFileSize)
import Test.Hspec hiding (fit, it)
import Util
cryptoFileTests :: Spec
cryptoFileTests = do
it "should write/read file" testWriteReadFile
it "should put/get file" testPutGetFile
it "should write/get file" testWriteGetFile
it "should put/read file" testPutReadFile
it "should fail reading empty or small file" testSmallFile
testFilePath :: FilePath
testFilePath = "tests/tmp/testcryptofile"
testWriteReadFile :: IO ()
testWriteReadFile = do
g <- C.newRandom
s <- atomically $ LB.fromStrict <$> C.randomBytes 100000 g
file <- atomically $ mkCryptoFile g
runRight_ $ do
CF.writeFile file s
liftIO $ CF.getFileContentsSize file `shouldReturn` 100000
liftIO $ getFileSize testFilePath `shouldReturn` 100000 + fromIntegral C.authTagSize
s' <- CF.readFile file
liftIO $ s `shouldBe` s'
testPutGetFile :: IO ()
testPutGetFile = do
g <- C.newRandom
s <- atomically $ LB.fromStrict <$> C.randomBytes 50000 g
s' <- atomically $ LB.fromStrict <$> C.randomBytes 50000 g
file <- atomically $ mkCryptoFile g
runRight_ $ do
CF.withFile file WriteMode $ \h -> liftIO $ do
CF.hPut h s
CF.hPut h s'
CF.hPutTag h
liftIO $ CF.getFileContentsSize file `shouldReturn` 100000
liftIO $ getFileSize testFilePath `shouldReturn` 100000 + fromIntegral C.authTagSize
CF.withFile file ReadMode $ \h -> do
s1 <- liftIO $ CF.hGet h 30000
s2 <- liftIO $ CF.hGet h 40000
s3 <- liftIO $ CF.hGet h 30000
CF.hGetTag h
liftIO $ (s <> s') `shouldBe` LB.fromStrict (s1 <> s2 <> s3)
testWriteGetFile :: IO ()
testWriteGetFile = do
g <- C.newRandom
s <- atomically $ LB.fromStrict <$> C.randomBytes 100000 g
file <- atomically $ mkCryptoFile g
runRight_ $ do
CF.writeFile file s
CF.withFile file ReadMode $ \h -> do
s' <- liftIO $ CF.hGet h 50000
s'' <- liftIO $ CF.hGet h 50000
CF.hGetTag h
liftIO $ runExceptT (CF.hGetTag h) `shouldReturn` Left FTCEInvalidAuthTag
liftIO $ s `shouldBe` LB.fromStrict (s' <> s'')
testPutReadFile :: IO ()
testPutReadFile = do
g <- C.newRandom
s <- atomically $ LB.fromStrict <$> C.randomBytes 50000 g
s' <- atomically $ LB.fromStrict <$> C.randomBytes 50000 g
file <- atomically $ mkCryptoFile g
runRight_ $ do
CF.withFile file WriteMode $ \h -> liftIO $ do
CF.hPut h s
CF.hPut h s'
runExceptT (CF.readFile file) `shouldReturn` Left FTCEInvalidAuthTag
runRight_ $ do
CF.withFile file WriteMode $ \h -> liftIO $ do
CF.hPut h s
CF.hPut h s'
CF.hPutTag h
s'' <- CF.readFile file
liftIO $ (s <> s') `shouldBe` s''
testSmallFile :: IO ()
testSmallFile = do
g <- C.newRandom
file <- atomically $ mkCryptoFile g
LB.writeFile testFilePath ""
runExceptT (CF.readFile file) `shouldReturn` Left FTCEInvalidFileSize
LB.writeFile testFilePath "123"
runExceptT (CF.readFile file) `shouldReturn` Left FTCEInvalidFileSize
mkCryptoFile :: TVar ChaChaDRG -> STM CryptoFile
mkCryptoFile g = CryptoFile testFilePath . Just <$> CF.randomArgs g