diff --git a/docker-compose.override.dev.yml b/docker-compose.override.dev.yml index db1da0d9d7a..0e694ade4d2 100644 --- a/docker-compose.override.dev.yml +++ b/docker-compose.override.dev.yml @@ -73,3 +73,22 @@ services: mode: host "webhook.endpoint": image: mccutchen/go-httpbin:2.20.0@sha256:b1620821b6ff191d911629f87a720b88df5397c2554045f1cfb1ffde17c9b898 + integration-tests: + platform: "linux/amd64" + profiles: + - integration + build: + context: ./ + dockerfile: ${INTEGRATION_TESTS_DOCKERFILE:-Dockerfile.integration-tests-debian} + image: "defectdojo/defectdojo-integration-tests:${INTEGRATION_TESTS_VERSION:-latest}" + depends_on: + - nginx + - uwsgi + entrypoint: ['/wait-for-it.sh', '${DD_DATABASE_HOST:-postgres}:${DD_DATABASE_PORT:-5432}', '-t', '30', '--', '/app/docker/entrypoint-integration-tests.sh'] + volumes: + - '.:/app:z' + environment: + DD_BASE_URL: 'http://nginx:8080/' + DD_ADMIN_USER: "${DD_ADMIN_USER:-admin}" + DD_ADMIN_PASSWORD: "${DD_ADMIN_PASSWORD:-admin}" + DD_INTEGRATION_TEST_FILENAME: "${DD_INTEGRATION_TEST_FILENAME:-}" diff --git a/docker-compose.override.integration_tests.yml b/docker-compose.override.integration_tests.yml index 24d522f73a0..611becefbec 100644 --- a/docker-compose.override.integration_tests.yml +++ b/docker-compose.override.integration_tests.yml @@ -1,6 +1,7 @@ --- services: integration-tests: + platform: "linux/amd64" build: context: ./ dockerfile: ${INTEGRATION_TESTS_DOCKERFILE:-Dockerfile.integration-tests-debian} diff --git a/readme-docs/DOCKER.md b/readme-docs/DOCKER.md index 0f9c5bcedf2..c2e63fb425a 100644 --- a/readme-docs/DOCKER.md +++ b/readme-docs/DOCKER.md @@ -353,6 +353,20 @@ Check the logs with: docker compose logs -f integration-tests ``` +### Running a single integration test from dev mode + +If your dev stack is already running (`docker/setEnv.sh dev && docker compose up`), you can run a single integration test without switching environments. +The dev override includes an `integration-tests` service behind a Docker Compose profile, so it won't start during normal `docker compose up`. + +Make sure the dev containers are up and healthy before running the test: + +``` +./run-integration-test-dev.sh tests/finding_test.py +``` + +This spins up the integration test runner container against your running dev stack and tears it down when done. +Note that test data is created in your dev database — the integration tests attempt to clean up after themselves. + # Checking Docker versions Run the following to determine the versions for docker and docker compose: diff --git a/run-integration-test-dev.sh b/run-integration-test-dev.sh new file mode 100755 index 00000000000..cd9927f48eb --- /dev/null +++ b/run-integration-test-dev.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Run a single integration test against the running dev stack. +# Requires dev mode to be active (./docker/setEnv.sh dev && docker compose up). +# +# Usage: +# ./run-integration-test-dev.sh tests/finding_test.py +# ./run-integration-test-dev.sh tests/risk_acceptance_test.py + +set -e + +TEST_FILE="${1:?Usage: $0 }" + +docker compose --profile integration run --rm --no-deps \ + -e "DD_INTEGRATION_TEST_FILENAME=${TEST_FILE}" \ + -e "LOG_LEVEL=${LOG_LEVEL:-INFO}" \ + integration-tests diff --git a/tests/base_test_class.py b/tests/base_test_class.py index 7850ec3770c..ce4f483ea77 100644 --- a/tests/base_test_class.py +++ b/tests/base_test_class.py @@ -13,6 +13,10 @@ from selenium.webdriver.support.ui import WebDriverWait # import time +logging.basicConfig( + level=os.environ.get("LOG_LEVEL", "WARNING"), + format="%(levelname)s %(name)s: %(message)s", +) logger = logging.getLogger(__name__) @@ -403,7 +407,7 @@ def assertNoConsoleErrors(self): The addition of the trigger exception is due to the Report Builder tests. The addition of the innerHTML exception is due to the test for quick reports in finding_test.py """ - accepted_javascript_messages = r"(zoom\-in\.cur.*)404\ \(Not\ Found\)|Uncaught TypeError: Cannot read properties of null \(reading \'trigger\'\)|Uncaught TypeError: Cannot read properties of null \(reading \'innerHTML\'\)" + accepted_javascript_messages = r"(zoom\-in\.cur.*)404\ \(Not\ Found\)|Uncaught TypeError: Cannot read properties of null \(reading \'trigger\'\)|Uncaught TypeError: Cannot read properties of null \(reading \'innerHTML\'\)|Cross-Origin-Opener-Policy header has been ignored" if entry["level"] == "SEVERE": # TODO: actually this seems to be the previous url @@ -420,12 +424,12 @@ def assertNoConsoleErrors(self): + self.driver.current_url, ) if self.accept_javascript_errors: - logger.warning( + logger.debug( "skipping SEVERE javascript error because accept_javascript_errors is True!", ) elif re.search(accepted_javascript_messages, entry["message"]): - logger.warning( - "skipping javascript errors related to known issues images, see https://github.com/DefectDojo/django-DefectDojo/blob/master/tests/base_test_class.py#L324", + logger.debug( + "skipping javascript errors related to known issues, see https://github.com/DefectDojo/django-DefectDojo/blob/master/tests/base_test_class.py#L324", ) else: self.assertNotEqual(entry["level"], "SEVERE")