From 667fda5686046bf6e8933ed868974fb66b495907 Mon Sep 17 00:00:00 2001 From: Simon Adorf Date: Fri, 5 Aug 2022 14:35:52 +0200 Subject: [PATCH] Implement tests. --- .github/workflows/build_and_test_on_pr.yml | 35 ++++------------ docker-compose.yml | 42 ++++++++++++++++++++ tests/conftest.py | 46 ++++++++++++++++++++++ tests/docker-compose.yml | 1 + tests/requirements.txt | 4 ++ tests/test_aiidalab.py | 26 ++++++++++++ 6 files changed, 126 insertions(+), 28 deletions(-) create mode 100644 docker-compose.yml create mode 100644 tests/conftest.py create mode 120000 tests/docker-compose.yml create mode 100644 tests/requirements.txt create mode 100644 tests/test_aiidalab.py diff --git a/.github/workflows/build_and_test_on_pr.yml b/.github/workflows/build_and_test_on_pr.yml index c852e0b2..32e74b07 100644 --- a/.github/workflows/build_and_test_on_pr.yml +++ b/.github/workflows/build_and_test_on_pr.yml @@ -40,32 +40,11 @@ jobs: tags: aiidalab-docker-stack:latest cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache - - name: Start and test the container - id: test_run + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + cache: pip # caching pip dependencies + - run: pip install -r tests/requirements.txt + - name: Run tests run: | - mkdir tmp - export DOCKERID=`docker run -v $PWD/tmp:/home/aiida -d aiidalab-docker-stack:latest` - echo "::set-output name=docker_id_first_run::${DOCKERID}" - docker exec --tty --user root $DOCKERID wait-for-services - docker exec --tty --user aiida $DOCKERID wait-for-services -<<<<<<< HEAD - docker exec --tty --user aiida $DOCKERID /bin/bash -l -c '/opt/conda/envs/pgsql/bin/pg_ctl -D /home/$SYSTEM_USER/.postgresql status' # Check that postgres is up. - docker exec --tty --user root $DOCKERID /bin/bash -l -c '/opt/conda/envs/rmq/bin/rabbitmqctl status' # Check that rabbitmq is up. -======= - docker exec --tty --user aiida $DOCKERID /bin/bash -l -c '/usr/lib/postgresql/10/bin/pg_ctl -D /home/$NB_USER/.postgresql status' # Check that postgres is up. - docker exec --tty --user root $DOCKERID /bin/bash -l -c 'service rabbitmq-server status' # Check that rabbitmq is up. ->>>>>>> ee7ece1 (Major revision to base the image on the jupyter docker stack.) - docker exec --tty --user aiida $DOCKERID /bin/bash -l -c 'conda create -y -n test_env python=3.8' # Check that one can create a new conda environment. - docker exec --tty --user aiida $DOCKERID /bin/bash -l -c 'conda activate test_env' # Check that new environment works. - sudo cp tmp/.ssh/id_rsa . # Copy id_rsa file from the mounted folder. - docker stop $DOCKERID # Stop the container. - export DOCKERID=`docker run -v $PWD/tmp:/home/aiida -d aiidalab-docker-stack:latest` # Start a new container using the same mounted folder. - echo "::set-output name=docker_id_second_run::${DOCKERID}" - docker exec --tty $DOCKERID wait-for-services - sudo diff id_rsa tmp/.ssh/id_rsa # Check that the id_rsa file wasn't modified. - - name: Show the container log (first run). - if: always() - run: docker logs "${{ steps.test_run.outputs.docker_id_first_run }}" - - name: Show the container log (second run). - if: always() - run: docker logs "${{ steps.test_run.outputs.docker_id_second_run }}" + pytest -v diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..819bc394 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,42 @@ +--- +version: '3.4' + +services: + + database: + image: postgres:12.3 + environment: + POSTGRES_USER: pguser + POSTGRES_PASSWORD: password + volumes: + - aiida-postgres-db:/var/lib/postgresql/data + + messaging: + image: rabbitmq:3.8.3-management + environment: + RABBITMQ_DEFAULT_USER: guest + RABBITMQ_DEFAULT_PASS: guest + volumes: + - aiida-rmq-data:/var/lib/rabbitmq/ + + aiidalab: + build: .. + environment: + RMQHOST: messaging + TZ: Europe/Zurich + DOCKER_STACKS_JUPYTER_CMD: notebook + SETUP_DEFAULT_AIIDA_PROFILE: 'true' + AIIDALAB_DEFAULT_APPS: '' + volumes: + - aiidalab-home-folder:/home/jovyan + depends_on: + - database + - messaging + ports: + - 8888 + + +volumes: + aiida-postgres-db: + aiida-rmq-data: + aiidalab-home-folder: diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..5be857f1 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,46 @@ +import pytest +import requests + +from requests.exceptions import ConnectionError + + +def is_responsive(url): + try: + response = requests.get(url) + if response.status_code == 200: + return True + except ConnectionError: + return False + + +@pytest.fixture(scope="session") +def notebook_service(docker_ip, docker_services): + """Ensure that HTTP service is up and responsive.""" + port = docker_services.port_for("aiidalab", 8888) + url = f"http://{docker_ip}:{port}" + docker_services.wait_until_responsive( + timeout=30.0, pause=0.1, check=lambda: is_responsive(url) + ) + return url + + +@pytest.fixture(scope="session") +def docker_compose(docker_services): + return docker_services._docker_compose + + +@pytest.fixture +def aiidalab_exec(docker_compose): + def execute(command, user=None, **kwargs): + if user: + command = f"exec -T --user={user} aiidalab {command}" + else: + command = f"exec -T aiidalab {command}" + return docker_compose.execute(command, **kwargs) + + return execute + + +@pytest.fixture +def nb_user(aiidalab_exec): + return aiidalab_exec("bash -c 'echo \"${NB_USER}\"'").decode().strip() diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml new file mode 120000 index 00000000..5c8318ef --- /dev/null +++ b/tests/docker-compose.yml @@ -0,0 +1 @@ +../docker-compose.yml \ No newline at end of file diff --git a/tests/requirements.txt b/tests/requirements.txt new file mode 100644 index 00000000..ade94cbc --- /dev/null +++ b/tests/requirements.txt @@ -0,0 +1,4 @@ +docker-compose==1.29.2 +pytest==7.1.2 +pytest-docker==1.0.0 +requests==2.28.1 diff --git a/tests/test_aiidalab.py b/tests/test_aiidalab.py new file mode 100644 index 00000000..14ad7f86 --- /dev/null +++ b/tests/test_aiidalab.py @@ -0,0 +1,26 @@ +import requests + + +def test_notebook_service_available(notebook_service): + response = requests.get(f"{notebook_service}/") + assert response.status_code == 200 + + +def test_pip_check(aiidalab_exec): + aiidalab_exec("pip check") + + +def test_aiidalab_available(aiidalab_exec, nb_user): + output = aiidalab_exec("aiidalab --version", user=nb_user).decode().strip().lower() + assert "aiidalab" in output + + +def test_create_conda_environment(aiidalab_exec, nb_user): + output = aiidalab_exec("conda create -y -n tmp", user=nb_user).decode().strip() + assert "conda activate tmp" in output + + +def test_verdi_status(aiidalab_exec, nb_user): + output = aiidalab_exec("verdi status", user=nb_user).decode().strip() + assert "Connected to RabbitMQ" in output + assert "Daemon is running" in output