| #!/bin/bash | |
| # | |
| # Copyright 2019 gRPC authors. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # | |
| set +e | |
| export TMPDIR=$(mktemp -d) | |
| trap "rm -rf ${TMPDIR}" EXIT | |
| export SERVER_PORT=50051 | |
| export UNIX_ADDR=abstract-unix-socket | |
| clean () { | |
| for i in {1..10}; do | |
| jobs -p | xargs -n1 pkill -P | |
| # A simple "wait" just hangs sometimes. Running `jobs` seems to help. | |
| sleep 1 | |
| if jobs | read; then | |
| return | |
| fi | |
| done | |
| echo "$(tput setaf 1) clean failed to kill tests $(tput sgr 0)" | |
| jobs | |
| pstree | |
| exit 1 | |
| } | |
| fail () { | |
| echo "$(tput setaf 1) $1 $(tput sgr 0)" | |
| clean | |
| exit 1 | |
| } | |
| pass () { | |
| echo "$(tput setaf 2) $1 $(tput sgr 0)" | |
| } | |
| EXAMPLES=( | |
| "helloworld" | |
| "route_guide" | |
| "features/advancedtls" | |
| "features/authentication" | |
| "features/authz" | |
| "features/cancellation" | |
| "features/compression" | |
| "features/customloadbalancer" | |
| "features/deadline" | |
| "features/dualstack" | |
| "features/encryption/TLS" | |
| "features/error_details" | |
| "features/error_handling" | |
| "features/flow_control" | |
| "features/interceptor" | |
| "features/load_balancing" | |
| "features/metadata" | |
| "features/metadata_interceptor" | |
| "features/multiplex" | |
| "features/name_resolving" | |
| "features/orca" | |
| "features/retry" | |
| "features/unix_abstract" | |
| "features/gracefulstop" | |
| ) | |
| declare -A SERVER_ARGS=( | |
| ["features/unix_abstract"]="-addr $UNIX_ADDR" | |
| ["default"]="-port $SERVER_PORT" | |
| ["features/advancedtls"]="-credentials_directory $(dirname $(realpath "$0"))/features/advancedtls/creds" | |
| ) | |
| declare -A CLIENT_ARGS=( | |
| ["features/unix_abstract"]="-addr $UNIX_ADDR" | |
| ["features/orca"]="-test=true" | |
| ["default"]="-addr localhost:$SERVER_PORT" | |
| ["features/advancedtls"]="-credentials_directory $(dirname $(realpath "$0"))/features/advancedtls/creds" | |
| ) | |
| declare -A SERVER_WAIT_COMMAND=( | |
| ["features/unix_abstract"]="lsof -U | grep $UNIX_ADDR" | |
| ["default"]="lsof -i :$SERVER_PORT | grep $SERVER_PORT" | |
| ["features/dualstack"]="lsof -i :50053 | grep 50053" | |
| ) | |
| wait_for_server () { | |
| example=$1 | |
| wait_command=${SERVER_WAIT_COMMAND[$example]:-${SERVER_WAIT_COMMAND["default"]}} | |
| echo "$(tput setaf 4) waiting for server to start $(tput sgr 0)" | |
| for i in {1..10}; do | |
| eval "$wait_command" 2>&1 &>/dev/null | |
| if [ $? -eq 0 ]; then | |
| pass "server started" | |
| return | |
| fi | |
| sleep 1 | |
| done | |
| fail "cannot determine if server started" | |
| } | |
| declare -A EXPECTED_SERVER_OUTPUT=( | |
| ["helloworld"]="Received: world" | |
| ["route_guide"]="" | |
| ["features/authentication"]="server starting on port 50051..." | |
| ["features/authz"]="unary echoing message \"hello world\"" | |
| ["features/cancellation"]="server: error receiving from stream: rpc error: code = Canceled desc = context canceled" | |
| ["features/compression"]="UnaryEcho called with message \"compress\"" | |
| ["features/customloadbalancer"]="serving on localhost:50051" | |
| ["features/deadline"]="" | |
| ["features/dualstack"]="serving on \[::\]:50051" | |
| ["features/encryption/TLS"]="" | |
| ["features/error_details"]="" | |
| ["features/error_handling"]="" | |
| ["features/flow_control"]="Stream ended successfully." | |
| ["features/interceptor"]="unary echoing message \"hello world\"" | |
| ["features/load_balancing"]="serving on :50051" | |
| ["features/metadata"]="message:\"this is examples/metadata\", sending echo" | |
| ["features/metadata_interceptor"]="key1 from metadata: " | |
| ["features/multiplex"]=":50051" | |
| ["features/name_resolving"]="serving on localhost:50051" | |
| ["features/orca"]="Server listening" | |
| ["features/retry"]="request succeeded count: 4" | |
| ["features/unix_abstract"]="serving on @abstract-unix-socket" | |
| ["features/advancedtls"]="" | |
| ["features/gracefulstop"]="Server stopped gracefully." | |
| ) | |
| declare -A EXPECTED_CLIENT_OUTPUT=( | |
| ["helloworld"]="Greeting: Hello world" | |
| ["route_guide"]="Feature: name: \"\", point:(416851321, -742674555)" | |
| ["features/authentication"]="UnaryEcho: hello world" | |
| ["features/authz"]="UnaryEcho: hello world" | |
| ["features/cancellation"]="cancelling context" | |
| ["features/compression"]="UnaryEcho call returned \"compress\", <nil>" | |
| ["features/customloadbalancer"]="Successful multiple iterations of 1:2 ratio" | |
| ["features/deadline"]="wanted = DeadlineExceeded, got = DeadlineExceeded" | |
| ["features/dualstack"]="Successful multiple iterations of 1:1:1 ratio" | |
| ["features/encryption/TLS"]="UnaryEcho: hello world" | |
| ["features/error_details"]="Greeting: Hello world" | |
| ["features/error_handling"]="Received error" | |
| ["features/flow_control"]="Stream ended successfully." | |
| ["features/interceptor"]="UnaryEcho: hello world" | |
| ["features/load_balancing"]="calling helloworld.Greeter/SayHello with pick_first" | |
| ["features/metadata"]="this is examples/metadata" | |
| ["features/metadata_interceptor"]="BidiStreaming Echo: hello world" | |
| ["features/multiplex"]="Greeting: Hello multiplex" | |
| ["features/name_resolving"]="calling helloworld.Greeter/SayHello to \"example:///resolver.example.grpc.io\"" | |
| ["features/orca"]="Per-call load report received: map\[db_queries:10\]" | |
| ["features/retry"]="UnaryEcho reply: message:\"Try and Success\"" | |
| ["features/unix_abstract"]="calling echo.Echo/UnaryEcho to unix-abstract:abstract-unix-socket" | |
| ["features/advancedtls"]="" | |
| ["features/gracefulstop"]="Successful unary requests processed by server and made by client are same." | |
| ) | |
| cd ./examples | |
| for example in ${EXAMPLES[@]}; do | |
| echo "$(tput setaf 4) testing: ${example} $(tput sgr 0)" | |
| # Build server | |
| if ! go build -o /dev/null ./${example}/*server/*.go; then | |
| fail "failed to build server" | |
| else | |
| pass "successfully built server" | |
| fi | |
| # Start server | |
| SERVER_LOG="$(mktemp)" | |
| server_args=${SERVER_ARGS[$example]:-${SERVER_ARGS["default"]}} | |
| go run ./$example/*server/*.go $server_args &> $SERVER_LOG & | |
| wait_for_server $example | |
| # Build client | |
| if ! go build -o /dev/null ./${example}/*client/*.go; then | |
| fail "failed to build client" | |
| else | |
| pass "successfully built client" | |
| fi | |
| # Start client | |
| CLIENT_LOG="$(mktemp)" | |
| client_args=${CLIENT_ARGS[$example]:-${CLIENT_ARGS["default"]}} | |
| if ! timeout 20 go run ${example}/*client/*.go $client_args &> $CLIENT_LOG; then | |
| fail "client failed to communicate with server | |
| got server log: | |
| $(cat $SERVER_LOG) | |
| got client log: | |
| $(cat $CLIENT_LOG) | |
| " | |
| else | |
| pass "client successfully communicated with server" | |
| fi | |
| # Check server log for expected output if expecting an | |
| # output | |
| if [ -n "${EXPECTED_SERVER_OUTPUT[$example]}" ]; then | |
| found=false | |
| # Poll for up to 10 seconds. | |
| for i in {1..10}; do | |
| if grep -q "${EXPECTED_SERVER_OUTPUT[$example]}" "$SERVER_LOG"; then | |
| found=true | |
| break | |
| fi | |
| sleep 1 | |
| done | |
| if [ "$found" = "false" ]; then | |
| fail "server log missing output: ${EXPECTED_SERVER_OUTPUT[$example]} | |
| got server log: | |
| $(cat $SERVER_LOG) | |
| got client log: | |
| $(cat $CLIENT_LOG) | |
| " | |
| else | |
| pass "server log contains expected output: ${EXPECTED_SERVER_OUTPUT[$example]}" | |
| fi | |
| fi | |
| # Check client log for expected output if expecting an | |
| # output | |
| if [ -n "${EXPECTED_CLIENT_OUTPUT[$example]}" ]; then | |
| if ! grep -q "${EXPECTED_CLIENT_OUTPUT[$example]}" $CLIENT_LOG; then | |
| fail "client log missing output: ${EXPECTED_CLIENT_OUTPUT[$example]} | |
| got server log: | |
| $(cat $SERVER_LOG) | |
| got client log: | |
| $(cat $CLIENT_LOG) | |
| " | |
| else | |
| pass "client log contains expected output: ${EXPECTED_CLIENT_OUTPUT[$example]}" | |
| fi | |
| fi | |
| clean | |
| echo "" | |
| done |