1-- test the websocket server
4import qualified Network.WebSockets as WS
5import ProjectM36.Server.WebSocket
6import ProjectM36.Server.Config
7import ProjectM36.Server
8import ProjectM36.Client
10import Control.Exception
11import Control.Concurrent
14import Data.Text hiding (map)
17import qualified Data.Map as M
18import qualified Data.ByteString.Lazy as BS
19import ProjectM36.Relation
20import Network.Transport.TCP (decodeEndPointAddress)
22--start the websocket server
23-- run some tutoriald against it
25launchTestServer :: IO (PortNumber, DatabaseName)
27 addressMVar <- newEmptyMVar
28 let config = defaultServerConfig { databaseName = testDatabaseName,
30 testDatabaseName = "test"
31 -- start normal server
32 _ <- forkIO (launchServer config (Just addressMVar) >> pure ())
33 serverAddress <- takeMVar addressMVar
34 let wsServerHost = "127.0.0.1"
36 Just (dbHost, dbPort, _) = decodeEndPointAddress serverAddress
37 -- start websocket server proxy -- runServer doesn't support returning an arbitrary socket
38 _ <- forkIO (WS.runServer wsServerHost wsServerPort (websocketProxyServer (read dbPort) dbHost))
39 --wait for socket to be listening
40 waitForListenSocket 5 (fromIntegral wsServerPort)
41 pure (fromIntegral wsServerPort, testDatabaseName)
43data TestException = WaitForSocketListenException
44 deriving (Show, Typeable)
46instance Exception TestException
48waitForListenSocket :: Int -> PortNumber -> IO ()
49waitForListenSocket secondsToTry port = do
50 if secondsToTry <= 0 then
51 throw WaitForSocketListenException
53 hostaddr <- inet_addr "127.0.0.1"
54 sock <- socket AF_INET Stream defaultProtocol
55 let handler :: IOException -> IO ()
58 waitForListenSocket (secondsToTry - 1) port
59 catch (connect sock (SockAddrInet port hostaddr)) handler
63 (port, dbname) <- launchTestServer
64 tcounts <- runTestTT (testList port dbname)
65 if errors tcounts + failures tcounts > 0 then exitFailure else exitSuccess
67testList :: PortNumber -> DatabaseName -> Test
68testList port dbName = TestList $ map (\f -> f port dbName) [testBasicConnection,
71basicConnection :: PortNumber -> WS.ClientApp () -> IO ()
72basicConnection port block = WS.runClient "127.0.0.1" (fromIntegral port) "/" block
74basicConnectionWithDatabase :: PortNumber -> DatabaseName -> WS.ClientApp () -> IO ()
75basicConnectionWithDatabase port dbname block = basicConnection port (\conn -> do
76 WS.sendTextData conn ("connectdb:" `append` (pack dbname))
79testBasicConnection :: PortNumber -> DatabaseName -> Test
80testBasicConnection port _ = TestCase $ basicConnection port (\conn -> WS.sendClose conn ("test close"::Text))
82testTutorialD :: PortNumber -> DatabaseName -> Test
83testTutorialD port dbname = TestCase $ basicConnectionWithDatabase port dbname testtutd
85 discardPromptInfo conn = do
86 response <- WS.receiveData conn :: IO BS.ByteString
87 let decoded = decode response :: Maybe (M.Map Text (M.Map Text Text))
90 Nothing -> assertFailure ("failed to decode prompt info: " ++ show response)
93 discardPromptInfo conn
94 WS.sendTextData conn ("executetutd:" `append` ":showexpr true")
95 discardPromptInfo conn
96 discardPromptInfo conn
98 --receive relation response
99 response <- WS.receiveData conn :: IO BS.ByteString
100 let decoded = decode response :: Maybe (M.Map Text Relation)
103 Just val -> assertEqual "round-trip true relation" (M.lookup "displayrelation" val) (Just relationTrue) >> WS.sendClose conn ("test close"::Text)
104 Nothing -> assertFailure ("failed to decode relation from: " ++ show response)
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