Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AUT-105: Add GitHub Workflows for building, integration and unit testing. #916

Merged
merged 10 commits into from
Jul 10, 2024
120 changes: 120 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: Tests
on:
push:
branches:
- main
pull_request:
branches:
- main

# Restrict tests to the most recent commit.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build Docker Images
runs-on: ubuntu-22.04
outputs:
testcases: ${{ steps.enum-tests.outputs.testcases }}
steps:
- name: Clone repository
uses: actions/checkout@v4

- name: Build images
shell: bash
run: make generate build

- name: Save images
shell: bash
run: |
mkdir -p docker-cache
docker save -o docker-cache/autograph-images.tar autograph-app autograph-app-hsm

- name: Enumerate tests
id: enum-tests
shell: bash
run: |
echo -n "testcases=" >> $GITHUB_OUTPUT
yq -o=json '.services | keys' tools/autograph-client/integration-tests.yml | jq -c >> $GITHUB_OUTPUT

- uses: actions/upload-artifact@v4
with:
name: autograph-images-${{ github.sha }}
path: docker-cache/

unit-tests:
name: Run Unit Tests
runs-on: ubuntu-22.04
needs:
- build
env:
DBNAME: autograph
PGPASSWORD: myautographdbpassword

services:
database:
image: postgres:11
env:
POSTGRES_DB: ${{ env.DBNAME }}
POSTGRES_PASSWORD: ${{ env.PGPASSWORD }}
POSTGRES_HOST_AUTH_METHOD: trust
ports:
- 5432:5432

steps:
- name: Clone repository
uses: actions/checkout@v4

- uses: actions/download-artifact@v4
with:
name: autograph-images-${{ github.sha }}
path: docker-cache/

- name: Initialize database
shell: bash
run: psql -h localhost -p 5432 -U postgres --no-password -f database/schema.sql ${{ env.DBNAME }}

- name: Load images
shell: bash
run: docker load -i docker-cache/autograph-images.tar

- name: Run Tests
shell: bash
env:
AUTOGRAPH_DB_DSN: postgres://myautographdbuser:${{ env.PGPASSWORD }}@localhost/${{ env.DBNAME }}?sslmode=disable
run: |
docker run \
--env AUTOGRAPH_DB_DSN \
--env RACE_TEST=0 \
--workdir /app/src/autograph \
--net=host \
--user 0 \
autograph-app ./bin/run_unit_tests.sh

integration-tests:
name: Run Integration Tests
runs-on: ubuntu-22.04
needs:
- build
strategy:
fail-fast: false # Don't cancel other jobs if a test fails
matrix:
testcase: ${{ fromJSON(needs.build.outputs.testcases) }}
steps:
- name: Clone repository
uses: actions/checkout@v4

- uses: actions/download-artifact@v4
with:
name: autograph-images-${{ github.sha }}
path: docker-cache/

- name: Load images
shell: bash
run: docker load -i docker-cache/autograph-images.tar

- name: Running ${{ matrix.testcase }}
shell: bash
run: docker compose -f tools/autograph-client/integration-tests.yml run ${{ matrix.testcase }}
33 changes: 13 additions & 20 deletions bin/run_integration_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,19 @@ docker cp autograph-app-hsm:/tmp/normandy_dev_root_hash.txt .
APP_HSM_NORMANDY_ROOT_HASH=$(grep '[0-9A-F]' normandy_dev_root_hash.txt | tr -d '\r\n')

# start the monitor lambda emulators
docker compose up -d monitor-lambda-emulator
AUTOGRAPH_ROOT_HASH=$APP_HSM_NORMANDY_ROOT_HASH docker compose up -d monitor-hsm-lambda-emulator

echo "waiting for monitor-lambda-emulator to start"
while test "true" != "$(docker inspect -f {{.State.Running}} autograph-monitor-lambda-emulator)"; do
echo -n "."
sleep 1 # wait before checking again
done
echo "waiting for monitor-hsm-lambda-emulator to start"
while test "true" != "$(docker inspect -f {{.State.Running}} autograph-monitor-hsm-lambda-emulator)"; do
echo -n "."
sleep 1 # wait before checking again
done
echo "checking autograph monitors"
docker compose run \
--rm \
-e AUTOGRAPH_URL=http://app:8000/ \
--entrypoint /usr/local/bin/lambda-selftest-entrypoint.sh \
monitor-lambda-emulator /go/bin/autograph-monitor

echo "checking monitoring using hsm root hash:" "$APP_HSM_NORMANDY_ROOT_HASH"
# exec in containers to workaround https://circleci.com/docs/2.0/building-docker-images/#accessing-services
docker compose exec monitor-lambda-emulator "/usr/local/bin/test_monitor.sh"
docker compose logs monitor-lambda-emulator
docker compose exec monitor-hsm-lambda-emulator "/usr/local/bin/test_monitor.sh"
docker compose logs monitor-hsm-lambda-emulator
docker compose run \
--rm \
-e AUTOGRAPH_URL=http://autograph-app-hsm:8001/ \
-e AUTOGRAPH_ROOT_HASH=$APP_HSM_NORMANDY_ROOT_HASH \
--entrypoint /usr/local/bin/lambda-selftest-entrypoint.sh \
monitor-hsm-lambda-emulator /go/bin/autograph-monitor

