First pass at breaking into two packages.

This commit is contained in:
Christian Lavoie 2018-01-10 15:40:02 -05:00
parent 3fb4d88526
commit 4bab2cadc6
34 changed files with 447 additions and 37 deletions

View file

@ -33,6 +33,7 @@ library
, transformers
, proto3-suite
, proto3-wire
, grpc-haskell-lowlevel
, async ==2.1.*
, tasty >= 0.11 && <0.12
@ -42,46 +43,12 @@ library
, vector
, sorted-list >=0.1.6.1 && <=0.3
c-sources:
cbits/grpc_haskell.c
exposed-modules:
-- NOTE: the order of these matters to c2hs.
Network.GRPC.Unsafe.Constants
Network.GRPC.Unsafe.Time
Network.GRPC.Unsafe.Slice
Network.GRPC.Unsafe.ChannelArgs
Network.GRPC.Unsafe.ByteBuffer
Network.GRPC.Unsafe.Metadata
Network.GRPC.Unsafe.Op
Network.GRPC.Unsafe
Network.GRPC.Unsafe.Security
Network.GRPC.LowLevel
Network.GRPC.LowLevel.Server.Unregistered
Network.GRPC.LowLevel.Client.Unregistered
Network.GRPC.LowLevel.CompletionQueue
Network.GRPC.LowLevel.CompletionQueue.Internal
Network.GRPC.LowLevel.CompletionQueue.Unregistered
Network.GRPC.LowLevel.GRPC
Network.GRPC.LowLevel.Op
Network.GRPC.LowLevel.Server
Network.GRPC.LowLevel.Call
Network.GRPC.LowLevel.Call.Unregistered
Network.GRPC.LowLevel.Client
Network.GRPC.HighLevel
Network.GRPC.HighLevel.Generated
Network.GRPC.HighLevel.Server
Network.GRPC.HighLevel.Server.Unregistered
Network.GRPC.HighLevel.Client
extra-libraries:
grpc
includes:
include/grpc_haskell.h
, grpc/grpc.h
, grpc/status.h
, grpc/support/time.h
, grpc/impl/codegen/compression_types.h
, grpc/slice_buffer.h
, grpc/slice.h
build-tools: c2hs
default-language: Haskell2010
ghc-options: -Wall -fwarn-incomplete-patterns -fno-warn-unused-do-bind
@ -101,6 +68,7 @@ executable hellos-server
, bytestring == 0.10.*
, containers ==0.5.*
, grpc-haskell
, grpc-haskell-lowlevel
, proto3-suite
, proto3-wire
, text
@ -120,6 +88,7 @@ executable hellos-client
, bytestring == 0.10.*
, containers ==0.5.*
, grpc-haskell
, grpc-haskell-lowlevel
, proto3-suite
, proto3-wire
, text
@ -139,6 +108,7 @@ executable echo-server
, bytestring == 0.10.*
, containers ==0.5.*
, grpc-haskell
, grpc-haskell-lowlevel
, optparse-generic
, proto3-suite
, proto3-wire
@ -162,6 +132,7 @@ executable arithmetic-server
, bytestring == 0.10.*
, containers ==0.5.*
, grpc-haskell
, grpc-haskell-lowlevel
, optparse-generic
, proto3-suite
, proto3-wire
@ -184,6 +155,7 @@ executable arithmetic-client
, bytestring == 0.10.*
, containers ==0.5.*
, grpc-haskell
, grpc-haskell-lowlevel
, optparse-generic
, proto3-suite
, proto3-wire
@ -206,6 +178,7 @@ executable echo-client
, bytestring == 0.10.*
, containers ==0.5.*
, grpc-haskell
, grpc-haskell-lowlevel
, optparse-generic
, proto3-suite
, proto3-wire
@ -243,9 +216,6 @@ test-suite tests
, text
, QuickCheck >=2.8 && <3.0
other-modules:
LowLevelTests,
LowLevelTests.Op,
UnsafeTests,
GeneratedTests
default-language: Haskell2010
ghc-options: -Wall -fwarn-incomplete-patterns -fno-warn-unused-do-bind -g -threaded -rtsopts

