diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..792d2420d0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +**/venv +**/.venv \ No newline at end of file diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 998a1e0fc4..0800837eb5 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -6,6 +6,7 @@ defaults: env: TEST_PRESET_TYPE: "minimal" + TEST_TAG: "consensus-specs-dockerfile-test:latest" on: push: @@ -66,6 +67,32 @@ jobs: - name: Run linter for test generators run: make lint_generators + dockerfile-test: + runs-on: self-hosted + needs: preclear + services: + registry: + image: registry:2 + ports: + - 5000:5000 + steps: + - name: Checkout this repo + uses: actions/checkout@v3.2.0 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + with: + driver-opts: network=host + - name: Build and push to local registry + uses: docker/build-push-action@v4 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: localhost:5000/${{ env.TEST_TAG }} + - name: Test the image + run: | + docker run localhost:5000/${{ env.TEST_TAG }} pylint --rcfile ./linter.ini --errors-only pysetup + pyspec-tests: runs-on: self-hosted needs: [preclear,lint,codespell,table_of_contents] diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000000..08e08fd155 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,16 @@ +# Build the consensus-specs image using the builder pattern. +# This image is base on the Debian slim distribution. +FROM python:3.11.0-slim-bullseye as base + + +FROM base as builder +RUN mkdir /consensus-specs +WORKDIR /consensus-specs +ENV DEBIAN_FRONTEND=noninteractive +RUN apt update && apt install -y git +RUN python -m pip install --upgrade pip + +COPY . . + +RUN pip install -r requirements_preinstallation.txt -e .[lint] -e .[test] +RUN python setup.py pyspecdev diff --git a/scripts/run_test.sh b/scripts/run_test.sh new file mode 100644 index 0000000000..130aaeb09a --- /dev/null +++ b/scripts/run_test.sh @@ -0,0 +1,76 @@ +#! /bin/sh + +# Run 'consensus-specs' tests from a container instance. +# *Be sure to launch Docker before running this script.* +# +# It does the below: +# 1. Run pytest for consensus-specs in a container. +# 2. Copy and paste the coverage report. +# 3. Remove all exited containers that use the consensus-specs: images. + + +# Constants +ALL_EXECUTABLE_SPECS=("phase0" "altair" "bellatrix" "capella" "deneb" "eip6110" "whisk") +TEST_PRESET_TYPE=minimal +WORKDIR="//consensus-specs//tests//core//pyspec" +ETH2SPEC_FOLDER_NAME="eth2spec" +CONTAINER_NAME="consensus-specs-tests" + +COV_HTML_OUT=.htmlcov + +# Default flag values +version=latest +number_of_core=4 + +# Generates coverage scope +coverage_scope=() +for spec in "${ALL_EXECUTABLE_SPECS[@]}" +do + coverage_scope+=("--cov=${ETH2SPEC_FOLDER_NAME}.${spec}.${TEST_PRESET_TYPE}") +done + +display_help() { + echo "Run 'consensus-specs' tests from a container instance." + echo "Be sure to launch Docker before running this script." + echo + echo "Syntax: run_test [-v TAG | -n NUMBER_OF_CORE | -h HELP]" + echo "-v Specify the image tag for consensus-specs." + echo "-n Specify the number of core to run tests." + echo "-h Get helps." +} + +# Parse provided flags +while getopts v:n:h flag +do + case "${flag}" in + v) version=$OPTARG;; + n) number_of_core=$OPTARG;; + h) display_help && $SHELL;; + \?) echo "not valid -$OPTARG" && $SHELL;; + esac +done + +# Stop and remove the 'consensus-specs-dockerfile-test' container. +# If this container doesn't exist, then a error message is printed +# (but the process is not stopped). +cleanup() { + echo "Stop and remove the 'consensus-specs-tests' container." + docker stop $CONTAINER_NAME || true && docker rm $CONTAINER_NAME || true +} + +# Copy the coverage report from the container to the local +copy_coverage_report() { + docker cp $$CONTAINER_NAME:$WORKDIR/$COV_HTML_OUT ./$COV_HTML_OUT +} + +cleanup +# Equivalent to `make test` +docker run -w $WORKDIR --name $CONTAINER_NAME consensus-specs:$version \ + pytest -n $number_of_core --disable-bls $coverage_scope --cov-report="html:${COV_HTML_OUT}" --cov-branch eth2spec + +# Get coverage report form container instance +$(copy_coverage_report) +# Only clean container after user exit console +trap cleanup EXIT + +$SHELL \ No newline at end of file diff --git a/tests/core/pyspec/README.md b/tests/core/pyspec/README.md index baa1322771..216791b3dd 100644 --- a/tests/core/pyspec/README.md +++ b/tests/core/pyspec/README.md @@ -76,6 +76,18 @@ Options: - `--disable-bls`, to disable BLS (only for tests that can run without) - `--bls-type`, `milagro` or `py_ecc` (default) +#### With Docker + +Run `docker build -f ./docker/Dockerfile -t consensus-specs .` from the root of the specs repository to build the test image. + +Then you can run the image with the below: +```shell +cd ./scripts +run_test.sh +``` + +This is equivalent to ``make test``. + ### How to view code coverage report Run `make open_cov` from the root of the specs repository after running `make test` to open the html code coverage report.