mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-24 19:35:33 +00:00
core: subscribe all queues (#6347)
* core: subscribe all queues * tests, plans, fixes * enable tests
This commit is contained in:
@@ -174,10 +174,6 @@ undocumentedEvents =
|
||||
"CEvtContactPQEnabled",
|
||||
"CEvtContactRatchetSync",
|
||||
"CEvtContactRequestAlreadyAccepted",
|
||||
"CEvtContactsDisconnected",
|
||||
"CEvtContactsSubscribed",
|
||||
"CEvtConnSubError",
|
||||
"CEvtConnSubSummary",
|
||||
"CEvtContactSwitch",
|
||||
"CEvtCustomChatEvent",
|
||||
"CEvtGroupMemberRatchetSync",
|
||||
@@ -185,7 +181,6 @@ undocumentedEvents =
|
||||
"CEvtHostConnected",
|
||||
"CEvtHostDisconnected",
|
||||
"CEvtNetworkStatus",
|
||||
"CEvtNetworkStatuses",
|
||||
"CEvtNewRemoteHost",
|
||||
"CEvtNoMemberContactCreating",
|
||||
"CEvtNtfMessage",
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
|
||||
source-repository-package
|
||||
type: git
|
||||
location: https://github.com/simplex-chat/simplexmq.git
|
||||
tag: a3d1a72eb06df0dc6e1f2a8d72cab8535870fb03
|
||||
tag: 80aa56cbcce92f4b61cda06a965eef3d0f640df1
|
||||
|
||||
source-repository-package
|
||||
type: git
|
||||
|
||||
@@ -106,7 +106,6 @@ defaultChatConfig =
|
||||
cleanupManagerInterval = 30 * 60, -- 30 minutes
|
||||
cleanupManagerStepDelay = 3 * 1000000, -- 3 seconds
|
||||
ciExpirationInterval = 30 * 60 * 1000000, -- 30 minutes
|
||||
coreApi = False,
|
||||
highlyAvailable = False,
|
||||
deliveryWorkerDelay = 0,
|
||||
deliveryBucketSize = 10000,
|
||||
|
||||
@@ -155,7 +155,6 @@ data ChatConfig = ChatConfig
|
||||
cleanupManagerInterval :: NominalDiffTime,
|
||||
cleanupManagerStepDelay :: Int64,
|
||||
ciExpirationInterval :: Int64, -- microseconds
|
||||
coreApi :: Bool,
|
||||
deliveryWorkerDelay :: Int64, -- microseconds
|
||||
deliveryBucketSize :: Int,
|
||||
highlyAvailable :: Bool,
|
||||
@@ -827,12 +826,7 @@ data ChatEvent
|
||||
| CEvtContactSndReady {user :: User, contact :: Contact}
|
||||
| CEvtContactAnotherClient {user :: User, contact :: Contact}
|
||||
| CEvtSubscriptionEnd {user :: User, connectionEntity :: ConnectionEntity}
|
||||
| CEvtContactsDisconnected {server :: SMPServer, contactRefs :: [ContactRef]}
|
||||
| CEvtContactsSubscribed {server :: SMPServer, contactRefs :: [ContactRef]}
|
||||
| CEvtConnSubError {user :: User, agentConnId :: AgentConnId, chatError :: ChatError}
|
||||
| CEvtConnSubSummary {user :: User, connSubResults :: [ConnSubResult]}
|
||||
| CEvtNetworkStatus {networkStatus :: NetworkStatus, connections :: [AgentConnId]}
|
||||
| CEvtNetworkStatuses {user_ :: Maybe User, networkStatuses :: [ConnNetworkStatus]} -- there is the same command response
|
||||
| CEvtNetworkStatus {server :: SMPServer, networkStatus :: NetworkStatus, connections :: [AgentConnId]}
|
||||
| CEvtHostConnected {protocol :: AProtocolType, transportHost :: TransportHost}
|
||||
| CEvtHostDisconnected {protocol :: AProtocolType, transportHost :: TransportHost}
|
||||
| CEvtReceivedGroupInvitation {user :: User, groupInfo :: GroupInfo, contact :: Contact, fromMemberRole :: GroupMemberRole, memberRole :: GroupMemberRole}
|
||||
@@ -912,9 +906,7 @@ allowRemoteEvent = \case
|
||||
|
||||
logEventToFile :: ChatEvent -> Bool
|
||||
logEventToFile = \case
|
||||
CEvtContactsDisconnected {} -> True
|
||||
CEvtContactsSubscribed {} -> True
|
||||
CEvtConnSubError {} -> True
|
||||
CEvtNetworkStatus {} -> True
|
||||
CEvtHostConnected {} -> True
|
||||
CEvtHostDisconnected {} -> True
|
||||
CEvtConnectionDisabled {} -> True
|
||||
|
||||
@@ -103,7 +103,6 @@ import Simplex.Messaging.Crypto.Ratchet (PQEncryption (..), PQSupport (..), patt
|
||||
import Simplex.Messaging.Encoding.String
|
||||
import Simplex.Messaging.Parsers (base64P)
|
||||
import Simplex.Messaging.Protocol (AProtoServerWithAuth (..), AProtocolType (..), MsgFlags (..), NtfServer, ProtoServerWithAuth (..), ProtocolServer, ProtocolType (..), ProtocolTypeI (..), SProtocolType (..), SubscriptionMode (..), UserProtocol, userProtocol)
|
||||
import qualified Simplex.Messaging.Protocol as SMP
|
||||
import Simplex.Messaging.ServiceScheme (ServiceScheme (..))
|
||||
import qualified Simplex.Messaging.TMap as TM
|
||||
import Simplex.Messaging.Transport.Client (defaultSocksProxyWithAuth)
|
||||
@@ -213,12 +212,8 @@ startChatController mainApp enableSndFiles = do
|
||||
|
||||
subscribeUsers :: Bool -> [User] -> CM' ()
|
||||
subscribeUsers onlyNeeded users = do
|
||||
let (us, us') = partition activeUser users
|
||||
subscribe us
|
||||
subscribe us'
|
||||
where
|
||||
subscribe :: [User] -> CM' ()
|
||||
subscribe = mapM_ $ runExceptT . subscribeUserConnections onlyNeeded
|
||||
let activeUserId_ = (\User {agentUserId = AgentUserId uId} -> uId) <$> find activeUser users
|
||||
withAgent (\a -> subscribeAllConnections a onlyNeeded activeUserId_) `catchAllErrors'` eToView'
|
||||
|
||||
startFilesToReceive :: [User] -> CM' ()
|
||||
startFilesToReceive users = do
|
||||
@@ -4133,63 +4128,6 @@ agentSubscriber = do
|
||||
|
||||
type AgentSubResult = Map ConnId (Either AgentErrorType (Maybe ClientServiceId))
|
||||
|
||||
-- TODO [certs rcv]
|
||||
subscribeUserConnections :: Bool -> User -> CM ()
|
||||
subscribeUserConnections onlyNeeded user = do
|
||||
(ctConnIds, uclConnIds, memberConnIds, pendingConnIds) <-
|
||||
withStore' $ \db -> do
|
||||
ctConnIds <- getContactConnsToSub db user onlyNeeded
|
||||
uclConnIds <- getUCLConnsToSub db user onlyNeeded
|
||||
memberConnIds <- getMemberConnsToSub db user onlyNeeded
|
||||
pendingConnIds <- getPendingConnsToSub db user onlyNeeded
|
||||
unsetConnectionToSubscribe db user
|
||||
pure (ctConnIds, uclConnIds, memberConnIds, pendingConnIds)
|
||||
let allConnIds = ctConnIds <> uclConnIds <> memberConnIds <> pendingConnIds
|
||||
rs <- withAgent $ \a -> subscribeConnections a allConnIds
|
||||
processContactNetStatuses rs ctConnIds
|
||||
unlessM (asks $ coreApi . config) $ notifyCLI rs allConnIds
|
||||
where
|
||||
processContactNetStatuses :: AgentSubResult -> [ConnId] -> CM ()
|
||||
processContactNetStatuses rs ctConnIds = do
|
||||
chatModifyVar connNetworkStatuses $ M.union (M.fromList statuses)
|
||||
let networkStatuses = map (uncurry ConnNetworkStatus) statuses
|
||||
toView $ CEvtNetworkStatuses (Just user) networkStatuses
|
||||
where
|
||||
statuses :: [(AgentConnId, NetworkStatus)]
|
||||
statuses = foldr' addStatus [] ctConnIds
|
||||
where
|
||||
addStatus :: ConnId -> [(AgentConnId, NetworkStatus)] -> [(AgentConnId, NetworkStatus)]
|
||||
addStatus connId nss =
|
||||
let ns = (AgentConnId connId, netStatus $ subSuccessOrErr connId rs)
|
||||
in ns : nss
|
||||
netStatus :: Maybe ChatError -> NetworkStatus
|
||||
netStatus = maybe NSConnected $ NSError . errorNetworkStatus
|
||||
errorNetworkStatus :: ChatError -> String
|
||||
errorNetworkStatus = \case
|
||||
ChatErrorAgent (BROKER _ (NETWORK _)) _ -> "network"
|
||||
ChatErrorAgent (SMP _ SMP.AUTH) _ -> "contact deleted"
|
||||
e -> show e
|
||||
notifyCLI :: AgentSubResult -> [ConnId] -> CM ()
|
||||
notifyCLI rs connIds = do
|
||||
let connSubResults = map (\(acId, err_) -> ConnSubResult (AgentConnId acId) err_) connIdsResults
|
||||
toView $ CEvtConnSubSummary user connSubResults
|
||||
whenM (asks $ subscriptionEvents . config) $ do
|
||||
let connSubErrs = filterErrors connIdsResults
|
||||
mapM_ (toView . uncurry (CEvtConnSubError user . AgentConnId)) connSubErrs
|
||||
where
|
||||
connIdsResults :: [(ConnId, Maybe ChatError)]
|
||||
connIdsResults = foldr' addResult [] connIds
|
||||
where
|
||||
addResult :: ConnId -> [(ConnId, Maybe ChatError)] -> [(ConnId, Maybe ChatError)]
|
||||
addResult connId idsResults = (connId, subSuccessOrErr connId rs) : idsResults
|
||||
filterErrors :: [(ConnId, Maybe ChatError)] -> [(ConnId, ChatError)]
|
||||
filterErrors = mapMaybe (\(a, e_) -> (a,) <$> e_)
|
||||
subSuccessOrErr :: ConnId -> AgentSubResult -> Maybe ChatError
|
||||
subSuccessOrErr connId rs = case M.lookup connId rs of
|
||||
Just (Right _) -> Nothing -- success
|
||||
Just (Left e) -> Just $ ChatErrorAgent e Nothing
|
||||
Nothing -> Just . ChatError . CEAgentNoSubResult $ AgentConnId connId
|
||||
|
||||
cleanupManager :: CM ()
|
||||
cleanupManager = do
|
||||
interval <- asks (cleanupManagerInterval . config)
|
||||
|
||||
@@ -131,23 +131,19 @@ processAgentMessageNoConn :: AEvent 'AENone -> CM ()
|
||||
processAgentMessageNoConn = \case
|
||||
CONNECT p h -> hostEvent $ CEvtHostConnected p h
|
||||
DISCONNECT p h -> hostEvent $ CEvtHostDisconnected p h
|
||||
DOWN srv conns -> serverEvent srv conns NSDisconnected CEvtContactsDisconnected
|
||||
UP srv conns -> serverEvent srv conns NSConnected CEvtContactsSubscribed
|
||||
DOWN srv conns -> serverEvent srv NSDisconnected conns
|
||||
UP srv conns -> serverEvent srv NSConnected conns
|
||||
SUSPENDED -> toView CEvtChatSuspended
|
||||
DEL_USER agentUserId -> toView $ CEvtAgentUserDeleted agentUserId
|
||||
ERRS cErrs -> errsEvent cErrs
|
||||
ERRS cErrs -> errsEvent $ L.toList cErrs
|
||||
where
|
||||
hostEvent :: ChatEvent -> CM ()
|
||||
hostEvent = whenM (asks $ hostEvents . config) . toView
|
||||
serverEvent srv conns nsStatus event = do
|
||||
serverEvent srv nsStatus conns = do
|
||||
chatModifyVar connNetworkStatuses $ \m -> foldl' (\m' cId -> M.insert cId nsStatus m') m connIds
|
||||
ifM (asks $ coreApi . config) (notifyAPI connIds) notifyCLI
|
||||
toView $ CEvtNetworkStatus srv nsStatus connIds
|
||||
where
|
||||
connIds = map AgentConnId conns
|
||||
notifyAPI = toView . CEvtNetworkStatus nsStatus
|
||||
notifyCLI = do
|
||||
cs <- withStore' (`getConnectionsContacts` conns)
|
||||
toView $ event srv cs
|
||||
errsEvent :: [(ConnId, AgentErrorType)] -> CM ()
|
||||
errsEvent cErrs = do
|
||||
vr <- chatVersionRange
|
||||
|
||||
@@ -277,7 +277,6 @@ defaultMobileConfig =
|
||||
defaultChatConfig
|
||||
{ confirmMigrations = MCYesUp,
|
||||
logLevel = CLLError,
|
||||
coreApi = True,
|
||||
deviceNameForRemote = "Mobile"
|
||||
}
|
||||
|
||||
|
||||
@@ -378,14 +378,40 @@ USE TEMP B-TREE FOR DISTINCT
|
||||
Query:
|
||||
SELECT DISTINCT c.conn_id, c.host, c.port, COALESCE(c.server_key_hash, s.key_hash)
|
||||
FROM commands c
|
||||
JOIN connections cs ON c.conn_id = cs.conn_id
|
||||
LEFT JOIN servers s ON s.host = c.host AND s.port = c.port
|
||||
ORDER BY c.conn_id
|
||||
WHERE cs.deleted = 0
|
||||
|
||||
Plan:
|
||||
SCAN c USING INDEX idx_commands_conn_id
|
||||
SEARCH cs USING PRIMARY KEY (conn_id=?)
|
||||
SEARCH s USING PRIMARY KEY (host=? AND port=?) LEFT-JOIN
|
||||
USE TEMP B-TREE FOR DISTINCT
|
||||
|
||||
Query:
|
||||
SELECT DISTINCT c.user_id, q.host, q.port, COALESCE(q.server_key_hash, s.key_hash)
|
||||
FROM rcv_queues q
|
||||
JOIN servers s ON q.host = s.host AND q.port = s.port
|
||||
JOIN connections c ON q.conn_id = c.conn_id
|
||||
WHERE c.deleted = 0 AND q.deleted = 0
|
||||
Plan:
|
||||
SCAN q USING INDEX idx_rcv_queues_link_id
|
||||
SEARCH c USING PRIMARY KEY (conn_id=?)
|
||||
SEARCH s USING PRIMARY KEY (host=? AND port=?)
|
||||
USE TEMP B-TREE FOR DISTINCT
|
||||
|
||||
Query:
|
||||
SELECT DISTINCT c.user_id, q.host, q.port, COALESCE(q.server_key_hash, s.key_hash)
|
||||
FROM rcv_queues q
|
||||
JOIN servers s ON q.host = s.host AND q.port = s.port
|
||||
JOIN connections c ON q.conn_id = c.conn_id
|
||||
WHERE q.to_subscribe = 1 AND c.deleted = 0 AND q.deleted = 0
|
||||
Plan:
|
||||
SEARCH q USING INDEX idx_rcv_queues_to_subscribe (to_subscribe=?)
|
||||
SEARCH s USING PRIMARY KEY (host=? AND port=?)
|
||||
SEARCH c USING PRIMARY KEY (conn_id=?)
|
||||
USE TEMP B-TREE FOR DISTINCT
|
||||
|
||||
Query:
|
||||
SELECT DISTINCT ntf_host, ntf_port, ntf_key_hash
|
||||
FROM ntf_tokens_to_delete
|
||||
@@ -555,10 +581,10 @@ SEARCH messages USING COVERING INDEX idx_messages_conn_id_internal_rcv_id (conn_
|
||||
Query:
|
||||
INSERT INTO rcv_queues
|
||||
( host, port, rcv_id, conn_id, rcv_private_key, rcv_dh_secret, e2e_priv_key, e2e_dh_secret,
|
||||
snd_id, queue_mode, status, rcv_queue_id, rcv_primary, replace_rcv_queue_id, smp_client_version, server_key_hash,
|
||||
snd_id, queue_mode, status, to_subscribe, rcv_queue_id, rcv_primary, replace_rcv_queue_id, smp_client_version, server_key_hash,
|
||||
link_id, link_key, link_priv_sig_key, link_enc_fixed_data,
|
||||
ntf_public_key, ntf_private_key, ntf_id, rcv_ntf_dh_secret
|
||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);
|
||||
) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);
|
||||
|
||||
Plan:
|
||||
|
||||
@@ -580,16 +606,15 @@ SEARCH messages USING COVERING INDEX idx_messages_conn_id_internal_snd_id (conn_
|
||||
|
||||
Query:
|
||||
INSERT INTO snd_queues
|
||||
(host, port, snd_id, queue_mode, conn_id, snd_public_key, snd_private_key, e2e_pub_key, e2e_dh_secret,
|
||||
(host, port, snd_id, queue_mode, conn_id, snd_private_key, e2e_pub_key, e2e_dh_secret,
|
||||
status, snd_queue_id, snd_primary, replace_snd_queue_id, smp_client_version, server_key_hash)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||
ON CONFLICT (host, port, snd_id) DO UPDATE SET
|
||||
host=EXCLUDED.host,
|
||||
port=EXCLUDED.port,
|
||||
snd_id=EXCLUDED.snd_id,
|
||||
queue_mode=EXCLUDED.queue_mode,
|
||||
conn_id=EXCLUDED.conn_id,
|
||||
snd_public_key=EXCLUDED.snd_public_key,
|
||||
snd_private_key=EXCLUDED.snd_private_key,
|
||||
e2e_pub_key=EXCLUDED.e2e_pub_key,
|
||||
e2e_dh_secret=EXCLUDED.e2e_dh_secret,
|
||||
@@ -734,7 +759,28 @@ SEARCH snd_queues USING PRIMARY KEY (host=? AND port=? AND snd_id=?)
|
||||
Query:
|
||||
SELECT
|
||||
c.user_id, COALESCE(q.server_key_hash, s.key_hash), q.conn_id, q.host, q.port, q.snd_id, q.queue_mode,
|
||||
q.snd_public_key, q.snd_private_key, q.e2e_pub_key, q.e2e_dh_secret, q.status,
|
||||
q.snd_private_key, q.e2e_pub_key, q.e2e_dh_secret, q.status,
|
||||
q.snd_queue_id, q.snd_primary, q.replace_snd_queue_id, q.switch_status, q.smp_client_version
|
||||
FROM snd_queues q
|
||||
JOIN servers s ON q.host = s.host AND q.port = s.port
|
||||
JOIN connections c ON q.conn_id = c.conn_id
|
||||
|
||||
JOIN (SELECT DISTINCT conn_id, snd_queue_id FROM snd_message_deliveries WHERE failed = 0) d
|
||||
ON d.conn_id = q.conn_id AND d.snd_queue_id = q.snd_queue_id
|
||||
WHERE c.deleted = 0
|
||||
|
||||
Plan:
|
||||
MATERIALIZE d
|
||||
SCAN snd_message_deliveries USING COVERING INDEX idx_snd_message_deliveries_expired
|
||||
SCAN d
|
||||
SEARCH q USING INDEX idx_snd_queue_id (conn_id=? AND snd_queue_id=?)
|
||||
SEARCH s USING PRIMARY KEY (host=? AND port=?)
|
||||
SEARCH c USING PRIMARY KEY (conn_id=?)
|
||||
|
||||
Query:
|
||||
SELECT
|
||||
c.user_id, COALESCE(q.server_key_hash, s.key_hash), q.conn_id, q.host, q.port, q.snd_id, q.queue_mode,
|
||||
q.snd_private_key, q.e2e_pub_key, q.e2e_dh_secret, q.status,
|
||||
q.snd_queue_id, q.snd_primary, q.replace_snd_queue_id, q.switch_status, q.smp_client_version
|
||||
FROM snd_queues q
|
||||
JOIN servers s ON q.host = s.host AND q.port = s.port
|
||||
@@ -747,7 +793,7 @@ SEARCH s USING PRIMARY KEY (host=? AND port=?)
|
||||
|
||||
Query:
|
||||
SELECT c.user_id, COALESCE(q.server_key_hash, s.key_hash), q.conn_id, q.host, q.port, q.rcv_id, q.rcv_private_key, q.rcv_dh_secret,
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.queue_mode, q.status,
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.queue_mode, q.status, c.enable_ntfs,
|
||||
q.rcv_queue_id, q.rcv_primary, q.replace_rcv_queue_id, q.switch_status, q.smp_client_version, q.delete_errors,
|
||||
q.ntf_public_key, q.ntf_private_key, q.ntf_id, q.rcv_ntf_dh_secret,
|
||||
q.link_id, q.link_key, q.link_priv_sig_key, q.link_enc_fixed_data
|
||||
@@ -762,7 +808,7 @@ SEARCH s USING PRIMARY KEY (host=? AND port=?)
|
||||
|
||||
Query:
|
||||
SELECT c.user_id, COALESCE(q.server_key_hash, s.key_hash), q.conn_id, q.host, q.port, q.rcv_id, q.rcv_private_key, q.rcv_dh_secret,
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.queue_mode, q.status,
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.queue_mode, q.status, c.enable_ntfs,
|
||||
q.rcv_queue_id, q.rcv_primary, q.replace_rcv_queue_id, q.switch_status, q.smp_client_version, q.delete_errors,
|
||||
q.ntf_public_key, q.ntf_private_key, q.ntf_id, q.rcv_ntf_dh_secret,
|
||||
q.link_id, q.link_key, q.link_priv_sig_key, q.link_enc_fixed_data
|
||||
@@ -777,7 +823,7 @@ SEARCH c USING PRIMARY KEY (conn_id=?)
|
||||
|
||||
Query:
|
||||
SELECT c.user_id, COALESCE(q.server_key_hash, s.key_hash), q.conn_id, q.host, q.port, q.rcv_id, q.rcv_private_key, q.rcv_dh_secret,
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.queue_mode, q.status,
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.queue_mode, q.status, c.enable_ntfs,
|
||||
q.rcv_queue_id, q.rcv_primary, q.replace_rcv_queue_id, q.switch_status, q.smp_client_version, q.delete_errors,
|
||||
q.ntf_public_key, q.ntf_private_key, q.ntf_id, q.rcv_ntf_dh_secret,
|
||||
q.link_id, q.link_key, q.link_priv_sig_key, q.link_enc_fixed_data
|
||||
@@ -792,7 +838,7 @@ SEARCH c USING PRIMARY KEY (conn_id=?)
|
||||
|
||||
Query:
|
||||
SELECT c.user_id, COALESCE(q.server_key_hash, s.key_hash), q.conn_id, q.host, q.port, q.rcv_id, q.rcv_private_key, q.rcv_dh_secret,
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.queue_mode, q.status,
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.queue_mode, q.status, c.enable_ntfs,
|
||||
q.rcv_queue_id, q.rcv_primary, q.replace_rcv_queue_id, q.switch_status, q.smp_client_version, q.delete_errors,
|
||||
q.ntf_public_key, q.ntf_private_key, q.ntf_id, q.rcv_ntf_dh_secret,
|
||||
q.link_id, q.link_key, q.link_priv_sig_key, q.link_enc_fixed_data
|
||||
@@ -807,7 +853,7 @@ SEARCH s USING PRIMARY KEY (host=? AND port=?)
|
||||
|
||||
Query:
|
||||
SELECT c.user_id, COALESCE(q.server_key_hash, s.key_hash), q.conn_id, q.host, q.port, q.rcv_id, q.rcv_private_key, q.rcv_dh_secret,
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.queue_mode, q.status,
|
||||
q.e2e_priv_key, q.e2e_dh_secret, q.snd_id, q.queue_mode, q.status, c.enable_ntfs,
|
||||
q.rcv_queue_id, q.rcv_primary, q.replace_rcv_queue_id, q.switch_status, q.smp_client_version, q.delete_errors,
|
||||
q.ntf_public_key, q.ntf_private_key, q.ntf_id, q.rcv_ntf_dh_secret,
|
||||
q.link_id, q.link_key, q.link_priv_sig_key, q.link_enc_fixed_data
|
||||
@@ -820,6 +866,30 @@ SEARCH q USING PRIMARY KEY (host=? AND port=? AND rcv_id=?)
|
||||
SEARCH s USING PRIMARY KEY (host=? AND port=?)
|
||||
SEARCH c USING PRIMARY KEY (conn_id=?)
|
||||
|
||||
Query:
|
||||
SELECT c.user_id, q.conn_id, q.host, q.port, COALESCE(q.server_key_hash, s.key_hash), q.rcv_id, q.rcv_private_key, q.status, c.enable_ntfs,
|
||||
q.rcv_queue_id, q.rcv_primary, q.replace_rcv_queue_id
|
||||
FROM rcv_queues q
|
||||
JOIN servers s ON q.host = s.host AND q.port = s.port
|
||||
JOIN connections c ON q.conn_id = c.conn_id
|
||||
WHERE c.deleted = 0 AND q.deleted = 0 AND c.user_id = ? AND q.host = ? AND q.port = ?
|
||||
Plan:
|
||||
SEARCH s USING PRIMARY KEY (host=? AND port=?)
|
||||
SEARCH q USING PRIMARY KEY (host=? AND port=?)
|
||||
SEARCH c USING PRIMARY KEY (conn_id=?)
|
||||
|
||||
Query:
|
||||
SELECT c.user_id, q.conn_id, q.host, q.port, COALESCE(q.server_key_hash, s.key_hash), q.rcv_id, q.rcv_private_key, q.status, c.enable_ntfs,
|
||||
q.rcv_queue_id, q.rcv_primary, q.replace_rcv_queue_id
|
||||
FROM rcv_queues q
|
||||
JOIN servers s ON q.host = s.host AND q.port = s.port
|
||||
JOIN connections c ON q.conn_id = c.conn_id
|
||||
WHERE q.to_subscribe = 1 AND c.deleted = 0 AND q.deleted = 0 AND c.user_id = ? AND q.host = ? AND q.port = ?
|
||||
Plan:
|
||||
SEARCH q USING INDEX idx_rcv_queues_to_subscribe (to_subscribe=? AND host=? AND port=?)
|
||||
SEARCH c USING PRIMARY KEY (conn_id=?)
|
||||
SEARCH s USING PRIMARY KEY (host=? AND port=?)
|
||||
|
||||
Query: DELETE FROM commands WHERE command_id = ?
|
||||
Plan:
|
||||
SEARCH commands USING INTEGER PRIMARY KEY (rowid=?)
|
||||
@@ -965,10 +1035,6 @@ Query: SELECT 1 FROM snd_message_deliveries WHERE conn_id = ? AND failed = 0 LIM
|
||||
Plan:
|
||||
SEARCH snd_message_deliveries USING COVERING INDEX idx_snd_message_deliveries_expired (conn_id=?)
|
||||
|
||||
Query: SELECT DISTINCT conn_id FROM snd_message_deliveries WHERE failed = 0
|
||||
Plan:
|
||||
SCAN snd_message_deliveries USING COVERING INDEX idx_snd_message_deliveries_expired
|
||||
|
||||
Query: SELECT conn_id FROM connections WHERE user_id = ?
|
||||
Plan:
|
||||
SEARCH connections USING COVERING INDEX idx_connections_user (user_id=?)
|
||||
@@ -1129,6 +1195,10 @@ Query: UPDATE rcv_queues SET rcv_primary = ?, replace_rcv_queue_id = ? WHERE con
|
||||
Plan:
|
||||
SEARCH rcv_queues USING COVERING INDEX idx_rcv_queue_id (conn_id=? AND rcv_queue_id=?)
|
||||
|
||||
Query: UPDATE rcv_queues SET to_subscribe = 0 WHERE to_subscribe = 1
|
||||
Plan:
|
||||
SEARCH rcv_queues USING COVERING INDEX idx_rcv_queues_to_subscribe (to_subscribe=?)
|
||||
|
||||
Query: UPDATE servers_stats SET servers_stats = ?, updated_at = ? WHERE servers_stats_id = 1
|
||||
Plan:
|
||||
SEARCH servers_stats USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
@@ -1355,20 +1355,6 @@ SEARCH cp USING COVERING INDEX idx_contact_profiles_contact_link (user_id=? AND
|
||||
SEARCH ct USING COVERING INDEX idx_contacts_contact_profile_id (contact_profile_id=?)
|
||||
SEARCH c USING COVERING INDEX idx_connections_contact_id (contact_id=?) LEFT-JOIN
|
||||
|
||||
Query:
|
||||
SELECT ct.contact_id, c.connection_id, c.agent_conn_id, ct.local_display_name
|
||||
FROM contacts ct
|
||||
JOIN connections c ON c.contact_id = ct.contact_id
|
||||
WHERE c.agent_conn_id IN (SELECT conn_id FROM temp_conn_ids)
|
||||
AND c.conn_type = ?
|
||||
AND ct.deleted = 0
|
||||
|
||||
Plan:
|
||||
SEARCH c USING INDEX sqlite_autoindex_connections_1 (agent_conn_id=?)
|
||||
LIST SUBQUERY 1
|
||||
SCAN temp_conn_ids
|
||||
SEARCH ct USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
SELECT g.group_id
|
||||
FROM groups g
|
||||
@@ -3117,76 +3103,6 @@ Query:
|
||||
Plan:
|
||||
SEARCH chat_items USING COVERING INDEX idx_chat_items_notes (user_id=? AND note_folder_id=? AND item_status=?)
|
||||
|
||||
Query:
|
||||
SELECT agent_conn_id
|
||||
FROM connections
|
||||
WHERE user_id = ?
|
||||
|
||||
AND conn_type = ?
|
||||
AND contact_id IS NULL
|
||||
AND conn_status != ?
|
||||
|
||||
Plan:
|
||||
SEARCH connections USING INDEX idx_connections_contact_id (contact_id=?)
|
||||
|
||||
Query:
|
||||
SELECT agent_conn_id
|
||||
FROM connections
|
||||
WHERE user_id = ?
|
||||
AND to_subscribe = 1
|
||||
AND conn_type = ?
|
||||
AND contact_id IS NULL
|
||||
AND conn_status != ?
|
||||
|
||||
Plan:
|
||||
SEARCH connections USING INDEX idx_connections_contact_id (contact_id=?)
|
||||
|
||||
Query:
|
||||
SELECT c.agent_conn_id
|
||||
FROM connections c
|
||||
JOIN contacts ct ON ct.contact_id = c.contact_id
|
||||
WHERE c.user_id = ?
|
||||
|
||||
AND c.conn_status != ?
|
||||
AND ct.contact_status = ? AND ct.deleted = 0
|
||||
|
||||
Plan:
|
||||
SEARCH c USING INDEX idx_connections_to_subscribe (user_id=?)
|
||||
SEARCH ct USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
SELECT c.agent_conn_id
|
||||
FROM connections c
|
||||
JOIN contacts ct ON ct.contact_id = c.contact_id
|
||||
WHERE c.user_id = ?
|
||||
AND c.to_subscribe = 1
|
||||
AND c.conn_status != ?
|
||||
AND ct.contact_status = ? AND ct.deleted = 0
|
||||
|
||||
Plan:
|
||||
SEARCH c USING INDEX idx_connections_to_subscribe (user_id=? AND to_subscribe=?)
|
||||
SEARCH ct USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
SELECT c.agent_conn_id
|
||||
FROM connections c
|
||||
JOIN user_contact_links ucl ON ucl.user_contact_link_id = c.user_contact_link_id
|
||||
WHERE c.user_id = ?
|
||||
AND c.conn_status != ?
|
||||
Plan:
|
||||
SEARCH c USING INDEX idx_connections_to_subscribe (user_id=?)
|
||||
SEARCH ucl USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
SELECT c.agent_conn_id
|
||||
FROM connections c
|
||||
JOIN user_contact_links ucl ON ucl.user_contact_link_id = c.user_contact_link_id
|
||||
WHERE c.user_id = ?
|
||||
AND c.to_subscribe = 1 AND c.conn_status != ?
|
||||
Plan:
|
||||
SEARCH c USING INDEX idx_connections_to_subscribe (user_id=? AND to_subscribe=?)
|
||||
SEARCH ucl USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
SELECT c.connection_id, c.agent_conn_id, c.conn_level, c.via_contact, c.via_user_contact_link, c.via_group_link, c.group_link_id, c.xcontact_id, c.custom_user_profile_id,
|
||||
c.conn_status, c.conn_type, c.contact_conn_initiated, c.local_alias, c.contact_id, c.group_member_id, c.user_contact_link_id,
|
||||
@@ -3837,56 +3753,6 @@ Query:
|
||||
Plan:
|
||||
SEARCH groups USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
WITH user_groups AS MATERIALIZED (
|
||||
SELECT g.group_id
|
||||
FROM groups g
|
||||
JOIN group_members mu ON mu.group_id = g.group_id
|
||||
WHERE g.user_id = ?
|
||||
AND mu.contact_id = ?
|
||||
AND mu.member_status NOT IN (?,?,?)
|
||||
)
|
||||
SELECT c.agent_conn_id
|
||||
FROM connections c
|
||||
JOIN group_members m ON m.group_member_id = c.group_member_id
|
||||
JOIN user_groups ug ON ug.group_id = m.group_id
|
||||
WHERE c.user_id = ?
|
||||
AND c.conn_status != ?
|
||||
AND m.member_status NOT IN (?,?,?)
|
||||
|
||||
Plan:
|
||||
MATERIALIZE user_groups
|
||||
SEARCH mu USING INDEX idx_group_members_contact_id (contact_id=?)
|
||||
SEARCH g USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH c USING INDEX idx_connections_to_subscribe (user_id=?)
|
||||
SEARCH m USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH ug USING AUTOMATIC COVERING INDEX (group_id=?)
|
||||
|
||||
Query:
|
||||
WITH user_groups AS MATERIALIZED (
|
||||
SELECT g.group_id
|
||||
FROM groups g
|
||||
JOIN group_members mu ON mu.group_id = g.group_id
|
||||
WHERE g.user_id = ?
|
||||
AND mu.contact_id = ?
|
||||
AND mu.member_status NOT IN (?,?,?)
|
||||
)
|
||||
SELECT c.agent_conn_id
|
||||
FROM connections c
|
||||
JOIN group_members m ON m.group_member_id = c.group_member_id
|
||||
JOIN user_groups ug ON ug.group_id = m.group_id
|
||||
WHERE c.user_id = ?
|
||||
AND c.conn_status != ?
|
||||
AND m.member_status NOT IN (?,?,?)
|
||||
AND c.to_subscribe = 1
|
||||
Plan:
|
||||
MATERIALIZE user_groups
|
||||
SEARCH mu USING INDEX idx_group_members_contact_id (contact_id=?)
|
||||
SEARCH g USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH c USING INDEX idx_connections_to_subscribe (user_id=? AND to_subscribe=?)
|
||||
SEARCH m USING INTEGER PRIMARY KEY (rowid=?)
|
||||
SEARCH ug USING AUTOMATIC COVERING INDEX (group_id=?)
|
||||
|
||||
Query:
|
||||
DELETE FROM chat_items
|
||||
WHERE group_scope_group_member_id = ?
|
||||
@@ -5133,7 +4999,7 @@ Query:
|
||||
FROM group_members m
|
||||
JOIN contact_profiles p ON p.contact_profile_id = COALESCE(m.member_profile_id, m.contact_profile_id)
|
||||
LEFT JOIN connections c ON c.group_member_id = m.group_member_id
|
||||
|
||||
|
||||
WHERE m.group_id = ? AND m.user_id = ? AND (m.contact_id IS NULL OR m.contact_id != ?)
|
||||
AND m.member_status IN (?, ?, ?, ?)
|
||||
AND m.group_member_id NOT IN (
|
||||
@@ -5575,9 +5441,6 @@ Query: SELECT chat_item_id FROM chat_items WHERE user_id = ? AND group_id = ?
|
||||
Plan:
|
||||
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_item_ts (user_id=? AND group_id=? AND msg_content_tag=?)
|
||||
|
||||
Query: CREATE TABLE temp_conn_ids (conn_id BLOB)
|
||||
Error: SQLite3 returned ErrorError while attempting to perform prepare "explain query plan CREATE TABLE temp_conn_ids (conn_id BLOB)": table temp_conn_ids already exists
|
||||
|
||||
Query: CREATE TABLE temp_delete_members (contact_profile_id INTEGER, member_profile_id INTEGER, local_display_name TEXT)
|
||||
Error: SQLite3 returned ErrorError while attempting to perform prepare "explain query plan CREATE TABLE temp_delete_members (contact_profile_id INTEGER, member_profile_id INTEGER, local_display_name TEXT)": table temp_delete_members already exists
|
||||
|
||||
@@ -5978,15 +5841,9 @@ SEARCH contacts USING COVERING INDEX sqlite_autoindex_contacts_2 (user_id=?)
|
||||
SEARCH display_names USING COVERING INDEX sqlite_autoindex_display_names_2 (user_id=?)
|
||||
SEARCH contact_profiles USING COVERING INDEX idx_contact_profiles_user_id (user_id=?)
|
||||
|
||||
Query: DROP TABLE IF EXISTS temp_conn_ids
|
||||
Plan:
|
||||
|
||||
Query: DROP TABLE IF EXISTS temp_delete_members
|
||||
Plan:
|
||||
|
||||
Query: DROP TABLE temp_conn_ids
|
||||
Plan:
|
||||
|
||||
Query: DROP TABLE temp_delete_members
|
||||
Plan:
|
||||
|
||||
@@ -6083,9 +5940,6 @@ Query: INSERT INTO snd_files (file_id, file_status, file_descr_id, group_member_
|
||||
Plan:
|
||||
SEARCH connections USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query: INSERT INTO temp_conn_ids (conn_id) VALUES (?)
|
||||
Plan:
|
||||
|
||||
Query: INSERT INTO user_contact_links (user_id, conn_req_contact, short_link_contact, short_link_data_set, short_link_large_data_set, created_at, updated_at) VALUES (?,?,?,?,?,?,?)
|
||||
Plan:
|
||||
|
||||
@@ -6396,10 +6250,6 @@ Query: UPDATE connections SET security_code = ?, security_code_verified_at = ?,
|
||||
Plan:
|
||||
SEARCH connections USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query: UPDATE connections SET to_subscribe = 0 WHERE user_id = ? AND to_subscribe = 1
|
||||
Plan:
|
||||
SEARCH connections USING INDEX idx_connections_to_subscribe (user_id=? AND to_subscribe=?)
|
||||
|
||||
Query: UPDATE contact_requests SET business_group_id = ? WHERE contact_request_id = ?
|
||||
Plan:
|
||||
SEARCH contact_requests USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
@@ -33,11 +33,9 @@ import Simplex.Chat.Styled
|
||||
import Simplex.Chat.Terminal.Notification (Notification (..), initializeNotifications)
|
||||
import Simplex.Chat.Types
|
||||
import Simplex.Chat.View
|
||||
import Simplex.Messaging.Agent.Protocol
|
||||
import Simplex.Messaging.Encoding.String
|
||||
import Simplex.Messaging.TMap (TMap)
|
||||
import qualified Simplex.Messaging.TMap as TM
|
||||
import Simplex.Messaging.Util (safeDecodeUtf8, tshow)
|
||||
import Simplex.Messaging.Util (tshow)
|
||||
import System.Console.ANSI.Types
|
||||
import System.IO (IOMode (..), hPutStrLn, withFile)
|
||||
import System.Mem.Weak (Weak)
|
||||
@@ -196,8 +194,6 @@ chatEventNotification t@ChatTerminal {sendNotification} cc = \case
|
||||
CEvtContactAnotherClient u ct -> do
|
||||
whenCurrUser cc u $ unsetActiveContact t ct
|
||||
when (contactNtf u ct False) $ sendNtf (viewContactName ct <> "> ", "connected to another client")
|
||||
CEvtContactsDisconnected srv _ -> serverNtf srv "disconnected"
|
||||
CEvtContactsSubscribed srv _ -> serverNtf srv "connected"
|
||||
CEvtReceivedGroupInvitation u g ct _ _ ->
|
||||
when (contactNtf u ct False) $
|
||||
sendNtf ("#" <> viewGroupName g <> " " <> viewContactName ct <> "> ", "invited you to join the group")
|
||||
@@ -215,7 +211,6 @@ chatEventNotification t@ChatTerminal {sendNotification} cc = \case
|
||||
_ -> pure ()
|
||||
where
|
||||
sendNtf = maybe (\_ -> pure ()) (. uncurry Notification) sendNotification
|
||||
serverNtf (SMPServer host _ _) str = sendNtf ("server " <> str, safeDecodeUtf8 $ strEncode host)
|
||||
|
||||
msgText :: MsgContent -> Maybe MarkdownList -> Text
|
||||
msgText (MCFile _) _ = "wants to send a file"
|
||||
|
||||
@@ -1813,7 +1813,7 @@ data NetworkStatus
|
||||
netStatusStr :: NetworkStatus -> String
|
||||
netStatusStr = \case
|
||||
NSUnknown -> "unknown"
|
||||
NSConnected -> "connected"
|
||||
NSConnected -> "subscribed"
|
||||
NSDisconnected -> "disconnected"
|
||||
NSError e -> "error: " <> e
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import qualified Data.ByteString.Lazy.Char8 as LB
|
||||
import Data.Char (isSpace, toUpper)
|
||||
import Data.Function (on)
|
||||
import Data.Int (Int64)
|
||||
import Data.List (groupBy, intercalate, intersperse, partition, sortOn)
|
||||
import Data.List (groupBy, intercalate, intersperse, sortOn)
|
||||
import Data.List.NonEmpty (NonEmpty (..))
|
||||
import qualified Data.List.NonEmpty as L
|
||||
import Data.Map.Strict (Map)
|
||||
@@ -384,7 +384,7 @@ contactList :: [ContactRef] -> String
|
||||
contactList cs = T.unpack . T.intercalate ", " $ map (\ContactRef {localDisplayName = n} -> "@" <> n) cs
|
||||
|
||||
chatEventToView :: (Maybe RemoteHostId, Maybe User) -> ChatConfig -> Bool -> CurrentTime -> TimeZone -> Maybe RemoteHostId -> ChatEvent -> [StyledString]
|
||||
chatEventToView hu ChatConfig {logLevel, showReactions, showReceipts, testView, coreApi} liveItems ts tz outputRH = \case
|
||||
chatEventToView hu ChatConfig {logLevel, showReactions, showReceipts, testView} liveItems ts tz outputRH = \case
|
||||
CEvtChatSuspended -> ["chat suspended"]
|
||||
CEvtContactSwitch u ct progress -> ttyUser u $ viewContactSwitch ct progress
|
||||
CEvtGroupMemberSwitch u g m progress -> ttyUser u $ viewGroupMemberSwitch g m progress
|
||||
@@ -452,15 +452,7 @@ chatEventToView hu ChatConfig {logLevel, showReactions, showReceipts, testView,
|
||||
CEvtSubscriptionEnd u acEntity ->
|
||||
let Connection {connId} = entityConnection acEntity
|
||||
in ttyUser u [sShow connId <> ": END"]
|
||||
CEvtContactsDisconnected srv cs -> [plain $ "server disconnected " <> showSMPServer srv <> " (" <> contactList cs <> ")"]
|
||||
CEvtContactsSubscribed srv cs -> [plain $ "server connected " <> showSMPServer srv <> " (" <> contactList cs <> ")"]
|
||||
CEvtConnSubError u connId e -> ttyUser u ["conn ID " <> sShow connId <> ": subscription error " <> sShow e]
|
||||
CEvtConnSubSummary u connSubResults ->
|
||||
ttyUser u $ [sShow (length subscribed) <> " connections subscribed" | not (null subscribed)] <> viewSubErrorsSummary errs
|
||||
where
|
||||
(errs, subscribed) = partition (isJust . connSubError) connSubResults
|
||||
CEvtNetworkStatus status conns -> if testView && coreApi then [plain $ show (length conns) <> " connections " <> netStatusStr status] else []
|
||||
CEvtNetworkStatuses u statuses -> if testView && coreApi then ttyUser' u $ viewNetworkStatuses statuses else []
|
||||
CEvtNetworkStatus srv status conns -> [plain $ netStatusStr status <> " " <> show (length conns) <> " connections on server " <> showSMPServer srv]
|
||||
CEvtReceivedGroupInvitation {user = u, groupInfo = g, contact = c, memberRole = r} -> ttyUser u $ viewReceivedGroupInvitation g c r
|
||||
CEvtUserJoinedGroup u g _ -> ttyUser u $ viewUserJoinedGroup g
|
||||
CEvtJoinedGroupMember u g m -> ttyUser u $ viewJoinedGroupMember g m
|
||||
|
||||
@@ -71,7 +71,7 @@ testBroadcastMessages ps = do
|
||||
withTestChat ps "alice" $ \alice ->
|
||||
withNewTestChat ps "bob" bobProfile $ \bob ->
|
||||
withNewTestChat ps "cath" cathProfile $ \cath -> do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
bob `connectVia` botLink
|
||||
bob #> "@broadcast_bot hello"
|
||||
bob <# "broadcast_bot> > hello"
|
||||
|
||||
@@ -1232,8 +1232,8 @@ testRestoreDirectory ps = do
|
||||
restoreDirectoryService ps 11 $ \superUser _dsLink ->
|
||||
withTestChat ps "bob" $ \bob ->
|
||||
withTestChat ps "cath" $ \cath -> do
|
||||
bob <## "5 connections subscribed"
|
||||
cath <## "5 connections subscribed"
|
||||
bob <## "subscribed 5 connections on server localhost"
|
||||
cath <## "subscribed 5 connections on server localhost"
|
||||
listGroups superUser bob cath
|
||||
groupFoundN 3 bob "privacy"
|
||||
groupFound bob "security"
|
||||
@@ -1365,7 +1365,7 @@ restoreDirectoryService :: HasCallStack => TestParams -> Int -> (TestCC -> Strin
|
||||
restoreDirectoryService ps connCount test = do
|
||||
dsLink <-
|
||||
withTestChat ps serviceDbPrefix $ \ds -> do
|
||||
ds .<## (show connCount <> " connections subscribed")
|
||||
ds .<## ("subscribed " <> show connCount <> " connections on server localhost")
|
||||
ds ##> "/sa"
|
||||
dsLink <- getContactLink ds False
|
||||
ds <## "auto_accept on"
|
||||
@@ -1381,8 +1381,8 @@ withDirectoryOwnersGroup ps cfg dsLink createOwnersGroup webFolder test = do
|
||||
runDirectory cfg opts $
|
||||
withTestChatCfg ps cfg "super_user" $ \superUser -> do
|
||||
if createOwnersGroup
|
||||
then superUser <## "2 connections subscribed"
|
||||
else superUser <## "1 connections subscribed"
|
||||
then superUser <## "subscribed 2 connections on server localhost"
|
||||
else superUser <## "subscribed 1 connections on server localhost"
|
||||
test superUser dsLink
|
||||
|
||||
runDirectory :: ChatConfig -> DirectoryOpts -> IO () -> IO ()
|
||||
|
||||
+45
-47
@@ -55,7 +55,7 @@ chatDirectTests = do
|
||||
describe "direct messages" $ do
|
||||
describe "add contact and send/receive messages" testAddContact
|
||||
it "retry connecting via the same link" testRetryConnecting
|
||||
xit'' "retry connecting via the same link with client timeout" testRetryConnectingClientTimeout
|
||||
it "retry connecting via the same link with client timeout" testRetryConnectingClientTimeout
|
||||
it "mark multiple messages as read" testMarkReadDirect
|
||||
it "clear chat with contact" testContactClear
|
||||
it "deleting contact deletes profile" testDeleteContactDeletesProfile
|
||||
@@ -243,14 +243,14 @@ testRetryConnecting ps = testChatCfgOpts2 cfg' opts' aliceProfile bobProfile tes
|
||||
inv <- withSmpServer' serverCfg' $ do
|
||||
alice ##> "/_connect 1"
|
||||
getInvitation alice
|
||||
alice <## "server disconnected localhost ()"
|
||||
alice <## "disconnected 1 connections on server localhost"
|
||||
bob ##> ("/_connect plan 1 " <> inv)
|
||||
bob <## "invitation link: ok to connect"
|
||||
_sLinkData <- getTermLine bob
|
||||
bob ##> ("/_connect 1 " <> inv)
|
||||
bob <##. "smp agent error: BROKER"
|
||||
withSmpServer' serverCfg' $ do
|
||||
alice <## "server connected localhost ()"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
threadDelay 250000
|
||||
bob ##> ("/_connect plan 1 " <> inv)
|
||||
bob <## "invitation link: ok to connect"
|
||||
@@ -264,8 +264,8 @@ testRetryConnecting ps = testChatCfgOpts2 cfg' opts' aliceProfile bobProfile tes
|
||||
bob <# "alice> message 1"
|
||||
bob #> "@alice message 2"
|
||||
alice <# "bob> message 2"
|
||||
bob <## "server disconnected localhost (@alice)"
|
||||
alice <## "server disconnected localhost (@bob)"
|
||||
bob <## "disconnected 1 connections on server localhost"
|
||||
alice <## "disconnected 1 connections on server localhost"
|
||||
serverCfg' =
|
||||
smpServerCfg
|
||||
{ transports = [("7003", transport @TLS, False)],
|
||||
@@ -312,8 +312,8 @@ testRetryConnectingClientTimeout ps = do
|
||||
withTestChatCfgOpts ps cfg' opts' "alice" $ \alice -> do
|
||||
withTestChatCfgOpts ps cfg' opts' "bob" $ \bob -> do
|
||||
threadDelay 250000
|
||||
alice <## "1 connections subscribed"
|
||||
bob <## "1 subscription errors (run with -c option to show each error)"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
-- bob <## "1 subscription errors (run with -c option to show each error)"
|
||||
bob ##> ("/_connect plan 1 " <> inv)
|
||||
bob <## "invitation link: ok to connect"
|
||||
_sLinkData <- getTermLine bob
|
||||
@@ -1249,7 +1249,7 @@ testAsyncInitiatingOffline withShortLink aliceCfg bobCfg ps = do
|
||||
bob ##> ("/c " <> inv)
|
||||
bob <## "confirmation sent!"
|
||||
withTestChatCfg ps aliceCfg "alice" $ \alice -> do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
concurrently_
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
@@ -1265,8 +1265,8 @@ testAsyncAcceptingOffline withShortLink aliceCfg bobCfg ps = do
|
||||
bob <## "confirmation sent!"
|
||||
withTestChatCfg ps aliceCfg "alice" $ \alice -> do
|
||||
withTestChatCfg ps bobCfg "bob" $ \bob -> do
|
||||
alice <## "1 connections subscribed"
|
||||
bob <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
concurrently_
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
@@ -1283,10 +1283,10 @@ testFullAsyncFast ps = do
|
||||
bob <## "confirmation sent!"
|
||||
threadDelay 250000
|
||||
withTestChat ps "alice" $ \alice -> do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "bob (Bob): contact is connected"
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob <## "alice (Alice): contact is connected"
|
||||
|
||||
testFullAsyncSlow :: HasCallStack => Bool -> ChatConfig -> ChatConfig -> TestParams -> IO ()
|
||||
@@ -1300,14 +1300,14 @@ testFullAsyncSlow withShortLink aliceCfg bobCfg ps = do
|
||||
bob ##> ("/c " <> inv)
|
||||
bob <## "confirmation sent!"
|
||||
withAlice $ \alice ->
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
withBob $ \bob ->
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
withAlice $ \alice -> do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "bob (Bob): contact is connected"
|
||||
withBob $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob <## "alice (Alice): contact is connected"
|
||||
where
|
||||
withAlice = withTestChatCfg ps aliceCfg "alice"
|
||||
@@ -1401,7 +1401,7 @@ testMaintenanceMode ps = do
|
||||
alice ##> "/_start"
|
||||
alice <## "chat started"
|
||||
-- chat works after start
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice #> "@bob hi again"
|
||||
bob <# "alice> hi again"
|
||||
bob #> "@alice hello"
|
||||
@@ -1422,7 +1422,7 @@ testMaintenanceMode ps = do
|
||||
|
||||
testChatWorking :: HasCallStack => TestCC -> TestCC -> IO ()
|
||||
testChatWorking alice bob = do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice #> "@bob hello again"
|
||||
bob <# "alice> hello again"
|
||||
bob #> "@alice hello too"
|
||||
@@ -1541,7 +1541,7 @@ testSubscribeAppNSE ps =
|
||||
(nseAlice </)
|
||||
alice ##> "/_app activate"
|
||||
alice <## "ok"
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "bob (Bob) wants to connect to you!"
|
||||
alice <## "to accept: /ac bob"
|
||||
alice <## "to reject: /rc bob (the sender will NOT be notified)"
|
||||
@@ -1752,8 +1752,8 @@ testUsersSubscribeAfterRestart ps = do
|
||||
|
||||
withTestChat ps "alice" $ \alice -> do
|
||||
-- second user is active
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "[user: alice] 1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
|
||||
-- second user receives message
|
||||
alice <##> bob
|
||||
@@ -2058,8 +2058,8 @@ testUsersRestartCIExpiration ps = do
|
||||
showActiveUser alice "alice (Alice)"
|
||||
|
||||
withTestChatCfg ps cfg "alice" $ \alice -> do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "[user: alisa] 1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
|
||||
-- first user messages
|
||||
alice ##> "/user alice"
|
||||
@@ -2157,8 +2157,8 @@ testEnableCIExpirationOnlyForOneUser ps = do
|
||||
alice #$> ("/_get chat @6 count=100", chat, chatFeatures <> [(1, "alisa 1"), (0, "alisa 2"), (1, "alisa 3"), (0, "alisa 4")])
|
||||
|
||||
withTestChatCfg ps cfg "alice" $ \alice -> do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "[user: alice] 1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
|
||||
-- messages are not deleted for second user after restart
|
||||
alice #$> ("/_get chat @6 count=100", chat, chatFeatures <> [(1, "alisa 1"), (0, "alisa 2"), (1, "alisa 3"), (0, "alisa 4")])
|
||||
@@ -2213,8 +2213,8 @@ testDisableCIExpirationOnlyForOneUser ps = do
|
||||
alice #$> ("/_get chat @6 count=100", chat, [(1,"chat banner")])
|
||||
|
||||
withTestChatCfg ps cfg "alice" $ \alice -> do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "[user: alice] 1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
|
||||
-- second user still has ttl configured after restart
|
||||
alice #$> ("/ttl", id, "old messages are set to be deleted after: 1 second(s)")
|
||||
@@ -2320,8 +2320,8 @@ testUsersTimedMessages ps = do
|
||||
alice <# "bob> alisa 4"
|
||||
|
||||
withTestChat ps "alice" $ \alice -> do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "[user: alice] 1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
|
||||
alice ##> "/user alice"
|
||||
showActiveUser alice "alice (Alice)"
|
||||
@@ -2670,7 +2670,7 @@ testAbortSwitchContact ps = do
|
||||
alice ##> "/abort switch bob"
|
||||
alice <## "error: command is prohibited, abortConnectionSwitch: not allowed"
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob <## "alice started changing address for you"
|
||||
-- alice changes address again
|
||||
alice #$> ("/switch bob", id, "switch started")
|
||||
@@ -2717,7 +2717,7 @@ testAbortSwitchGroupMember ps = do
|
||||
alice ##> "/abort switch #team bob"
|
||||
alice <## "error: command is prohibited, abortConnectionSwitch: not allowed"
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "2 connections subscribed"
|
||||
bob <## "subscribed 2 connections on server localhost"
|
||||
bob <## "#team: alice started changing address for you"
|
||||
-- alice changes address again
|
||||
alice #$> ("/switch #team bob", id, "switch started")
|
||||
@@ -2816,7 +2816,7 @@ testMsgDecryptError ps =
|
||||
alice <# "bob> hey"
|
||||
setupDesynchronizedRatchet ps alice
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
alice #> "@bob hello again"
|
||||
bob <# "alice> skipped message ID 9..11"
|
||||
bob <# "alice> hello again"
|
||||
@@ -2827,7 +2827,7 @@ setupDesynchronizedRatchet :: HasCallStack => TestParams -> TestCC -> IO ()
|
||||
setupDesynchronizedRatchet ps alice = do
|
||||
copyDb "bob" "bob_old"
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
alice #> "@bob 1"
|
||||
bob <# "alice> 1"
|
||||
bob #> "@alice 2"
|
||||
@@ -2838,7 +2838,7 @@ setupDesynchronizedRatchet ps alice = do
|
||||
alice <# "bob> 4"
|
||||
threadDelay 500000
|
||||
withTestChat ps "bob_old" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob ##> "/sync alice"
|
||||
bob <## "error: command is prohibited, synchronizeRatchet: not allowed"
|
||||
alice #> "@bob 1"
|
||||
@@ -2869,7 +2869,7 @@ testSyncRatchet ps =
|
||||
alice <# "bob> hey"
|
||||
setupDesynchronizedRatchet ps alice
|
||||
withTestChat ps "bob_old" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob ##> "/sync alice"
|
||||
bob <## "connection synchronization started"
|
||||
alice <## "bob: connection synchronization agreed"
|
||||
@@ -2908,7 +2908,7 @@ testSyncRatchetCodeReset ps =
|
||||
aliceInfo bob True
|
||||
setupDesynchronizedRatchet ps alice
|
||||
withTestChat ps "bob_old" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob ##> "/sync alice"
|
||||
bob <## "connection synchronization started"
|
||||
alice <## "bob: connection synchronization agreed"
|
||||
@@ -3132,7 +3132,7 @@ testUpdatePeerChatVRange ps =
|
||||
contactInfoChatVRange bob supportedChatVRange
|
||||
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
|
||||
bob #> "@alice hello 1"
|
||||
alice <# "bob> hello 1"
|
||||
@@ -3144,7 +3144,7 @@ testUpdatePeerChatVRange ps =
|
||||
contactInfoChatVRange bob supportedChatVRange
|
||||
|
||||
withTestChatCfg ps cfg11 "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
|
||||
bob #> "@alice hello 2"
|
||||
alice <# "bob> hello 2"
|
||||
@@ -3159,17 +3159,15 @@ testUpdatePeerChatVRange ps =
|
||||
|
||||
testGetNetworkStatuses :: HasCallStack => TestParams -> IO ()
|
||||
testGetNetworkStatuses ps = do
|
||||
withNewTestChatCfg ps cfg "alice" aliceProfile $ \alice -> do
|
||||
withNewTestChatCfg ps cfg "bob" bobProfile $ \bob -> do
|
||||
withNewTestChat ps "alice" aliceProfile $ \alice -> do
|
||||
withNewTestChat ps "bob" bobProfile $ \bob -> do
|
||||
connectUsers alice bob
|
||||
alice ##> "/_network_statuses"
|
||||
alice <## "1 connections connected"
|
||||
withTestChatCfg ps cfg "alice" $ \alice ->
|
||||
withTestChatCfg ps cfg "bob" $ \bob -> do
|
||||
alice <## "1 connections connected"
|
||||
bob <## "1 connections connected"
|
||||
where
|
||||
cfg = testCfg {coreApi = True}
|
||||
alice <## "1 connections subscribed"
|
||||
withTestChat ps "alice" $ \alice ->
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
|
||||
vr11 :: VersionRangeChat
|
||||
vr11 = mkVersionRange (VersionChat 1) (VersionChat 1)
|
||||
|
||||
@@ -818,7 +818,7 @@ testXFTPContinueRcv ps = do
|
||||
|
||||
-- server is down - file is not received
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob ##> "/fr 1 ./tests/tmp"
|
||||
bob
|
||||
<### [ "saving file 1 from alice to ./tests/tmp/test.pdf",
|
||||
@@ -833,7 +833,7 @@ testXFTPContinueRcv ps = do
|
||||
withXFTPServer $ do
|
||||
-- server is up - file reception is continued
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob <## "completed receiving file 1 (test.pdf) from alice"
|
||||
src <- B.readFile "./tests/fixtures/test.pdf"
|
||||
dest <- B.readFile "./tests/tmp/test.pdf"
|
||||
@@ -866,7 +866,7 @@ testXFTPMarkToReceive = do
|
||||
bob <## "chat started"
|
||||
|
||||
bob
|
||||
<### [ "1 connections subscribed",
|
||||
<### [ "subscribed 1 connections on server localhost",
|
||||
"started receiving file 1 (test.pdf) from alice",
|
||||
"saving file 1 from alice to test.pdf"
|
||||
]
|
||||
@@ -892,7 +892,7 @@ testXFTPRcvError ps = do
|
||||
-- server is up w/t store log - file reception should fail
|
||||
withXFTPServer' xftpServerConfig {storeLogFile = Nothing} $ do
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob ##> "/fr 1 ./tests/tmp"
|
||||
bob
|
||||
<### [ "saving file 1 from alice to ./tests/tmp/test.pdf",
|
||||
|
||||
+39
-39
@@ -94,8 +94,8 @@ chatGroupTests = do
|
||||
-- TODO [postgres] this test hangs with PostgreSQL
|
||||
it "send multiple messages (many chat batches)" testSendMultiManyBatches
|
||||
#endif
|
||||
xit'' "shared message body is reused" testSharedMessageBody
|
||||
xit'' "shared batch body is reused" testSharedBatchBody
|
||||
it "shared message body is reused" testSharedMessageBody
|
||||
it "shared batch body is reused" testSharedBatchBody
|
||||
describe "async group connections" $ do
|
||||
xit "create and join group when clients go offline" testGroupAsync
|
||||
describe "group links" $ do
|
||||
@@ -1774,10 +1774,10 @@ testGroupDelayedModeration ps = do
|
||||
alice <## "message marked deleted by you"
|
||||
cath <# "#team cath> [marked deleted by alice] hi"
|
||||
withTestChatCfg ps cfg "bob" $ \bob -> do
|
||||
bob <## "2 connections subscribed"
|
||||
bob <## "subscribed 2 connections on server localhost"
|
||||
bob <## "#team: alice added cath (Catherine) to the group (connecting...)"
|
||||
withTestChatCfg ps cfg "cath" $ \cath -> do
|
||||
cath <## "3 connections subscribed"
|
||||
cath <## "subscribed 3 connections on server localhost"
|
||||
cath <## "#team: member bob (Bob) is connected"
|
||||
bob
|
||||
<### [ "#team: new member cath is connected",
|
||||
@@ -1828,13 +1828,13 @@ testGroupDelayedModerationFullDelete ps = do
|
||||
cath <## "updated group preferences:"
|
||||
cath <## "Full deletion: on"
|
||||
withTestChatCfg ps cfg "bob" $ \bob -> do
|
||||
bob <## "2 connections subscribed"
|
||||
bob <## "subscribed 2 connections on server localhost"
|
||||
bob <## "#team: alice added cath (Catherine) to the group (connecting...)"
|
||||
bob <## "alice updated group #team:"
|
||||
bob <## "updated group preferences:"
|
||||
bob <## "Full deletion: on"
|
||||
withTestChatCfg ps cfg "cath" $ \cath -> do
|
||||
cath <## "3 connections subscribed"
|
||||
cath <## "subscribed 3 connections on server localhost"
|
||||
cath <## "#team: member bob (Bob) is connected"
|
||||
bob
|
||||
<### [ "#team: new member cath is connected",
|
||||
@@ -2004,7 +2004,7 @@ testSharedMessageBody ps =
|
||||
withNewTestChatOpts ps opts' "cath" cathProfile $ \cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
|
||||
alice <##. "server disconnected localhost"
|
||||
alice <## "disconnected 4 connections on server localhost"
|
||||
alice #> "#team hello"
|
||||
bodiesCount1 <- withCCAgentTransaction alice $ \db ->
|
||||
DB.query_ db "SELECT count(1) FROM snd_message_bodies" :: IO [[Int]]
|
||||
@@ -2014,9 +2014,9 @@ testSharedMessageBody ps =
|
||||
withTestChatOpts ps opts' "bob" $ \bob ->
|
||||
withTestChatOpts ps opts' "cath" $ \cath -> do
|
||||
concurrentlyN_
|
||||
[ alice <##. "server connected localhost",
|
||||
bob <## "3 connections subscribed",
|
||||
cath <## "3 connections subscribed"
|
||||
[ alice <## "subscribed 4 connections on server localhost",
|
||||
bob <## "subscribed 3 connections on server localhost",
|
||||
cath <## "subscribed 3 connections on server localhost"
|
||||
]
|
||||
bob <# "#team alice> hello"
|
||||
cath <# "#team alice> hello"
|
||||
@@ -2024,7 +2024,7 @@ testSharedMessageBody ps =
|
||||
DB.query_ db "SELECT count(1) FROM snd_message_bodies" :: IO [[Int]]
|
||||
bodiesCount2 `shouldBe` [[0]]
|
||||
|
||||
alice <##. "server disconnected localhost"
|
||||
alice <## "disconnected 4 connections on server localhost"
|
||||
where
|
||||
tmp = tmpPath ps
|
||||
serverCfg' =
|
||||
@@ -2048,7 +2048,7 @@ testSharedBatchBody ps =
|
||||
withNewTestChatOpts ps opts' "cath" cathProfile $ \cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
|
||||
alice <##. "server disconnected localhost"
|
||||
alice <## "disconnected 4 connections on server localhost"
|
||||
|
||||
let cm i = "{\"msgContent\": {\"type\": \"text\", \"text\": \"message " <> show i <> "\"}}"
|
||||
cms = intercalate ", " (map cm [1 .. 300 :: Int])
|
||||
@@ -2064,9 +2064,9 @@ testSharedBatchBody ps =
|
||||
withTestChatOpts ps opts' "bob" $ \bob ->
|
||||
withTestChatOpts ps opts' "cath" $ \cath -> do
|
||||
concurrentlyN_
|
||||
[ alice <##. "server connected localhost",
|
||||
bob <## "3 connections subscribed",
|
||||
cath <## "3 connections subscribed"
|
||||
[ alice <## "subscribed 4 connections on server localhost",
|
||||
bob <## "subscribed 3 connections on server localhost",
|
||||
cath <## "subscribed 3 connections on server localhost"
|
||||
]
|
||||
forM_ [(1 :: Int) .. 300] $ \i -> do
|
||||
concurrently_
|
||||
@@ -2076,7 +2076,7 @@ testSharedBatchBody ps =
|
||||
DB.query_ db "SELECT count(1) FROM snd_message_bodies" :: IO [[Int]]
|
||||
bodiesCount2 `shouldBe` [[0]]
|
||||
|
||||
alice <##. "server disconnected localhost"
|
||||
alice <## "disconnected 4 connections on server localhost"
|
||||
where
|
||||
tmp = tmpPath ps
|
||||
serverCfg' =
|
||||
@@ -2115,7 +2115,7 @@ testGroupAsync ps = do
|
||||
bob <# "#team alice> hello bob"
|
||||
withTestChat ps "alice" $ \alice -> do
|
||||
withNewTestChat ps "cath" cathProfile $ \cath -> do
|
||||
alice <## "2 connections subscribed"
|
||||
alice <## "subscribed 2 connections on server localhost"
|
||||
connectUsers alice cath
|
||||
alice ##> "/a team cath"
|
||||
concurrentlyN_
|
||||
@@ -2135,18 +2135,18 @@ testGroupAsync ps = do
|
||||
withTestChat ps "cath" $ \cath -> do
|
||||
concurrentlyN_
|
||||
[ do
|
||||
bob <## "2 connections subscribed"
|
||||
bob <## "subscribed 2 connections on server localhost"
|
||||
bob <## "#team: alice added cath (Catherine) to the group (connecting...)"
|
||||
bob <# "#team alice> hello cath"
|
||||
bob <## "#team: new member cath is connected",
|
||||
do
|
||||
cath <## "3 connections subscribed"
|
||||
cath <## "subscribed 3 connections on server localhost"
|
||||
cath <## "#team: member bob (Bob) is connected"
|
||||
]
|
||||
threadDelay 500000
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
withNewTestChat ps "dan" danProfile $ \dan -> do
|
||||
bob <## "4 connections subscribed"
|
||||
bob <## "subscribed 4 connections on server localhost"
|
||||
connectUsers bob dan
|
||||
bob ##> "/a team dan"
|
||||
concurrentlyN_
|
||||
@@ -2167,15 +2167,15 @@ testGroupAsync ps = do
|
||||
withTestChat ps "dan" $ \dan -> do
|
||||
concurrentlyN_
|
||||
[ do
|
||||
alice <## "4 connections subscribed"
|
||||
alice <## "subscribed 4 connections on server localhost"
|
||||
alice <## "#team: bob added dan (Daniel) to the group (connecting...)"
|
||||
alice <## "#team: new member dan is connected",
|
||||
do
|
||||
cath <## "4 connections subscribed"
|
||||
cath <## "subscribed 4 connections on server localhost"
|
||||
cath <## "#team: bob added dan (Daniel) to the group (connecting...)"
|
||||
cath <## "#team: new member dan is connected",
|
||||
do
|
||||
dan <## "5 connections subscribed"
|
||||
dan <## "subscribed 5 connections on server localhost"
|
||||
dan <## "#team: member alice (Alice) is connected"
|
||||
dan <## "#team: member cath (Catherine) is connected"
|
||||
]
|
||||
@@ -2185,10 +2185,10 @@ testGroupAsync ps = do
|
||||
withTestChat ps "cath" $ \cath -> do
|
||||
withTestChat ps "dan" $ \dan -> do
|
||||
concurrentlyN_
|
||||
[ alice <## "6 connections subscribed",
|
||||
bob <## "6 connections subscribed",
|
||||
cath <## "6 connections subscribed",
|
||||
dan <## "6 connections subscribed"
|
||||
[ alice <## "subscribed 6 connections server localhost",
|
||||
bob <## "subscribed 6 connections server localhost",
|
||||
cath <## "subscribed 6 connections server localhost",
|
||||
dan <## "subscribed 6 connections server localhost"
|
||||
]
|
||||
alice #> "#team hello"
|
||||
concurrentlyN_
|
||||
@@ -3529,12 +3529,12 @@ testPlanGroupLinkConnecting ps = do
|
||||
threadDelay 100000
|
||||
withTestChat ps "alice" $ \alice -> do
|
||||
alice
|
||||
<### [ "1 connections subscribed",
|
||||
<### [ "subscribed 1 connections on server localhost",
|
||||
"bob (Bob): accepting request to join group #team..."
|
||||
]
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
threadDelay 500000
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob <## "#team: joining the group..."
|
||||
bob <## "#team: you joined the group"
|
||||
|
||||
@@ -3576,12 +3576,12 @@ testPlanGroupLinkConnectingSlow ps = do
|
||||
threadDelay 100000
|
||||
withTestChatCfg ps testCfgSlow "alice" $ \alice -> do
|
||||
alice
|
||||
<### [ "1 connections subscribed",
|
||||
<### [ "subscribed 1 connections on server localhost",
|
||||
"bob (Bob): accepting request to join group #team..."
|
||||
]
|
||||
withTestChatCfg ps testCfgSlow "bob" $ \bob -> do
|
||||
threadDelay 500000
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob <## "#team: joining the group..."
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> gLink)
|
||||
@@ -3606,7 +3606,7 @@ testGroupMsgDecryptError ps =
|
||||
alice <# "#team bob> hey"
|
||||
setupDesynchronizedRatchet ps alice
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "2 connections subscribed"
|
||||
bob <## "subscribed 2 connections on server localhost"
|
||||
alice #> "#team hello again"
|
||||
bob <# "#team alice> skipped message ID 9..11"
|
||||
bob <# "#team alice> hello again"
|
||||
@@ -3617,7 +3617,7 @@ setupDesynchronizedRatchet :: HasCallStack => TestParams -> TestCC -> IO ()
|
||||
setupDesynchronizedRatchet ps alice = do
|
||||
copyDb "bob" "bob_old"
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "2 connections subscribed"
|
||||
bob <## "subscribed 2 connections on server localhost"
|
||||
alice #> "#team 1"
|
||||
bob <# "#team alice> 1"
|
||||
bob #> "#team 2"
|
||||
@@ -3627,7 +3627,7 @@ setupDesynchronizedRatchet ps alice = do
|
||||
bob #> "#team 4"
|
||||
alice <# "#team bob> 4"
|
||||
withTestChat ps "bob_old" $ \bob -> do
|
||||
bob <## "2 connections subscribed"
|
||||
bob <## "subscribed 2 connections on server localhost"
|
||||
bob ##> "/sync #team alice"
|
||||
bob <## "error: command is prohibited, synchronizeRatchet: not allowed"
|
||||
alice #> "#team 1"
|
||||
@@ -3655,7 +3655,7 @@ testGroupSyncRatchet ps =
|
||||
alice <# "#team bob> hey"
|
||||
setupDesynchronizedRatchet ps alice
|
||||
withTestChat ps "bob_old" $ \bob -> do
|
||||
bob <## "2 connections subscribed"
|
||||
bob <## "subscribed 2 connections on server localhost"
|
||||
bob `send` "#team 1"
|
||||
-- "send prohibited" error is not printed in group as SndMessage is created,
|
||||
-- but it should be displayed in per member snd statuses
|
||||
@@ -3700,7 +3700,7 @@ testGroupSyncRatchetCodeReset ps =
|
||||
aliceInfo bob True
|
||||
setupDesynchronizedRatchet ps alice
|
||||
withTestChat ps "bob_old" $ \bob -> do
|
||||
bob <## "2 connections subscribed"
|
||||
bob <## "subscribed 2 connections on server localhost"
|
||||
bob ##> "/sync #team alice"
|
||||
bob <## "connection synchronization started"
|
||||
alice <## "#team bob: connection synchronization agreed"
|
||||
@@ -4429,7 +4429,7 @@ testMemberContactInvitedConnectionReplaced ps = do
|
||||
where
|
||||
subscriptions :: TestCC -> Int -> IO ()
|
||||
subscriptions cc n =
|
||||
cc <## (show n <> " connections subscribed")
|
||||
cc <## ("subscribed " <> show n <> " connections on server localhost")
|
||||
checkConnectionsWork alice bob = do
|
||||
alice <##> bob
|
||||
alice @@@ [("@bob", "hey"), ("@cath", "sent invitation to join group team as admin"), ("#team", "connected")]
|
||||
@@ -7001,7 +7001,7 @@ testGroupMemberInactive ps = do
|
||||
threadDelay 1500000
|
||||
|
||||
withTestChatCfgOpts ps cfg' opts' "bob" $ \bob -> do
|
||||
bob <## "2 connections subscribed"
|
||||
bob <## "subscribed 2 connections on server localhost"
|
||||
bob <# "#team alice> 1"
|
||||
bob <# "#team alice> 2"
|
||||
bob <#. "#team alice> skipped message ID"
|
||||
@@ -8284,7 +8284,7 @@ testChannelsSenderDeduplicateOwn ps = do
|
||||
dan #> "#team 6"
|
||||
|
||||
withTestChatCfg ps cfg "bob" $ \bob -> do
|
||||
bob <## "6 connections subscribed"
|
||||
bob <## "subscribed 6 connections server localhost"
|
||||
bob
|
||||
<### [ WithTime "#team alice> 1",
|
||||
WithTime "#team alice> 2",
|
||||
|
||||
+35
-36
@@ -321,27 +321,27 @@ testRetryConnectingViaContactLink ps = testChatCfgOpts2 cfg' opts' aliceProfile
|
||||
cLink <- withSmpServer' serverCfg' $ do
|
||||
alice ##> "/ad"
|
||||
getContactLink alice True
|
||||
alice <## "server disconnected localhost ()"
|
||||
alice <## "disconnected 1 connections on server localhost"
|
||||
bob ##> ("/_connect plan 1 " <> cLink)
|
||||
bob <## "contact address: ok to connect"
|
||||
_sLinkData <- getTermLine bob
|
||||
bob ##> ("/_connect 1 " <> cLink)
|
||||
bob <##. "smp agent error: BROKER"
|
||||
withSmpServer' serverCfg' $ do
|
||||
alice <## "server connected localhost ()"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
threadDelay 250000
|
||||
bob ##> ("/_connect plan 1 " <> cLink)
|
||||
bob <## "contact address: ok to connect"
|
||||
_sLinkData <- getTermLine bob
|
||||
bob ##> ("/_connect 1 " <> cLink)
|
||||
alice <#? bob
|
||||
alice <## "server disconnected localhost ()"
|
||||
bob <## "server disconnected localhost ()"
|
||||
alice <## "disconnected 1 connections on server localhost"
|
||||
bob <## "disconnected 1 connections on server localhost"
|
||||
alice ##> "/ac bob"
|
||||
alice <##. "smp agent error: BROKER"
|
||||
withSmpServer' serverCfg' $ do
|
||||
alice <## "server connected localhost ()"
|
||||
bob <## "server connected localhost ()"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
alice ##> "/ac bob"
|
||||
alice <## "bob (Bob): accepting contact request, you can send messages to contact"
|
||||
concurrently_
|
||||
@@ -351,8 +351,8 @@ testRetryConnectingViaContactLink ps = testChatCfgOpts2 cfg' opts' aliceProfile
|
||||
bob <# "alice> message 1"
|
||||
bob #> "@alice message 2"
|
||||
alice <# "bob> message 2"
|
||||
alice <## "server disconnected localhost (@bob)"
|
||||
bob <## "server disconnected localhost (@alice)"
|
||||
alice <## "disconnected 2 connections on server localhost"
|
||||
bob <## "disconnected 1 connections on server localhost"
|
||||
serverCfg' =
|
||||
smpServerCfg
|
||||
{ transports = [("7003", transport @TLS, False)],
|
||||
@@ -1086,7 +1086,7 @@ testPlanAddressConnecting ps = do
|
||||
|
||||
threadDelay 100000
|
||||
withTestChat ps "alice" $ \alice -> do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "bob (Bob) wants to connect to you!"
|
||||
alice <## "to accept: /ac bob"
|
||||
alice <## "to reject: /rc bob (the sender will NOT be notified)"
|
||||
@@ -1094,7 +1094,7 @@ testPlanAddressConnecting ps = do
|
||||
alice <## "bob (Bob): accepting contact request, you can send messages to contact"
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
threadDelay 500000
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob <## "alice (Alice): contact is connected"
|
||||
bob @@@ [("@alice", "Audio/video calls: enabled")]
|
||||
bob ##> ("/_connect plan 1 " <> cLink)
|
||||
@@ -1130,7 +1130,7 @@ testPlanAddressConnectingSlow ps = do
|
||||
|
||||
threadDelay 100000
|
||||
withTestChatCfg ps testCfgSlow "alice" $ \alice -> do
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "bob (Bob) wants to connect to you!"
|
||||
alice <## "to accept: /ac bob"
|
||||
alice <## "to reject: /rc bob (the sender will NOT be notified)"
|
||||
@@ -1138,7 +1138,7 @@ testPlanAddressConnectingSlow ps = do
|
||||
alice <## "bob (Bob): accepting contact request..."
|
||||
withTestChatCfg ps testCfgSlow "bob" $ \bob -> do
|
||||
threadDelay 500000
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob @@@ [("@alice", "")]
|
||||
bob ##> ("/_connect plan 1 " <> cLink)
|
||||
bob <## "contact address: connecting to contact alice"
|
||||
@@ -1548,12 +1548,12 @@ testSetConnectionIncognitoProhibitedDuringNegotiation ps = do
|
||||
bob <## "confirmation sent!"
|
||||
withTestChat ps "alice" $ \alice -> do
|
||||
threadDelay 250000
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice <## "bob (Bob): contact is connected"
|
||||
alice ##> "/_set incognito :1 on"
|
||||
alice <## "chat db error: SEPendingConnectionNotFound {connId = 1}"
|
||||
withTestChat ps "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
bob <## "alice (Alice): contact is connected"
|
||||
alice <##> bob
|
||||
alice `hasContactProfiles` ["alice", "bob"]
|
||||
@@ -1571,11 +1571,11 @@ testSetConnectionIncognitoProhibitedDuringNegotiationSlow ps = do
|
||||
bob <## "confirmation sent!"
|
||||
withTestChatCfg ps testCfgSlow "alice" $ \alice -> do
|
||||
threadDelay 250000
|
||||
alice <## "1 connections subscribed"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
alice ##> "/_set incognito :1 on"
|
||||
alice <## "chat db error: SEPendingConnectionNotFound {connId = 1}"
|
||||
withTestChatCfg ps testCfgSlow "bob" $ \bob -> do
|
||||
bob <## "1 connections subscribed"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
concurrently_
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
@@ -3035,11 +3035,11 @@ testShortLinkInvitationConnectRetry ps = testChatOpts2 opts' aliceProfile bobPro
|
||||
bob ##> ("/_prepare contact 1 " <> fullLink <> " " <> shortLink <> " " <> contactSLinkData)
|
||||
bob <## "alice: contact is prepared"
|
||||
pure shortLink
|
||||
alice <## "server disconnected localhost ()"
|
||||
alice <## "disconnected 1 connections on server localhost"
|
||||
bob ##> "/_connect contact @2 text hello"
|
||||
bob <##. "smp agent error: BROKER"
|
||||
withSmpServer' serverCfg' $ do
|
||||
alice <## "server connected localhost ()"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
threadDelay 250000
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "invitation link: known prepared contact alice"
|
||||
@@ -3053,8 +3053,8 @@ testShortLinkInvitationConnectRetry ps = testChatOpts2 opts' aliceProfile bobPro
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
alice <##> bob
|
||||
alice <## "server disconnected localhost (@bob)"
|
||||
bob <## "server disconnected localhost (@alice)"
|
||||
alice <## "disconnected 1 connections on server localhost"
|
||||
bob <## "disconnected 1 connections on server localhost"
|
||||
tmp = tmpPath ps
|
||||
serverCfg' =
|
||||
smpServerCfg
|
||||
@@ -3200,11 +3200,11 @@ testShortLinkAddressConnectRetry ps =
|
||||
bob ##> ("/_prepare contact 1 " <> fullLink <> " " <> shortLink <> " " <> contactSLinkData)
|
||||
bob <## "alice: contact is prepared"
|
||||
pure shortLink
|
||||
alice <## "server disconnected localhost ()"
|
||||
alice <## "disconnected 1 connections on server localhost"
|
||||
bob ##> "/_connect contact @2 text hello"
|
||||
bob <##. "smp agent error: BROKER"
|
||||
withSmpServer' serverCfg' $ do
|
||||
alice <## "server connected localhost ()"
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
threadDelay 250000
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "contact address: known prepared contact alice"
|
||||
@@ -3225,8 +3225,8 @@ testShortLinkAddressConnectRetry ps =
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
alice <##> bob
|
||||
alice <## "server disconnected localhost (@bob)"
|
||||
bob <## "server disconnected localhost (@alice)"
|
||||
alice <## "disconnected 2 connections on server localhost"
|
||||
bob <## "disconnected 1 connections on server localhost"
|
||||
where
|
||||
tmp = tmpPath ps
|
||||
serverCfg' =
|
||||
@@ -3255,11 +3255,11 @@ testShortLinkAddressConnectRetryIncognito ps =
|
||||
bob ##> ("/_prepare contact 1 " <> fullLink <> " " <> shortLink <> " " <> contactSLinkData)
|
||||
bob <## "alice: contact is prepared"
|
||||
pure shortLink
|
||||
alice <## "server disconnected localhost ()"
|
||||
alice <## "disconnected 1 connections on server localhost"
|
||||
bob ##> "/_connect contact @2 incognito=on text hello"
|
||||
bob <##. "smp agent error: BROKER"
|
||||
bobIncognito <- withSmpServer' serverCfg' $ do
|
||||
alice <## "server connected localhost ()"
|
||||
withSmpServer' serverCfg' $ do
|
||||
alice <## "subscribed 1 connections on server localhost"
|
||||
threadDelay 250000
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "contact address: known prepared contact alice"
|
||||
@@ -3288,9 +3288,8 @@ testShortLinkAddressConnectRetryIncognito ps =
|
||||
bob ?<# "alice> hi"
|
||||
bob ?#> "@alice hey"
|
||||
alice <# (bobIncognito <> "> hey")
|
||||
pure bobIncognito
|
||||
alice <## ("server disconnected localhost (@" <> bobIncognito <> ")")
|
||||
bob <## "server disconnected localhost (@alice)"
|
||||
alice <## "disconnected 2 connections on server localhost"
|
||||
bob <## "disconnected 1 connections on server localhost"
|
||||
where
|
||||
tmp = tmpPath ps
|
||||
serverCfg' =
|
||||
@@ -3545,15 +3544,15 @@ testShortLinkGroupRetry ps = testChatOpts2 opts' aliceProfile bobProfile test ps
|
||||
bob ##> ("/_prepare group 1 " <> fullLink <> " " <> shortLink <> " " <> groupSLinkData)
|
||||
bob <## "#team: group is prepared"
|
||||
pure shortLink
|
||||
alice <## "server disconnected localhost (@bob)"
|
||||
bob <## "server disconnected localhost (@alice)"
|
||||
alice <## "disconnected 2 connections on server localhost"
|
||||
bob <## "disconnected 1 connections on server localhost"
|
||||
bob ##> "/_connect group #1"
|
||||
bob <##. "smp agent error: BROKER"
|
||||
withSmpServer' serverCfg' $ do
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "group link: known prepared group #team"
|
||||
alice <## "server connected localhost (@bob)"
|
||||
bob <## "server connected localhost (@alice)"
|
||||
alice <## "subscribed 2 connections on server localhost"
|
||||
bob <## "subscribed 1 connections on server localhost"
|
||||
threadDelay 250000
|
||||
bob ##> "/_connect group #1"
|
||||
bob <## "#team: connection started"
|
||||
@@ -3572,8 +3571,8 @@ testShortLinkGroupRetry ps = testChatOpts2 opts' aliceProfile bobProfile test ps
|
||||
bob <# "#team alice> 1"
|
||||
bob #> "#team 2"
|
||||
alice <# "#team bob> 2"
|
||||
alice <## "server disconnected localhost (@bob)"
|
||||
bob <## "server disconnected localhost (@alice)"
|
||||
alice <## "disconnected 3 connections on server localhost"
|
||||
bob <## "disconnected 2 connections on server localhost"
|
||||
tmp = tmpPath ps
|
||||
serverCfg' =
|
||||
smpServerCfg
|
||||
|
||||
+1
-10
@@ -5,7 +5,7 @@
|
||||
|
||||
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||
|
||||
module MobileTests where
|
||||
module MobileTests (mobileTests) where
|
||||
|
||||
import ChatTests.DBUtils
|
||||
import ChatTests.Utils
|
||||
@@ -111,14 +111,6 @@ chatStarted =
|
||||
chatStartedTagged
|
||||
#endif
|
||||
|
||||
networkStatuses :: LB.ByteString
|
||||
networkStatuses =
|
||||
#if defined(darwin_HOST_OS) && defined(swiftJSON)
|
||||
networkStatusesSwift
|
||||
#else
|
||||
networkStatusesTagged
|
||||
#endif
|
||||
|
||||
parsedMarkdown :: LB.ByteString
|
||||
parsedMarkdown =
|
||||
#if defined(darwin_HOST_OS) && defined(swiftJSON)
|
||||
@@ -151,7 +143,6 @@ testChatApi ps = do
|
||||
chatSendCmd cc "/u" `shouldReturn` activeUser
|
||||
chatSendCmd cc "/create user alice Alice" `shouldReturn` activeUserExists
|
||||
chatSendCmd cc "/_start" `shouldReturn` chatStarted
|
||||
chatRecvMsg cc `shouldReturn` networkStatuses
|
||||
chatRecvMsgWait cc 10000 `shouldReturn` ""
|
||||
chatParseMarkdown "hello" `shouldBe` "{}"
|
||||
chatParseMarkdown "*hello*" `shouldBe` parsedMarkdown
|
||||
|
||||
Reference in New Issue
Block a user