core: allow repeat receive after cancel for XFTP files (#2134)
This commit is contained in:
parent
d3268e4a72
commit
1a7a79d504
@ -107,6 +107,7 @@ tests:
|
|||||||
- deepseq == 1.4.*
|
- deepseq == 1.4.*
|
||||||
- hspec == 2.7.*
|
- hspec == 2.7.*
|
||||||
- network == 3.1.*
|
- network == 3.1.*
|
||||||
|
- silently == 1.2.*
|
||||||
- stm == 2.5.*
|
- stm == 2.5.*
|
||||||
ghc-options:
|
ghc-options:
|
||||||
- -threaded
|
- -threaded
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
cabal-version: 1.12
|
cabal-version: 1.12
|
||||||
|
|
||||||
-- This file has been generated from package.yaml by hpack version 0.35.0.
|
-- This file has been generated from package.yaml by hpack version 0.35.1.
|
||||||
--
|
--
|
||||||
-- see: https://github.com/sol/hpack
|
-- see: https://github.com/sol/hpack
|
||||||
|
|
||||||
@ -389,6 +389,7 @@ test-suite simplex-chat-test
|
|||||||
, process ==1.6.*
|
, process ==1.6.*
|
||||||
, random >=1.1 && <1.3
|
, random >=1.1 && <1.3
|
||||||
, record-hasfield ==1.0.*
|
, record-hasfield ==1.0.*
|
||||||
|
, silently ==1.2.*
|
||||||
, simple-logger ==0.1.*
|
, simple-logger ==0.1.*
|
||||||
, simplex-chat
|
, simplex-chat
|
||||||
, simplexmq >=5.0
|
, simplexmq >=5.0
|
||||||
|
@ -1401,13 +1401,27 @@ processChatCommand = \case
|
|||||||
_ -> throwChatError $ CEFileInternal "invalid chat ref for file transfer"
|
_ -> throwChatError $ CEFileInternal "invalid chat ref for file transfer"
|
||||||
ci <- withStore $ \db -> getChatItemByFileId db user fileId
|
ci <- withStore $ \db -> getChatItemByFileId db user fileId
|
||||||
pure $ CRSndFileCancelled user ci ftm fts
|
pure $ CRSndFileCancelled user ci ftm fts
|
||||||
FTRcv ftr@RcvFileTransfer {cancelled, fileStatus}
|
FTRcv ftr@RcvFileTransfer {cancelled, fileStatus, xftpRcvFile}
|
||||||
| cancelled -> throwChatError $ CEFileCancel fileId "file already cancelled"
|
| cancelled -> throwChatError $ CEFileCancel fileId "file already cancelled"
|
||||||
| rcvFileComplete fileStatus -> throwChatError $ CEFileCancel fileId "file transfer is complete"
|
| rcvFileComplete fileStatus -> throwChatError $ CEFileCancel fileId "file transfer is complete"
|
||||||
| otherwise -> do
|
| otherwise -> case xftpRcvFile of
|
||||||
cancelRcvFileTransfer user ftr >>= mapM_ (deleteAgentConnectionAsync user)
|
Nothing -> do
|
||||||
ci <- withStore $ \db -> getChatItemByFileId db user fileId
|
cancelRcvFileTransfer user ftr >>= mapM_ (deleteAgentConnectionAsync user)
|
||||||
pure $ CRRcvFileCancelled user ci ftr
|
ci <- withStore $ \db -> getChatItemByFileId db user fileId
|
||||||
|
pure $ CRRcvFileCancelled user ci ftr
|
||||||
|
Just XFTPRcvFile {agentRcvFileId} -> do
|
||||||
|
forM_ (liveRcvFileTransferPath ftr) $ \filePath -> do
|
||||||
|
fsFilePath <- toFSFilePath filePath
|
||||||
|
removeFile fsFilePath `E.catch` \(_ :: E.SomeException) -> pure ()
|
||||||
|
forM_ agentRcvFileId $ \(AgentRcvFileId aFileId) ->
|
||||||
|
withAgent $ \a -> xftpDeleteRcvFile a (aUserId user) aFileId
|
||||||
|
ci <- withStore $ \db -> do
|
||||||
|
liftIO $ do
|
||||||
|
updateCIFileStatus db user fileId CIFSRcvInvitation
|
||||||
|
updateRcvFileStatus db fileId FSNew
|
||||||
|
updateRcvFileAgentId db fileId Nothing
|
||||||
|
getChatItemByFileId db user fileId
|
||||||
|
pure $ CRRcvFileCancelled user ci ftr
|
||||||
FileStatus fileId -> withUser $ \user -> do
|
FileStatus fileId -> withUser $ \user -> do
|
||||||
fileStatus <- withStore $ \db -> getFileTransferProgress db user fileId
|
fileStatus <- withStore $ \db -> getFileTransferProgress db user fileId
|
||||||
pure $ CRFileTransferStatus user fileStatus
|
pure $ CRFileTransferStatus user fileStatus
|
||||||
@ -1808,7 +1822,7 @@ deleteFile' user CIFileInfo {filePath, fileId, fileStatus} sendCancel = do
|
|||||||
delete :: m ()
|
delete :: m ()
|
||||||
delete = withFilesFolder $ \filesFolder ->
|
delete = withFilesFolder $ \filesFolder ->
|
||||||
forM_ filePath $ \fPath -> do
|
forM_ filePath $ \fPath -> do
|
||||||
let fsFilePath = filesFolder <> "/" <> fPath
|
let fsFilePath = filesFolder </> fPath
|
||||||
removeFile fsFilePath `E.catch` \(_ :: E.SomeException) ->
|
removeFile fsFilePath `E.catch` \(_ :: E.SomeException) ->
|
||||||
removePathForcibly fsFilePath `E.catch` \(_ :: E.SomeException) -> pure ()
|
removePathForcibly fsFilePath `E.catch` \(_ :: E.SomeException) -> pure ()
|
||||||
-- perform an action only if filesFolder is set (i.e. on mobile devices)
|
-- perform an action only if filesFolder is set (i.e. on mobile devices)
|
||||||
@ -1925,7 +1939,7 @@ receiveViaCompleteFD user fileId RcvFileDescr {fileDescrText, fileDescrComplete}
|
|||||||
rd <- parseRcvFileDescription fileDescrText
|
rd <- parseRcvFileDescription fileDescrText
|
||||||
aFileId <- withAgent $ \a -> xftpReceiveFile a (aUserId user) rd
|
aFileId <- withAgent $ \a -> xftpReceiveFile a (aUserId user) rd
|
||||||
startReceivingFile user fileId
|
startReceivingFile user fileId
|
||||||
withStore' $ \db -> updateRcvFileAgentId db fileId (AgentRcvFileId aFileId)
|
withStore' $ \db -> updateRcvFileAgentId db fileId (Just $ AgentRcvFileId aFileId)
|
||||||
|
|
||||||
startReceivingFile :: ChatMonad m => User -> FileTransferId -> m ()
|
startReceivingFile :: ChatMonad m => User -> FileTransferId -> m ()
|
||||||
startReceivingFile user fileId = do
|
startReceivingFile user fileId = do
|
||||||
|
@ -3074,7 +3074,7 @@ getRcvFileDescrByFileId_ db fileId =
|
|||||||
toRcvFileDescr (fileDescrId, fileDescrText, fileDescrPartNo, fileDescrComplete) =
|
toRcvFileDescr (fileDescrId, fileDescrText, fileDescrPartNo, fileDescrComplete) =
|
||||||
RcvFileDescr {fileDescrId, fileDescrText, fileDescrPartNo, fileDescrComplete}
|
RcvFileDescr {fileDescrId, fileDescrText, fileDescrPartNo, fileDescrComplete}
|
||||||
|
|
||||||
updateRcvFileAgentId :: DB.Connection -> FileTransferId -> AgentRcvFileId -> IO ()
|
updateRcvFileAgentId :: DB.Connection -> FileTransferId -> Maybe AgentRcvFileId -> IO ()
|
||||||
updateRcvFileAgentId db fileId aFileId = do
|
updateRcvFileAgentId db fileId aFileId = do
|
||||||
currentTs <- getCurrentTime
|
currentTs <- getCurrentTime
|
||||||
DB.execute db "UPDATE rcv_files SET agent_rcv_file_id = ?, updated_at = ? WHERE file_id = ?" (aFileId, currentTs, fileId)
|
DB.execute db "UPDATE rcv_files SET agent_rcv_file_id = ?, updated_at = ? WHERE file_id = ?" (aFileId, currentTs, fileId)
|
||||||
|
@ -10,8 +10,11 @@ import Control.Concurrent.Async (concurrently_)
|
|||||||
import qualified Data.ByteString.Char8 as B
|
import qualified Data.ByteString.Char8 as B
|
||||||
import Simplex.Chat.Controller (ChatConfig (..), InlineFilesConfig (..), XFTPFileConfig (..), defaultInlineFilesConfig)
|
import Simplex.Chat.Controller (ChatConfig (..), InlineFilesConfig (..), XFTPFileConfig (..), defaultInlineFilesConfig)
|
||||||
import Simplex.Chat.Options (ChatOpts (..))
|
import Simplex.Chat.Options (ChatOpts (..))
|
||||||
|
import Simplex.FileTransfer.Client.Main (xftpClientCLI)
|
||||||
import Simplex.Messaging.Util (unlessM)
|
import Simplex.Messaging.Util (unlessM)
|
||||||
import System.Directory (copyFile, doesFileExist)
|
import System.Directory (copyFile, doesFileExist)
|
||||||
|
import System.Environment (withArgs)
|
||||||
|
import System.IO.Silently (capture_)
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|
||||||
chatFileTests :: SpecWith FilePath
|
chatFileTests :: SpecWith FilePath
|
||||||
@ -54,6 +57,7 @@ chatFileTests = do
|
|||||||
it "with changed XFTP config: send and receive file" testXFTPWithChangedConfig
|
it "with changed XFTP config: send and receive file" testXFTPWithChangedConfig
|
||||||
it "with relative paths: send and receive file" testXFTPWithRelativePaths
|
it "with relative paths: send and receive file" testXFTPWithRelativePaths
|
||||||
it "continue receiving file after restart" testXFTPContinueRcv
|
it "continue receiving file after restart" testXFTPContinueRcv
|
||||||
|
it "cancel receiving file, repeat receive" testXFTPCancelRcvRepeat
|
||||||
|
|
||||||
runTestFileTransfer :: HasCallStack => TestCC -> TestCC -> IO ()
|
runTestFileTransfer :: HasCallStack => TestCC -> TestCC -> IO ()
|
||||||
runTestFileTransfer alice bob = do
|
runTestFileTransfer alice bob = do
|
||||||
@ -1088,6 +1092,41 @@ testXFTPContinueRcv tmp = do
|
|||||||
where
|
where
|
||||||
cfg = testCfg {xftpFileConfig = Just $ XFTPFileConfig {minFileSize = 0}, tempDir = Just "./tests/tmp"}
|
cfg = testCfg {xftpFileConfig = Just $ XFTPFileConfig {minFileSize = 0}, tempDir = Just "./tests/tmp"}
|
||||||
|
|
||||||
|
testXFTPCancelRcvRepeat :: HasCallStack => FilePath -> IO ()
|
||||||
|
testXFTPCancelRcvRepeat =
|
||||||
|
testChatCfg2 cfg aliceProfile bobProfile $ \alice bob -> do
|
||||||
|
withXFTPServer $ do
|
||||||
|
xftpCLI ["rand", "./tests/tmp/testfile", "17mb"] `shouldReturn` ["File created: " <> "./tests/tmp/testfile"]
|
||||||
|
|
||||||
|
connectUsers alice bob
|
||||||
|
|
||||||
|
alice #> "/f @bob ./tests/tmp/testfile"
|
||||||
|
alice <## "use /fc 1 to cancel sending"
|
||||||
|
bob <# "alice> sends file testfile (17.0 MiB / 17825792 bytes)"
|
||||||
|
bob <## "use /fr 1 [<dir>/ | <path>] to receive it"
|
||||||
|
bob ##> "/fr 1 ./tests/tmp"
|
||||||
|
bob <## "saving file 1 from alice to ./tests/tmp/testfile_1"
|
||||||
|
-- alice <## "started sending file 1 (testfile) to bob" -- TODO "started uploading" ?
|
||||||
|
alice <## "uploaded file 1 (testfile) for bob"
|
||||||
|
bob <## "started receiving file 1 (testfile) from alice"
|
||||||
|
|
||||||
|
bob ##> "/fc 1"
|
||||||
|
bob <## "cancelled receiving file 1 (testfile) from alice"
|
||||||
|
|
||||||
|
bob ##> "/fr 1 ./tests/tmp"
|
||||||
|
bob <## "started receiving file 1 (testfile) from alice"
|
||||||
|
bob <## "saving file 1 from alice to ./tests/tmp/testfile_1"
|
||||||
|
bob <## "completed receiving file 1 (testfile) from alice"
|
||||||
|
|
||||||
|
src <- B.readFile "./tests/tmp/testfile"
|
||||||
|
dest <- B.readFile "./tests/tmp/testfile_1"
|
||||||
|
dest `shouldBe` src
|
||||||
|
where
|
||||||
|
cfg = testCfg {xftpFileConfig = Just $ XFTPFileConfig {minFileSize = 0}, tempDir = Just "./tests/tmp"}
|
||||||
|
|
||||||
|
xftpCLI :: [String] -> IO [String]
|
||||||
|
xftpCLI params = lines <$> capture_ (withArgs params xftpClientCLI)
|
||||||
|
|
||||||
startFileTransfer :: HasCallStack => TestCC -> TestCC -> IO ()
|
startFileTransfer :: HasCallStack => TestCC -> TestCC -> IO ()
|
||||||
startFileTransfer alice bob =
|
startFileTransfer alice bob =
|
||||||
startFileTransfer' alice bob "test.jpg" "136.5 KiB / 139737 bytes"
|
startFileTransfer' alice bob "test.jpg" "136.5 KiB / 139737 bytes"
|
||||||
|
Loading…
Reference in New Issue
Block a user