From 812b76b357aea4e317b8b34cf9599a8f8b438b4e Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Tue, 2 Jul 2024 10:50:35 -0500 Subject: [PATCH] Working e2e Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> --- .github/workflows/ci.yaml | 9 +- docker-compose.yml | 206 ++++++++++++++++++-------------------- internal/testing/e2e/e2e | 126 +++++++++-------------- 3 files changed, 148 insertions(+), 193 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c3230f72d88..41bc5e231d5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -150,14 +150,15 @@ jobs: - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d with: python-version: '3.10' + - name: Print Bash version + run: bash --version - name: Install dependencies run: | go mod download pip install gql[all] - - name: Set up JetStream - uses: nats-io/jetstream-gh-action@v1 - with: - nats_version: '2.9.17' + - name: Set up NATS Server with JetStream + run: | + docker run -d --name nats-server -p 4222:4222 -p 8222:8222 nats:2.9.17 -js - name: Wait for PostgreSQL to be ready run: | until pg_isready -h localhost -p 5432 -U guac -d guac; do diff --git a/docker-compose.yml b/docker-compose.yml index d769ba7361a..94fdf817405 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,120 +25,106 @@ services: timeout: 10s retries: 3 start_period: 5s - postgres: - image: docker.io/library/postgres:16 + + guac-collectsub: + networks: [ frontend ] + image: $GUAC_IMAGE + command: "/opt/guac/guaccsub" + working_dir: /guac + restart: on-failure + ports: + - "2782:2782" + depends_on: + nats: + condition: service_healthy + volumes: + - ./container_files/guac:/guac:z + healthcheck: + test: [ "CMD", "wget", "--spider", "http://localhost:2782" ] + interval: 10s + timeout: 10s + retries: 3 + start_period: 5s + + guac-ingestor: + networks: [ frontend ] + image: $GUAC_IMAGE + command: "/opt/guac/guacingest" + working_dir: /guac + restart: on-failure + depends_on: + guac-collectsub: + condition: service_healthy + volumes: + - ./container_files/guac:/guac:z + - blobstore:/tmp/blobstore + + oci-collector: + networks: [ frontend ] + image: $GUAC_IMAGE + command: "/opt/guac/guaccollect image" + working_dir: /guac + restart: on-failure + depends_on: + guac-collectsub: + condition: service_healthy + volumes: + - ./container_files/guac:/guac:z + - blobstore:/tmp/blobstore + + depsdev-collector: + networks: [ frontend ] + image: $GUAC_IMAGE + command: "/opt/guac/guaccollect deps_dev" + working_dir: /guac + restart: on-failure environment: - POSTGRES_USER: guac - POSTGRES_PASSWORD: guac + - DEPS_DEV_APIKEY + depends_on: + guac-collectsub: + condition: service_healthy + volumes: + - ./container_files/guac:/guac:z + - blobstore:/tmp/blobstore + ports: + - "9091:9091" # for prometheus metrics + + osv-certifier: + networks: [ frontend ] + image: $GUAC_IMAGE + command: "/opt/guac/guacone certifier osv" + working_dir: /guac + restart: on-failure + depends_on: + guac-collectsub: + condition: service_healthy + volumes: + - ./container_files/guac:/guac:z + guac-rest: + networks: [ frontend ] + image: $GUAC_IMAGE + command: "/opt/guac/guacrest" + working_dir: /guac + restart: on-failure + ports: + - "8081:8081" volumes: - - ./postgres-data:/var/lib/postgresql/data:z + - ./container_files/guac:/guac:z + depends_on: + guac-graphql: + condition: service_healthy healthcheck: - test: [ "CMD", "pg_isready", "--username=guac", "--dbname=guac" ] + test: + [ + "CMD", + "wget", + "--spider", + "http://localhost:8081/healthz" + ] interval: 10s - timeout: 5s - retries: 5 - start_period: 10s -# -# guac-collectsub: -# networks: [ frontend ] -# image: $GUAC_IMAGE -# command: "/opt/guac/guaccsub" -# working_dir: /guac -# restart: on-failure -# ports: -# - "2782:2782" -# depends_on: -# nats: -# condition: service_healthy -# volumes: -# - ./container_files/guac:/guac:z -# healthcheck: -# test: [ "CMD", "wget", "--spider", "http://localhost:2782" ] -# interval: 10s -# timeout: 10s -# retries: 3 -# start_period: 5s -# -# guac-ingestor: -# networks: [ frontend ] -# image: $GUAC_IMAGE -# command: "/opt/guac/guacingest" -# working_dir: /guac -# restart: on-failure -# depends_on: -# guac-collectsub: -# condition: service_healthy -# volumes: -# - ./container_files/guac:/guac:z -# - blobstore:/tmp/blobstore -# -# oci-collector: -# networks: [ frontend ] -# image: $GUAC_IMAGE -# command: "/opt/guac/guaccollect image" -# working_dir: /guac -# restart: on-failure -# depends_on: -# guac-collectsub: -# condition: service_healthy -# volumes: -# - ./container_files/guac:/guac:z -# - blobstore:/tmp/blobstore -# -# depsdev-collector: -# networks: [ frontend ] -# image: $GUAC_IMAGE -# command: "/opt/guac/guaccollect deps_dev" -# working_dir: /guac -# restart: on-failure -# environment: -# - DEPS_DEV_APIKEY -# depends_on: -# guac-collectsub: -# condition: service_healthy -# volumes: -# - ./container_files/guac:/guac:z -# - blobstore:/tmp/blobstore -# ports: -# - "9091:9091" # for prometheus metrics -# -# osv-certifier: -# networks: [ frontend ] -# image: $GUAC_IMAGE -# command: "/opt/guac/guacone certifier osv" -# working_dir: /guac -# restart: on-failure -# depends_on: -# guac-collectsub: -# condition: service_healthy -# volumes: -# - ./container_files/guac:/guac:z -# -# guac-rest: -# networks: [ frontend ] -# image: $GUAC_IMAGE -# command: "/opt/guac/guacrest" -# working_dir: /guac -# restart: on-failure -# ports: -# - "8081:8081" -# volumes: -# - ./container_files/guac:/guac:z -# depends_on: -# guac-graphql: -# condition: service_healthy -# healthcheck: -# test: -# [ -# "CMD", -# "wget", -# "--spider", -# "http://localhost:8081/healthz" -# ] -# interval: 10s -# timeout: 10s -# retries: 3 -# start_period: 5s + timeout: 10s + retries: 3 + start_period: 5s networks: diff --git a/internal/testing/e2e/e2e b/internal/testing/e2e/e2e index 07b568e0e88..2bda19c31ff 100755 --- a/internal/testing/e2e/e2e +++ b/internal/testing/e2e/e2e @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/env bash # # Copyright 2023 The GUAC Authors. @@ -42,9 +42,9 @@ git checkout $guac_data_hash popd popd -#echo @@@@ Starting up guac server in background -#go run "${GUAC_DIR}/cmd/guacgql --gql-backend=ent" & -# +echo @@@@ Starting up guac server in background +go run "${GUAC_DIR}/cmd/guacgql --gql-backend=ent" & + echo -n "Waiting for guac server to start" set +e for _ in {1..36} ; do @@ -92,9 +92,9 @@ wipe_data() { fi } -#go run ${GUAC_DIR}"/cmd/guacingest --add-vuln-on-ingest=true" & -#go run ${GUAC_DIR}"/cmd/guacone collect deps_dev -p" & -#go run ${GUAC_DIR}"/cmd/guaccsub" & +go run ${GUAC_DIR}"/cmd/guacingest --add-vuln-on-ingest=true" & +go run ${GUAC_DIR}"/cmd/guacone collect deps_dev -p" & +go run ${GUAC_DIR}"/cmd/guaccsub" & # Define ingestion commands declare -a ingestion_commands=( @@ -102,19 +102,34 @@ declare -a ingestion_commands=( "go run ${GUAC_DIR}/cmd/guaccollect files ${GUAC_DIR}/guac-data/docs/ --service-poll=false" ) -#declare -A queries -# -#queries["PkgQ1"]=' .packages |= sort ' -#queries["PkgQ2"]=' .packages[].namespaces |= sort ' -#queries["PkgQ3"]=' .packages[].namespaces |= sort_by(.namespace) | .packages[].namespaces[].names[].versions |= sort_by(.id) | .packages[].namespaces[].names[].versions[].qualifiers |= sort_by(.key) | del(.. | .id?) ' -#queries["PkgQ4"]=' del(.. | .id?) ' -#queries["IsDependencyQ1"]=' .IsDependency |= sort ' -#queries["IsDependencyQ2"]='del(.. | .id?) | del(.. | .origin?)' -#queries["PathQ1"]='del(.. | .id?) | del(.. | .origin?)' -#queries["OSVQ1"]='del(.. | .id?)' -#queries["CertifyVulnQ1"]='del(.. | .id?) | del(.. | .timeScanned?)' -#queries["ArtifactsQ1"]=' .artifacts |= sort ' -#queries["PkgQ9"]=' .packages[].namespaces |= sort_by(.namespace) | .packages[].namespaces[].names[].versions |= sort_by(.id) | .packages[].namespaces[].names[].versions[].qualifiers |= sort_by(.key) | del(.. | .id?) ' +declare -A queryValues + +queryValues["PkgQ1"]='.packages |= sort' +queryValues["PkgQ2"]='.packages[].namespaces |= sort' +queryValues["PkgQ3"]='.packages[].namespaces |= sort_by(.namespace) | .packages[].namespaces[].names[].versions |= sort_by(.purl) | .packages[].namespaces[].names[].versions[].qualifiers |= sort_by(.key) | del(.. | .id?)' +queryValues["PkgQ4"]='del(.. | .id?)' +queryValues["IsDependencyQ1"]='.IsDependency |= sort' +queryValues["IsDependencyQ2"]='del(.. | .id?) | del(.. | .origin?)' +queryValues["PathQ1"]='del(.. | .id?) | del(.. | .origin?)' +queryValues["OSVQ1"]='del(.. | .id?)' +queryValues["CertifyVulnQ1"]='del(.. | .id?) | del(.. | .timeScanned?)' +queryValues["ArtifactsQ1"]='.artifacts |= sort' +queryValues["PkgQ9"]='.packages[].namespaces |= sort_by(.namespace) | .packages[].namespaces[].names[].versions |= sort_by(.id) | .packages[].namespaces[].names[].versions[].qualifiers |= sort_by(.key) | del(.. | .id?)' + +# Define an indexed array to maintain the order of the queries +queryOrder=( + "PkgQ1" + "PkgQ2" + "PkgQ3" + "PkgQ4" + "IsDependencyQ1" + "IsDependencyQ2" + "PathQ1" + "OSVQ1" + "CertifyVulnQ1" + "ArtifactsQ1" + "PkgQ9" +) queries="${GUAC_DIR}/demo/graphql/queries.gql" @@ -135,74 +150,27 @@ for command in "${ingestion_commands[@]}"; do sleep 60 echo @@@@ Running queries and validating output -# for query in "${!queries[@]}"; do -# gql_query=$(gql-cli http://localhost:8080/query -o "$query") -# jq_filter="${queries[$query]}" -# echo "$gql_query" | jq "$jq_filter" > "${GUAC_DIR}/got${query}.json" -# diff -u "${SCRIPT_DIR}/expect${query}.json" "${GUAC_DIR}/got${query}.json" -# done - -# log_database_schema - - echo @@@@ Running query PkgQ1 | tee -a "$LOG_FILE" - gql-cli http://localhost:8080/query -o PkgQ1 < "$queries" | jq ' .packages |= sort ' > "${GUAC_DIR}/gotPkgQ1.json" - diff -u "${SCRIPT_DIR}/expectPkgQ1.json" "${GUAC_DIR}/gotPkgQ1.json" | tee -a "$LOG_FILE" - - echo @@@@ Running query PkgQ2 | tee -a "$LOG_FILE" - gql-cli http://localhost:8080/query -o PkgQ2 < "$queries" | jq ' .packages[].namespaces |= sort ' > "${GUAC_DIR}/gotPkgQ2.json" - diff -u "${SCRIPT_DIR}/expectPkgQ2.json" "${GUAC_DIR}/gotPkgQ2.json" | tee -a "$LOG_FILE" - - echo @@@@ Running query PkgQ3 | tee -a "$LOG_FILE" - gql-cli http://localhost:8080/query -o PkgQ3 < "$queries" | jq ' .packages[].namespaces |= sort_by(.namespace) | .packages[].namespaces[].names[].versions |= sort_by(.purl) | .packages[].namespaces[].names[].versions[].qualifiers |= sort_by(.key) | del(.. | .id?) ' > "${GUAC_DIR}/gotPkgQ3.json" - diff -u "${SCRIPT_DIR}/expectPkgQ3.json" "${GUAC_DIR}/gotPkgQ3.json" | tee -a "$LOG_FILE" - - echo @@@@ Running query PkgQ4 | tee -a "$LOG_FILE" - gql-cli http://localhost:8080/query -o PkgQ4 < "$queries" | jq ' del(.. | .id?) '> "${GUAC_DIR}/gotPkgQ4.json" - diff -u "${SCRIPT_DIR}/expectPkgQ4.json" "${GUAC_DIR}/gotPkgQ4.json" | tee -a "$LOG_FILE" - - echo @@@@ Running query IsDependencyQ1 | tee -a "$LOG_FILE" - gql-cli http://localhost:8080/query -o IsDependencyQ1 < "$queries" | jq ' .IsDependency |= sort ' > "${GUAC_DIR}/gotIsDependencyQ1.json" - diff -u "${SCRIPT_DIR}/expectIsDependencyQ1.json" "${GUAC_DIR}/gotIsDependencyQ1.json" | tee -a "$LOG_FILE" - echo @@@@ Running query IsDependencyQ2 | tee -a "$LOG_FILE" - gql-cli http://localhost:8080/query -o IsDependencyQ2 < "$queries" | jq 'del(.. | .id?) | del(.. | .origin?)' > "${GUAC_DIR}/gotIsDependencyQ2.json" - diff -u "${SCRIPT_DIR}/expectIsDependencyQ2.json" "${GUAC_DIR}/gotIsDependencyQ2.json" | tee -a "$LOG_FILE" - - echo @@@@ Running id one | tee -a "$LOG_FILE" id1=$(gql-cli http://localhost:8080/query -o PkgQ5 < "$queries" | jq -r ' .packages[0].namespaces[0].names[0].id ') - echo "id one: $id1" | tee -a "$LOG_FILE" - - echo @@@@ Running query id two | tee -a "$LOG_FILE" id2=$(gql-cli http://localhost:8080/query -o PkgQ6 < "$queries" | jq -r ' .packages[0].namespaces[0].names[0].id ') - echo "id two id: $id2" | tee -a "$LOG_FILE" - -# echo @@@@ Running query PathQ1 | tee -a "$LOG_FILE" -# gql-cli http://localhost:8080/query -o PathQ1 -V subject:"${id1}" target:"${id2}" < "$queries" | jq 'del(.. | .id?) | del(.. | .origin?)' > "${GUAC_DIR}/gotPathQ1.json" -# diff -u "${SCRIPT_DIR}/expectPathQ1.json" "${GUAC_DIR}/gotPathQ1.json" | tee -a "$LOG_FILE" - - echo @@@@ Running query OSVQ1 | tee -a "$LOG_FILE" - gql-cli http://localhost:8080/query -o OSVQ1 < "$queries" | jq 'del(.. | .id?)' > "${GUAC_DIR}/gotOSVQ1.json" - diff -u "${SCRIPT_DIR}/expectOSVQ1.json" "${GUAC_DIR}/gotOSVQ1.json" | tee -a "$LOG_FILE" - - echo @@@@ Running query CertifyVulnQ1 | tee -a "$LOG_FILE" - # Vulnerabilities are ingested during ingestion time, which causes the timestamp to be different, and for us to see multiple certify vulns - gql-cli http://localhost:8080/query -o CertifyVulnQ1 < "$queries" | jq 'del(.. | .id?) | del(.. | .timeScanned?)' > "${GUAC_DIR}/gotCertifyVulnQ1.json" - diff -u "${SCRIPT_DIR}/expectCertifyVulnQ1.json" "${GUAC_DIR}/gotCertifyVulnQ1.json" | tee -a "$LOG_FILE" - id3=$(gql-cli http://localhost:8080/query -o PkgQ7 < "$queries" | jq -r ' .packages[0].namespaces[0].names[0].id ') id4=$(gql-cli http://localhost:8080/query -o PkgQ8 < "$queries" | jq -r ' .packages[0].namespaces[0].names[0].versions[0].id ') + for query in "${queryOrder[@]}"; do + echo @@@@ Running query "$query" | tee -a "$LOG_FILE" + if [ "$query" == "PathQ1" ]; then + gql-cli http://localhost:8080/query -o "$query" -V subject:"${id1}" target:"${id2}" < "$queries" | jq "${queryValues[$query]}" > "${GUAC_DIR}/got${query}.json" + else + gql-cli http://localhost:8080/query -o "$query" < "$queries" | jq "${queryValues[$query]}" > "${GUAC_DIR}/got${query}.json" + fi + diff -u "${SCRIPT_DIR}/expect${query}.json" "${GUAC_DIR}/got${query}.json" | tee -a "$LOG_FILE" + done + + # Run the additional query that doesn't follow the same format + echo @@@@ Running query path.py | tee -a "$LOG_FILE" "${GUAC_DIR}/demo/graphql/path.py" "$id3" "$id4" | tail -n +2 | jq 'del(.. | .id?) | del(.. | .origin?) | del(.. | .qualifiers?)' > "${GUAC_DIR}/gotPathPy.json" diff -u "${SCRIPT_DIR}/expectPathPy.json" "${GUAC_DIR}/gotPathPy.json" | tee -a "$LOG_FILE" - echo @@@@ Running query ArtifactsQ1 | tee -a "$LOG_FILE" - gql-cli http://localhost:8080/query -o ArtifactsQ1 < "$queries" | jq ' .artifacts |= sort '> "${GUAC_DIR}/gotArtifactsQ1.json" - diff -u "${SCRIPT_DIR}/expectArtifactsQ1.json" "${GUAC_DIR}/gotArtifactsQ1.json" | tee -a "$LOG_FILE" - - echo @@@@ Running query PkgQ9 | tee -a "$LOG_FILE" - gql-cli http://localhost:8080/query -o PkgQ9 < "$queries" | jq ' .packages[].namespaces |= sort_by(.namespace) | .packages[].namespaces[].names[].versions |= sort_by(.id) | .packages[].namespaces[].names[].versions[].qualifiers |= sort_by(.key) | del(.. | .id?) ' > "${GUAC_DIR}/gotPkgQ9.json" - diff -u "${SCRIPT_DIR}/expectPkgQ9.json" "${GUAC_DIR}/gotPkgQ9.json" | tee -a "$LOG_FILE" - echo @@@@ Fully ingested command: "$command" | tee -a "$LOG_FILE" # Wipe data after each ingestion command