Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
haskell-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
198
Issues
198
List
Board
Labels
Milestones
Merge Requests
12
Merge Requests
12
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
haskell-gargantext
Commits
4bab5513
Verified
Commit
4bab5513
authored
Nov 13, 2024
by
Przemyslaw Kaminski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[notification] test WS unsubscription
Ref:
#238
,
#341
,
#418
parent
1bec4e19
Pipeline
#6963
passed with stages
in 33 minutes and 54 seconds
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
64 additions
and
7 deletions
+64
-7
Notifications.hs
test/Test/API/Notifications.hs
+64
-7
No files found.
test/Test/API/Notifications.hs
View file @
4bab5513
...
...
@@ -20,7 +20,7 @@ module Test.API.Notifications (
import
Control.Concurrent
(
threadDelay
)
import
Control.Concurrent.STM.TChan
import
Control.Concurrent.STM.TSem
(
newTSem
,
signalTSem
)
import
Control.Concurrent.STM.TSem
(
newTSem
,
signalTSem
,
waitTSem
)
import
Control.Lens
((
^.
))
import
Control.Monad.STM
(
atomically
)
import
Data.Aeson
qualified
as
Aeson
...
...
@@ -31,6 +31,7 @@ import Gargantext.Core.Notifications.Dispatcher.Types qualified as DT
import
Gargantext.System.Logging
(
logMsg
,
LogLevel
(
DEBUG
),
withLogger
)
import
Network.WebSockets
qualified
as
WS
import
Prelude
import
System.Timeout
qualified
as
Timeout
import
Test.API.Setup
(
SpecContext
(
..
),
withTestDBAndPort
)
import
Test.Database.Types
(
test_config
)
import
Test.Hspec
...
...
@@ -51,14 +52,14 @@ tests = sequential $ aroundAll withTestDBAndPort $ do
-- This semaphore is used to inform the main thread that the WS
-- client has subscribed. I think it's better to use async
-- locking mechanisms than blindly call 'threadDelay'.
w
aitWS
TSem
<-
atomically
$
newTSem
0
w
s
TSem
<-
atomically
$
newTSem
0
tchan
<-
newTChanIO
::
IO
(
TChan
(
Maybe
DT
.
Notification
))
-- setup a websocket connection
let
wsConnect
conn
=
withLogger
()
$
\
ioL
->
do
-- logMsg ioL DEBUG $ "[wsConnect] subscribing topic: " <> show topic
WS
.
sendTextData
conn
$
Aeson
.
encode
(
DT
.
WSSubscribe
topic
)
-- inform the test process that we sent the subscription request
atomically
$
signalTSem
w
aitWS
TSem
atomically
$
signalTSem
w
s
TSem
-- logMsg ioL DEBUG $ "[wsConnect] waiting for notification"
d
<-
WS
.
receiveData
conn
...
...
@@ -68,26 +69,82 @@ tests = sequential $ aroundAll withTestDBAndPort $ do
withAsyncWSConnection
(
"127.0.0.1"
,
port
)
wsConnect
$
\
_a
->
do
-- wait for ws process to inform us about topic subscription
waitForTSem
w
aitWS
TSem
500
waitForTSem
w
s
TSem
500
threadDelay
300
_000
CE
.
notify
nc
$
CET
.
Ping
-- the ping value that should come from the notification
waitForTChanValue
tchan
(
Just
DT
.
NPing
)
1
_000
it
"ping WS unsubscribe works"
$
\
(
SpecContext
testEnv
port
_app
_
)
->
do
let
nc
=
(
test_config
testEnv
)
^.
gc_notifications_config
let
topic
=
DT
.
Ping
-- Setup a WS client connection. Subscribe to a topic and
-- confirm the notification works. Then unsubscribe from it, and
-- check that a new notification didn't arrive.
wsTSem
<-
atomically
$
newTSem
0
tchan
<-
newTChanIO
::
IO
(
TChan
(
Maybe
DT
.
Notification
))
-- setup a websocket connection
let
wsConnect
conn
=
withLogger
()
$
\
ioL
->
do
-- logMsg ioL DEBUG $ "[wsConnect] subscribing topic: " <> show topic
WS
.
sendTextData
conn
$
Aeson
.
encode
(
DT
.
WSSubscribe
topic
)
-- inform the test process that we sent the subscription request
atomically
$
signalTSem
wsTSem
-- logMsg ioL DEBUG $ "[wsConnect] waiting for notification"
d
<-
WS
.
receiveData
conn
-- logMsg ioL DEBUG $ "[wsConnect] received " <> show d
let
dec
=
Aeson
.
decode
d
::
Maybe
DT
.
Notification
atomically
$
writeTChan
tchan
dec
-- now ubsubscribe from a topic and make sure nothing arrives
WS
.
sendTextData
conn
$
Aeson
.
encode
(
DT
.
WSUnsubscribe
topic
)
-- Signal that we finished unsubscribing
atomically
$
signalTSem
wsTSem
mTimeout
<-
Timeout
.
timeout
(
200
_000
)
$
do
-- NOTE This shouldn't happen now, we will test the tchan
d
<-
WS
.
receiveData
conn
let
dec
=
Aeson
.
decode
d
::
Maybe
DT
.
Notification
atomically
$
writeTChan
tchan
dec
case
mTimeout
of
-- It should have timed out
Nothing
->
atomically
$
writeTChan
tchan
Nothing
-- | write something incorrect so the test will fail
Just
_
->
atomically
$
writeTChan
tchan
(
Just
DT
.
NPing
)
withAsyncWSConnection
(
"127.0.0.1"
,
port
)
wsConnect
$
\
_a
->
do
-- wait for ws process to inform us about topic subscription
waitForTSem
wsTSem
500
threadDelay
300
_000
CE
.
notify
nc
$
CET
.
Ping
-- the ping value that should come from the notification
waitForTChanValue
tchan
(
Just
DT
.
NPing
)
1
_000
-- wait for lock from ws (it should have unsubscribed by now)
waitForTSem
wsTSem
500
-- send the notification (which the client shouldn't receive)
CE
.
notify
nc
$
CET
.
Ping
-- wait for the value
waitForTChanValue
tchan
Nothing
1
_000
it
"simple update tree WS notification works"
$
\
(
SpecContext
testEnv
port
_app
_
)
->
do
let
nc
=
(
test_config
testEnv
)
^.
gc_notifications_config
let
topic
=
DT
.
UpdateTree
0
w
aitWS
TSem
<-
atomically
$
newTSem
0
-- initially locked
w
s
TSem
<-
atomically
$
newTSem
0
-- initially locked
tchan
<-
newTChanIO
::
IO
(
TChan
(
Maybe
DT
.
Notification
))
-- setup a websocket connection
let
wsConnect
conn
=
withLogger
()
$
\
ioL
->
do
-- logMsg ioL DEBUG $ "[wsConnect] subscribing topic: " <> show topic
WS
.
sendTextData
conn
$
Aeson
.
encode
(
DT
.
WSSubscribe
topic
)
-- inform the test process that we sent the subscription request
atomically
$
signalTSem
w
aitWS
TSem
atomically
$
signalTSem
w
s
TSem
-- logMsg ioL DEBUG $ "[wsConnect] waiting for notification"
d
<-
WS
.
receiveData
conn
...
...
@@ -96,7 +153,7 @@ tests = sequential $ aroundAll withTestDBAndPort $ do
atomically
$
writeTChan
tchan
dec
withAsyncWSConnection
(
"127.0.0.1"
,
port
)
wsConnect
$
\
_a
->
do
waitForTSem
w
aitWS
TSem
500
waitForTSem
w
s
TSem
500
let
nodeId
=
0
CE
.
notify
nc
$
CET
.
UpdateTreeFirstLevel
nodeId
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment