mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-03-30 22:55:50 +00:00
* rfc: client certificates for high volume clients (opertors' chat relays, notification servers, service bots) * client certificates types (WIP) * parameterize Transport * protocol/schema/api changes * agent API * rename command * agent subscriptions return local ClientServiceId to chat * verify transmissions * fix receiving client certificates, refactor * ntf server: remove shared queue for all notification subscriptions (#1543) * ntf server: remove shared queue for all notification subscriptions * wait for subscriber with timeout * safer * refactor * log * remove unused * WIP service subscriptions and associations, refactor * process service subscriptions * rename * simplify switching subscriptions * SMP service handshake with additional server handshake response * notification delivery and STM persistence for services * smp server: database storage, store log, fix encoding for STORE error, replace String with Text in locks and error * stats * more stats * rename SMP commands * service subscriptions in ntf server agent (tests fail) * fix * refactor * exports * subscribe ntf server as service for associated queues * test ntf service connection, fix SOKS response, fix service associations not removed in STM storage * INI option to support services * ntf server: downgrade subscriptions when service is no longer supported, track counts of subscribed queues * smp protocol: include service certificate fingerprint in the string signed over with entity key (TODO two tests fail) * fix test * ntf server prometheus stats, use Int64 in SOKS/ENDS responses (to avoid conversions), additional error status for ntf subscription * update RFC * refactor useServiceAuth to avoid ad hoc decisions about which commands use service signatures, and to prohibit service signatures on other commands * remove duplicate service signature syntax check from checkCredentials, it is checked in verifyTransmission * service errors, todos * fix checkCredentials in ntf server, service errors * refactor service auth * refactor * service agent: store returned queue count instead of expected * refactor serverThread * refactor serviceSig * rename * refactor, rename, test repeat NSUB service association * respond with error to SUBS * smp server: export/import service records between database and store log * comment * comments * ghc 8.10.7
88 lines
3.1 KiB
Haskell
88 lines
3.1 KiB
Haskell
{-# LANGUAGE LambdaCase #-}
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
{-# LANGUAGE TypeFamilies #-}
|
|
|
|
module Util where
|
|
|
|
import Control.Concurrent.Async
|
|
import Control.Exception as E
|
|
import Control.Logger.Simple
|
|
import Control.Monad (replicateM, when)
|
|
import Data.Either (partitionEithers)
|
|
import Data.List (tails)
|
|
import GHC.Conc (getNumCapabilities, getNumProcessors, setNumCapabilities)
|
|
import System.Directory (doesFileExist, removeFile)
|
|
import System.Environment (lookupEnv)
|
|
import System.Process (callCommand)
|
|
import System.Timeout (timeout)
|
|
import Test.Hspec hiding (fit, it)
|
|
import qualified Test.Hspec as Hspec
|
|
import Test.Hspec.Core.Spec (Example (..), Result (..), ResultStatus (..))
|
|
|
|
skip :: String -> SpecWith a -> SpecWith a
|
|
skip = before_ . pendingWith
|
|
|
|
withNumCapabilities :: Int -> IO a -> IO a
|
|
withNumCapabilities new a = getNumCapabilities >>= \old -> bracket_ (setNumCapabilities new) (setNumCapabilities old) a
|
|
|
|
withNCPUCapabilities :: IO a -> IO a
|
|
withNCPUCapabilities a = getNumProcessors >>= \p -> withNumCapabilities p a
|
|
|
|
inParrallel :: Int -> IO () -> IO ()
|
|
inParrallel n action = do
|
|
streams <- replicateM n $ async action
|
|
(es, rs) <- partitionEithers <$> mapM waitCatch streams
|
|
map show es `shouldBe` []
|
|
length rs `shouldBe` n
|
|
|
|
combinations :: Int -> [a] -> [[a]]
|
|
combinations 0 _ = [[]]
|
|
combinations k xs = [y : ys | y : xs' <- tails xs, ys <- combinations (k - 1) xs']
|
|
|
|
removeFileIfExists :: FilePath -> IO ()
|
|
removeFileIfExists filePath = do
|
|
fileExists <- doesFileExist filePath
|
|
when fileExists $ removeFile filePath
|
|
|
|
newtype TestWrapper a = TestWrapper a
|
|
|
|
-- TODO [ntfdb] running wiht LogWarn level shows potential issue "Queue count differs"
|
|
testLogLevel :: LogLevel
|
|
testLogLevel = LogError
|
|
|
|
instance Example a => Example (TestWrapper a) where
|
|
type Arg (TestWrapper a) = Arg a
|
|
evaluateExample (TestWrapper action) params hooks state = do
|
|
ci <- envCI
|
|
runTest `E.catches` [E.Handler (onTestFailure ci), E.Handler (onTestException ci)]
|
|
where
|
|
tt = 120
|
|
runTest =
|
|
timeout (tt * 1000000) (evaluateExample action params hooks state) `finally` callCommand "sync" >>= \case
|
|
Just r -> pure r
|
|
Nothing -> throwIO $ userError $ "test timed out after " <> show tt <> " seconds"
|
|
onTestFailure :: Bool -> ResultStatus -> IO Result
|
|
onTestFailure ci = \case
|
|
Failure loc_ reason | ci -> do
|
|
putStrLn $ "Test failed: location " ++ show loc_ ++ ", reason: " ++ show reason
|
|
retryTest
|
|
r -> E.throwIO r
|
|
onTestException :: Bool -> SomeException -> IO Result
|
|
onTestException False e = E.throwIO e
|
|
onTestException True e = do
|
|
putStrLn $ "Test exception: " ++ show e
|
|
retryTest
|
|
retryTest = do
|
|
putStrLn "Retrying with more logs..."
|
|
setLogLevel LogDebug
|
|
runTest `finally` setLogLevel testLogLevel -- change this to match log level in Test.hs
|
|
|
|
envCI :: IO Bool
|
|
envCI = (Just "true" ==) <$> lookupEnv "CI"
|
|
|
|
it :: (HasCallStack, Example a) => String -> a -> SpecWith (Arg a)
|
|
it label action = Hspec.it label (TestWrapper action)
|
|
|
|
fit :: (HasCallStack, Example a) => String -> a -> SpecWith (Arg a)
|
|
fit = fmap focus . it
|