mirror of
https://github.com/unclechu/gRPC-haskell.git
synced 2024-11-26 21:19:43 +01:00
fix wrong endpoint test, add test, tweak handler types (#29)
* fix testWrongEndpoint * test that unregistered requests are ignored by request_registered_call * handler returns status code, drop Grpc prefix from status codes
This commit is contained in:
parent
4ce7497a33
commit
5ba5c8a42a
7 changed files with 79 additions and 35 deletions
|
@ -14,11 +14,11 @@ serverMeta :: MetadataMap
|
||||||
serverMeta = [("test_meta", "test_meta_value")]
|
serverMeta = [("test_meta", "test_meta_value")]
|
||||||
|
|
||||||
handler :: U.ServerCall -> ByteString -> MetadataMap -> MethodName
|
handler :: U.ServerCall -> ByteString -> MetadataMap -> MethodName
|
||||||
-> IO (ByteString, MetadataMap, StatusDetails)
|
-> IO (ByteString, MetadataMap, StatusCode, StatusDetails)
|
||||||
handler _call reqBody _reqMeta _method = do
|
handler _call reqBody _reqMeta _method = do
|
||||||
--putStrLn $ "Got request for method: " ++ show method
|
--putStrLn $ "Got request for method: " ++ show method
|
||||||
--putStrLn $ "Got metadata: " ++ show reqMeta
|
--putStrLn $ "Got metadata: " ++ show reqMeta
|
||||||
return (reqBody, serverMeta, StatusDetails "")
|
return (reqBody, serverMeta, StatusOk, StatusDetails "")
|
||||||
|
|
||||||
unregMain :: IO ()
|
unregMain :: IO ()
|
||||||
unregMain = withGRPC $ \grpc -> do
|
unregMain = withGRPC $ \grpc -> do
|
||||||
|
@ -35,7 +35,7 @@ regMain = withGRPC $ \grpc -> do
|
||||||
forever $ do
|
forever $ do
|
||||||
let method = head (registeredMethods server)
|
let method = head (registeredMethods server)
|
||||||
result <- serverHandleNormalCall server method 15 serverMeta $
|
result <- serverHandleNormalCall server method 15 serverMeta $
|
||||||
\_call reqBody _reqMeta -> return (reqBody, serverMeta,
|
\_call reqBody _reqMeta -> return (reqBody, serverMeta, StatusOk,
|
||||||
StatusDetails "")
|
StatusDetails "")
|
||||||
case result of
|
case result of
|
||||||
Left x -> putStrLn $ "registered call result error: " ++ show x
|
Left x -> putStrLn $ "registered call result error: " ++ show x
|
||||||
|
@ -45,7 +45,7 @@ regMain = withGRPC $ \grpc -> do
|
||||||
regLoop :: Server -> RegisteredMethod -> IO ()
|
regLoop :: Server -> RegisteredMethod -> IO ()
|
||||||
regLoop server method = forever $ do
|
regLoop server method = forever $ do
|
||||||
result <- serverHandleNormalCall server method 15 serverMeta $
|
result <- serverHandleNormalCall server method 15 serverMeta $
|
||||||
\_call reqBody _reqMeta -> return (reqBody, serverMeta,
|
\_call reqBody _reqMeta -> return (reqBody, serverMeta, StatusOk,
|
||||||
StatusDetails "")
|
StatusDetails "")
|
||||||
case result of
|
case result of
|
||||||
Left x -> putStrLn $ "registered call result error: " ++ show x
|
Left x -> putStrLn $ "registered call result error: " ++ show x
|
||||||
|
|
|
@ -170,7 +170,7 @@ serverOpsSendNormalRegisteredResponse
|
||||||
-- trailing meta, and use it for both kinds of call handlers.
|
-- trailing meta, and use it for both kinds of call handlers.
|
||||||
type ServerHandler
|
type ServerHandler
|
||||||
= ServerCall -> ByteString -> MetadataMap
|
= ServerCall -> ByteString -> MetadataMap
|
||||||
-> IO (ByteString, MetadataMap, StatusDetails)
|
-> IO (ByteString, MetadataMap, C.StatusCode, StatusDetails)
|
||||||
|
|
||||||
-- TODO: we will want to replace this with some more general concept that also
|
-- TODO: we will want to replace this with some more general concept that also
|
||||||
-- works with streaming calls in the future.
|
-- works with streaming calls in the future.
|
||||||
|
@ -193,8 +193,9 @@ serverHandleNormalCall s@Server{..} rm timeLimit initMeta f = do
|
||||||
Nothing -> error "serverHandleNormalCall(R): payload empty."
|
Nothing -> error "serverHandleNormalCall(R): payload empty."
|
||||||
Just requestBody -> do
|
Just requestBody -> do
|
||||||
requestMeta <- serverCallGetMetadata call
|
requestMeta <- serverCallGetMetadata call
|
||||||
(respBody, trailingMeta, details) <- f call requestBody requestMeta
|
(respBody, trailingMeta, status, details) <- f call
|
||||||
let status = C.GrpcStatusOk
|
requestBody
|
||||||
|
requestMeta
|
||||||
let respOps = serverOpsSendNormalRegisteredResponse
|
let respOps = serverOpsSendNormalRegisteredResponse
|
||||||
respBody initMeta trailingMeta status details
|
respBody initMeta trailingMeta status details
|
||||||
respOpsResults <- runOps (unServerCall call) serverCQ respOps
|
respOpsResults <- runOps (unServerCall call) serverCQ respOps
|
||||||
|
|
|
@ -53,7 +53,7 @@ serverOpsSendNormalResponse body metadata code details =
|
||||||
-- request body and response body respectively.
|
-- request body and response body respectively.
|
||||||
type ServerHandler
|
type ServerHandler
|
||||||
= ServerCall -> ByteString -> MetadataMap -> MethodName
|
= ServerCall -> ByteString -> MetadataMap -> MethodName
|
||||||
-> IO (ByteString, MetadataMap, StatusDetails)
|
-> IO (ByteString, MetadataMap, C.StatusCode, StatusDetails)
|
||||||
|
|
||||||
-- | Handle one unregistered call.
|
-- | Handle one unregistered call.
|
||||||
serverHandleNormalCall :: Server
|
serverHandleNormalCall :: Server
|
||||||
|
@ -76,8 +76,10 @@ serverHandleNormalCall s@Server{..} timeLimit srvMetadata f = do
|
||||||
methodName <- serverCallGetMethodName call
|
methodName <- serverCallGetMethodName call
|
||||||
hostName <- serverCallGetHost call
|
hostName <- serverCallGetHost call
|
||||||
grpcDebug $ "call_details host is: " ++ show hostName
|
grpcDebug $ "call_details host is: " ++ show hostName
|
||||||
(respBody, respMetadata, details) <- f call body requestMeta methodName
|
(respBody, respMetadata, status, details) <- f call
|
||||||
let status = C.GrpcStatusOk
|
body
|
||||||
|
requestMeta
|
||||||
|
methodName
|
||||||
let respOps = serverOpsSendNormalResponse
|
let respOps = serverOpsSendNormalResponse
|
||||||
respBody respMetadata status details
|
respBody respMetadata status details
|
||||||
respOpsResults <- runOps call' serverCQ respOps
|
respOpsResults <- runOps call' serverCQ respOps
|
||||||
|
|
|
@ -14,6 +14,8 @@ import Foreign.Ptr
|
||||||
#include <grpc/impl/codegen/grpc_types.h>
|
#include <grpc/impl/codegen/grpc_types.h>
|
||||||
#include <grpc_haskell.h>
|
#include <grpc_haskell.h>
|
||||||
|
|
||||||
|
{#context prefix = "grpc" #}
|
||||||
|
|
||||||
{#enum grpc_op_type as OpType {underscoreToCase} deriving (Eq, Show)#}
|
{#enum grpc_op_type as OpType {underscoreToCase} deriving (Eq, Show)#}
|
||||||
{#enum grpc_status_code as StatusCode {underscoreToCase} deriving (Eq, Show)#}
|
{#enum grpc_status_code as StatusCode {underscoreToCase} deriving (Eq, Show)#}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,8 @@ lowLevelTests = testGroup "Unit tests of low-level Haskell library"
|
||||||
, testServerCreateDestroy
|
, testServerCreateDestroy
|
||||||
, testServerCall
|
, testServerCall
|
||||||
, testServerTimeoutNoClient
|
, testServerTimeoutNoClient
|
||||||
-- , testWrongEndpoint
|
, testWrongEndpoint
|
||||||
|
, testMixRegisteredUnregistered
|
||||||
, testPayload
|
, testPayload
|
||||||
, testPayloadUnregistered
|
, testPayloadUnregistered
|
||||||
, testServerCancel
|
, testServerCancel
|
||||||
|
@ -79,13 +80,9 @@ testServerTimeoutNoClient :: TestTree
|
||||||
testServerTimeoutNoClient =
|
testServerTimeoutNoClient =
|
||||||
serverOnlyTest "wait timeout when client DNE" [("/foo", Normal)] $ \s -> do
|
serverOnlyTest "wait timeout when client DNE" [("/foo", Normal)] $ \s -> do
|
||||||
let rm = head (registeredMethods s)
|
let rm = head (registeredMethods s)
|
||||||
r <- serverHandleNormalCall s rm 1 mempty $ \_ _ _ ->
|
r <- serverHandleNormalCall s rm 1 mempty dummyHandler
|
||||||
return ("", mempty, StatusDetails "details")
|
|
||||||
r @?= Left GRPCIOTimeout
|
r @?= Left GRPCIOTimeout
|
||||||
|
|
||||||
-- TODO: fix this test: currently, client seems to hang and server times out,
|
|
||||||
-- expecting that the client reports an invalid endpoint. Also, investigate
|
|
||||||
-- intermittent crashes on shorter server timeouts (tried 2, 5 seconds)
|
|
||||||
testWrongEndpoint :: TestTree
|
testWrongEndpoint :: TestTree
|
||||||
testWrongEndpoint =
|
testWrongEndpoint =
|
||||||
csTest "client requests unknown endpoint" client server [("/foo", Normal)]
|
csTest "client requests unknown endpoint" client server [("/foo", Normal)]
|
||||||
|
@ -95,14 +92,55 @@ testWrongEndpoint =
|
||||||
client c = do
|
client c = do
|
||||||
rm <- clientRegisterMethod c "/bar" Normal
|
rm <- clientRegisterMethod c "/bar" Normal
|
||||||
r <- clientRequest c rm 1 "Hello!" mempty
|
r <- clientRequest c rm 1 "Hello!" mempty
|
||||||
r @?= Left (GRPCIOBadStatusCode GrpcStatusDeadlineExceeded
|
r @?= Left (GRPCIOBadStatusCode StatusDeadlineExceeded
|
||||||
(StatusDetails "Deadline Exceeded"))
|
(StatusDetails "Deadline Exceeded"))
|
||||||
server s = do
|
server s = do
|
||||||
length (registeredMethods s) @?= 1
|
length (registeredMethods s) @?= 1
|
||||||
let rm = head (registeredMethods s)
|
let rm = head (registeredMethods s)
|
||||||
r <- serverHandleNormalCall s rm 10 mempty $ \_ _ _ -> do
|
r <- serverHandleNormalCall s rm 2 mempty dummyHandler
|
||||||
return ("reply test", dummyMeta, StatusDetails "details string")
|
r @?= Left GRPCIOTimeout
|
||||||
r @?= Right ()
|
|
||||||
|
testMixRegisteredUnregistered :: TestTree
|
||||||
|
testMixRegisteredUnregistered =
|
||||||
|
csTest "server uses unregistered calls to handle unknown endpoints"
|
||||||
|
client
|
||||||
|
server
|
||||||
|
[("/foo", Normal)]
|
||||||
|
where
|
||||||
|
client c = do
|
||||||
|
rm1 <- clientRegisterMethod c "/foo" Normal
|
||||||
|
rm2 <- clientRegisterMethod c "/bar" Normal
|
||||||
|
clientRequest c rm1 1 "Hello" mempty >>= do
|
||||||
|
checkReqRslt $ \NormalRequestResult{..} -> do
|
||||||
|
rspBody @?= "reply test"
|
||||||
|
initMD @?= Just dummyMeta
|
||||||
|
trailMD @?= dummyMeta
|
||||||
|
clientRequest c rm2 1 "bad endpoint" mempty >>= do
|
||||||
|
checkReqRslt $ \NormalRequestResult{..} -> do
|
||||||
|
rspBody @?= ""
|
||||||
|
r3 <- clientRequest c rm1 1 "Hello" mempty
|
||||||
|
r3 @?= deadlineExceededStatus
|
||||||
|
return ()
|
||||||
|
server s = do
|
||||||
|
concurrently regThread unregThread
|
||||||
|
return ()
|
||||||
|
where regThread = do
|
||||||
|
let rm = head (registeredMethods s)
|
||||||
|
r <- serverHandleNormalCall s rm 2 dummyMeta $ \_ body _ -> do
|
||||||
|
body @?= "Hello"
|
||||||
|
return ("reply test", dummyMeta, StatusOk, StatusDetails "")
|
||||||
|
return ()
|
||||||
|
unregThread = do
|
||||||
|
r1 <- U.serverHandleNormalCall s 2 mempty $ \_ _ _ method -> do
|
||||||
|
method @?= "/bar"
|
||||||
|
return ("", mempty, StatusOk,
|
||||||
|
StatusDetails "Wrong endpoint")
|
||||||
|
r2 <- U.serverHandleNormalCall s 2 mempty $ \_ _ _ method -> do
|
||||||
|
method @?= "/bar"
|
||||||
|
return ("", mempty, StatusNotFound,
|
||||||
|
StatusDetails "Wrong endpoint")
|
||||||
|
r2 @?= Left GRPCIOTimeout
|
||||||
|
return ()
|
||||||
|
|
||||||
-- TODO: There seems to be a race here (and in other client/server pairs, of
|
-- TODO: There seems to be a race here (and in other client/server pairs, of
|
||||||
-- course) about what gets reported when there is a failure. E.g., if one of the
|
-- course) about what gets reported when there is a failure. E.g., if one of the
|
||||||
|
@ -119,7 +157,7 @@ testPayload =
|
||||||
rm <- clientRegisterMethod c "/foo" Normal
|
rm <- clientRegisterMethod c "/foo" Normal
|
||||||
clientRequest c rm 10 "Hello!" clientMD >>= do
|
clientRequest c rm 10 "Hello!" clientMD >>= do
|
||||||
checkReqRslt $ \NormalRequestResult{..} -> do
|
checkReqRslt $ \NormalRequestResult{..} -> do
|
||||||
rspCode @?= GrpcStatusOk
|
rspCode @?= StatusOk
|
||||||
rspBody @?= "reply test"
|
rspBody @?= "reply test"
|
||||||
details @?= "details string"
|
details @?= "details string"
|
||||||
initMD @?= Just dummyMeta
|
initMD @?= Just dummyMeta
|
||||||
|
@ -130,7 +168,8 @@ testPayload =
|
||||||
r <- serverHandleNormalCall s rm 11 dummyMeta $ \_ reqBody reqMD -> do
|
r <- serverHandleNormalCall s rm 11 dummyMeta $ \_ reqBody reqMD -> do
|
||||||
reqBody @?= "Hello!"
|
reqBody @?= "Hello!"
|
||||||
checkMD "Server metadata mismatch" clientMD reqMD
|
checkMD "Server metadata mismatch" clientMD reqMD
|
||||||
return ("reply test", dummyMeta, StatusDetails "details string")
|
return ("reply test", dummyMeta, StatusOk,
|
||||||
|
StatusDetails "details string")
|
||||||
r @?= Right ()
|
r @?= Right ()
|
||||||
|
|
||||||
testServerCancel :: TestTree
|
testServerCancel :: TestTree
|
||||||
|
@ -140,14 +179,14 @@ testServerCancel =
|
||||||
client c = do
|
client c = do
|
||||||
rm <- clientRegisterMethod c "/foo" Normal
|
rm <- clientRegisterMethod c "/foo" Normal
|
||||||
res <- clientRequest c rm 10 "" mempty
|
res <- clientRequest c rm 10 "" mempty
|
||||||
res @?= Left (GRPCIOBadStatusCode GrpcStatusCancelled
|
res @?= Left (GRPCIOBadStatusCode StatusCancelled
|
||||||
(StatusDetails
|
(StatusDetails
|
||||||
"Received RST_STREAM err=8"))
|
"Received RST_STREAM err=8"))
|
||||||
server s = do
|
server s = do
|
||||||
let rm = head (registeredMethods s)
|
let rm = head (registeredMethods s)
|
||||||
r <- serverHandleNormalCall s rm 10 mempty $ \c _ _ -> do
|
r <- serverHandleNormalCall s rm 10 mempty $ \c _ _ -> do
|
||||||
serverCallCancel c GrpcStatusCancelled ""
|
serverCallCancel c StatusCancelled ""
|
||||||
return (mempty, mempty, "")
|
return (mempty, mempty, StatusOk, "")
|
||||||
r @?= Right ()
|
r @?= Right ()
|
||||||
|
|
||||||
testPayloadUnregistered :: TestTree
|
testPayloadUnregistered :: TestTree
|
||||||
|
@ -157,14 +196,14 @@ testPayloadUnregistered =
|
||||||
client c = do
|
client c = do
|
||||||
U.clientRequest c "/foo" 10 "Hello!" mempty >>= do
|
U.clientRequest c "/foo" 10 "Hello!" mempty >>= do
|
||||||
checkReqRslt $ \NormalRequestResult{..} -> do
|
checkReqRslt $ \NormalRequestResult{..} -> do
|
||||||
rspCode @?= GrpcStatusOk
|
rspCode @?= StatusOk
|
||||||
rspBody @?= "reply test"
|
rspBody @?= "reply test"
|
||||||
details @?= "details string"
|
details @?= "details string"
|
||||||
server s = do
|
server s = do
|
||||||
r <- U.serverHandleNormalCall s 11 mempty $ \_ body _md meth -> do
|
r <- U.serverHandleNormalCall s 11 mempty $ \_ body _md meth -> do
|
||||||
body @?= "Hello!"
|
body @?= "Hello!"
|
||||||
meth @?= "/foo"
|
meth @?= "/foo"
|
||||||
return ("reply test", mempty, "details string")
|
return ("reply test", mempty, StatusOk, "details string")
|
||||||
r @?= Right ()
|
r @?= Right ()
|
||||||
|
|
||||||
testGoaway :: TestTree
|
testGoaway :: TestTree
|
||||||
|
@ -201,7 +240,7 @@ testSlowServer =
|
||||||
let rm = head (registeredMethods s)
|
let rm = head (registeredMethods s)
|
||||||
serverHandleNormalCall s rm 1 mempty $ \_ _ _ -> do
|
serverHandleNormalCall s rm 1 mempty $ \_ _ _ -> do
|
||||||
threadDelay (2*10^(6 :: Int))
|
threadDelay (2*10^(6 :: Int))
|
||||||
return ("", mempty, StatusDetails "")
|
return ("", mempty, StatusOk, StatusDetails "")
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -211,16 +250,16 @@ dummyMeta :: M.Map ByteString ByteString
|
||||||
dummyMeta = [("foo","bar")]
|
dummyMeta = [("foo","bar")]
|
||||||
|
|
||||||
dummyHandler :: ServerCall -> ByteString -> MetadataMap
|
dummyHandler :: ServerCall -> ByteString -> MetadataMap
|
||||||
-> IO (ByteString, MetadataMap, StatusDetails)
|
-> IO (ByteString, MetadataMap, StatusCode, StatusDetails)
|
||||||
dummyHandler _ _ _ = return ("", mempty, StatusDetails "")
|
dummyHandler _ _ _ = return ("", mempty, StatusOk, StatusDetails "")
|
||||||
|
|
||||||
unavailableStatus :: Either GRPCIOError a
|
unavailableStatus :: Either GRPCIOError a
|
||||||
unavailableStatus =
|
unavailableStatus =
|
||||||
Left (GRPCIOBadStatusCode GrpcStatusUnavailable (StatusDetails ""))
|
Left (GRPCIOBadStatusCode StatusUnavailable (StatusDetails ""))
|
||||||
|
|
||||||
deadlineExceededStatus :: Either GRPCIOError a
|
deadlineExceededStatus :: Either GRPCIOError a
|
||||||
deadlineExceededStatus =
|
deadlineExceededStatus =
|
||||||
Left (GRPCIOBadStatusCode GrpcStatusDeadlineExceeded
|
Left (GRPCIOBadStatusCode StatusDeadlineExceeded
|
||||||
(StatusDetails "Deadline Exceeded"))
|
(StatusDetails "Deadline Exceeded"))
|
||||||
|
|
||||||
nop :: Monad m => a -> m ()
|
nop :: Monad m => a -> m ()
|
||||||
|
|
|
@ -51,12 +51,12 @@ testCancelFromServer =
|
||||||
runSerialTest $ \grpc ->
|
runSerialTest $ \grpc ->
|
||||||
withClientServerUnaryCall grpc $
|
withClientServerUnaryCall grpc $
|
||||||
\(c@Client{..}, s@Server{..}, cc@ClientCall{..}, sc@ServerCall{..}) -> do
|
\(c@Client{..}, s@Server{..}, cc@ClientCall{..}, sc@ServerCall{..}) -> do
|
||||||
serverCallCancel sc GrpcStatusPermissionDenied "TestStatus"
|
serverCallCancel sc StatusPermissionDenied "TestStatus"
|
||||||
clientRes <- runOps unClientCall clientCQ clientRecvOps
|
clientRes <- runOps unClientCall clientCQ clientRecvOps
|
||||||
case clientRes of
|
case clientRes of
|
||||||
Left x -> error $ "Client recv error: " ++ show x
|
Left x -> error $ "Client recv error: " ++ show x
|
||||||
Right [_,_,OpRecvStatusOnClientResult _ code details] -> do
|
Right [_,_,OpRecvStatusOnClientResult _ code details] -> do
|
||||||
code @?= GrpcStatusPermissionDenied
|
code @?= StatusPermissionDenied
|
||||||
assertBool "Received status details or RST_STREAM error" $
|
assertBool "Received status details or RST_STREAM error" $
|
||||||
details == "TestStatus"
|
details == "TestStatus"
|
||||||
||
|
||
|
||||||
|
|
|
@ -196,7 +196,7 @@ payloadServer = do
|
||||||
opSendMessage respOps 1 respbb
|
opSendMessage respOps 1 respbb
|
||||||
B.useAsCString "ok" $ \detailsStr ->
|
B.useAsCString "ok" $ \detailsStr ->
|
||||||
opSendStatusServer respOps 2 0 (MetadataKeyValPtr nullPtr)
|
opSendStatusServer respOps 2 0 (MetadataKeyValPtr nullPtr)
|
||||||
GrpcStatusOk detailsStr
|
StatusOk detailsStr
|
||||||
serverCall <- peek serverCallPtr
|
serverCall <- peek serverCallPtr
|
||||||
respBatchError <- grpcCallStartBatch serverCall respOps 3
|
respBatchError <- grpcCallStartBatch serverCall respOps 3
|
||||||
(tag 103) reserved
|
(tag 103) reserved
|
||||||
|
|
Loading…
Reference in a new issue