2-- test the websocket server
4import qualified Network.WebSockets as WS
5import ProjectM36.Server.WebSocket
6import ProjectM36.Server.Config
7import ProjectM36.Server
8import ProjectM36.Client
12import Control.Exception
13import Control.Concurrent
16import Data.Text hiding (map)
18import qualified Data.Map as M
19import qualified Data.ByteString.Lazy as BS
20import ProjectM36.Relation
21#if MIN_VERSION_network_transport_tcp(0,6,0)
22import Network.Transport.TCP.Internal (decodeEndPointAddress)
24import Network.Transport.TCP (decodeEndPointAddress)
28--start the websocket server
29-- run some tutoriald against it
31launchTestServer :: IO (PortNumber, DatabaseName)
33 addressMVar <- newEmptyMVar
34 let config = defaultServerConfig { databaseName = testDatabaseName,
37 testDatabaseName = "test"
38 -- start normal server
39 _ <- forkIO (launchServer config (Just addressMVar) >> pure ())
40 serverAddress <- takeMVar addressMVar
41 let wsServerHost = "127.0.0.1"
43 Just (dbHost, dbPort, _) = decodeEndPointAddress serverAddress
44 -- start websocket server proxy -- runServer doesn't support returning an arbitrary socket
45 _ <- forkIO (WS.runServer wsServerHost wsServerPort (websocketProxyServer (read dbPort) dbHost))
46 --wait for socket to be listening
47 waitForListenSocket 5 (fromIntegral wsServerPort)
48 pure (fromIntegral wsServerPort, testDatabaseName)
50data TestException = WaitForSocketListenException
51 deriving (Show, Typeable)
53instance Exception TestException
55waitForListenSocket :: Int -> PortNumber -> IO ()
56waitForListenSocket secondsToTry port =
57 if secondsToTry <= 0 then
58 throw WaitForSocketListenException
60 hostaddr <- inet_addr "127.0.0.1"
61 sock <- socket AF_INET Stream defaultProtocol
62 let handler :: IOException -> IO ()
65 waitForListenSocket (secondsToTry - 1) port
66 catch (connect sock (SockAddrInet port hostaddr)) handler
70 (port, dbname) <- launchTestServer
71 tcounts <- runTestTT (testList port dbname)
72 if errors tcounts + failures tcounts > 0 then exitFailure else exitSuccess
74testList :: PortNumber -> DatabaseName -> Test
75testList port dbName = TestList $ map (\f -> f port dbName) [testBasicConnection,
78basicConnection :: PortNumber -> WS.ClientApp () -> IO ()
79basicConnection port = WS.runClient "127.0.0.1" (fromIntegral port) "/"
81basicConnectionWithDatabase :: PortNumber -> DatabaseName -> WS.ClientApp () -> IO ()
82basicConnectionWithDatabase port dbname block = basicConnection port (\conn -> do
83 WS.sendTextData conn ("connectdb:" `append` pack dbname)
86testBasicConnection :: PortNumber -> DatabaseName -> Test
87testBasicConnection port _ = TestCase $ basicConnection port (\conn -> WS.sendClose conn ("test close"::Text))
89testTutorialD :: PortNumber -> DatabaseName -> Test
90testTutorialD port dbname = TestCase $ basicConnectionWithDatabase port dbname testtutd
92 discardPromptInfo conn = do
93 response <- WS.receiveData conn :: IO BS.ByteString
94 let decoded = decode response :: Maybe (M.Map Text (M.Map Text Text))
97 Nothing -> assertFailure ("failed to decode prompt info: " ++ show response)
100 discardPromptInfo conn
101 WS.sendTextData conn ("executetutd/json:" `append` ":showexpr true")
102 discardPromptInfo conn
103 discardPromptInfo conn
105 --receive relation response
106 response <- WS.receiveData conn :: IO BS.ByteString
107 let decoded = decode response :: Maybe (M.Map Text (M.Map Text Relation))
109 Nothing -> assertFailure "failed to decode"
111 assertEqual "round-trip true relation" ((decoded' M.! "displayrelation") M.! "json") relationTrue
112 WS.sendClose conn ("test close" :: Text)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list