1
lowlevel/LICENSE Symbolic link
View file

@ -0,0 +1 @@
../LICENSE

1
lowlevel/README.md Symbolic link
View file

@ -0,0 +1 @@
../README.md

1
lowlevel/Setup.hs Symbolic link
View file

@ -0,0 +1 @@
../Setup.hs

View file

@ -0,0 +1,119 @@
name: grpc-haskell-lowlevel
version: 0.0.0.0
synopsis: Haskell implementation of gRPC layered on shared C library.
homepage: https://github.com/awakenetworks/gRPC-haskell
license: Apache-2.0
license-file: LICENSE
author: Awake Networks
maintainer: opensource@awakenetworks.com
copyright: Copyright 2016 Awake Networks
category: Network
build-type: Simple
cabal-version: >=1.10
Flag Debug
Description: Adds debug logging.
Manual: True
Default: False
library
build-depends:
base >=4.8 && <5.0
, clock >=0.6.0 && <0.8.0
, bytestring ==0.10.*
, stm == 2.4.*
, containers ==0.5.*
, managed >= 1.0.0 && < 1.1
, pipes >=4.1 && <=4.4
, transformers
, proto3-suite
, proto3-wire
, async ==2.1.*
, tasty >= 0.11 && <0.12
, tasty-hunit >= 0.9 && <0.10
, tasty-quickcheck >= 0.8.4 && < 0.9
, safe ==0.3.*
, vector
, sorted-list >=0.1.6.1 && <=0.3
c-sources:
cbits/grpc_haskell.c
exposed-modules:
-- NOTE: the order of these matters to c2hs.
Network.GRPC.Unsafe.Constants
Network.GRPC.Unsafe.Time
Network.GRPC.Unsafe.Slice
Network.GRPC.Unsafe.ChannelArgs
Network.GRPC.Unsafe.ByteBuffer
Network.GRPC.Unsafe.Metadata
Network.GRPC.Unsafe.Op
Network.GRPC.Unsafe
Network.GRPC.Unsafe.Security
Network.GRPC.LowLevel
Network.GRPC.LowLevel.Server.Unregistered
Network.GRPC.LowLevel.Client.Unregistered
Network.GRPC.LowLevel.CompletionQueue
Network.GRPC.LowLevel.CompletionQueue.Internal
Network.GRPC.LowLevel.CompletionQueue.Unregistered
Network.GRPC.LowLevel.GRPC
Network.GRPC.LowLevel.Op
Network.GRPC.LowLevel.Server
Network.GRPC.LowLevel.Call
Network.GRPC.LowLevel.Call.Unregistered
Network.GRPC.LowLevel.Client
extra-libraries:
grpc
includes:
include/grpc_haskell.h
, grpc/grpc.h
, grpc/status.h
, grpc/support/time.h
, grpc/impl/codegen/compression_types.h
, grpc/slice_buffer.h
, grpc/slice.h
build-tools: c2hs
default-language: Haskell2010
ghc-options: -Wall -fwarn-incomplete-patterns -fno-warn-unused-do-bind
include-dirs: include
hs-source-dirs: src
default-extensions: CPP
CC-Options: -std=c99
if flag(debug)
CPP-Options: -DDEBUG
CC-Options: -DGRPC_HASKELL_DEBUG -std=c99
test-suite tests
build-depends:
base >=4.8 && <5.0
, grpc-haskell-lowlevel
, bytestring ==0.10.*
, unix
, time
, async
, tasty >= 0.11 && <0.12
, tasty-hunit >= 0.9 && <0.10
, tasty-quickcheck >= 0.8.4 && < 0.9
, containers ==0.5.*
, managed >= 1.0.0 && < 1.1
, pipes >=4.1 && <=4.4
, proto3-suite
, transformers
, safe
, clock >=0.6.0 && <0.8.0
, turtle >= 1.2.0
, text
, QuickCheck >=2.8 && <3.0
other-modules:
LowLevelTests,
LowLevelTests.Op,
UnsafeTests
default-language: Haskell2010
ghc-options: -Wall -fwarn-incomplete-patterns -fno-warn-unused-do-bind -g -threaded -rtsopts
hs-source-dirs: tests
main-is: Properties.hs
type: exitcode-stdio-1.0
default-extensions: CPP
if flag(debug)
CPP-Options: -DDEBUG
CC-Options: -DGRPC_HASKELL_DEBUG

