diff --git a/.travis.yml b/.travis.yml index 5c59b4b9..9d7c4f07 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,10 @@ language: python +python: "3.6" matrix: include: # Run tests - - python: - - "3.6" - addons: + - addons: postgresql: "9.4" services: - postgresql @@ -19,8 +18,7 @@ matrix: - python manage.py makemigrations registrations changes --dry-run | grep 'No changes detected' || (echo 'There are changes which require migrations.' && exit 1) # Create docker image on merge to develop - - python: "2.7" - sudo: required + - sudo: required dist: trusty services: [docker] env: @@ -30,8 +28,10 @@ matrix: - secure: "HdNKmMAw+2K6APKFp/Cy5SVxFDDDtx83UeIA5h9mBF4wrjRQcNLwZCbDGQTKmeZ/HZZLqxj3H8k034Y1vw6iQRGvv2X5Jazanh6ett4zH6QNd8Tnk4CqsZZ7MIG71ZFaSbdotpq2KgWP//Sz2BlnzXugr2CWbydTDOGE3dyRwwphs8DXgUu2gOeSFVolf3H0zYbnWPkDyb4EB/lOsTETEXRN1F3jgwY58RQU6LAV/k/FAr4WDWE+qX8f9Kr13UhMJYKS8mouJsSU1Q2Uq/hMXz/2QZ1h8vdv/lV9l3JRcK7JOEwXRGyFNYVFpBMSzUQpb6OwcaLgiBQ25y4HLtrViiVGg1abGrWqXH2Uiv1gnkKsJ37VIXtR7gso7n48j7lNBUHdJUE6JdiktOlmt1KvLjGzdWyukmMpRB2Ci2KQkPbAqF7pxgC7Tq0x/XT+2M85g/xv+U9uP+SBPA5V1ZPaHntHgWKjjlU224tfXB/PhVRe3wSx2kHKQEHzbxGCB0i5bLkcVhMUxpuod6H6cYt5RqI3JQMWcQMup7suUyQKn8iu8oLeVAZIeJAEZRSLSUvFpvAvEmrNyflUtOLJ3eCCXaAgThej5ZNaH9np1yVMa8CVt3ccudA2l8M00oC2qu1qkgbY2SPePBkfo9htoUWJ7cQF0oGrim/TA4TBM6BQwOk=" before_script: - docker pull "$IMAGE_NAME" || true + - pip install -r seaworthy/requirements.txt script: - docker build --tag "$IMAGE_NAME" --cache-from "$IMAGE_NAME" . + - (cd seaworthy; py.test -v --hub-image "$IMAGE_NAME" test.py) before_deploy: - pip install docker-ci-deploy==0.3.0 @@ -42,8 +42,8 @@ matrix: on: branch: develop - - python: "2.7" - sudo: required + # Create docker images for tagged releases + - sudo: required dist: trusty services: [docker] env: @@ -53,8 +53,10 @@ matrix: - secure: "HdNKmMAw+2K6APKFp/Cy5SVxFDDDtx83UeIA5h9mBF4wrjRQcNLwZCbDGQTKmeZ/HZZLqxj3H8k034Y1vw6iQRGvv2X5Jazanh6ett4zH6QNd8Tnk4CqsZZ7MIG71ZFaSbdotpq2KgWP//Sz2BlnzXugr2CWbydTDOGE3dyRwwphs8DXgUu2gOeSFVolf3H0zYbnWPkDyb4EB/lOsTETEXRN1F3jgwY58RQU6LAV/k/FAr4WDWE+qX8f9Kr13UhMJYKS8mouJsSU1Q2Uq/hMXz/2QZ1h8vdv/lV9l3JRcK7JOEwXRGyFNYVFpBMSzUQpb6OwcaLgiBQ25y4HLtrViiVGg1abGrWqXH2Uiv1gnkKsJ37VIXtR7gso7n48j7lNBUHdJUE6JdiktOlmt1KvLjGzdWyukmMpRB2Ci2KQkPbAqF7pxgC7Tq0x/XT+2M85g/xv+U9uP+SBPA5V1ZPaHntHgWKjjlU224tfXB/PhVRe3wSx2kHKQEHzbxGCB0i5bLkcVhMUxpuod6H6cYt5RqI3JQMWcQMup7suUyQKn8iu8oLeVAZIeJAEZRSLSUvFpvAvEmrNyflUtOLJ3eCCXaAgThej5ZNaH9np1yVMa8CVt3ccudA2l8M00oC2qu1qkgbY2SPePBkfo9htoUWJ7cQF0oGrim/TA4TBM6BQwOk=" before_script: - docker pull "$IMAGE_NAME" || true + - pip install -r seaworthy/requirements.txt script: - docker build --tag "$IMAGE_NAME" --cache-from "$IMAGE_NAME" . + - (cd seaworthy; py.test -v --hub-image "$IMAGE_NAME" test.py) before_deploy: - pip install docker-ci-deploy==0.3.0 diff --git a/seaworthy/conftest.py b/seaworthy/conftest.py new file mode 100644 index 00000000..ac4fd459 --- /dev/null +++ b/seaworthy/conftest.py @@ -0,0 +1,13 @@ +import os + + +def pytest_addoption(parser): + parser.addoption( + "--hub-image", action="store", default=os.environ.get( + "HUB_IMAGE", "praekeltfoundation/ndoh-hub:develop"), + help="NDOH Hub image to test" + ) + + +def pytest_report_header(config): + return "NDOH Hub Docker image: {}".format(config.getoption("--hub-image")) diff --git a/seaworthy/fixtures.py b/seaworthy/fixtures.py new file mode 100644 index 00000000..55720225 --- /dev/null +++ b/seaworthy/fixtures.py @@ -0,0 +1,39 @@ +import pytest +from seaworthy.definitions import ContainerDefinition +from seaworthy.containers.postgresql import PostgreSQLContainer + +HUB_IMAGE = pytest.config.getoption("--hub-image") + + +class HubContainer(ContainerDefinition): + WAIT_PATTERNS = (r"Listening at: unix:/var/run/gunicorn/gunicorn.sock",) + + def __init__(self, name, db_url, image=HUB_IMAGE): + super().__init__(name, image, self.WAIT_PATTERNS) + self.db_url = db_url + + def base_kwargs(self): + return { + "ports": { + "8000/tcp": None, + }, + "environment": { + "HUB_DATABASE": self.db_url, + }, + } + + +postgresql_container = PostgreSQLContainer("postgresql") +postgresql_fixture, clean_postgresql_fixture = ( + postgresql_container.pytest_clean_fixtures("postgresql_container") +) + +hub_container = HubContainer("ndoh-hub", postgresql_container.database_url()) +hub_fixture = hub_container.pytest_fixture( + "hub_container", dependencies=["postgresql_container"]) + +__all__ = [ + "clean_postgresql_fixture", + "hub_fixture", + "postgresql_fixture", +] diff --git a/seaworthy/requirements.txt b/seaworthy/requirements.txt new file mode 100644 index 00000000..7d272a6b --- /dev/null +++ b/seaworthy/requirements.txt @@ -0,0 +1 @@ +seaworthy[pytest] >= 0.3.0 diff --git a/seaworthy/test.py b/seaworthy/test.py new file mode 100644 index 00000000..90d56fa5 --- /dev/null +++ b/seaworthy/test.py @@ -0,0 +1,34 @@ +import cgi + +from fixtures import * # noqa: F401,F403 + + +def mime_type(content_type): + return cgi.parse_header(content_type)[0] + + +class TestHubContainer: + def test_db_tables_created(self, hub_container, postgresql_container): + """ + When the Django container starts, it should run its migrations + """ + django_logs = hub_container.get_logs().decode("utf-8") + assert "Running migrations" in django_logs + + psql_output = postgresql_container.exec_psql( + ("SELECT COUNT(*) FROM information_schema.tables WHERE " + "table_schema='public';") + ) + count = int(psql_output.output.strip()) + assert count > 0 + + def test_admin_page(self, hub_container, postgresql_container): + """ + When we try to access the django admin page, it should be returned + """ + client = hub_container.http_client() + response = client.get("/admin") + + assert response.status_code == 200 + assert mime_type(response.headers["content-type"]) == "text/html" + assert "Log in | Django site admin" in response.text