diff --git a/grpc-haskell.cabal b/grpc-haskell.cabal index 556083a..c89d95a 100644 --- a/grpc-haskell.cabal +++ b/grpc-haskell.cabal @@ -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 diff --git a/lowlevel/LICENSE b/lowlevel/LICENSE new file mode 120000 index 0000000..ea5b606 --- /dev/null +++ b/lowlevel/LICENSE @@ -0,0 +1 @@ +../LICENSE \ No newline at end of file diff --git a/lowlevel/README.md b/lowlevel/README.md new file mode 120000 index 0000000..32d46ee --- /dev/null +++ b/lowlevel/README.md @@ -0,0 +1 @@ +../README.md \ No newline at end of file diff --git a/lowlevel/Setup.hs b/lowlevel/Setup.hs new file mode 120000 index 0000000..115f3bb --- /dev/null +++ b/lowlevel/Setup.hs @@ -0,0 +1 @@ +../Setup.hs \ No newline at end of file diff --git a/cbits/grpc_haskell.c b/lowlevel/cbits/grpc_haskell.c similarity index 100% rename from cbits/grpc_haskell.c rename to lowlevel/cbits/grpc_haskell.c diff --git a/lowlevel/grpc-haskell-lowlevel.cabal b/lowlevel/grpc-haskell-lowlevel.cabal new file mode 100644 index 0000000..4ccf212 --- /dev/null +++ b/lowlevel/grpc-haskell-lowlevel.cabal @@ -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 diff --git a/lowlevel/grpc-wtf.log b/lowlevel/grpc-wtf.log new file mode 100644 index 0000000..0295bfe --- /dev/null +++ b/lowlevel/grpc-wtf.log @@ -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 diff --git a/include/grpc_haskell.h b/lowlevel/include/grpc_haskell.h similarity index 100% rename from include/grpc_haskell.h rename to lowlevel/include/grpc_haskell.h diff --git a/src/Network/GRPC/LowLevel.hs b/lowlevel/src/Network/GRPC/LowLevel.hs similarity index 100% rename from src/Network/GRPC/LowLevel.hs rename to lowlevel/src/Network/GRPC/LowLevel.hs diff --git a/src/Network/GRPC/LowLevel/Call.hs b/lowlevel/src/Network/GRPC/LowLevel/Call.hs similarity index 100% rename from src/Network/GRPC/LowLevel/Call.hs rename to lowlevel/src/Network/GRPC/LowLevel/Call.hs diff --git a/src/Network/GRPC/LowLevel/Call/Unregistered.hs b/lowlevel/src/Network/GRPC/LowLevel/Call/Unregistered.hs similarity index 100% rename from src/Network/GRPC/LowLevel/Call/Unregistered.hs rename to lowlevel/src/Network/GRPC/LowLevel/Call/Unregistered.hs diff --git a/src/Network/GRPC/LowLevel/Client.hs b/lowlevel/src/Network/GRPC/LowLevel/Client.hs similarity index 100% rename from src/Network/GRPC/LowLevel/Client.hs rename to lowlevel/src/Network/GRPC/LowLevel/Client.hs diff --git a/src/Network/GRPC/LowLevel/Client/Unregistered.hs b/lowlevel/src/Network/GRPC/LowLevel/Client/Unregistered.hs similarity index 100% rename from src/Network/GRPC/LowLevel/Client/Unregistered.hs rename to lowlevel/src/Network/GRPC/LowLevel/Client/Unregistered.hs diff --git a/src/Network/GRPC/LowLevel/CompletionQueue.hs b/lowlevel/src/Network/GRPC/LowLevel/CompletionQueue.hs similarity index 100% rename from src/Network/GRPC/LowLevel/CompletionQueue.hs rename to lowlevel/src/Network/GRPC/LowLevel/CompletionQueue.hs diff --git a/src/Network/GRPC/LowLevel/CompletionQueue/Internal.hs b/lowlevel/src/Network/GRPC/LowLevel/CompletionQueue/Internal.hs similarity index 100% rename from src/Network/GRPC/LowLevel/CompletionQueue/Internal.hs rename to lowlevel/src/Network/GRPC/LowLevel/CompletionQueue/Internal.hs diff --git a/src/Network/GRPC/LowLevel/CompletionQueue/Unregistered.hs b/lowlevel/src/Network/GRPC/LowLevel/CompletionQueue/Unregistered.hs similarity index 100% rename from src/Network/GRPC/LowLevel/CompletionQueue/Unregistered.hs rename to lowlevel/src/Network/GRPC/LowLevel/CompletionQueue/Unregistered.hs diff --git a/src/Network/GRPC/LowLevel/GRPC.hs b/lowlevel/src/Network/GRPC/LowLevel/GRPC.hs similarity index 100% rename from src/Network/GRPC/LowLevel/GRPC.hs rename to lowlevel/src/Network/GRPC/LowLevel/GRPC.hs diff --git a/src/Network/GRPC/LowLevel/Op.hs b/lowlevel/src/Network/GRPC/LowLevel/Op.hs similarity index 100% rename from src/Network/GRPC/LowLevel/Op.hs rename to lowlevel/src/Network/GRPC/LowLevel/Op.hs diff --git a/src/Network/GRPC/LowLevel/Server.hs b/lowlevel/src/Network/GRPC/LowLevel/Server.hs similarity index 100% rename from src/Network/GRPC/LowLevel/Server.hs rename to lowlevel/src/Network/GRPC/LowLevel/Server.hs diff --git a/src/Network/GRPC/LowLevel/Server/Unregistered.hs b/lowlevel/src/Network/GRPC/LowLevel/Server/Unregistered.hs similarity index 100% rename from src/Network/GRPC/LowLevel/Server/Unregistered.hs rename to lowlevel/src/Network/GRPC/LowLevel/Server/Unregistered.hs diff --git a/src/Network/GRPC/Unsafe.chs b/lowlevel/src/Network/GRPC/Unsafe.chs similarity index 100% rename from src/Network/GRPC/Unsafe.chs rename to lowlevel/src/Network/GRPC/Unsafe.chs diff --git a/src/Network/GRPC/Unsafe/ByteBuffer.chs b/lowlevel/src/Network/GRPC/Unsafe/ByteBuffer.chs similarity index 100% rename from src/Network/GRPC/Unsafe/ByteBuffer.chs rename to lowlevel/src/Network/GRPC/Unsafe/ByteBuffer.chs diff --git a/src/Network/GRPC/Unsafe/ChannelArgs.chs b/lowlevel/src/Network/GRPC/Unsafe/ChannelArgs.chs similarity index 100% rename from src/Network/GRPC/Unsafe/ChannelArgs.chs rename to lowlevel/src/Network/GRPC/Unsafe/ChannelArgs.chs diff --git a/src/Network/GRPC/Unsafe/Constants.hsc b/lowlevel/src/Network/GRPC/Unsafe/Constants.hsc similarity index 100% rename from src/Network/GRPC/Unsafe/Constants.hsc rename to lowlevel/src/Network/GRPC/Unsafe/Constants.hsc diff --git a/src/Network/GRPC/Unsafe/Metadata.chs b/lowlevel/src/Network/GRPC/Unsafe/Metadata.chs similarity index 100% rename from src/Network/GRPC/Unsafe/Metadata.chs rename to lowlevel/src/Network/GRPC/Unsafe/Metadata.chs diff --git a/src/Network/GRPC/Unsafe/Op.chs b/lowlevel/src/Network/GRPC/Unsafe/Op.chs similarity index 100% rename from src/Network/GRPC/Unsafe/Op.chs rename to lowlevel/src/Network/GRPC/Unsafe/Op.chs diff --git a/src/Network/GRPC/Unsafe/Security.chs b/lowlevel/src/Network/GRPC/Unsafe/Security.chs similarity index 100% rename from src/Network/GRPC/Unsafe/Security.chs rename to lowlevel/src/Network/GRPC/Unsafe/Security.chs diff --git a/src/Network/GRPC/Unsafe/Slice.chs b/lowlevel/src/Network/GRPC/Unsafe/Slice.chs similarity index 100% rename from src/Network/GRPC/Unsafe/Slice.chs rename to lowlevel/src/Network/GRPC/Unsafe/Slice.chs diff --git a/src/Network/GRPC/Unsafe/Time.chs b/lowlevel/src/Network/GRPC/Unsafe/Time.chs similarity index 100% rename from src/Network/GRPC/Unsafe/Time.chs rename to lowlevel/src/Network/GRPC/Unsafe/Time.chs diff --git a/tests/LowLevelTests.hs b/lowlevel/tests/LowLevelTests.hs similarity index 100% rename from tests/LowLevelTests.hs rename to lowlevel/tests/LowLevelTests.hs diff --git a/tests/LowLevelTests/Op.hs b/lowlevel/tests/LowLevelTests/Op.hs similarity index 100% rename from tests/LowLevelTests/Op.hs rename to lowlevel/tests/LowLevelTests/Op.hs diff --git a/lowlevel/tests/Properties.hs b/lowlevel/tests/Properties.hs new file mode 100644 index 0000000..ce84244 --- /dev/null +++ b/lowlevel/tests/Properties.hs @@ -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 + ] diff --git a/lowlevel/tests/UnsafeTests.hs b/lowlevel/tests/UnsafeTests.hs new file mode 100644 index 0000000..936378a --- /dev/null +++ b/lowlevel/tests/UnsafeTests.hs @@ -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 diff --git a/stack.yaml b/stack.yaml index 39edf2c..1467d16 100644 --- a/stack.yaml +++ b/stack.yaml @@ -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