100
lowlevel/grpc-wtf.log Normal file
View file

@ -0,0 +1,100 @@
these derivations will be built:
/nix/store/ds475dvh1kyjvvvxyqwnlpk3wda8vp15-grpc-haskell-0.0.0.0.drv
/nix/store/9psg2p0cj48iyyqz8gyapzgd958iq2gx-ghc-8.0.2-with-packages.drv
building path(s) /nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0
setupCompilerEnvironmentPhase
Build with /nix/store/hg0ppf88q1rw0q7x3zqhlxbnviq0ddcg-ghc-8.0.2.
unpacking sources
unpacking source archive /nix/store/icbw54842rh6pppwinamf4mq9y8pyk7n-gRPC-haskell
source root is gRPC-haskell
patching sources
compileBuildDriverPhase
setupCompileFlags: -package-db=/tmp/nix-build-grpc-haskell-0.0.0.0.drv-0/package.conf.d -j4 -threaded
[1 of 1] Compiling Main ( Setup.hs, /tmp/nix-build-grpc-haskell-0.0.0.0.drv-0/Main.o )
Linking Setup ...
configuring
configureFlags: --verbose --prefix=/nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0 --libdir=$prefix/lib/$compiler --libsubdir=$pkgid --with-gcc=gcc --package-db=/tmp/nix-build-grpc-haskell-0.0.0.0.drv-0/package.conf.d --ghc-option=-optl=-Wl,-rpath=/nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0/lib/ghc-8.0.2/grpc-haskell-0.0.0.0 --ghc-option=-j4 --disable-split-objs --disable-library-profiling --disable-profiling --enable-shared --disable-coverage --enable-library-vanilla --enable-executable-dynamic --disable-tests --ghc-option=-split-sections --extra-include-dirs=/nix/store/ajvhxxnnx0xiajn0n4vls7v3v29bbmjm-grpc-1.2.0-e2cfe9d/include --extra-lib-dirs=/nix/store/ajvhxxnnx0xiajn0n4vls7v3v29bbmjm-grpc-1.2.0-e2cfe9d/lib
Configuring grpc-haskell-0.0.0.0...
Flags chosen: with-examples=False, debug=False
Dependency async ==2.1.*: using async-2.1.1
Dependency base >=4.8 && <5.0: using base-4.9.1.0
Dependency bytestring ==0.10.*: using bytestring-0.10.8.1
Dependency clock >=0.6.0 && <0.8.0: using clock-0.7.2
Dependency containers ==0.5.*: using containers-0.5.7.1
Dependency managed >=1.0.0 && <1.1: using managed-1.0.5
Dependency pipes >=4.1 && <=4.4: using pipes-4.3.2
Dependency proto3-suite -any: using proto3-suite-0.1.0.0
Dependency proto3-wire -any: using proto3-wire-1.0.0
Dependency safe ==0.3.*: using safe-0.3.14
Dependency sorted-list >=0.1.6.1 && <=0.3: using sorted-list-0.2.0.0
Dependency stm ==2.4.*: using stm-2.4.4.1
Dependency tasty ==0.11.*: using tasty-0.11.2
Dependency tasty-hunit ==0.9.*: using tasty-hunit-0.9.2
Dependency tasty-quickcheck >=0.8.4 && <0.9: using tasty-quickcheck-0.8.4
Dependency transformers -any: using transformers-0.5.2.0
Dependency vector -any: using vector-0.11.0.0
Using Cabal-1.24.2.0 compiled by ghc-8.0
Using compiler: ghc-8.0.2
Using install prefix:
/nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0
Binaries installed in:
/nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0/bin
Libraries installed in:
/nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0/lib/ghc-8.0.2/grpc-haskell-0.0.0.0
Dynamic libraries installed in:
/nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0/lib/ghc-8.0.2/x86_64-linux-ghc-8.0.2
Private binaries installed in:
/nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0/libexec
Data files installed in:
/nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0/share/x86_64-linux-ghc-8.0.2/grpc-haskell-0.0.0.0
Documentation installed in:
/nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0/share/doc/x86_64-linux-ghc-8.0.2/grpc-haskell-0.0.0.0
Configuration files installed in:
/nix/store/l0jccwz2422mkh40w7c092cxq5xpifg5-grpc-haskell-0.0.0.0/etc
No alex found
Using ar found on system at:
/nix/store/p6wcdqa2ks82xq7d4d5019drrjxlqrdj-binutils-2.27/bin/ar
Using c2hs version 0.28.1 found on system at:
/nix/store/rm05q3q5igssqy6qvqzaxz1y1fnxf47m-c2hs-0.28.1/bin/c2hs
No cpphs found
Using gcc version 5.4.0 given by user at:
/nix/store/r54jv402shjggj3fn2dy895iycy3afxi-gcc-wrapper-5.4.0/bin/gcc
Using ghc version 8.0.2 found on system at:
/nix/store/hg0ppf88q1rw0q7x3zqhlxbnviq0ddcg-ghc-8.0.2/bin/ghc
Using ghc-pkg version 8.0.2 found on system at:
/nix/store/hg0ppf88q1rw0q7x3zqhlxbnviq0ddcg-ghc-8.0.2/bin/ghc-pkg
No ghcjs found
No ghcjs-pkg found
No greencard found
Using haddock version 2.17.3 found on system at:
/nix/store/hg0ppf88q1rw0q7x3zqhlxbnviq0ddcg-ghc-8.0.2/bin/haddock
No happy found
Using haskell-suite found on system at: haskell-suite-dummy-location
Using haskell-suite-pkg found on system at: haskell-suite-pkg-dummy-location
No hmake found
Using hpc version 0.67 found on system at:
/nix/store/hg0ppf88q1rw0q7x3zqhlxbnviq0ddcg-ghc-8.0.2/bin/hpc
Using hsc2hs version 0.68.1 found on system at:
/nix/store/hg0ppf88q1rw0q7x3zqhlxbnviq0ddcg-ghc-8.0.2/bin/hsc2hs
Using hscolour version 1.24 found on system at:
/nix/store/bgcks3g9g5nqpgnvbfgri8pynmm3sks9-hscolour-1.24.1/bin/HsColour
No jhc found
Using ld found on system at:
/nix/store/r54jv402shjggj3fn2dy895iycy3afxi-gcc-wrapper-5.4.0/bin/ld
No lhc found
No lhc-pkg found
No pkg-config found
Using strip version 2.27 found on system at:
/nix/store/p6wcdqa2ks82xq7d4d5019drrjxlqrdj-binutils-2.27/bin/strip
Using tar found on system at:
/nix/store/rhjsykhxrzj3ca8da6b4g6v1yx53xpi3-gnutar-1.29/bin/tar
No uhc found
building
Building grpc-haskell-0.0.0.0...
Preprocessing library grpc-haskell-0.0.0.0...
Setup: can't find source for Network/GRPC/Unsafe/Constants in src,
dist/build/autogen
builder for /nix/store/ds475dvh1kyjvvvxyqwnlpk3wda8vp15-grpc-haskell-0.0.0.0.drv failed with exit code 1
cannot build derivation /nix/store/9psg2p0cj48iyyqz8gyapzgd958iq2gx-ghc-8.0.2-with-packages.drv: 1 dependencies couldn't be built
error: build of /nix/store/9psg2p0cj48iyyqz8gyapzgd958iq2gx-ghc-8.0.2-with-packages.drv failed
/home/clavoie/.nix-profile/bin/nix-shell: failed to build all dependencies

