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
150
Issues
150
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
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