#!/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\", " ["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 if ! grep -q "${EXPECTED_SERVER_OUTPUT[$example]}" $SERVER_LOG; 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