echo "checking read-only API"
# user bob doesn't exist in the softhsm config
Expand Down Expand Up @@ -100,7 +93,7 @@ docker compose run \
--rm \
--user 0 \
-e TARGET=http://app:8000 \
-e VERIFY=1 \
-e VERIFY=1 \
--workdir /app/src/autograph/tools/autograph-client \
--entrypoint ./build_test_apks.sh \
app
Expand Down
7 changes: 3 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ services:
monitor:
container_name: autograph-monitor
image: autograph-app
command:
[
"/go/bin/autograph-monitor",
]
command: ["/go/bin/autograph-monitor"]

monitor-lambda-emulator:
container_name: autograph-monitor-lambda-emulator
Expand All @@ -83,6 +80,7 @@ services:
# set a non-empty value to use the lambda handler
- LAMBDA_TASK_ROOT=/usr/local/bin/
- AUTOGRAPH_ROOT_HASH
command: ["/go/bin/autograph-monitor"]
ports:
- "9000:8080"
links:
Expand All @@ -104,6 +102,7 @@ services:
# set a non-empty value to use the lambda handler
- LAMBDA_TASK_ROOT=/usr/local/bin/
- AUTOGRAPH_ROOT_HASH
command: ["/go/bin/autograph-monitor"]
ports:
- "9001:8080"
links:
Expand Down
70 changes: 70 additions & 0 deletions tools/autograph-client/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
include:
- ../../docker-compose.yml
services:
test-api-app:
container_name: test-api-app
image: autograph-app
user: "0"
links:
- app
depends_on:
- app
entrypoint: ./test-entrypoint.sh
environment:
- CHECK_BOB=1
- AUTOGRAPH_URL=http://app:8000
working_dir: "/app/src/autograph/tools/autograph-client"
command: [ "./integration_test_api.sh" ]

test-api-hsm:
container_name: test-api-hsm
image: autograph-app
user: "0"
links:
- app-hsm
depends_on:
- app-hsm
entrypoint: ./test-entrypoint.sh
environment:
- AUTOGRAPH_URL=http://app-hsm:8001
working_dir: "/app/src/autograph/tools/autograph-client"
command: [ "./integration_test_api.sh" ]

test-gpg-signing:
container_name: test-gpg-signing
extends:
service: test-api-app
command: [ "./integration_test_gpg2_signer.sh" ]

test-xpi-signing:
container_name: test-xpi-signing
extends:
service: test-api-app
command: [ "./integration_test_xpis.sh" ]

test-xpi-signing-hsm:
container_name: test-xpi-signing-hsm
extends:
service: test-api-hsm
environment:
- SIGNER_ID_PREFIX=hsm-
command: [ "./integration_test_xpis.sh" ]

test-apk-signing:
container_name: test-apk-signing
extends:
service: test-api-app
environment:
- TARGET=http://app:8000
- VERIFY=1
command: [ "./build_test_apks.sh" ]

test-monitor-app:
container_name: test-monitor-app
extends:
file: ../../docker-compose.yml
service: monitor-lambda-emulator
entrypoint: [ "/usr/local/bin/lambda-selftest-entrypoint.sh" ]

# TODO: Add a monitor test for the HSM lambda - tricky because we need
# a way to dynamically grab the root hash from the HSM.
23 changes: 23 additions & 0 deletions tools/autograph-client/test-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env sh

# Wait for the heartbeat
RESULT=$(curl --silent \
--connect-timeout 5 \
--max-time 10 \
--retry-connrefused \
--retry 5 \
--retry-delay 5 \
--retry-max-time 60 \
"${AUTOGRAPH_URL}/__heartbeat__")
RETCODE=$?
if [ $RETCODE -ne 0 ]; then
echo "Failed to reach autograph heartbeat" >&2
exit $RETCODE
else
echo "Autograph is running: ${RESULT}"
echo "Starting test"
fi

# Run the test
set -e
exec "$@"
8 changes: 5 additions & 3 deletions tools/autograph-monitor/Dockerfile.lambda-emulator
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ FROM autograph-app

USER root

RUN cp /app/src/autograph/bin/test_monitor.sh /usr/local/bin/test_monitor.sh
RUN curl -Lo /usr/local/bin/aws-lambda-rie \
https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie \
&& \
chmod +x /usr/local/bin/aws-lambda-rie /usr/local/bin/test_monitor.sh
chmod +x /usr/local/bin/aws-lambda-rie

COPY lambda-selftest-entrypoint.sh /usr/local/bin/lambda-selftest-entrypoint.sh

USER app
CMD ["/usr/local/bin/aws-lambda-rie", "/go/bin/autograph-monitor"]
ENTRYPOINT ["/usr/local/bin/aws-lambda-rie"]
CMD ["/go/bin/autograph-monitor"]
12 changes: 10 additions & 2 deletions bin/test_monitor.sh → ...aph-monitor/lambda-selftest-entrypoint.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@
set -e
set -o pipefail

# Fork to start the AWS runtime emulator
/usr/local/bin/aws-lambda-rie "$@" &
AWS_RUNTIME_PID=$!
cleanup() {
kill -TERM $AWS_RUNTIME_PID
wait $AWS_RUNTIME_PID
}
trap cleanup EXIT SIGINT SIGTERM

# invoke a test monitor run in a lambda monitor
MONITOR_ERROR=$(curl -w '\n' -X POST 'http://localhost:8080/2015-03-31/functions/function/invocations' -d '{}')
MONITOR_ERROR=$(curl -s -w '\n' -X POST 'http://localhost:8080/2015-03-31/functions/function/invocations' -d '{}')

# If the result was null - then we succeeded!
if [ "${MONITOR_ERROR}" == "null" ]; then
Expand All @@ -19,4 +28,3 @@ else
echo "${MONITOR_ERROR}" | jq >&2
fi
exit 1