From 7a7b9c46dcde6050f9b04000ae774e919a39d6cf Mon Sep 17 00:00:00 2001 From: Ross Whitfield Date: Wed, 19 Jun 2024 15:54:04 +1000 Subject: [PATCH] Add code coverage --- .github/workflows/unittest.yml | 21 +++++++++- Dockerfile.coverage | 20 ++++++++++ config/docker-compose.coverage.yml | 64 ++++++++++++++++++++++++++++++ docker-entrypoint-coverage.sh | 27 +++++++++++++ environment.yml | 1 + 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 Dockerfile.coverage create mode 100644 config/docker-compose.coverage.yml create mode 100755 docker-entrypoint-coverage.sh diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index 61312b3..7c128ee 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -34,9 +34,28 @@ jobs: cache-downloads-key: ${{ runner.os }}-downloads-${{ hashFiles('**/environment.yml') }} - name: Start docker containers run: | - cp ./config/docker-compose.envlocal.yml docker-compose.yml + cp ./config/docker-compose.coverage.yml docker-compose.yml docker compose up --build -d - name: Sleep, wait for containers to start up run: sleep 30 - name: Run unit tests run: python -m pytest tests/ + - name: Stop but dont remove docker containers + # Stopping the containers allows the code coverage to be written to disk + run: docker exec -it live_data_server_livedata_1 /bin/bash -c "pkill coverage" + - name: Copy code coverage out of docker container + run: docker cp live_data_server_livedata_1:/var/www/livedata/app /tmp/ + - name: Combine and show code coverage + shell: bash -l {0} + run: | + cd /tmp/app + coverage combine + coverage xml + cp coverage.xml $OLDPWD + coverage report + - name: Bring down docker containers completely now + # This will completely remove the containers + run: docker-compose down + - uses: codecov/codecov-action@v4 + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true diff --git a/Dockerfile.coverage b/Dockerfile.coverage new file mode 100644 index 0000000..c3733b8 --- /dev/null +++ b/Dockerfile.coverage @@ -0,0 +1,20 @@ +FROM continuumio/miniconda3:23.10.0-1 + +COPY environment.yml . +RUN conda env create + +WORKDIR /var/www/livedata + +COPY docker-entrypoint-coverage.sh /usr/bin/docker-entrypoint.sh + +COPY src/live_data_server app +RUN mkdir ./static + +WORKDIR /var/www/livedata/app + +RUN echo "[run]\nsource=live_data_server,plots\nparallel=True\nrelative_files=True" > /var/www/livedata/app/.coveragerc + +#ENV COVERAGE_PROCESS_START /var/www/livedata/app/.coveragerc + +RUN chmod +x /usr/bin/docker-entrypoint.sh +ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "livedata", "/usr/bin/docker-entrypoint.sh"] diff --git a/config/docker-compose.coverage.yml b/config/docker-compose.coverage.yml new file mode 100644 index 0000000..cb9a630 --- /dev/null +++ b/config/docker-compose.coverage.yml @@ -0,0 +1,64 @@ +services: + + nginx: + image: nginx:1.21.1 + ports: + - "80:80" + - "443:443" + volumes: + - web-static:/var/www/livedata/static + - ./config/nginx/envlocal.conf:/etc/nginx/conf.d/nginx.conf + depends_on: + livedata: + condition: service_healthy + + livedata: + build: + context: . + dockerfile: Dockerfile.coverage + network: host + environment: + APP_DEBUG: 1 # 0 for False, otherwise will evaluate to True + DJANGO_SUPERUSER_USERNAME: ${DATABASE_USER} + DJANGO_SUPERUSER_PASSWORD: ${DATABASE_PASS} + DATABASE_NAME: ${DATABASE_NAME} + DATABASE_USER: ${DATABASE_USER} + DATABASE_PASS: ${DATABASE_PASS} + DATABASE_HOST: ${DATABASE_HOST} + DATABASE_PORT: ${DATABASE_PORT} + LIVE_PLOT_SECRET_KEY: ${LIVE_PLOT_SECRET_KEY} + command: /usr/bin/docker-entrypoint.sh + volumes: + - web-static:/var/www/livedata/static + healthcheck: + test: wget --no-verbose --tries=1 --spider http://localhost:8000/admin || exit 1 + interval: 60s + retries: 5 + start_period: 20s + timeout: 10s + ports: + - "8000:8000" + depends_on: + db: + condition: service_healthy + + db: + # do not upgrade to version > 9.6.23 unless you also upgrade livedata image + image: postgres:9.6.23 + environment: + POSTGRES_DB: ${DATABASE_NAME} + POSTGRES_USER: ${DATABASE_USER} + POSTGRES_PASSWORD: ${DATABASE_PASS} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USER} -d ${DATABASE_NAME}"] + interval: 5s + timeout: 5s + retries: 5 + ports: + - "${DATABASE_PORT}:${DATABASE_PORT}" + volumes: + - db-data:/var/lib/postgresql/data/ + +volumes: + web-static: + db-data: diff --git a/docker-entrypoint-coverage.sh b/docker-entrypoint-coverage.sh new file mode 100755 index 0000000..eeca130 --- /dev/null +++ b/docker-entrypoint-coverage.sh @@ -0,0 +1,27 @@ +#!/bin/sh +set -e + +# wait for database +until PGPASSWORD=${DATABASE_PASS} psql -h "${DATABASE_HOST}" -U "${DATABASE_USER}" -d "${DATABASE_NAME}" -c '\q'; do + >&2 echo "Postgres is unavailable - sleeping" + sleep 1 +done + +cd /var/www/livedata/app + +# collect static files +python manage.py collectstatic --noinput + +# migrate django models +python manage.py makemigrations --noinput +python manage.py migrate --noinput + +# create superuser +#echo "from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SUPERUSER_USERNAME}', '${DJANGO_SUPERUSER_USERNAME}@example.com', '${DJANGO_SUPERUSER_PASSWORD}')" | python manage.py shell + +# Create the webcache +python manage.py createcachetable webcache +python manage.py ensure_adminuser --username=${DJANGO_SUPERUSER_USERNAME} --email='workflow@example.com' --password=${DJANGO_SUPERUSER_PASSWORD} + +# run application with code coverage +coverage run -m gunicorn live_data_server.wsgi:application -b :8000 diff --git a/environment.yml b/environment.yml index 557e413..45b39e3 100644 --- a/environment.yml +++ b/environment.yml @@ -17,3 +17,4 @@ dependencies: - toml - requests<2.31 # can remove this condition once we allow newer versions of openssl - pre-commit + - coverage