diff --git a/.scripts/get-env.sh b/.scripts/get-env.sh index 8ee236b..0b7f832 100755 --- a/.scripts/get-env.sh +++ b/.scripts/get-env.sh @@ -1,16 +1,27 @@ #!/bin/bash -eval "$(cat graph-api.env)" -if [[ -z "${APOLLO_KEY}" ]]; then +if ls graph-api.env > /dev/null 2>&1; then + eval "$(cat graph-api.env)" +fi + +if [[ -z "${APOLLO_KEY}" || -z "${APOLLO_GRAPH_REF}" ]]; then source "$(dirname $0)/graph-api-env.sh" eval "$(cat graph-api.env)" if [[ -z "${APOLLO_KEY}" ]]; then echo ------------------------------------------------------------------------------------------- - echo environment keyfile required, run: make graph-api-key + echo APOLLO_KEY not found, run: make graph-api-env + echo ------------------------------------------------------------------------------------------- + exit 1 + fi + + if [[ -z "${APOLLO_GRAPH_REF}" ]]; then + echo ------------------------------------------------------------------------------------------- + echo APOLLO_GRAPH_REF not found, run: make graph-api-env echo ------------------------------------------------------------------------------------------- exit 1 fi fi export APOLLO_KEY=$APOLLO_KEY +export APOLLO_GRAPH_REF=$APOLLO_GRAPH_REF diff --git a/.scripts/get-graph-ref.sh b/.scripts/get-graph-ref.sh index cdae5b7..553119f 100755 --- a/.scripts/get-graph-ref.sh +++ b/.scripts/get-graph-ref.sh @@ -8,10 +8,18 @@ echo "then copy your Graph NAME and optionally @ and enter it at the pr echo "@ will default to @current, if omitted." echo "" echo "Enter the @ of a federated graph in Apollo Studio:" +if [[ -n "$APOLLO_GRAPH_REF" ]]; then + echo "" + echo "press for default: $APOLLO_GRAPH_REF" +fi read -p "> " graph if [[ -z "$graph" ]]; then + if [[ -n "$APOLLO_GRAPH_REF" ]]; then + graph=$APOLLO_GRAPH_REF + else >&2 echo "Error: no graph ref specified." exit 1 + fi fi export graph=$graph diff --git a/.scripts/graph-api-env.sh b/.scripts/graph-api-env.sh new file mode 100755 index 0000000..5f79f6c --- /dev/null +++ b/.scripts/graph-api-env.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +if ls graph-api.env > /dev/null 2>&1; then + eval "$(cat graph-api.env)" +fi + +echo ------------------------------------------------------------------------------------------- +echo Enter your Graph API Key +echo ------------------------------------------------------------------------------------------- +echo "Go to your graph settings in https://studio.apollographql.com/" +echo "then create a Graph API Key with Contributor permissions" +echo "(for metrics reporting) and enter it at the prompt below." + +if [[ -n "$APOLLO_KEY" ]]; then + echo "" + echo "press to use existing key: *************** (from ./graph-api.env)" +fi + +read -s -p "> " key +echo +if [[ -z "$key" ]]; then + if [[ -n "$APOLLO_KEY" ]]; then + key=$APOLLO_KEY + else + >&2 echo "Error: no key specified." + exit 1 + fi +fi + +echo "APOLLO_KEY=${key}" > graph-api.env + +# -------------------------------------------------------------------------- +# APOLLO_GRAPH_REF +# -------------------------------------------------------------------------- +echo "" +if [[ -z "${graph}" ]]; then + source "$(dirname $0)/get-graph-ref.sh" +fi + +echo "APOLLO_GRAPH_REF=${graph}" >> graph-api.env diff --git a/.scripts/k8s-ci.sh b/.scripts/k8s-ci.sh index 949077c..140b2b2 100755 --- a/.scripts/k8s-ci.sh +++ b/.scripts/k8s-ci.sh @@ -1,7 +1,7 @@ #!/bin/bash .scripts/k8s-up.sh $1 -.scripts/k8s-smoke.sh +.scripts/k8s-smoke.sh $1 code=$? .scripts/k8s-down.sh exit $code diff --git a/.scripts/k8s-smoke.sh b/.scripts/k8s-smoke.sh index 5320c90..92707ee 100755 --- a/.scripts/k8s-smoke.sh +++ b/.scripts/k8s-smoke.sh @@ -1,11 +1,14 @@ #!/bin/bash +env="${1:-dev}" +port="${2:-80}" + retry=60 code=1 until [[ $retry -le 0 || $code -eq 0 ]] do kubectl get all - .scripts/smoke.sh 80 + ( cd ./test/${env}; ./smoke.sh $port ) code=$? diff --git a/.scripts/query.sh b/.scripts/query.sh index c28a4ef..60d7224 100755 --- a/.scripts/query.sh +++ b/.scripts/query.sh @@ -2,6 +2,24 @@ PORT="${1:-4000}" +read -r -d '' QUERY <<"EOF" +{ + allProducts { + id, + sku, + createdBy { + email, + totalProductsCreated + } + } +} +EOF + +QUERY=$(echo "${QUERY}" | awk -v ORS= -v OFS= '{$1=$1}1') + echo ------------------------------------------------------------------------------------------- -(set -x; curl -X POST -H 'Content-Type: application/json' --data '{ "query": "{ allProducts { id, sku, createdBy { email, totalProductsCreated } } }" }' http://localhost:$PORT/) +ACT=$(set -x; curl -X POST -H 'Content-Type: application/json' --data '{ "query": "'"${QUERY}"'" }' http://localhost:$PORT/) +echo "" +echo "Result:" +echo "$ACT" echo ------------------------------------------------------------------------------------------- diff --git a/.scripts/smoke.sh b/.scripts/smoke.sh deleted file mode 100755 index bca3ba5..0000000 --- a/.scripts/smoke.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -PORT="${1:-4000}" - -echo Smoke test - -sleep 2 - -echo ------------------------------------------------------------------------------------------- -ACT=$(set -x; curl -X POST -H 'Content-Type: application/json' --data '{ "query": "{ allProducts { id, sku, createdBy { email, totalProductsCreated } } }" }' http://localhost:$PORT/) -EXP='{"data":{"allProducts":[{"id":"apollo-federation","sku":"federation","createdBy":{"email":"support@apollographql.com","totalProductsCreated":1337}},{"id":"apollo-studio","sku":"studio","createdBy":{"email":"support@apollographql.com","totalProductsCreated":1337}}]}}' -echo $ACT -if [ "$ACT" = "$EXP" ]; then - echo "Success!" -else - echo "Error: query failed" - echo " - got:$ACT" - echo " - expecting:$EXP" - echo ------------------------------------------------------------------------------------------- - exit 1 -fi -echo ------------------------------------------------------------------------------------------- diff --git a/Makefile b/Makefile index ee1faad..3659f39 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ .PHONY: default -default: demo-k8s +default: demo -.PHONY: demo-k8s -demo-k8s: k8s-up-dev k8s-smoke k8s-down +.PHONY: demo +demo: k8s-up-dev smoke k8s-down .PHONY: k8s-up k8s-up: @@ -20,13 +20,25 @@ k8s-up-stage: k8s-up-prod: .scripts/k8s-up.sh prod -.PHONY: k8s-query -k8s-query: +.PHONY: query +query: .scripts/query.sh 80 -.PHONY: k8s-smoke -k8s-smoke: - .scripts/k8s-smoke.sh 80 +.PHONY: smoke +smoke: + .scripts/k8s-smoke.sh + +.PHONY: smoke-dev +smoke-dev: + .scripts/k8s-smoke.sh dev + +.PHONY: smoke-stage +smoke-stage: + .scripts/k8s-smoke.sh stage + +.PHONY: smoke-prod +smoke-prod: + .scripts/k8s-smoke.sh prod .PHONY: k8s-nginx-dump k8s-nginx-dump: @@ -99,9 +111,11 @@ promote-dev-stage: cp infra/dev/kustomization.yaml infra/stage cp subgraphs/dev/kustomization.yaml subgraphs/stage cp router/dev/kustomization.yaml router/stage + cp test/dev/smoke.sh test/stage .PHONY: promote-stage-prod promote-stage-prod: cp infra/stage/kustomization.yaml infra/prod cp subgraphs/stage/kustomization.yaml subgraphs/prod cp router/stage/kustomization.yaml router/prod + cp test/stage/smoke.sh test/prod diff --git a/README.md b/README.md index feaa74a..a45a6b2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Kubernetes-native GraphOps -This is the `config repo` for the [apollographq/supergraph-demo](https://github.com/apollographql/supergraph-demo) `source repo`. +This is the `GraphOps Repo` for the [apollographq/supergraph-demo](https://github.com/apollographql/supergraph-demo) `Source Repo`. ![CI](https://github.com/apollographql/supergraph-demo-gitops/actions/workflows/main.yml/badge.svg) @@ -22,94 +22,112 @@ Contents: Large-scale graph operators use Kubernetes to run their Graph Router and Subgraph Services, with continuous app and service delivery. -Kubernetes provides a mature control-plane for deploying and operating your graph using container images like those produced by the [supergraph-demo](https://github.com/apollographql/supergraph-demo) `source repo`. +Kubernetes provides a mature control-plane for deploying and operating your graph using container images like those produced by the [supergraph-demo](https://github.com/apollographql/supergraph-demo) `Source Repo`. ## Overview This repo follows the [Declarative GitOps CD for Kubernetes Best Practices](https://argoproj.github.io/argo-cd/user-guide/best_practices/): -`source repo` - provides docker images via `Bump image versions` PR +`Source Repo` - provides image tag versions via `Bump image versions` PR * [apollographql/supergraph-demo](https://github.com/apollographql/supergraph-demo) produces the artifacts: - * subgraph docker images w/ embedded subgraph schemas - * supergraph-router docker image that can be fed a composed supergraph schema via + * Subgraph docker images w/ embedded subgraph schemas + * Supergraph-router docker image that can be fed a composed supergraph schema via * (a) Apollo Uplink - for update in place * (b) via a `ConfigMap` for declarative k8s config management -* continuous integration: - * auto bumps package version numbers & container tags. - * builds/publishes container images to container registry. +* Continuous integration: + * Bumps package version numbers & container tags. + * Builds/publishes container images to container registry. * `Bump image versions` PRs to propagate image version bumps to this repo. + * see end of the [example artifact release workflow](https://github.com/apollographql/supergraph-demo/blob/main/.github/workflows/release.yml) -`graph registry` - provides supergraph schema via `Bump supergraph schema` PR +`Graph Registry` - provides supergraph schema via `Bump supergraph schema` PR -* Managed Federation publishes supergraph schemas to the Apollo Registry - * subgraphs publish their schema to the Apollo Registry after deployment. - * Apollo Studio composes subgraph schemas into a supergraph schema - * Apollo Studio runs a suite of schema checks and operation checks prior to publishing the supergraph schema for use. +* Graph schemas published to the Apollo Registry + * Subgraphs publish their schema to the Apollo Registry after deployment. + * Supergraph schema is published after Apollo Studio does: + * Managed composition + * Schema checks + * Operation checks + * No breaking changes are detected * Published supergraph schemas are made available via: * `Apollo Uplink` - that the Gateway can poll for live updates (default). * `Apollo Registry` - for retrieval via `rover supergraph fetch`. * `Apollo Build Webhook` - for triggering custom CD with the composed supergraph schema. -* `Bump supergraph schema` PRs are created by the [supergraph-build-webhook.yml workflow](https://github.com/apollographql/supergraph-demo-k8s-graphops/blob/main/.github/workflows/supergraph-build-webhook.yml): - * run immediately when triggered by the Apollo Build Webhook - * run on a schedule, to poll in case a webhook is lost - -`config repo` (this repo) - receives image and schema versions from above - -* has the full k8s configs for dev, stage, and prod environments: - * cluster - base cluster & GitOps config - * infra - nginx, etc. - * router - supergraph router config - * subgraphs - products, inventory, users -* supports promoting config from dev -> stage -> prod +* `Bump supergraph schema` PRs are created by the [supergraph-build-webhook.yml workflow](https://github.com/apollographql/supergraph-demo-k8s-graphops/blob/main/.github/workflows/supergraph-build-webhook.yml) via: + * Supergraph build webhook from Apollo Studio + * Polling on a schedule in case a webhook is lost + +`GraphOps Repo` (this repo) - declarative graph config for Kubernetes for GitOps + +* Declarative k8s configs for `dev`, `stage`, and `prod` + * [./clusters](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/tree/main/clusters) - base cluster & GitOps config + * [./infra](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/tree/main/infra) - nginx, etc. + * [./router](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/tree/main/router) - supergraph router config + * [./subgraphs](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/tree/main/subgraphs) - products, inventory, users +* Promote config from `dev` -> `stage` -> `prod` * `make promote-dev-stage` * `make promote-stage-prod` -* continous deployment: +* Continuous deployment: * via GitOps operators like [Flux](https://fluxcd.io/) and [ArgoCD](https://argoproj.github.io/argo-cd/) * using progressive delivery controllers like [Argo Rollouts](https://argoproj.github.io/argo-rollouts/) and [Flagger](https://flagger.app/) * or your favorite tools! -`kustomize` is used for k8s-native config management: +`kustomize` for k8s-native config management: -* [https://kustomize.io/](https://kustomize.io/). +* [https://kustomize.io/](https://kustomize.io/) * [kustomize helm example](https://github.com/fluxcd/flux2-kustomize-helm-example) * [multi-tenancy example](https://github.com/fluxcd/flux2-multi-tenancy) * [best-practices discussion thread](https://github.com/fluxcd/flux/issues/1071) ## Config Flow -This `config repo` contains the Kubernetes config resources for `dev`, `stage` and `prod` environments. - -* `Bump image versions` PR is opened (auto-merge): - * when new Gateway docker image versions are published: - * see end of the [example monorepo release workflow](https://github.com/apollographql/supergraph-demo/blob/main/.github/workflows/release.yml) - * bumps package versions in this `source repo`. - * does an incremental monorepo build and pushes new docker images to DockerHub. - * opens `config repo` PR to bump the docker image versions in the `dev` environment (auto-merge). -* `Bump supergraph schema` PR is opened (auto-merge): - * when Managed Federation sends a supergraph schema build webhook - * `rover supergraph fetch` is used to retrieve the supergraph schema from the Apollo Registry -* `kustomize` the config resource for each environment: - * new supergraph `ConfigMap` - * updated Gateway `Deployment` which references - * supergraph `ConfigMap` - * Gateway image versions -* `Deploy` via: - * `kubectl apply` in place - resulting in a [rolling upgrade](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/configGeneration.md) - * GitOps tools like [ArgoCD](https://argoproj.github.io/) and [Flux](https://fluxcd.io/) - * Progressive delivery controllers like [Argo Rollouts](https://argoproj.github.io/argo-rollouts/) or [Flagger](https://flagger.app/) - * Supports `BlueGreen` and `Canary` deployment strategies -* `Rollback` via git and deploy as usual +Config data flows from the following sources: + +* `Source Repo`: + * `Bump image versions` PR is opened on the `GraphOps Repo`: + * when new Gateway docker image versions are published: + * see end of the [example artifact release workflow](https://github.com/apollographql/supergraph-demo/blob/main/.github/workflows/release.yml) + * bumps package versions in the `Source Repo`. + * does an incremental monorepo build and pushes new docker images to DockerHub. + * opens `GraphOps Repo` PR to bump the docker image versions in the `dev` environment (auto-merge). + +* `Graph Registry`: + * `Bump supergraph schema` PR is opened on the `GraphOps Repo`: + * when Managed Federation sends a supergraph schema build webhook + * `rover supergraph fetch` is used to retrieve the supergraph schema from the Apollo Registry. + +* `GraphOps Repo`: + * GraphOps team crafts the declarative configurations for each environment. + * [./clusters](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/tree/main/clusters) - base cluster & GitOps config + * [./infra](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/tree/main/infra) - nginx, etc. + * [./router](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/tree/main/router) - supergraph router config + * [./subgraphs](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/tree/main/subgraphs) - products, inventory, users + * PRs for [docker image bumps](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/pull/42) are (auto-)merged into the `GraphOps Repo`. + * PR for [supergraph schema bumps](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/pull/36) are (auto-)merged into the `GraphOps Repo`. + * `GraphOps Repo` has definitive desired state for each environment. + +Continous deployment of config data flows from the `GraphOps Repo` into the target k8s cluster: + +* Via `kubectl apply -k` or GitOps tools like [ArgoCD](https://argoproj.github.io/argo-cd/user-guide/kustomize/) or [Flux](https://fluxcd.io/docs/components/kustomize/) + +* `kustomize` is used to generate parameterized config resources for each environment: + * for example: [./router/dev/kustomization.yaml](https://github.com/apollographql/supergraph-demo-k8s-graph-ops/blob/main/router/dev/kustomization.yaml) + * `configMapGenerator` supergraph.graphl schema + * `images` with tag version bumps +* Progressive delivery controllers like [Argo Rollouts](https://argoproj.github.io/argo-rollouts/) or [Flagger](https://flagger.app/) may also be used + * `BlueGreen` and `Canary` deployment strategies +* `Rollback` via git commit & GitOps or progressive delivery controller [rollback](https://argoproj.github.io/argo-rollouts/FAQ.html#how-does-bluegreen-rollback-work). ## Docker Images from Source Repo -New Gateway docker image versions are published as source changes are push to the main branch of the [supergraph-demo](https://github.com/apollographql/supergraph-demo) repo. +New Gateway docker image versions are published as source changes are pushed to the main branch of the [supergraph-demo](https://github.com/apollographql/supergraph-demo) repo. This is done by the [release.yml workflow](https://github.com/apollographql/supergraph-demo/blob/main/.github/workflows/release.yml), which does an incremental matrix build and pushes new docker images to DockerHub, and then opens a `Bump image versions` PR in this repo that uses `kustomize edit set image` to inject the new image version tags into the [kustomization.yaml](https://github.com/apollographql/supergraph-demo-k8s-graphops/blob/main/router/dev/kustomization.yaml) for each environment. ![publish-artifacts-workflow](docs/media/publish-artifacts-workflow.png) -Note: This workflow can be easily adapted for a single repo per package scenarios, where they separately publish their own docker images. +**Note: This workflow can be easily adapted for a single-repo-per-package scenarios, where they separately publish their own docker images and issue separate version bump PRs to this `GraphOps Repo`.** ## Supergraph Schemas from Graph Registry @@ -122,7 +140,7 @@ Note: This workflow can be easily adapted for a single repo per package scenario 2. `Bump supergraph schema` PR with auto-merge enabled when changes detected * Workflow: [supergraph-build-webhook.yml](https://github.com/apollographql/supergraph-demo-k8s-graphops/blob/main/.github/workflows/supergraph-build-webhook.yml) - * Commits a new supergraph.graphql to the `config repo` with the new version from Apollo Studio + * Commits a new supergraph.graphql to the `GraphOps Repo` with the new version from Apollo Studio * Additional CI checks on the supergraph schema are required for the PR to merge * Auto-merged when CI checks pass @@ -160,7 +178,7 @@ You'll need: then run: ```sh -make demo-k8s +make demo ``` which runs: @@ -328,7 +346,7 @@ spec: and 3 subgraph services [subgraphs/base/subgraphs.yaml](subgraphs/base/subgraphs.yaml): -`make demo-k8s` then runs the following in a loop until the query succeeds or 2 min timeout: +`make demo` then runs the following in a loop until the query succeeds or 2 min timeout: ### Make a GraphQL Query @@ -377,7 +395,7 @@ Success! ### Cleanup -`make demo-k8s` then cleans up: +`make demo` then cleans up: ``` deployment.apps "graph-router" deleted @@ -395,7 +413,7 @@ Promoting configs from from dev -> stage -> prod can be as simple as: * `make promote-stage-prod` 1. push the changes -The GitOps operator in each Kubernetes cluster will pull the environment configuration from this `config repo` and any changes will be applied to that cluster. +The GitOps operator in each Kubernetes cluster will pull the environment configuration from this `GraphOps Repo` and any changes will be applied to that cluster. ## GitOps & Progressive Delivery @@ -409,6 +427,6 @@ Example coming soon! ## Learn More -Checkout the [apollographq/supergraph-demo](https://github.com/apollographql/supergraph-demo) `source repo`. +Checkout the [apollographq/supergraph-demo](https://github.com/apollographql/supergraph-demo) `Source Repo`. Learn more about [how Apollo can help your teams ship faster](https://www.apollographql.com/docs/studio/). diff --git a/docs/media/webhook-proxy.png b/docs/media/webhook-proxy.png index b156647..94c7215 100644 Binary files a/docs/media/webhook-proxy.png and b/docs/media/webhook-proxy.png differ diff --git a/router/prod/kustomization.yaml b/router/prod/kustomization.yaml index ee8e253..1df0d65 100644 --- a/router/prod/kustomization.yaml +++ b/router/prod/kustomization.yaml @@ -10,4 +10,4 @@ resources: images: - name: prasek/supergraph-router:latest newName: prasek/supergraph-router - newTag: 1.1.1 + newTag: 1.1.4 diff --git a/router/stage/kustomization.yaml b/router/stage/kustomization.yaml index ee8e253..1df0d65 100644 --- a/router/stage/kustomization.yaml +++ b/router/stage/kustomization.yaml @@ -10,4 +10,4 @@ resources: images: - name: prasek/supergraph-router:latest newName: prasek/supergraph-router - newTag: 1.1.1 + newTag: 1.1.4 diff --git a/subgraphs/prod/kustomization.yaml b/subgraphs/prod/kustomization.yaml index ada9e25..33fb6d5 100644 --- a/subgraphs/prod/kustomization.yaml +++ b/subgraphs/prod/kustomization.yaml @@ -5,10 +5,10 @@ resources: images: - name: prasek/subgraph-inventory:latest newName: prasek/subgraph-inventory - newTag: 1.1.1 + newTag: 1.1.10 - name: prasek/subgraph-products:latest newName: prasek/subgraph-products - newTag: 1.1.1 + newTag: 1.1.5 - name: prasek/subgraph-users:latest newName: prasek/subgraph-users - newTag: 1.1.1 + newTag: 1.1.9 diff --git a/subgraphs/stage/kustomization.yaml b/subgraphs/stage/kustomization.yaml index f61b375..33fb6d5 100644 --- a/subgraphs/stage/kustomization.yaml +++ b/subgraphs/stage/kustomization.yaml @@ -5,10 +5,10 @@ resources: images: - name: prasek/subgraph-inventory:latest newName: prasek/subgraph-inventory - newTag: 1.1.5 + newTag: 1.1.10 - name: prasek/subgraph-products:latest newName: prasek/subgraph-products - newTag: 1.1.1 + newTag: 1.1.5 - name: prasek/subgraph-users:latest newName: prasek/subgraph-users - newTag: 1.1.4 + newTag: 1.1.9 diff --git a/test/dev/smoke.sh b/test/dev/smoke.sh new file mode 100755 index 0000000..1d48b81 --- /dev/null +++ b/test/dev/smoke.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +PORT="${1:-80}" +TESTS=(1 2) +OK_CHECK="\xE2\x9C\x85" +FAIL_MARK="\xE2\x9D\x8C" +ROCKET="\xF0\x9F\x9A\x80" + +# -------------------------------------------------------------------- +# QUERY 1 +# -------------------------------------------------------------------- +read -r -d '' QUERY_1 <<"EOF" +{ + allProducts { + delivery { + estimatedDelivery, + fastestDelivery + }, + createdBy { + name, + email + } + } +} +EOF + +read -r -d '' EXP_1 <<"EOF" +{"data":{"allProducts":[{"delivery":{"estimatedDelivery":"6/25/2021","fastestDelivery":"6/24/2021"},"createdBy":{"name":"Apollo Studio Support","email":"support@apollographql.com"}},{"delivery":{"estimatedDelivery":"6/25/2021","fastestDelivery":"6/24/2021"},"createdBy":{"name":"Apollo Studio Support","email":"support@apollographql.com"}}]}} +EOF + +# -------------------------------------------------------------------- +# QUERY 2 +# -------------------------------------------------------------------- +read -r -d '' QUERY_2 <<"EOF" +{ + allProducts { + id, + sku, + createdBy { + email, + totalProductsCreated + } + } +} +EOF + +read -r -d '' EXP_2 <<"EOF" +{"data":{"allProducts":[{"id":"apollo-federation","sku":"federation","createdBy":{"email":"support@apollographql.com","totalProductsCreated":1337}},{"id":"apollo-studio","sku":"studio","createdBy":{"email":"support@apollographql.com","totalProductsCreated":1337}}]}} +EOF + +set -e + +echo Running smoke tests ... +sleep 2 + +for test in ${TESTS[@]}; do + echo "" + echo ------------------------- + echo Test $test + echo ------------------------- + query_var="QUERY_$test" + exp_var="EXP_$test" + QUERY=$(echo "${!query_var}" | awk -v ORS= -v OFS= '{$1=$1}1') + EXP="${!exp_var}" + ACT=$(set -x; curl -X POST -H 'Content-Type: application/json' --data '{ "query": "'"${QUERY}"'" }' http://localhost:$PORT/) + if [ "$ACT" = "$EXP" ]; then + echo "" + echo "Result:" + echo "$ACT" + echo "" + printf "$OK_CHECK Test ${test} \n" + else + echo ------------------------- + printf "$FAIL_MARK Test $test\n" + echo ------------------------- + echo "[Expected]" + echo "$EXP" + echo ------------------------- + echo "[Actual]" + echo "$ACT" + echo ------------------------- + printf "$FAIL_MARK Test $test\n" + echo ------------------------- + exit 1 + fi +done +echo "" +printf "$OK_CHECK All tests pass! $ROCKET\n" diff --git a/test/prod/smoke.sh b/test/prod/smoke.sh new file mode 100755 index 0000000..1d48b81 --- /dev/null +++ b/test/prod/smoke.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +PORT="${1:-80}" +TESTS=(1 2) +OK_CHECK="\xE2\x9C\x85" +FAIL_MARK="\xE2\x9D\x8C" +ROCKET="\xF0\x9F\x9A\x80" + +# -------------------------------------------------------------------- +# QUERY 1 +# -------------------------------------------------------------------- +read -r -d '' QUERY_1 <<"EOF" +{ + allProducts { + delivery { + estimatedDelivery, + fastestDelivery + }, + createdBy { + name, + email + } + } +} +EOF + +read -r -d '' EXP_1 <<"EOF" +{"data":{"allProducts":[{"delivery":{"estimatedDelivery":"6/25/2021","fastestDelivery":"6/24/2021"},"createdBy":{"name":"Apollo Studio Support","email":"support@apollographql.com"}},{"delivery":{"estimatedDelivery":"6/25/2021","fastestDelivery":"6/24/2021"},"createdBy":{"name":"Apollo Studio Support","email":"support@apollographql.com"}}]}} +EOF + +# -------------------------------------------------------------------- +# QUERY 2 +# -------------------------------------------------------------------- +read -r -d '' QUERY_2 <<"EOF" +{ + allProducts { + id, + sku, + createdBy { + email, + totalProductsCreated + } + } +} +EOF + +read -r -d '' EXP_2 <<"EOF" +{"data":{"allProducts":[{"id":"apollo-federation","sku":"federation","createdBy":{"email":"support@apollographql.com","totalProductsCreated":1337}},{"id":"apollo-studio","sku":"studio","createdBy":{"email":"support@apollographql.com","totalProductsCreated":1337}}]}} +EOF + +set -e + +echo Running smoke tests ... +sleep 2 + +for test in ${TESTS[@]}; do + echo "" + echo ------------------------- + echo Test $test + echo ------------------------- + query_var="QUERY_$test" + exp_var="EXP_$test" + QUERY=$(echo "${!query_var}" | awk -v ORS= -v OFS= '{$1=$1}1') + EXP="${!exp_var}" + ACT=$(set -x; curl -X POST -H 'Content-Type: application/json' --data '{ "query": "'"${QUERY}"'" }' http://localhost:$PORT/) + if [ "$ACT" = "$EXP" ]; then + echo "" + echo "Result:" + echo "$ACT" + echo "" + printf "$OK_CHECK Test ${test} \n" + else + echo ------------------------- + printf "$FAIL_MARK Test $test\n" + echo ------------------------- + echo "[Expected]" + echo "$EXP" + echo ------------------------- + echo "[Actual]" + echo "$ACT" + echo ------------------------- + printf "$FAIL_MARK Test $test\n" + echo ------------------------- + exit 1 + fi +done +echo "" +printf "$OK_CHECK All tests pass! $ROCKET\n" diff --git a/test/stage/smoke.sh b/test/stage/smoke.sh new file mode 100755 index 0000000..1d48b81 --- /dev/null +++ b/test/stage/smoke.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +PORT="${1:-80}" +TESTS=(1 2) +OK_CHECK="\xE2\x9C\x85" +FAIL_MARK="\xE2\x9D\x8C" +ROCKET="\xF0\x9F\x9A\x80" + +# -------------------------------------------------------------------- +# QUERY 1 +# -------------------------------------------------------------------- +read -r -d '' QUERY_1 <<"EOF" +{ + allProducts { + delivery { + estimatedDelivery, + fastestDelivery + }, + createdBy { + name, + email + } + } +} +EOF + +read -r -d '' EXP_1 <<"EOF" +{"data":{"allProducts":[{"delivery":{"estimatedDelivery":"6/25/2021","fastestDelivery":"6/24/2021"},"createdBy":{"name":"Apollo Studio Support","email":"support@apollographql.com"}},{"delivery":{"estimatedDelivery":"6/25/2021","fastestDelivery":"6/24/2021"},"createdBy":{"name":"Apollo Studio Support","email":"support@apollographql.com"}}]}} +EOF + +# -------------------------------------------------------------------- +# QUERY 2 +# -------------------------------------------------------------------- +read -r -d '' QUERY_2 <<"EOF" +{ + allProducts { + id, + sku, + createdBy { + email, + totalProductsCreated + } + } +} +EOF + +read -r -d '' EXP_2 <<"EOF" +{"data":{"allProducts":[{"id":"apollo-federation","sku":"federation","createdBy":{"email":"support@apollographql.com","totalProductsCreated":1337}},{"id":"apollo-studio","sku":"studio","createdBy":{"email":"support@apollographql.com","totalProductsCreated":1337}}]}} +EOF + +set -e + +echo Running smoke tests ... +sleep 2 + +for test in ${TESTS[@]}; do + echo "" + echo ------------------------- + echo Test $test + echo ------------------------- + query_var="QUERY_$test" + exp_var="EXP_$test" + QUERY=$(echo "${!query_var}" | awk -v ORS= -v OFS= '{$1=$1}1') + EXP="${!exp_var}" + ACT=$(set -x; curl -X POST -H 'Content-Type: application/json' --data '{ "query": "'"${QUERY}"'" }' http://localhost:$PORT/) + if [ "$ACT" = "$EXP" ]; then + echo "" + echo "Result:" + echo "$ACT" + echo "" + printf "$OK_CHECK Test ${test} \n" + else + echo ------------------------- + printf "$FAIL_MARK Test $test\n" + echo ------------------------- + echo "[Expected]" + echo "$EXP" + echo ------------------------- + echo "[Actual]" + echo "$ACT" + echo ------------------------- + printf "$FAIL_MARK Test $test\n" + echo ------------------------- + exit 1 + fi +done +echo "" +printf "$OK_CHECK All tests pass! $ROCKET\n"