1#!/bin/bash
2#
3#  Copyright 2019 gRPC authors.
4#
5#  Licensed under the Apache License, Version 2.0 (the "License");
6#  you may not use this file except in compliance with the License.
7#  You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11#  Unless required by applicable law or agreed to in writing, software
12#  distributed under the License is distributed on an "AS IS" BASIS,
13#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#  See the License for the specific language governing permissions and
15#  limitations under the License.
16#
17
18set +e
19
20export TMPDIR=$(mktemp -d)
21trap "rm -rf ${TMPDIR}" EXIT
22
23clean () {
24  for i in {1..10}; do
25    jobs -p | xargs -n1 pkill -P
26    # A simple "wait" just hangs sometimes.  Running `jobs` seems to help.
27    sleep 1
28    if jobs | read; then
29      return
30    fi
31  done
32  echo "$(tput setaf 1) clean failed to kill tests $(tput sgr 0)"
33  jobs
34  pstree
35  exit 1
36}
37
38fail () {
39    echo "$(tput setaf 1) $1 $(tput sgr 0)"
40    clean
41    exit 1
42}
43
44pass () {
45    echo "$(tput setaf 2) $1 $(tput sgr 0)"
46}
47
48EXAMPLES=(
49    "helloworld"
50    "route_guide"
51    "features/authentication"
52    "features/compression"
53    "features/deadline"
54    "features/encryption/TLS"
55    "features/errors"
56    "features/interceptor"
57    "features/load_balancing"
58    "features/metadata"
59    "features/multiplex"
60    "features/name_resolving"
61)
62
63declare -A EXPECTED_SERVER_OUTPUT=(
64    ["helloworld"]="Received: world"
65    ["route_guide"]=""
66    ["features/authentication"]="server starting on port 50051..."
67    ["features/compression"]="UnaryEcho called with message \"compress\""
68    ["features/deadline"]=""
69    ["features/encryption/TLS"]=""
70    ["features/errors"]=""
71    ["features/interceptor"]="unary echoing message \"hello world\""
72    ["features/load_balancing"]="serving on :50051"
73    ["features/metadata"]="message:\"this is examples/metadata\", sending echo"
74    ["features/multiplex"]=":50051"
75    ["features/name_resolving"]="serving on localhost:50051"
76)
77
78declare -A EXPECTED_CLIENT_OUTPUT=(
79    ["helloworld"]="Greeting: Hello world"
80    ["route_guide"]="Feature: name: \"\", point:(416851321, -742674555)"
81    ["features/authentication"]="UnaryEcho:  hello world"
82    ["features/compression"]="UnaryEcho call returned \"compress\", <nil>"
83    ["features/deadline"]="wanted = DeadlineExceeded, got = DeadlineExceeded"
84    ["features/encryption/TLS"]="UnaryEcho:  hello world"
85    ["features/errors"]="Greeting: Hello world"
86    ["features/interceptor"]="UnaryEcho:  hello world"
87    ["features/load_balancing"]="calling helloworld.Greeter/SayHello with pick_first"
88    ["features/metadata"]="this is examples/metadata"
89    ["features/multiplex"]="Greeting:  Hello multiplex"
90    ["features/name_resolving"]="calling helloworld.Greeter/SayHello to \"example:///resolver.example.grpc.io\""
91)
92
93cd ./examples
94
95for example in ${EXAMPLES[@]}; do
96    echo "$(tput setaf 4) testing: ${example} $(tput sgr 0)"
97
98    # Build server
99    if ! go build -o /dev/null ./${example}/*server/*.go; then
100        fail "failed to build server"
101    else
102        pass "successfully built server"
103    fi
104
105    # Build client
106    if ! go build -o /dev/null ./${example}/*client/*.go; then
107        fail "failed to build client"
108    else
109        pass "successfully built client"
110    fi
111
112    # Start server
113    SERVER_LOG="$(mktemp)"
114    go run ./$example/*server/*.go &> $SERVER_LOG  &
115
116    CLIENT_LOG="$(mktemp)"
117    if ! timeout 20 go run ${example}/*client/*.go &> $CLIENT_LOG; then
118        fail "client failed to communicate with server
119        got server log:
120        $(cat $SERVER_LOG)
121        got client log:
122        $(cat $CLIENT_LOG)
123        "
124    else
125        pass "client successfully communitcated with server"
126    fi
127
128    # Check server log for expected output if expecting an
129    # output
130    if [ -n "${EXPECTED_SERVER_OUTPUT[$example]}" ]; then
131        if ! grep -q "${EXPECTED_SERVER_OUTPUT[$example]}" $SERVER_LOG; then
132            fail "server log missing output: ${EXPECTED_SERVER_OUTPUT[$example]}
133            got server log:
134            $(cat $SERVER_LOG)
135            got client log:
136            $(cat $CLIENT_LOG)
137            "
138        else
139            pass "server log contains expected output: ${EXPECTED_SERVER_OUTPUT[$example]}"
140        fi
141    fi
142
143    # Check client log for expected output if expecting an
144    # output
145    if [ -n "${EXPECTED_CLIENT_OUTPUT[$example]}" ]; then
146        if ! grep -q "${EXPECTED_CLIENT_OUTPUT[$example]}" $CLIENT_LOG; then
147            fail "client log missing output: ${EXPECTED_CLIENT_OUTPUT[$example]}
148            got server log:
149            $(cat $SERVER_LOG)
150            got client log:
151            $(cat $CLIENT_LOG)
152            "
153        else
154            pass "client log contains expected output: ${EXPECTED_CLIENT_OUTPUT[$example]}"
155        fi
156    fi
157    clean
158    echo ""
159done
160