View file

@ -0,0 +1,14 @@
import LowLevelTests
import LowLevelTests.Op
import Test.Tasty
import UnsafeTests
import GeneratedTests
main :: IO ()
main = defaultMain $ testGroup "GRPC Unit Tests"
[ unsafeTests
, unsafeProperties
, lowLevelOpTests
, lowLevelTests
, generatedTests
]

View file

@ -0,0 +1,203 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module UnsafeTests (unsafeTests, unsafeProperties) where
import Control.Exception (bracket_)
import Control.Monad
import qualified Data.ByteString as B
import Foreign.Marshal.Alloc
import Foreign.Storable
import GHC.Exts
import Network.GRPC.LowLevel.GRPC (threadDelaySecs)
import Network.GRPC.Unsafe
import Network.GRPC.Unsafe.ByteBuffer
import Network.GRPC.Unsafe.ChannelArgs
import Network.GRPC.Unsafe.Metadata
import Network.GRPC.Unsafe.Security
import Network.GRPC.Unsafe.Slice
import Network.GRPC.Unsafe.Time
import System.Clock
import Test.QuickCheck.Gen as QC
import Test.QuickCheck.Property as QC
import Test.Tasty
import Test.Tasty.HUnit as HU (testCase, (@?=))
import Test.Tasty.QuickCheck as QC
unsafeTests :: TestTree
unsafeTests = testGroup "Unit tests for unsafe C bindings"
[ roundtripSliceUnit "\NULabc\NUL"
, roundtripSliceUnit largeByteString
, roundtripByteBufferUnit largeByteString
, roundtripTimeSpec (TimeSpec 123 123)
, testMetadata
, testNow
, testCreateDestroyMetadata
, testCreateDestroyMetadataKeyVals
, testCreateDestroyDeadline
, testCreateDestroyChannelArgs
, testCreateDestroyClientCreds
, testCreateDestroyServerCreds
]
unsafeProperties :: TestTree
unsafeProperties = testGroup "QuickCheck properties for unsafe C bindings"
[ roundtripSliceQC
, roundtripByteBufferQC
, roundtripMetadataQC
, metadataIsList
]
instance Arbitrary B.ByteString where
arbitrary = B.pack <$> arbitrary
instance Arbitrary MetadataMap where
arbitrary = do
--keys are not allowed to contain \NUL, but values are.
ks <- arbitrary `suchThat` all (B.notElem 0)
let l = length ks
vs <- vector l
return $ fromList (zip ks vs)
roundtripMetadataKeyVals :: MetadataMap -> IO MetadataMap
roundtripMetadataKeyVals m = do
(kvPtr, l) <- createMetadata m
m' <- getAllMetadata kvPtr l
metadataFree kvPtr
return m'
roundtripMetadataQC :: TestTree
roundtripMetadataQC = QC.testProperty "Metadata roundtrip" $
\m -> QC.ioProperty $ do m' <- roundtripMetadataKeyVals m
return $ m === m'
metadataIsList :: TestTree
metadataIsList = QC.testProperty "Metadata IsList instance" $
\(md :: MetadataMap) -> md == (fromList $ toList md)
largeByteString :: B.ByteString
largeByteString = B.pack $ take (32*1024*1024) $ cycle [97..99]
roundtripSlice :: B.ByteString -> IO B.ByteString
roundtripSlice bs = do
slice <- byteStringToSlice bs
unslice <- sliceToByteString slice
freeSlice slice
return unslice
roundtripSliceQC :: TestTree
roundtripSliceQC = QC.testProperty "Slice roundtrip: QuickCheck" $
\bs -> QC.ioProperty $ do bs' <- roundtripSlice bs
return $ bs == bs'
roundtripSliceUnit :: B.ByteString -> TestTree
roundtripSliceUnit bs = testCase "ByteString slice roundtrip" $ do
unslice <- roundtripSlice bs
unslice HU.@?= bs
roundtripByteBuffer :: B.ByteString -> IO B.ByteString
roundtripByteBuffer bs = do
slice <- byteStringToSlice bs
buffer <- grpcRawByteBufferCreate slice 1
reader <- byteBufferReaderCreate buffer
readSlice <- grpcByteBufferReaderReadall reader
bs' <- sliceToByteString readSlice
freeSlice slice
byteBufferReaderDestroy reader
grpcByteBufferDestroy buffer
freeSlice readSlice
return bs'
roundtripByteBufferQC :: TestTree
roundtripByteBufferQC = QC.testProperty "ByteBuffer roundtrip: QuickCheck" $
\bs -> QC.ioProperty $ do bs' <- roundtripByteBuffer bs
return $ bs == bs'
roundtripByteBufferUnit :: B.ByteString -> TestTree
roundtripByteBufferUnit bs = testCase "ByteBuffer roundtrip" $ do
bs' <- roundtripByteBuffer bs
bs' HU.@?= bs
roundtripTimeSpec :: TimeSpec -> TestTree
roundtripTimeSpec t = testCase "CTimeSpec roundtrip" $ do
p <- malloc
let c = CTimeSpec t
poke p c
c' <- peek p
c' @?= c
free p
testMetadata :: TestTree
testMetadata = testCase "Metadata setter/getter roundtrip" $ do
m <- metadataAlloc 3
setMetadataKeyVal "hello" "world" m 0
setMetadataKeyVal "foo" "bar" m 1
setMetadataKeyVal "Haskell" "Curry" m 2
k0 <- getMetadataKey m 0
v0 <- getMetadataVal m 0
k1 <- getMetadataKey m 1
v1 <- getMetadataVal m 1
k2 <- getMetadataKey m 2
v2 <- getMetadataVal m 2
k0 HU.@?= "hello"
v0 HU.@?= "world"
k1 HU.@?= "foo"
v1 HU.@?= "bar"
k2 HU.@?= "Haskell"
v2 HU.@?= "Curry"
metadataFree m
currTimeMillis :: ClockType -> IO Int
currTimeMillis t = do
gprT <- gprNow t
tMillis <- gprTimeToMillis gprT
timespecDestroy gprT
return tMillis
testNow :: TestTree
testNow = testCase "Create/destroy various clock types" $ do
_ <- currTimeMillis GprClockMonotonic
_ <- currTimeMillis GprClockRealtime
_ <- currTimeMillis GprClockPrecise
return ()
testCreateDestroyMetadata :: TestTree
testCreateDestroyMetadata = testCase "Create/destroy metadataArrayPtr" $ do
grpc $ withMetadataArrayPtr $ const $ return ()
testCreateDestroyMetadataKeyVals :: TestTree
testCreateDestroyMetadataKeyVals = testCase "Create/destroy metadata key/values" $ do
grpc $ withMetadataKeyValPtr 10 $ const $ return ()
testCreateDestroyDeadline :: TestTree
testCreateDestroyDeadline = testCase "Create/destroy deadline" $ do
grpc $ withDeadlineSeconds 10 $ const $ return ()
testCreateDestroyChannelArgs :: TestTree
testCreateDestroyChannelArgs = testCase "Create/destroy channel args" $
grpc $ withChannelArgs [CompressionAlgArg GrpcCompressDeflate] $
const $ return ()
testCreateDestroyClientCreds :: TestTree
testCreateDestroyClientCreds = testCase "Create/destroy client credentials" $
grpc $ withChannelCredentials Nothing Nothing Nothing $ const $ return ()
testCreateDestroyServerCreds :: TestTree
testCreateDestroyServerCreds = testCase "Create/destroy server credentials" $
grpc $ withServerCredentials Nothing
"tests/ssl/testServerKey.pem"
"tests/ssl/testServerCert.pem"
SslDontRequestClientCertificate
$ const $ return ()
assertCqEventComplete :: Event -> IO ()
assertCqEventComplete e = do
eventCompletionType e HU.@?= OpComplete
eventSuccess e HU.@?= True
grpc :: IO a -> IO ()
grpc = bracket_ grpcInit grpcShutdown . void
_nowarnUnused :: a
_nowarnUnused = assertCqEventComplete `undefined` threadDelaySecs

View file

@ -6,6 +6,7 @@ resolver: lts-8.23
# Local packages, usually specified by relative directory name
packages:
- 'lowlevel'
- '.'
- location:
git: git@github.com:awakenetworks/proto3-suite.git