diff --git a/.azure-pipelines/pipelines.yml b/.azure-pipelines/pipelines.yml index 7341b06627ffe..71528a58c1ee8 100644 --- a/.azure-pipelines/pipelines.yml +++ b/.azure-pipelines/pipelines.yml @@ -158,6 +158,24 @@ jobs: artifactName: docker condition: always() + - job: examples + dependsOn: ["docker"] + displayName: "Verify examples run as documented" + pool: + vmImage: "ubuntu-18.04" + steps: + - task: DownloadBuildArtifacts@0 + inputs: + buildType: current + artifactName: "docker" + itemPattern: "docker/envoy-docker-images.tar.xz" + downloadType: single + targetPath: $(Build.StagingDirectory) + - bash: ./ci/do_ci.sh verify_examples + env: + ENVOY_DOCKER_BUILD_DIR: $(Build.StagingDirectory) + NO_BUILD_SETUP: 1 + - job: macOS dependsOn: ["format"] timeoutInMinutes: 360 diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 40fa5312b805c..1bde1fd6edb28 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -12,8 +12,11 @@ if [[ "$1" == "fix_format" || "$1" == "check_format" || "$1" == "check_repositor fi SRCDIR="${PWD}" -. "$(dirname "$0")"/setup_cache.sh -. "$(dirname "$0")"/build_setup.sh $build_setup_args +NO_BUILD_SETUP="${NO_BUILD_SETUP:-}" +if [[ -z "$NO_BUILD_SETUP" ]]; then + . "$(dirname "$0")"/setup_cache.sh + . "$(dirname "$0")"/build_setup.sh $build_setup_args +fi cd "${SRCDIR}" if [[ "${ENVOY_BUILD_ARCH}" == "x86_64" ]]; then @@ -365,6 +368,23 @@ elif [[ "$CI_TARGET" == "docs" ]]; then echo "generating docs..." docs/build.sh exit 0 +elif [[ "$CI_TARGET" == "verify_examples" ]]; then + echo "verify examples..." + docker load < "$ENVOY_DOCKER_BUILD_DIR/docker/envoy-docker-images.tar.xz" + images=($(docker image list --format "{{.Repository}}")) + tags=($(docker image list --format "{{.Tag}}")) + for i in "${!images[@]}"; do + if [[ "${images[i]}" =~ "envoy" ]]; then + docker tag "${images[$i]}:${tags[$i]}" "${images[$i]}:latest" + fi + done + docker images + sudo apt-get update -y + sudo apt-get install -y -qq --no-install-recommends redis-tools + export DOCKER_NO_PULL=1 + umask 027 + ci/verify_examples.sh + exit 0 else echo "Invalid do_ci.sh target, see ci/README.md for valid targets." exit 1 diff --git a/ci/verify_examples.sh b/ci/verify_examples.sh index 711ceb5f25a30..4e459464aeda4 100755 --- a/ci/verify_examples.sh +++ b/ci/verify_examples.sh @@ -1,43 +1,67 @@ -#!/bin/bash +#!/bin/bash -E -set -e +TESTFILTER="${1:-*}" +FAILED=() +SRCDIR="${SRCDIR:-$(pwd)}" +EXCLUDED_BUILD_CONFIGS=${EXCLUDED_BUILD_CONFIGS:-"^./jaeger-native-tracing|docker-compose"} -verify() { - echo $1 - CONTAINER_ID="$(docker ps -aqf name=$1)" - if [ "false" == "$(docker inspect -f {{.State.Running}} ${CONTAINER_ID})" ] - then - echo "error: $1 not running" - exit 1 - fi + +trap_errors () { + local frame=0 command line sub file + if [[ -n "$example" ]]; then + command=" (${example})" + fi + set +v + while read -r line sub file < <(caller "$frame"); do + if [[ "$frame" -ne "0" ]]; then + FAILED+=(" > ${sub}@ ${file} :${line}") + else + FAILED+=("${sub}@ ${file} :${line}${command}") + fi + ((frame++)) + done + set -v +} + +trap trap_errors ERR +trap exit 1 INT + + +run_examples () { + local examples example + cd "${SRCDIR}/examples" || exit 1 + examples=$(find . -mindepth 1 -maxdepth 1 -type d -name "$TESTFILTER" | sort) + for example in $examples; do + pushd "$example" > /dev/null || return 1 + ./verify.sh + popd > /dev/null || return 1 + done } -# Test front proxy example -cd examples/front-proxy -docker-compose up --build -d -for CONTAINER_NAME in "frontproxy_front-envoy" "frontproxy_service1" "frontproxy_service2" -do - verify $CONTAINER_NAME -done -cd ../ - -# Test grpc bridge example -# install go -GO_VERSION="1.14.7" -curl -O https://storage.googleapis.com/golang/go$GO_VERSION.linux-amd64.tar.gz -tar -xf go$GO_VERSION.linux-amd64.tar.gz -sudo mv go /usr/local -export PATH=$PATH:/usr/local/go/bin -export GOPATH=$HOME/go -mkdir -p $GOPATH/src/github.com/envoyproxy/envoy/examples/ -cp -r grpc-bridge $GOPATH/src/github.com/envoyproxy/envoy/examples/ -# build example -cd $GOPATH/src/github.com/envoyproxy/envoy/examples/grpc-bridge -./script/bootstrap -./script/build -# verify example works -docker-compose up --build -d -for CONTAINER_NAME in "grpcbridge_python" "grpcbridge_grpc" -do - verify $CONTAINER_NAME -done +verify_build_configs () { + local config configs missing + missing=() + cd "${SRCDIR}/examples" || return 1 + configs="$(find . -name "*.yaml" -o -name "*.lua" | grep -vE "${EXCLUDED_BUILD_CONFIGS}" | cut -d/ -f2-)" + for config in $configs; do + grep "\"$config\"" BUILD || missing+=("$config") + done + if [[ -n "${missing[*]}" ]]; then + for config in "${missing[@]}"; do + echo "Missing config: $config" >&2 + done + return 1 + fi +} + +verify_build_configs +run_examples + + +if [[ "${#FAILED[@]}" -ne "0" ]]; then + echo "TESTS FAILED:" + for failed in "${FAILED[@]}"; do + echo "$failed" >&2 + done + exit 1 +fi diff --git a/examples/cors/verify.sh b/examples/cors/verify.sh new file mode 100755 index 0000000000000..260cc161286a1 --- /dev/null +++ b/examples/cors/verify.sh @@ -0,0 +1,47 @@ +#!/bin/bash -e + +export NAME=cors +export PATHS=frontend,backend + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Test service" +responds_with \ + "Envoy CORS Webpage" \ + http://localhost:8000 + +run_log "Test cors server: disabled" +responds_with \ + Success \ + -H "Origin: http://example.com" \ + http://localhost:8002/cors/disabled +responds_without_header \ + access-control-allow-origin \ + -H "Origin: http://example.com" \ + http://localhost:8002/cors/disabled + +run_log "Test cors server: open" +responds_with \ + Success \ + -H 'Origin: http://example.com' \ + http://localhost:8002/cors/open +responds_with_header \ + "access-control-allow-origin: http://example.com" \ + -H "Origin: http://example.com" \ + http://localhost:8002/cors/open + +run_log "Test cors server: restricted" +responds_with \ + Success \ + -H "Origin: http://example.com" \ + http://localhost:8002/cors/restricted +responds_without_header \ + access-control-allow-origin \ + -H "Origin: http://example.com" \ + http://localhost:8002/cors/restricted +responds_with_header \ + "access-control-allow-origin: http://foo.envoyproxy.io" \ + -H "Origin: http://foo.envoyproxy.io" \ + http://localhost:8002/cors/restricted diff --git a/examples/csrf/verify.sh b/examples/csrf/verify.sh new file mode 100755 index 0000000000000..24c28cd2d93a2 --- /dev/null +++ b/examples/csrf/verify.sh @@ -0,0 +1,69 @@ +#!/bin/bash -e + +export NAME=csrf +export PATHS=samesite,crosssite + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Test services" +responds_with \ + "Envoy CSRF Demo" \ + http://localhost:8002 +responds_with \ + "Envoy CSRF Demo" \ + http://localhost:8000 + +run_log "Test stats server" +responds_with \ + ":" \ + http://localhost:8001/stats + +run_log "Test csrf server: disabled" +responds_with \ + Success \ + -X POST \ + -H "Origin: http://example.com" \ + http://localhost:8000/csrf/disabled +responds_with_header \ + "access-control-allow-origin: http://example.com" \ + -X POST \ + -H "Origin: http://example.com" \ + http://localhost:8000/csrf/disabled + +run_log "Test csrf server: shadow" +responds_with \ + Success \ + -X POST \ + -H "Origin: http://example.com" \ + http://localhost:8000/csrf/shadow +responds_with_header \ + "access-control-allow-origin: http://example.com" \ + -X POST \ + -H "Origin: http://example.com" \ + http://localhost:8000/csrf/shadow + +run_log "Test csrf server: enabled" +responds_with \ + "Invalid origin" \ + -X POST \ + -H "Origin: http://example.com" \ + http://localhost:8000/csrf/enabled +responds_with_header \ + "HTTP/1.1 403 Forbidden" \ + -X POST \ + -H "Origin: http://example.com" \ + http://localhost:8000/csrf/enabled + +run_log "Test csrf server: additional_origin" +responds_with \ + Success \ + -X POST \ + -H "Origin: http://example.com" \ + http://localhost:8000/csrf/additional_origin +responds_with_header \ + "access-control-allow-origin: http://example.com" \ + -X POST \ + -H "Origin: http://example.com" \ + http://localhost:8000/csrf/additional_origin diff --git a/examples/ext_authz/verify.sh b/examples/ext_authz/verify.sh new file mode 100755 index 0000000000000..60cef4b1c5812 --- /dev/null +++ b/examples/ext_authz/verify.sh @@ -0,0 +1,47 @@ +#!/bin/bash -e + +export NAME=ext_authz + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Test services responds with 403" +responds_with_header \ + "HTTP/1.1 403 Forbidden"\ + http://localhost:8000/service + +run_log "Restart front-envoy with FRONT_ENVOY_YAML=config/http-service.yaml" +docker-compose down +FRONT_ENVOY_YAML=config/http-service.yaml docker-compose up -d +sleep 10 + +run_log "Test service responds with 403" +responds_with_header \ + "HTTP/1.1 403 Forbidden"\ + http://localhost:8000/service + +run_log "Test authenticated service responds with 200" +responds_with_header \ + "HTTP/1.1 200 OK" \ + -H "Authorization: Bearer token1" \ + http://localhost:8000/service + +run_log "Restart front-envoy with FRONT_ENVOY_YAML=config/opa-service/v2.yaml" +docker-compose down +FRONT_ENVOY_YAML=config/opa-service/v2.yaml docker-compose up -d +sleep 10 + +run_log "Test OPA service responds with 200" +responds_with_header \ + "HTTP/1.1 200 OK" \ + http://localhost:8000/service + +run_log "Check OPA logs" +docker-compose logs ext_authz-opa-service | grep decision_id -A 30 + +run_log "Check OPA service rejects POST" +responds_with_header \ + "HTTP/1.1 403 Forbidden" \ + -X POST \ + http://localhost:8000/service diff --git a/examples/fault-injection/verify.sh b/examples/fault-injection/verify.sh new file mode 100755 index 0000000000000..611acddc15ed8 --- /dev/null +++ b/examples/fault-injection/verify.sh @@ -0,0 +1,59 @@ +#!/bin/bash -e + +export NAME=fault-injection + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Send requests for 20 seconds" +docker-compose exec -T envoy bash -c \ + "bash send_request.sh & export pid=\$! && sleep 20 && kill \$pid" \ + &> /dev/null + +run_log "Check logs" +docker-compose logs | grep "HTTP/1.1\" 200" + + +_fault_injection_test () { + local action code existing_200s existing_codes + action="$1" + code="$2" + existing_codes=0 + + # enable fault injection and check for http hits of type $code + existing_codes=$(docker-compose logs | grep -c "HTTP/1.1\" ${code}" || :) + run_log "Enable ${action} fault injection" + docker-compose exec -T envoy bash "enable_${action}_fault_injection.sh" + run_log "Send requests for 20 seconds" + docker-compose exec -T envoy bash -c \ + "bash send_request.sh & export pid=\$! && sleep 20 && kill \$pid" \ + &> /dev/null + run_log "Check logs again" + new_codes=$(docker-compose logs | grep -c "HTTP/1.1\" ${code}") + if [[ "$new_codes" -le "$existing_codes" ]]; then + echo "ERROR: expected to find new logs with response code $code" >&2 + return 1 + fi + + # disable fault injection and check for http hits of type 200 + existing_200s=$(docker-compose logs | grep -c "HTTP/1.1\" 200") + run_log "Disable ${action} fault injection" + docker-compose exec -T envoy bash "disable_${action}_fault_injection.sh" + run_log "Send requests for 20 seconds" + docker-compose exec -T envoy bash -c \ + "bash send_request.sh & export pid=\$! && sleep 20 && kill \$pid" \ + &> /dev/null + run_log "Check logs again" + new_200s=$(docker-compose logs | grep -c "HTTP/1.1\" 200") + if [[ "$new_200s" -le "$existing_200s" ]]; then + echo "ERROR: expected to find new logs with response code 200" >&2 + return 1 + fi +} + +_fault_injection_test abort 503 +_fault_injection_test delay 200 + +run_log "Check tree" +docker-compose exec -T envoy tree /srv/runtime diff --git a/examples/front-proxy/Dockerfile-jaeger-service b/examples/front-proxy/Dockerfile-jaeger-service new file mode 100644 index 0000000000000..4fa93db5f2499 --- /dev/null +++ b/examples/front-proxy/Dockerfile-jaeger-service @@ -0,0 +1,19 @@ +FROM envoyproxy/envoy-alpine-dev:latest + +RUN apk update && apk add py3-pip bash curl +RUN pip3 install -q Flask==0.11.1 requests==2.18.4 +RUN mkdir /code +ADD ./service.py /code +ADD ./start_service.sh /usr/local/bin/start_service.sh +RUN chmod u+x /usr/local/bin/start_service.sh +# +# for discussion on jaeger binary compatibility, and the source of the file, see here: +# https://github.com/envoyproxy/envoy/issues/11382#issuecomment-638012072 +# +RUN echo "4a7d17d4724ee890490bcd6cfdedb12a02316a3d33214348d30979abd201f1ca /usr/local/lib/libjaegertracing_plugin.so" > /tmp/checksum \ + && curl -Ls https://github.com/tetratelabs/getenvoy-package/files/3518103/getenvoy-centos-jaegertracing-plugin.tar.gz \ + | tar zxf - -C /usr/local/lib \ + && mv /usr/local/lib/libjaegertracing.so.0.4.2 /usr/local/lib/libjaegertracing_plugin.so \ + && sha256sum -c /tmp/checksum \ + && rm /tmp/checksum +ENTRYPOINT /usr/local/bin/start_service.sh diff --git a/examples/front-proxy/verify.sh b/examples/front-proxy/verify.sh new file mode 100755 index 0000000000000..0e85be8b875a8 --- /dev/null +++ b/examples/front-proxy/verify.sh @@ -0,0 +1,44 @@ +#!/bin/bash -e + +export NAME=front-proxy + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Test service: localhost:8080/service/1" +responds_with \ + "Hello from behind Envoy (service 1)!" \ + http://localhost:8080/service/1 + +run_log "Test service: localhost:8080/service/2" +responds_with \ + "Hello from behind Envoy (service 2)!" \ + http://localhost:8080/service/2 + +run_log "Test service: https://localhost:8443/service/1" +responds_with \ + "Hello from behind Envoy (service 1)!" \ + -k https://localhost:8443/service/1 + +run_log "Scale up docker service1=3" +docker-compose scale service1=3 +run_log "Snooze for 5 while docker-compose scales..." +sleep 5 + +run_log "Test round-robin localhost:8080/service/1" +docker-compose exec -T front-envoy bash -c "\ + curl -s http://localhost:8080/service/1 \ + && curl -s http://localhost:8080/service/1 \ + && curl -s http://localhost:8080/service/1" \ + | grep Hello | grep "service 1" + + +run_log "Test service inside front-envoy: localhost:8080/service/2" +docker-compose exec -T front-envoy curl -s http://localhost:8080/service/2 | grep Hello | grep "service 2" + +run_log "Test service info: localhost:8080/server_info" +docker-compose exec -T front-envoy curl -s http://localhost:8001/server_info | jq '.' + +run_log "Test service stats: localhost:8080/stats" +docker-compose exec -T front-envoy curl -s http://localhost:8001/stats | grep ":" diff --git a/examples/grpc-bridge/verify.sh b/examples/grpc-bridge/verify.sh new file mode 100755 index 0000000000000..6b2dfe4c502fa --- /dev/null +++ b/examples/grpc-bridge/verify.sh @@ -0,0 +1,24 @@ +#!/bin/bash -e + +export NAME=grpc-bridge +# this allows us to bring up the stack manually after generating stubs +export MANUAL=true + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Generate protocol stubs" +docker-compose -f docker-compose-protos.yaml up +docker container prune -f + +ls client/kv/kv_pb2.py +ls server/kv/kv.pb.go + +bring_up_example + +run_log "Set key value foo=bar" +docker-compose exec -T grpc-client /client/grpc-kv-client.py set foo bar | grep setf + +run_log "Get key foo" +docker-compose exec -T grpc-client /client/grpc-kv-client.py get foo | grep bar diff --git a/examples/jaeger-native-tracing/docker-compose.yaml b/examples/jaeger-native-tracing/docker-compose.yaml index b0060928551aa..6198572ad105c 100644 --- a/examples/jaeger-native-tracing/docker-compose.yaml +++ b/examples/jaeger-native-tracing/docker-compose.yaml @@ -20,10 +20,9 @@ services: service1: build: context: ../front-proxy - dockerfile: Dockerfile-service + dockerfile: Dockerfile-jaeger-service volumes: - ./service1-envoy-jaeger.yaml:/etc/service-envoy.yaml - - ./libjaegertracing.so.0.4.2:/usr/local/lib/libjaegertracing_plugin.so networks: envoymesh: aliases: @@ -39,10 +38,9 @@ services: service2: build: context: ../front-proxy - dockerfile: Dockerfile-service + dockerfile: Dockerfile-jaeger-service volumes: - ./service2-envoy-jaeger.yaml:/etc/service-envoy.yaml - - ./libjaegertracing.so.0.4.2:/usr/local/lib/libjaegertracing_plugin.so networks: envoymesh: aliases: diff --git a/examples/jaeger-native-tracing/verify.sh b/examples/jaeger-native-tracing/verify.sh new file mode 100755 index 0000000000000..8461a97750e88 --- /dev/null +++ b/examples/jaeger-native-tracing/verify.sh @@ -0,0 +1,18 @@ +#!/bin/bash -e + +export NAME=jaeger-native +export DELAY=10 + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Test services" +responds_with \ + Hello \ + http://localhost:8000/trace/1 + +run_log "Test Jaeger UI" +responds_with \ + "" \ + http://localhost:16686 diff --git a/examples/jaeger-tracing/verify.sh b/examples/jaeger-tracing/verify.sh new file mode 100755 index 0000000000000..9882f1f3ed5c2 --- /dev/null +++ b/examples/jaeger-tracing/verify.sh @@ -0,0 +1,17 @@ +#!/bin/bash -e + +export NAME=jaeger-tracing + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Test services" +responds_with \ + Hello \ + http://localhost:8000/trace/1 + +run_log "Test Jaeger UI" +responds_with \ + "" \ + http://localhost:16686 diff --git a/examples/load-reporting-service/verify.sh b/examples/load-reporting-service/verify.sh new file mode 100755 index 0000000000000..7ddc13ce1bfe5 --- /dev/null +++ b/examples/load-reporting-service/verify.sh @@ -0,0 +1,18 @@ +#!/bin/bash -e + +export NAME=load-reporting +export UPARGS="--scale http_service=2" + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + +run_log "Send requests" +bash send_requests.sh 2> /dev/null +run_log "Check logs: http 1" +docker-compose logs http_service | grep http_service_1 | grep HTTP | grep 200 + +run_log "Check logs: http 2" +docker-compose logs http_service | grep http_service_2 | grep HTTP | grep 200 + +run_log "Check logs: lrs_server" +docker-compose logs lrs_server | grep "up and running" diff --git a/examples/lua/verify.sh b/examples/lua/verify.sh new file mode 100755 index 0000000000000..56a391da6ad4e --- /dev/null +++ b/examples/lua/verify.sh @@ -0,0 +1,12 @@ +#!/bin/bash -e + +export NAME=lua + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Test connection" +responds_with \ + foo \ + http://localhost:8000 diff --git a/examples/mysql/verify.sh b/examples/mysql/verify.sh new file mode 100755 index 0000000000000..407d08204ff88 --- /dev/null +++ b/examples/mysql/verify.sh @@ -0,0 +1,31 @@ +#!/bin/bash -e + +export NAME=mysql +export DELAY=10 + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + +_mysql () { + local mysql_client + mysql_client=(docker run --network envoymesh mysql:5.5 mysql -h envoy -P 1999 -u root) + "${mysql_client[@]}" "${@}" +} + +run_log "Create a mysql database" +_mysql -e "CREATE DATABASE test;" +_mysql -e "show databases;" | grep test + +run_log "Create a mysql table" +_mysql -e "USE test; CREATE TABLE test ( text VARCHAR(255) ); INSERT INTO test VALUES ('hello, world!');" +_mysql -e "SELECT COUNT(*) from test.test;" | grep 1 + +run_log "Check mysql egress stats" +responds_with \ + egress_mysql \ + "http://localhost:8001/stats?filter=egress_mysql" + +run_log "Check mysql TCP stats" +responds_with \ + mysql_tcp \ + "http://localhost:8001/stats?filter=mysql_tcp" diff --git a/examples/redis/Dockerfile-proxy b/examples/redis/Dockerfile-proxy index 92b320ea14879..9266482b53fe8 100644 --- a/examples/redis/Dockerfile-proxy +++ b/examples/redis/Dockerfile-proxy @@ -1,2 +1,5 @@ FROM envoyproxy/envoy-dev:latest + +COPY ./envoy.yaml /etc/envoy.yaml +RUN chmod go+r /etc/envoy.yaml CMD /usr/local/bin/envoy -c /etc/envoy.yaml -l debug --service-cluster proxy diff --git a/examples/redis/docker-compose.yaml b/examples/redis/docker-compose.yaml index 5b2d82a6e1163..fb4bd1f0b638e 100644 --- a/examples/redis/docker-compose.yaml +++ b/examples/redis/docker-compose.yaml @@ -5,8 +5,6 @@ services: build: context: . dockerfile: Dockerfile-proxy - volumes: - - ./envoy.yaml:/etc/envoy.yaml networks: - envoymesh expose: diff --git a/examples/redis/verify.sh b/examples/redis/verify.sh new file mode 100755 index 0000000000000..117cb5ffce467 --- /dev/null +++ b/examples/redis/verify.sh @@ -0,0 +1,20 @@ +#!/bin/bash -e + +export NAME=redis + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Test set" +redis-cli -h localhost -p 1999 set foo FOO | grep OK +redis-cli -h localhost -p 1999 set bar BAR | grep OK + +run_log "Test get" +redis-cli -h localhost -p 1999 get foo | grep FOO +redis-cli -h localhost -p 1999 get bar | grep BAR + +run_log "Test redis stats" +responds_with \ + egress_redis \ + "http://localhost:8001/stats?usedonly&filter=redis.egress_redis.command" diff --git a/examples/verify-common.sh b/examples/verify-common.sh new file mode 100644 index 0000000000000..d27155f39f0e7 --- /dev/null +++ b/examples/verify-common.sh @@ -0,0 +1,129 @@ +#!/bin/bash -e + +DELAY="${DELAY:-0}" +DOCKER_NO_PULL="${DOCKER_NO_PULL:-}" +MANUAL="${MANUAL:-}" +NAME="${NAME:-}" +PATHS="${PATHS:-.}" +UPARGS="${UPARGS:-}" + + +run_log () { + echo -e "\n> [${NAME}] ${*}" +} + +bring_up_example_stack () { + local args path up_args + args=("${UPARGS[@]}") + path="$1" + read -ra up_args <<< "up --build -d ${args[*]}" + if [[ -z "$DOCKER_NO_PULL" ]]; then + run_log "Pull the images ($path)" + docker-compose pull + echo + fi + run_log "Bring up services ($path)" + docker-compose "${up_args[@]}" || return 1 + echo +} + +bring_up_example () { + local path paths + read -ra paths <<< "$(echo "$PATHS" | tr ',' ' ')" + for path in "${paths[@]}"; do + pushd "$path" > /dev/null || return 1 + bring_up_example_stack "$path" || { + echo "ERROR: starting ${NAME} ${path}" >&2 + return 1 + } + popd > /dev/null || return 1 + done + if [[ "$DELAY" -ne "0" ]]; then + run_log "Snooze for ${DELAY} while ${NAME} gets started" + sleep "$DELAY" + fi + for path in "${paths[@]}"; do + pushd "$path" > /dev/null || return 1 + docker-compose ps + docker-compose logs + popd > /dev/null || return 1 + done +} + +cleanup_stack () { + local path + path="$1" + run_log "Cleanup ($path)" + docker-compose down + docker system prune -f +} + +cleanup () { + local path paths + read -ra paths <<< "$(echo "$PATHS" | tr ',' ' ')" + for path in "${paths[@]}"; do + pushd "$path" > /dev/null || return 1 + cleanup_stack "$path" || { + echo "ERROR: cleanup ${NAME} ${path}" >&2 + return 1 + } + popd > /dev/null + done +} + +_curl () { + local arg curl_command + curl_command=(curl -s) + if [[ ! "$*" =~ "-X" ]]; then + curl_command+=(-X GET) + fi + for arg in "${@}"; do + curl_command+=("$arg") + done + "${curl_command[@]}" || { + echo "ERROR: curl (${curl_command[*]})" >&2 + return 1 + } +} + +responds_with () { + local expected + expected="$1" + shift + _curl "${@}" | grep "$expected" || { + echo "ERROR: curl expected (${*}): $expected" >&2 + return 1 + } +} + +responds_with_header () { + local expected + expected="$1" + shift + _curl --head "${@}" | grep "$expected" || { + echo "ERROR: curl header (${*}): $expected" >&2 + return 1 + } +} + +responds_without_header () { + local expected + expected="$1" + shift + _curl --head "${@}" | grep "$expected" | [[ "$(wc -l)" -eq 0 ]] || { + echo "ERROR: curl without header (${*}): $expected" >&2 + return 1 + } +} + + +trap 'cleanup' EXIT + +if [[ -z "$NAME" ]]; then + echo "ERROR: You must set the '$NAME' variable before sourcing this script" >&2 + exit 1 +fi + +if [[ -z "$MANUAL" ]]; then + bring_up_example +fi diff --git a/examples/zipkin-tracing/verify.sh b/examples/zipkin-tracing/verify.sh new file mode 100755 index 0000000000000..c2135e1d99de6 --- /dev/null +++ b/examples/zipkin-tracing/verify.sh @@ -0,0 +1,19 @@ +#!/bin/bash -e + +export NAME=zipkin + +# shellcheck source=examples/verify-common.sh +. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh" + + +run_log "Test connection" +responds_with \ + "Hello from behind Envoy (service 1)!" \ + http://localhost:8000/trace/1 + +run_log "Test dashboard" +# this could do with using the healthcheck and waiting +sleep 20 +responds_with \ + "" \ + http://localhost:9411/zipkin/