mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-03-29 14:30:22 +00:00
* 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
185 lines
6.6 KiB
Haskell
185 lines
6.6 KiB
Haskell
{-# LANGUAGE DataKinds #-}
|
|
{-# LANGUAGE DuplicateRecordFields #-}
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
module FileDescriptionTests where
|
|
|
|
import Control.Exception (bracket_)
|
|
import qualified Data.ByteString.Char8 as B
|
|
import qualified Data.Yaml as Y
|
|
import Simplex.FileTransfer.Description
|
|
import Simplex.FileTransfer.Protocol
|
|
import qualified Simplex.Messaging.Crypto as C
|
|
import Simplex.Messaging.Encoding.String (StrEncoding (..))
|
|
import Simplex.Messaging.Protocol (EntityId (..))
|
|
import Simplex.Messaging.ServiceScheme (ServiceScheme (..))
|
|
import System.Directory (removeFile)
|
|
import Test.Hspec hiding (fit, it)
|
|
import Util
|
|
|
|
fileDescriptionTests :: Spec
|
|
fileDescriptionTests = do
|
|
describe "file description parsing / serializing" $ do
|
|
it "parse YAML file description" testParseYAMLFileDescription
|
|
it "serialize YAML file description" testSerializeYAMLFileDescription
|
|
it "parse file description" testParseFileDescription
|
|
it "serialize file description" testSerializeFileDescription
|
|
describe "file description URIs" $ do
|
|
it "round trip file description URI" testFileDescriptionURI
|
|
it "round trip file description URI with extra JSON" testFileDescriptionURIExtras
|
|
|
|
fileDescPath :: FilePath
|
|
fileDescPath = "tests/fixtures/file_description.yaml"
|
|
|
|
tmpFileDescPath :: FilePath
|
|
tmpFileDescPath = "tests/tmp/file_description.yaml"
|
|
|
|
testSbKey :: C.SbKey
|
|
testSbKey = either error id $ strDecode "00n8p1tJq5E-SGnHcYTOrS4A9I07gTA_WFD6MTFFFOY="
|
|
|
|
testCbNonce :: C.CbNonce
|
|
testCbNonce = either error id $ strDecode "dPSF-wrQpDiK_K6sYv0BDBZ9S4dg-jmu"
|
|
|
|
fileDesc :: FileDescription 'FRecipient
|
|
fileDesc =
|
|
FileDescription
|
|
{ party = SFRecipient,
|
|
size = FileSize $ mb 26,
|
|
digest = FileDigest "abc",
|
|
key = testSbKey,
|
|
nonce = testCbNonce,
|
|
chunkSize = defaultChunkSize,
|
|
chunks =
|
|
[ FileChunk
|
|
{ chunkNo = 1,
|
|
digest = chunkDigest,
|
|
chunkSize = defaultChunkSize,
|
|
replicas =
|
|
[ FileChunkReplica {server = "xftp://abc=@example1.com", replicaId, replicaKey},
|
|
FileChunkReplica {server = "xftp://abc=@example3.com", replicaId, replicaKey}
|
|
]
|
|
},
|
|
FileChunk
|
|
{ chunkNo = 2,
|
|
digest = chunkDigest,
|
|
chunkSize = defaultChunkSize,
|
|
replicas =
|
|
[ FileChunkReplica {server = "xftp://abc=@example2.com", replicaId, replicaKey},
|
|
FileChunkReplica {server = "xftp://abc=@example4.com", replicaId, replicaKey}
|
|
]
|
|
},
|
|
FileChunk
|
|
{ chunkNo = 3,
|
|
digest = chunkDigest,
|
|
chunkSize = defaultChunkSize,
|
|
replicas =
|
|
[ FileChunkReplica {server = "xftp://abc=@example1.com", replicaId, replicaKey},
|
|
FileChunkReplica {server = "xftp://abc=@example4.com", replicaId, replicaKey}
|
|
]
|
|
},
|
|
FileChunk
|
|
{ chunkNo = 4,
|
|
digest = chunkDigest,
|
|
chunkSize = FileSize $ mb 2,
|
|
replicas =
|
|
[ FileChunkReplica {server = "xftp://abc=@example2.com", replicaId, replicaKey},
|
|
FileChunkReplica {server = "xftp://abc=@example3.com", replicaId, replicaKey}
|
|
]
|
|
}
|
|
],
|
|
redirect = Nothing
|
|
}
|
|
where
|
|
defaultChunkSize = FileSize $ mb 8
|
|
replicaId = ChunkReplicaId $ EntityId "abc"
|
|
replicaKey = C.APrivateAuthKey C.SEd25519 "MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe"
|
|
chunkDigest = FileDigest "ghi"
|
|
|
|
yamlFileDesc :: YAMLFileDescription
|
|
yamlFileDesc =
|
|
YAMLFileDescription
|
|
{ party = FRecipient,
|
|
size = "26mb",
|
|
chunkSize = "8mb",
|
|
digest = FileDigest "abc",
|
|
key = testSbKey,
|
|
nonce = testCbNonce,
|
|
replicas =
|
|
[ YAMLServerReplicas
|
|
{ server = "xftp://abc=@example1.com",
|
|
chunks =
|
|
[ "1:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe:Z2hp",
|
|
"3:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe:Z2hp"
|
|
]
|
|
},
|
|
YAMLServerReplicas
|
|
{ server = "xftp://abc=@example2.com",
|
|
chunks =
|
|
[ "2:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe:Z2hp",
|
|
"4:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe:Z2hp:2mb"
|
|
]
|
|
},
|
|
YAMLServerReplicas
|
|
{ server = "xftp://abc=@example3.com",
|
|
chunks =
|
|
[ "1:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe",
|
|
"4:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe"
|
|
]
|
|
},
|
|
YAMLServerReplicas
|
|
{ server = "xftp://abc=@example4.com",
|
|
chunks =
|
|
[ "2:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe",
|
|
"3:YWJj:MC4CAQAwBQYDK2VwBCIEIDfEfevydXXfKajz3sRkcQ7RPvfWUPoq6pu1TYHV1DEe"
|
|
]
|
|
}
|
|
],
|
|
redirect = Nothing
|
|
}
|
|
|
|
testParseYAMLFileDescription :: IO ()
|
|
testParseYAMLFileDescription = do
|
|
yfd <- Y.decodeFileThrow fileDescPath
|
|
yfd `shouldBe` yamlFileDesc
|
|
|
|
testSerializeYAMLFileDescription :: IO ()
|
|
testSerializeYAMLFileDescription = withRemoveTmpFile $ do
|
|
Y.encodeFile tmpFileDescPath yamlFileDesc
|
|
fdSer <- B.readFile tmpFileDescPath
|
|
fdExp <- B.readFile fileDescPath
|
|
fdSer `shouldBe` fdExp
|
|
|
|
testParseFileDescription :: IO ()
|
|
testParseFileDescription = do
|
|
r <- strDecode <$> B.readFile fileDescPath
|
|
case r of
|
|
Left e -> expectationFailure $ show e
|
|
Right fd -> fd `shouldBe` fileDesc
|
|
|
|
testSerializeFileDescription :: IO ()
|
|
testSerializeFileDescription = withRemoveTmpFile $ do
|
|
B.writeFile tmpFileDescPath $ strEncode fileDesc
|
|
fdSer <- B.readFile tmpFileDescPath
|
|
fdExp <- B.readFile fileDescPath
|
|
fdSer `shouldBe` fdExp
|
|
|
|
testFileDescriptionURI :: IO ()
|
|
testFileDescriptionURI = do
|
|
vfd <- either fail pure $ validateFileDescription fileDesc
|
|
let descr = FileDescriptionURI SSSimplex vfd mempty
|
|
strDecode (strEncode descr) `shouldBe` Right descr
|
|
|
|
testFileDescriptionURIExtras :: IO ()
|
|
testFileDescriptionURIExtras = do
|
|
vfd <- either fail pure $ validateFileDescription fileDesc
|
|
let descr = FileDescriptionURI SSSimplex vfd $ Just "{\"something\":\"extra\",\"more\":true}"
|
|
strDecode (strEncode descr) `shouldBe` Right descr
|
|
|
|
withRemoveTmpFile :: IO () -> IO ()
|
|
withRemoveTmpFile =
|
|
bracket_
|
|
(pure ())
|
|
(removeFile tmpFileDescPath)
|