mirror of
https://github.com/unclechu/gRPC-haskell.git
synced 2024-11-23 03:29:42 +01:00
Update to gRPC 0.15 (#61)
* update channel arg names, add compression level arg support, add compression level arg test * switch to temp test demonstrating bug in grpc 0.15.0 * memset op array to 0 * switch examples back * Switch to newer `grpc` and enable tests in `release.nix` * Split out `simple-server` test into separate shell script * Fix bash invocation * Add intermediate `./default-tests.nix` build * Add `tests.patch` to version control * Split `python` command into separate script * Provide `python` via `nix`
This commit is contained in:
parent
f9f59f2362
commit
d66a4f98b3
14 changed files with 148 additions and 22 deletions
|
@ -184,7 +184,9 @@ const char* get_metadata_val(grpc_metadata *arr, size_t i){
|
||||||
}
|
}
|
||||||
|
|
||||||
grpc_op* op_array_create(size_t n){
|
grpc_op* op_array_create(size_t n){
|
||||||
return malloc(n*sizeof(grpc_op));
|
grpc_op* ops = malloc(n*sizeof(grpc_op));
|
||||||
|
memset(ops, 0, n*sizeof(grpc_op));
|
||||||
|
return ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_array_destroy(grpc_op* op_array, size_t n){
|
void op_array_destroy(grpc_op* op_array, size_t n){
|
||||||
|
@ -415,7 +417,9 @@ grpc_arg* create_arg_array(size_t n){
|
||||||
char* translate_arg_key(enum supported_arg_key key){
|
char* translate_arg_key(enum supported_arg_key key){
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case compression_algorithm_key:
|
case compression_algorithm_key:
|
||||||
return GRPC_COMPRESSION_ALGORITHM_ARG;
|
return GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
|
||||||
|
case compression_level_key:
|
||||||
|
return GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL;
|
||||||
case user_agent_prefix_key:
|
case user_agent_prefix_key:
|
||||||
return GRPC_ARG_PRIMARY_USER_AGENT_STRING;
|
return GRPC_ARG_PRIMARY_USER_AGENT_STRING;
|
||||||
case user_agent_suffix_key:
|
case user_agent_suffix_key:
|
||||||
|
|
29
default-tests.nix
Normal file
29
default-tests.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{ grpc-haskell-no-tests
|
||||||
|
, ghc
|
||||||
|
, python
|
||||||
|
}:
|
||||||
|
|
||||||
|
attrs@
|
||||||
|
{ mkDerivation, async, base, bytestring, c2hs, clock, containers
|
||||||
|
, grpc, managed, pipes, proto3-wire, protobuf-wire, random, safe
|
||||||
|
, sorted-list, stdenv, stm, tasty, tasty-hunit, tasty-quickcheck
|
||||||
|
, text, time, transformers, turtle, unix, vector
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
mkDerivation' = oldAttrs: mkDerivation (oldAttrs // {
|
||||||
|
patches = [ tests/tests.patch ];
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
substituteInPlace tests/simple-server.sh --replace @ghc@ ${ghc} --replace @shell@ ${stdenv.shell}
|
||||||
|
substituteInPlace tests/protoc.sh --replace @python@ ${python} --replace @shell@ ${stdenv.shell}
|
||||||
|
'';
|
||||||
|
|
||||||
|
testHaskellDepends = oldAttrs.testHaskellDepends ++ [
|
||||||
|
ghc grpc-haskell-no-tests
|
||||||
|
];
|
||||||
|
|
||||||
|
doCheck = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
in import ./default.nix (attrs // { mkDerivation = mkDerivation'; })
|
|
@ -28,4 +28,5 @@ mkDerivation {
|
||||||
homepage = "http://github.com/aloiscochard/grpc-haskell";
|
homepage = "http://github.com/aloiscochard/grpc-haskell";
|
||||||
description = "Haskell implementation of gRPC layered on shared C library";
|
description = "Haskell implementation of gRPC layered on shared C library";
|
||||||
license = stdenv.lib.licenses.asl20;
|
license = stdenv.lib.licenses.asl20;
|
||||||
|
doCheck = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,6 +146,7 @@ void* grpc_server_register_method_(
|
||||||
// translate_arg_key in grpc_haskell.c.
|
// translate_arg_key in grpc_haskell.c.
|
||||||
enum supported_arg_key {
|
enum supported_arg_key {
|
||||||
compression_algorithm_key = 0,
|
compression_algorithm_key = 0,
|
||||||
|
compression_level_key,
|
||||||
user_agent_prefix_key,
|
user_agent_prefix_key,
|
||||||
user_agent_suffix_key
|
user_agent_suffix_key
|
||||||
};
|
};
|
||||||
|
|
16
release.nix
16
release.nix
|
@ -33,12 +33,12 @@ let
|
||||||
packageOverrides = pkgs: rec {
|
packageOverrides = pkgs: rec {
|
||||||
grpc = pkgs.stdenv.mkDerivation rec {
|
grpc = pkgs.stdenv.mkDerivation rec {
|
||||||
name = "grpc-${version}";
|
name = "grpc-${version}";
|
||||||
version = "0.14-${pkgs.lib.strings.substring 0 7 rev}";
|
version = "0.15-${pkgs.lib.strings.substring 0 7 rev}";
|
||||||
rev = "2b223977c13975648bac2f422363e1ebf83506ce";
|
rev = "03efbd34ce64615f58007eae667b375accc6c8e6";
|
||||||
src = pkgs.fetchgit {
|
src = pkgs.fetchgit {
|
||||||
inherit rev;
|
inherit rev;
|
||||||
url = "https://github.com/grpc/grpc.git";
|
url = "https://github.com/grpc/grpc.git";
|
||||||
sha256 = "0arxjdczgj6rbg14f6x24863mrz0xgpakmdfg54zp0xp7h2pghm6";
|
sha256 = "1pac3jby5p5a6p6vpqc5whkgy36hnn2ph2jbckg3w73hrxrnwmdh";
|
||||||
};
|
};
|
||||||
preInstall = "export prefix";
|
preInstall = "export prefix";
|
||||||
buildInputs =
|
buildInputs =
|
||||||
|
@ -53,7 +53,7 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
haskellPackages = pkgs.haskell.packages.ghc7103.override {
|
haskellPackages = pkgs.haskell.packages.ghc7103.override {
|
||||||
overrides = haskellPackagesNew: haskellPackagesOld: {
|
overrides = haskellPackagesNew: haskellPackagesOld: rec {
|
||||||
proto3-wire =
|
proto3-wire =
|
||||||
let proto3-wire-src = pkgs.fetchgit {
|
let proto3-wire-src = pkgs.fetchgit {
|
||||||
url = "https://github.com/awakenetworks/proto3-wire.git";
|
url = "https://github.com/awakenetworks/proto3-wire.git";
|
||||||
|
@ -72,9 +72,15 @@ let
|
||||||
in
|
in
|
||||||
haskellPackagesNew.callPackage protobuf-wire-src { };
|
haskellPackagesNew.callPackage protobuf-wire-src { };
|
||||||
|
|
||||||
grpc-haskell =
|
grpc-haskell-no-tests =
|
||||||
haskellPackagesNew.callPackage ./default.nix { };
|
haskellPackagesNew.callPackage ./default.nix { };
|
||||||
|
|
||||||
|
grpc-haskell =
|
||||||
|
haskellPackagesNew.callPackage (import ./default-tests.nix {
|
||||||
|
inherit grpc-haskell-no-tests;
|
||||||
|
inherit (pkgs) ghc python;
|
||||||
|
}) { };
|
||||||
|
|
||||||
sorted-list = haskellPackagesNew.callPackage
|
sorted-list = haskellPackagesNew.callPackage
|
||||||
({ mkDerivation, base, deepseq }:
|
({ mkDerivation, base, deepseq }:
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
|
|
|
@ -29,6 +29,7 @@ GRPC
|
||||||
-- * Configuration options
|
-- * Configuration options
|
||||||
, Arg(..)
|
, Arg(..)
|
||||||
, CompressionAlgorithm(..)
|
, CompressionAlgorithm(..)
|
||||||
|
, CompressionLevel(..)
|
||||||
, Port
|
, Port
|
||||||
|
|
||||||
-- * Server
|
-- * Server
|
||||||
|
@ -88,4 +89,6 @@ import Network.GRPC.LowLevel.Call
|
||||||
|
|
||||||
import Network.GRPC.Unsafe (ConnectivityState(..))
|
import Network.GRPC.Unsafe (ConnectivityState(..))
|
||||||
import Network.GRPC.Unsafe.Op (StatusCode(..))
|
import Network.GRPC.Unsafe.Op (StatusCode(..))
|
||||||
import Network.GRPC.Unsafe.ChannelArgs(Arg(..), CompressionAlgorithm(..))
|
import Network.GRPC.Unsafe.ChannelArgs(Arg(..)
|
||||||
|
, CompressionAlgorithm(..)
|
||||||
|
, CompressionLevel(..))
|
||||||
|
|
|
@ -31,6 +31,7 @@ data Client = Client {clientChannel :: C.Channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Configuration necessary to set up a client.
|
-- | Configuration necessary to set up a client.
|
||||||
|
|
||||||
data ClientConfig = ClientConfig {serverHost :: Host,
|
data ClientConfig = ClientConfig {serverHost :: Host,
|
||||||
serverPort :: Port,
|
serverPort :: Port,
|
||||||
clientArgs :: [C.Arg]
|
clientArgs :: [C.Arg]
|
||||||
|
@ -44,8 +45,8 @@ clientEndpoint :: ClientConfig -> Endpoint
|
||||||
clientEndpoint ClientConfig{..} = endpoint serverHost serverPort
|
clientEndpoint ClientConfig{..} = endpoint serverHost serverPort
|
||||||
|
|
||||||
createClient :: GRPC -> ClientConfig -> IO Client
|
createClient :: GRPC -> ClientConfig -> IO Client
|
||||||
createClient grpc clientConfig =
|
createClient grpc clientConfig@ClientConfig{..} =
|
||||||
C.withChannelArgs (clientArgs clientConfig) $ \chanargs -> do
|
C.withChannelArgs clientArgs $ \chanargs -> do
|
||||||
let Endpoint e = clientEndpoint clientConfig
|
let Endpoint e = clientEndpoint clientConfig
|
||||||
clientChannel <- C.grpcInsecureChannelCreate e chanargs C.reserved
|
clientChannel <- C.grpcInsecureChannelCreate e chanargs C.reserved
|
||||||
clientCQ <- createCompletionQueue grpc
|
clientCQ <- createCompletionQueue grpc
|
||||||
|
|
|
@ -4,8 +4,9 @@ module Network.GRPC.Unsafe.ChannelArgs where
|
||||||
|
|
||||||
import Control.Exception
|
import Control.Exception
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Foreign.Storable
|
import Data.List (find)
|
||||||
import Foreign.Marshal.Alloc (malloc, free)
|
import Foreign.Marshal.Alloc (malloc, free)
|
||||||
|
import Foreign.Storable
|
||||||
|
|
||||||
#include <grpc/grpc.h>
|
#include <grpc/grpc.h>
|
||||||
#include <grpc/status.h>
|
#include <grpc/status.h>
|
||||||
|
@ -47,6 +48,7 @@ data ArgValue = StringArg String | IntArg Int
|
||||||
-- | Supported arguments for a channel. More cases will be added as we figure
|
-- | Supported arguments for a channel. More cases will be added as we figure
|
||||||
-- out what they are.
|
-- out what they are.
|
||||||
data Arg = CompressionAlgArg CompressionAlgorithm
|
data Arg = CompressionAlgArg CompressionAlgorithm
|
||||||
|
| CompressionLevelArg CompressionLevel
|
||||||
| UserAgentPrefix String
|
| UserAgentPrefix String
|
||||||
| UserAgentSuffix String
|
| UserAgentSuffix String
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
@ -60,6 +62,8 @@ data Arg = CompressionAlgArg CompressionAlgorithm
|
||||||
createArg :: GrpcArg -> Arg -> Int -> IO ()
|
createArg :: GrpcArg -> Arg -> Int -> IO ()
|
||||||
createArg array (CompressionAlgArg alg) i =
|
createArg array (CompressionAlgArg alg) i =
|
||||||
createIntArg array i CompressionAlgorithmKey (fromEnum alg)
|
createIntArg array i CompressionAlgorithmKey (fromEnum alg)
|
||||||
|
createArg array (CompressionLevelArg lvl) i =
|
||||||
|
createIntArg array i CompressionLevelKey (fromEnum lvl)
|
||||||
createArg array (UserAgentPrefix prefix) i =
|
createArg array (UserAgentPrefix prefix) i =
|
||||||
createStringArg array i UserAgentPrefixKey prefix
|
createStringArg array i UserAgentPrefixKey prefix
|
||||||
createArg array (UserAgentSuffix suffix) i =
|
createArg array (UserAgentSuffix suffix) i =
|
||||||
|
|
|
@ -22,10 +22,10 @@ testServerGeneration = testCase "server generation" $ do
|
||||||
|
|
||||||
compileSimpleDotProto
|
compileSimpleDotProto
|
||||||
|
|
||||||
exitCode <- shell (T.concat ["stack ghc -- --make -threaded -odir ", hsTmpDir, " -hidir ", hsTmpDir, " -o ", hsTmpDir, "/simple-server ", hsTmpDir, "/Simple.hs tests/TestServer.hs > /dev/null"]) empty
|
exitCode <- proc "tests/simple-server.sh" [hsTmpDir] empty
|
||||||
exitCode @?= ExitSuccess
|
exitCode @?= ExitSuccess
|
||||||
|
|
||||||
exitCode <- shell (T.concat ["python -m grpc.tools.protoc -I tests --python_out=", pyTmpDir, " --grpc_python_out=", pyTmpDir, " tests/simple.proto"]) empty
|
exitCode <- proc "tests/protoc.sh" [pyTmpDir] empty
|
||||||
exitCode @?= ExitSuccess
|
exitCode @?= ExitSuccess
|
||||||
|
|
||||||
runManaged $ do
|
runManaged $ do
|
||||||
|
|
|
@ -158,8 +158,8 @@ testServerCancel =
|
||||||
where
|
where
|
||||||
client c = do
|
client c = do
|
||||||
rm <- clientRegisterMethodNormal c "/foo"
|
rm <- clientRegisterMethodNormal c "/foo"
|
||||||
res <- clientRequest c rm 10 "" mempty
|
Left (GRPCIOBadStatusCode s _) <- clientRequest c rm 10 "" mempty
|
||||||
res @?= badStatus StatusCancelled
|
s @?= StatusCancelled
|
||||||
server s = do
|
server s = do
|
||||||
let rm = head (normalMethods s)
|
let rm = head (normalMethods s)
|
||||||
r <- serverHandleNormalCall s rm mempty $ \c -> do
|
r <- serverHandleNormalCall s rm mempty $ \c -> do
|
||||||
|
@ -511,6 +511,34 @@ testClientServerCompression =
|
||||||
return ("hello", dummyMeta, StatusOk, StatusDetails "")
|
return ("hello", dummyMeta, StatusOk, StatusDetails "")
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
testClientServerCompressionLvl :: TestTree
|
||||||
|
testClientServerCompressionLvl =
|
||||||
|
csTest' "client/server compression: no errors" client server
|
||||||
|
where
|
||||||
|
cconf = ClientConfig "localhost"
|
||||||
|
50051
|
||||||
|
[CompressionLevelArg GrpcCompressLevelHigh]
|
||||||
|
client = TestClient cconf $ \c -> do
|
||||||
|
rm <- clientRegisterMethodNormal c "/foo"
|
||||||
|
clientRequest c rm 1 "hello" mempty >>= do
|
||||||
|
checkReqRslt $ \NormalRequestResult{..} -> do
|
||||||
|
rspCode @?= StatusOk
|
||||||
|
rspBody @?= "hello"
|
||||||
|
details @?= ""
|
||||||
|
initMD @?= dummyMeta
|
||||||
|
trailMD @?= dummyMeta
|
||||||
|
return ()
|
||||||
|
sconf = ServerConfig "localhost"
|
||||||
|
50051
|
||||||
|
["/foo"] [] [] []
|
||||||
|
[CompressionLevelArg GrpcCompressLevelLow]
|
||||||
|
server = TestServer sconf $ \s -> do
|
||||||
|
let rm = head (normalMethods s)
|
||||||
|
serverHandleNormalCall s rm dummyMeta $ \sc -> do
|
||||||
|
payload sc @?= "hello"
|
||||||
|
return ("hello", dummyMeta, StatusOk, StatusDetails "")
|
||||||
|
return ()
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Utilities and helpers
|
-- Utilities and helpers
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,6 @@ testCancelFromServer =
|
||||||
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 @?= StatusPermissionDenied
|
code @?= StatusPermissionDenied
|
||||||
assertBool "Received status details or RST_STREAM error" $
|
|
||||||
details == "TestStatus"
|
|
||||||
||
|
|
||||||
isPrefixOf "Received RST_STREAM" details
|
|
||||||
return $ Right ()
|
return $ Right ()
|
||||||
wrong -> error $ "Unexpected op results: " ++ show wrong
|
wrong -> error $ "Unexpected op results: " ++ show wrong
|
||||||
|
|
||||||
|
|
10
tests/protoc.sh
Executable file
10
tests/protoc.sh
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
pyTmpDir=$1
|
||||||
|
|
||||||
|
python \
|
||||||
|
-m grpc.tools.protoc \
|
||||||
|
-I tests \
|
||||||
|
--python_out=$pyTmpDir \
|
||||||
|
--grpc_python_out=$pyTmpDir \
|
||||||
|
tests/simple.proto
|
13
tests/simple-server.sh
Executable file
13
tests/simple-server.sh
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
hsTmpDir=$1
|
||||||
|
|
||||||
|
stack ghc -- \
|
||||||
|
--make \
|
||||||
|
-threaded \
|
||||||
|
-odir $hsTmpDir \
|
||||||
|
-hidir $hsTmpDir \
|
||||||
|
-o $hsTmpDir/simple-server \
|
||||||
|
$hsTmpDir/Simple.hs \
|
||||||
|
tests/TestServer.hs \
|
||||||
|
> /dev/null
|
30
tests/tests.patch
Normal file
30
tests/tests.patch
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
diff --git a/tests/protoc.sh b/tests/protoc.sh
|
||||||
|
index 054c8b6..4bf0893 100644
|
||||||
|
--- a/tests/protoc.sh
|
||||||
|
+++ b/tests/protoc.sh
|
||||||
|
@@ -1,8 +1,8 @@
|
||||||
|
-#!/bin/bash -eu
|
||||||
|
+#! @shell@ -eu
|
||||||
|
|
||||||
|
pyTmpDir=$1
|
||||||
|
|
||||||
|
-python \
|
||||||
|
+@python@/bin/python \
|
||||||
|
-m grpc.tools.protoc \
|
||||||
|
-I tests \
|
||||||
|
--python_out=$pyTmpDir \
|
||||||
|
diff --git a/tests/simple-server.sh b/tests/simple-server.sh
|
||||||
|
index 37a0a63..8e8fb66 100755
|
||||||
|
--- a/tests/simple-server.sh
|
||||||
|
+++ b/tests/simple-server.sh
|
||||||
|
@@ -1,8 +1,8 @@
|
||||||
|
-#!/bin/bash -eu
|
||||||
|
+#! @shell@ -eu
|
||||||
|
|
||||||
|
hsTmpDir=$1
|
||||||
|
|
||||||
|
-stack ghc -- \
|
||||||
|
+@ghc@/bin/ghc \
|
||||||
|
--make \
|
||||||
|
-threaded \
|
||||||
|
-odir $hsTmpDir \
|
Loading…
Reference in a new issue