Skip to content

Commit

Permalink
Add test for #257, improve testing
Browse files Browse the repository at this point in the history
The problem is fixed in latest `http2`
(`7036a3429fb08bfcd5947230c37d1f3e63dfb3a6`).  See
kazu-yamamoto/http2#151 for the `http2` bug report.

Closes #257.
  • Loading branch information
edsko committed Dec 4, 2024
1 parent b2e4cfe commit e3b00f9
Show file tree
Hide file tree
Showing 25 changed files with 337 additions and 128 deletions.
45 changes: 28 additions & 17 deletions .github/workflows/haskell-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
#
# For more information, see https://github.com/haskell-CI/haskell-ci
#
# version: 0.19.20240708
# version: 0.19.20241202
#
# REGENDATA ("0.19.20240708",["github","cabal.project.ci"])
# REGENDATA ("0.19.20241202",["github","cabal.project.ci"])
#
name: Haskell-CI
on:
Expand Down Expand Up @@ -64,17 +64,30 @@ jobs:
allow-failure: false
fail-fast: false
steps:
- name: apt
- name: apt-get install
run: |
apt-get update
apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5
apt-get install -y libsnappy-dev protobuf-compiler
- name: Install GHCup
run: |
mkdir -p "$HOME/.ghcup/bin"
curl -sL https://downloads.haskell.org/ghcup/0.1.30.0/x86_64-linux-ghcup-0.1.30.0 > "$HOME/.ghcup/bin/ghcup"
chmod a+x "$HOME/.ghcup/bin/ghcup"
"$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false)
- name: Install cabal-install
run: |
"$HOME/.ghcup/bin/ghcup" install cabal 3.12.1.0 || (cat "$HOME"/.ghcup/logs/*.* && false)
apt-get update
apt-get install -y libsnappy-dev protobuf-compiler
echo "CABAL=$HOME/.ghcup/bin/cabal-3.12.1.0 -vnormal+nowrap" >> "$GITHUB_ENV"
- name: Install GHC (GHCup)
if: matrix.setup-method == 'ghcup'
run: |
"$HOME/.ghcup/bin/ghcup" install ghc "$HCVER" || (cat "$HOME"/.ghcup/logs/*.* && false)
HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER")
HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#')
HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#')
echo "HC=$HC" >> "$GITHUB_ENV"
echo "HCPKG=$HCPKG" >> "$GITHUB_ENV"
echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV"
env:
HCKIND: ${{ matrix.compilerKind }}
HCNAME: ${{ matrix.compiler }}
Expand All @@ -85,21 +98,12 @@ jobs:
echo "LANG=C.UTF-8" >> "$GITHUB_ENV"
echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV"
echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"
HCDIR=/opt/$HCKIND/$HCVER
HC=$("$HOME/.ghcup/bin/ghcup" whereis ghc "$HCVER")
HCPKG=$(echo "$HC" | sed 's#ghc$#ghc-pkg#')
HADDOCK=$(echo "$HC" | sed 's#ghc$#haddock#')
echo "HC=$HC" >> "$GITHUB_ENV"
echo "HCPKG=$HCPKG" >> "$GITHUB_ENV"
echo "HADDOCK=$HADDOCK" >> "$GITHUB_ENV"
echo "CABAL=$HOME/.ghcup/bin/cabal-3.12.1.0 -vnormal+nowrap" >> "$GITHUB_ENV"
HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')
echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV"
echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV"
echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV"
echo "HEADHACKAGE=false" >> "$GITHUB_ENV"
echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV"
echo "GHCJSARITH=0" >> "$GITHUB_ENV"
env:
HCKIND: ${{ matrix.compilerKind }}
HCNAME: ${{ matrix.compiler }}
Expand Down Expand Up @@ -224,9 +228,16 @@ jobs:
if [ $((HCNUMVER < 91000)) -ne 0 ] ; then echo "package trailers-only-tutorial" >> cabal.project ; fi
if [ $((HCNUMVER < 91000)) -ne 0 ] ; then echo " ghc-options: -Werror=missing-methods" >> cabal.project ; fi
cat >> cabal.project <<EOF
constraints: any.ghc-source-gen==0.4.5.0
allow-newer: proto-lens:base
allow-newer: proto-lens-runtime:base
source-repository-package
type: git
location: https://github.com/edsko/wai
tag: 5610f8d67c1fb5e5bec951cca1b3e810b03fc922
subdir: time-manager
package grpc-spec
tests: True
flags: +snappy
Expand All @@ -235,7 +246,7 @@ jobs:
package grapesy
tests: True
benchmarks: True
flags: +build-demo +build-stress-test
flags: +build-demo +build-stress-test
ghc-options: -Werror
package quickstart-tutorial
Expand Down Expand Up @@ -313,8 +324,8 @@ jobs:
rm -f cabal.project.local
$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
- name: save cache
uses: actions/cache/save@v4
if: always()
uses: actions/cache/save@v4
with:
key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
path: ~/.cabal/store
16 changes: 14 additions & 2 deletions cabal.project
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
packages:
packages:
./grpc-spec
, ./grapesy
, ./tutorials/quickstart
Expand All @@ -16,7 +16,19 @@ package grpc-spec
package grapesy
tests: True
benchmarks: True
flags: +build-demo +build-stress-test
flags: +build-demo +build-stress-test

-- TODO: Temporary
-- <https://github.com/yesodweb/wai/pull/1016>
source-repository-package
type: git
location: https://github.com/edsko/wai
tag: 5610f8d67c1fb5e5bec951cca1b3e810b03fc922
subdir: time-manager

-- TODO: Temporary
-- <https://github.com/google/ghc-source-gen/issues/109#issuecomment-2517622160>
constraints: any.ghc-source-gen==0.4.5.0

--
-- ghc 9.10
Expand Down
16 changes: 14 additions & 2 deletions cabal.project.ci
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
packages:
packages:
./grpc-spec
, ./grapesy
, ./tutorials/quickstart
Expand All @@ -17,7 +17,7 @@ package grpc-spec
package grapesy
tests: True
benchmarks: True
flags: +build-demo +build-stress-test
flags: +build-demo +build-stress-test
ghc-options: -Werror

package quickstart-tutorial
Expand All @@ -41,6 +41,18 @@ package conduit-tutorial
package trailers-only-tutorial
ghc-options: -Werror

-- TODO: Temporary
-- <https://github.com/yesodweb/wai/pull/1016>
source-repository-package
type: git
location: https://github.com/edsko/wai
tag: 5610f8d67c1fb5e5bec951cca1b3e810b03fc922
subdir: time-manager

-- TODO: Temporary
-- <https://github.com/google/ghc-source-gen/issues/109#issuecomment-2517622160>
constraints: any.ghc-source-gen==0.4.5.0

--
-- ghc 9.10
--
Expand Down
15 changes: 10 additions & 5 deletions grapesy/grapesy.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ common lang
DataKinds
DeriveAnyClass
DeriveFunctor
DeriveGeneric
DeriveTraversable
DerivingStrategies
DerivingVia
Expand Down Expand Up @@ -155,27 +156,27 @@ library
, exceptions >= 0.10 && < 0.11
, grpc-spec >= 0.1 && < 0.2
, http-types >= 0.12 && < 0.13
, http2-tls >= 0.4.1 && < 0.5
, http2-tls >= 0.4.5 && < 0.5
, lens >= 5.0 && < 5.4
, mtl >= 2.2 && < 2.4
, network >= 3.2.4 && < 3.3
, network-run >= 0.4.1 && < 0.5
, network-run >= 0.4.3 && < 0.5
, proto-lens >= 0.7 && < 0.8
, random >= 1.2 && < 1.3
, recv >= 0.1 && < 0.2
, stm >= 2.5 && < 2.6
, text >= 1.2 && < 2.2
, time-manager >= 0.1 && < 0.2
, time-manager >= 0.2 && < 0.3
, tls >= 1.7 && < 2.2
, unbounded-delays >= 0.1.1 && < 0.2
, unordered-containers >= 0.2 && < 0.3
, utf8-string >= 1.0 && < 1.1

-- We pin very specific versions of http2.
--
-- Other versions should be tested against the full grapesy test suite
-- New versions should be tested against the full grapesy test suite
-- (regular tests and stress tests).
, http2 == 5.3.5
, http2 == 5.3.9

test-suite test-record-dot
import: lang, common-executable-flags
Expand Down Expand Up @@ -229,6 +230,7 @@ test-suite test-grapesy
Test.Sanity.Disconnect
Test.Sanity.EndOfStream
Test.Sanity.Interop
Test.Sanity.Reclamation
Test.Sanity.StreamingType.CustomFormat
Test.Sanity.StreamingType.NonStreaming
Test.Util
Expand Down Expand Up @@ -304,6 +306,7 @@ test-suite test-stress
, exceptions
, http2
, network
, text
, tls

build-depends:
Expand All @@ -314,8 +317,10 @@ test-suite test-stress
, filepath >= 1.4.2.1 && < 1.6
, ghc-events >= 0.17 && < 0.20
, optparse-applicative >= 0.16 && < 0.19
, pretty-show >= 1.10 && < 1.11
, process >= 1.6.12 && < 1.7
, random >= 1.2 && < 1.3
, temporary >= 1.3 && < 1.4

if !flag(build-stress-test)
buildable:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Data.Text (Text)
import Network.GRPC.Client
import Network.GRPC.Common
import Network.GRPC.Common.Protobuf
import Network.GRPC.Spec.Serialization (buildGrpcStatus)
import Network.GRPC.Spec (fromGrpcStatus)

import Interop.Client.Connect
import Interop.Cmdline
Expand All @@ -30,7 +30,7 @@ runTest cmdline = do
echoStatus :: Proto EchoStatus
echoStatus =
defMessage
& #code .~ fromIntegral (buildGrpcStatus $ GrpcError GrpcUnknown)
& #code .~ fromIntegral (fromGrpcStatus $ GrpcError GrpcUnknown)
& #message .~ statusMessage

statusMessage :: Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Data.Text (Text)
import Network.GRPC.Client
import Network.GRPC.Common
import Network.GRPC.Common.Protobuf
import Network.GRPC.Spec.Serialization (buildGrpcStatus)
import Network.GRPC.Spec (fromGrpcStatus)

import Interop.Client.Connect
import Interop.Cmdline
Expand Down Expand Up @@ -39,7 +39,7 @@ runTest cmdline = do
echoStatus :: Proto EchoStatus
echoStatus =
defMessage
& #code .~ fromIntegral (buildGrpcStatus $ GrpcError GrpcUnknown)
& #code .~ fromIntegral (fromGrpcStatus $ GrpcError GrpcUnknown)
& #message .~ statusMessage

statusMessage :: Text
Expand Down
4 changes: 2 additions & 2 deletions grapesy/interop/Interop/Server/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Control.Exception
import Network.GRPC.Common
import Network.GRPC.Common.Protobuf
import Network.GRPC.Server
import Network.GRPC.Spec.Serialization (parseGrpcStatus)
import Network.GRPC.Spec (toGrpcStatus)

import Interop.Util.Exceptions

Expand Down Expand Up @@ -54,7 +54,7 @@ constructResponseMetadata call = do
-- See <https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md#status_code_and_message>
echoStatus :: Proto EchoStatus -> IO ()
echoStatus status =
case parseGrpcStatus code of
case toGrpcStatus code of
Just GrpcOk ->
return ()
Just (GrpcError err) ->
Expand Down
2 changes: 1 addition & 1 deletion grapesy/src/Network/GRPC/Server/Context.hs
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,4 @@ defaultServerTopLevel h unmask req resp =
-- See <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0330-exception-backtraces.rst>.
defaultServerExceptionToClient :: SomeException -> IO (Maybe Text)
defaultServerExceptionToClient (SomeException e) =
return $ Just (Text.pack $ displayException e)
return $ Just (Text.pack $ "Server-side exception: " ++ displayException e)
4 changes: 2 additions & 2 deletions grapesy/src/Network/GRPC/Server/Handler.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import Control.Monad.IO.Class
import Data.Kind
import Data.Proxy
import GHC.Stack
import Network.HTTP2.Internal qualified as HTTP2
import System.ThreadManager (KilledByThreadManager(..))

import Network.GRPC.Common
import Network.GRPC.Server.Call
Expand Down Expand Up @@ -242,7 +242,7 @@ waitForHandler unmask call handlerThread = loop

handleException :: SomeException -> IO ()
handleException err
| Just (HTTP2.KilledByHttp2ThreadManager mErr) <- fromException err = do
| Just (KilledByThreadManager mErr) <- fromException err = do
let exitReason :: ExitCase ()
exitReason =
case mErr of
Expand Down
7 changes: 4 additions & 3 deletions grapesy/src/Network/GRPC/Server/Run.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import Control.Concurrent.STM
import Control.Exception
import Control.Monad
import Data.Default
import GHC.Generics (Generic)
import Network.HTTP2.Server qualified as HTTP2
import Network.HTTP2.TLS.Server qualified as HTTP2.TLS
import Network.Run.TCP qualified as Run
Expand Down Expand Up @@ -62,7 +63,7 @@ data ServerConfig = ServerConfig {
-- Set to 'Nothing' to disable.
, serverSecure :: Maybe SecureConfig
}
deriving (Show)
deriving stock (Show, Generic)

-- | Offer insecure connection (no TLS)
data InsecureConfig = InsecureConfig {
Expand All @@ -76,7 +77,7 @@ data InsecureConfig = InsecureConfig {
-- 'getInsecureSocket' for a way to figure out what this port actually is.
, insecurePort :: PortNumber
}
deriving (Show)
deriving stock (Show, Generic)

-- | Offer secure connection (over TLS)
data SecureConfig = SecureConfig {
Expand Down Expand Up @@ -107,7 +108,7 @@ data SecureConfig = SecureConfig {
-- | SSL key log
, secureSslKeyLog :: SslKeyLog
}
deriving (Show)
deriving stock (Show, Generic)

{-------------------------------------------------------------------------------
Simple interface
Expand Down
3 changes: 2 additions & 1 deletion grapesy/src/Network/GRPC/Util/TLS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Control.Exception
import Data.Default
import Data.X509 qualified as X509
import Data.X509.CertificateStore qualified as X509
import GHC.Generics (Generic)
import System.Environment
import System.X509 qualified as X509

Expand Down Expand Up @@ -134,7 +135,7 @@ data SslKeyLog =
--
-- This is the default.
| SslKeyLogFromEnv
deriving (Show, Eq)
deriving stock (Show, Eq, Generic)

instance Default SslKeyLog where
def = SslKeyLogFromEnv
Expand Down
2 changes: 2 additions & 0 deletions grapesy/test-grapesy/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Test.Sanity.Compression qualified as Compression
import Test.Sanity.Disconnect qualified as Disconnect
import Test.Sanity.EndOfStream qualified as EndOfStream
import Test.Sanity.Interop qualified as Interop
import Test.Sanity.Reclamation qualified as Reclamation
import Test.Sanity.StreamingType.CustomFormat qualified as StreamingType.CustomFormat
import Test.Sanity.StreamingType.NonStreaming qualified as StreamingType.NonStreaming

Expand All @@ -38,6 +39,7 @@ main = do
]
, Compression.tests
, Interop.tests
, Reclamation.tests
, BrokenDeployments.tests
]
, testGroup "Regression" [
Expand Down
9 changes: 6 additions & 3 deletions grapesy/test-grapesy/Test/Driver/Dialogue/Execution.hs
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,12 @@ clientLocal clock call = \(LocalSteps steps) ->
-> Bool
isGrpcException mErr (Left err) = and [
grpcError err == GrpcUnknown
, grpcErrorMessage err == Just (case mErr of
Nothing -> "HandlerTerminated"
Just err' -> Text.pack $ show err')
, grpcErrorMessage err == Just (mconcat [
"Server-side exception: "
, case mErr of
Nothing -> "HandlerTerminated"
Just err' -> Text.pack $ show err'
])
]
isGrpcException _ (Right _) = False

Expand Down
Loading

0 comments on commit e3b00f9

Please sign in to comment.