diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aab241b1a..ca6fd710e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,7 +19,7 @@ on: jobs: workspace_container_tests: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 @@ -37,7 +37,7 @@ jobs: - name: Run tests shell: bash run: | - sh scripts/run_tests.sh + sh test/run_tests.sh workspace_deluxe_tests: runs-on: ubuntu-latest diff --git a/Dockerfile b/Dockerfile index 3c6a15f24..27a655ea8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,13 @@ FROM eclipse-temurin:11-jdk as build -COPY . /tmp/workspace_deluxe WORKDIR /tmp -RUN apt-get update -y && \ - apt-get install -y ant git ca-certificates python3-sphinx && \ - git clone https://github.com/kbase/jars && \ - cd workspace_deluxe && \ +RUN apt update -y && \ + apt install -y ant git ca-certificates python3-sphinx && \ + git clone https://github.com/kbase/jars + +COPY . /tmp/workspace_deluxe + +RUN cd workspace_deluxe && \ make docker_deps # updated/slimmed down version of what's in kbase/kb_jre diff --git a/scripts/run_tests.sh b/scripts/run_tests.sh deleted file mode 100644 index 19c20b591..000000000 --- a/scripts/run_tests.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash -# -# Script to run the python workspace_container_test.py locally or on GitHub Actions. -# Builds and mounts auth2, workspace, and mongo docker containers, and then calls -# the python script. -# -# See .github/workflows/test.yml for GitHub Actions implementation. - -# build images -docker compose build -build_exit_code=$? -if [ $build_exit_code -ne 0 ]; then - echo "Error: docker compose build failed with exit code $build_exit_code" - exit $build_exit_code -fi - -# bring up the containers -docker compose up -d -compose_up_exit_code=$? -if [ $compose_up_exit_code -ne 0 ]; then - echo "Error: docker-compose up command failed with exit code $compose_up_exit_code." - exit $compose_up_exit_code -fi - -max_retries=50 -counter=0 -exit_code=666 - -# limit the number of retries of the script -while [ $counter -lt $max_retries ]; do - # wait for the workspace container to start up - # logs should stop being generated and the last line of the logs should be something like - # INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 3811 ms - if docker logs -n 5 "workspace_deluxe-workspace-1" 2>&1 | grep -q -F -m 1 'org.apache.catalina.startup.Catalina.start Server startup in' > /dev/null; then - # get the path to the 'scripts' directory and add it to the python execution path - current_dir="$( dirname -- "$( readlink -f -- "$0"; )"; )" - PYTHONPATH="$current_dir":$PYTHONPATH python -m pytest scripts/workspace_container_test.py - exit_code=$? - break - fi - echo "Waiting for the workspace to be ready..." - counter=$(( counter + 1)) - sleep 5 -done - -if [ $counter -eq $max_retries ]; then - echo "Workspace server start up not detected after $max_retries retries. " - echo "Last 20 lines of workspace container logs:" - docker logs -n 20 "workspace_deluxe-workspace-1" - exit_code=1 -fi - -docker compose down -exit $exit_code diff --git a/scripts/workspace_container_test.py b/scripts/workspace_container_test.py deleted file mode 100644 index f2b45847c..000000000 --- a/scripts/workspace_container_test.py +++ /dev/null @@ -1,76 +0,0 @@ -from lib.biokbase.workspace.client import Workspace -import pytest -import requests -import json - -""" workspace_container_test.py - -Very simple tests to ensure that local workspace and auth2 servers are functioning correctly. -Requires the python libraries `pytest` and `requests` to be installed. - -Assumes that the workspace and auth2 are running locally on ports 8080 and 7058 respectively. - -Use the wrapper shell script, `run_tests.sh`, to create the necessary set up and run the tests: - -sh scripts/run_tests.sh - -""" - -WORKSPACE_VERSION = "0.14.3" - -AUTH_URL = "http://localhost:8080" -WS_URL = "http://localhost:7058" -USER_NAME = "some_dull_user" -WS_NAME = "my_cool_new_workspace" - -def test_create_user_create_workspace() -> None: - """create a user and then create a workspace for that user""" - user_token = create_auth2_user_token() - get_ws_version(user_token) - create_read_workspace(user_token) - -def create_auth2_user_token() -> str: - """create a user and generate a token for that user""" - # create a new user - user_json = json.dumps({"user": USER_NAME, "display": "Blah blah"}) - response = requests.post( - AUTH_URL + "/testmode/api/V2/testmodeonly/user", - data=user_json, - headers={"content-type":"application/json"} - ) - assert response.status_code == 200 - user_data = response.json() - assert 'created' in user_data - - # create the token - token_json = json.dumps({ "user": USER_NAME, "type": "Login" }) - response = requests.post( - AUTH_URL + "/testmode/api/V2/testmodeonly/token", - data=token_json, - headers={"content-type":"application/json"} - ) - assert response.status_code == 200 - token_data = response.json() - assert 'created' in token_data - assert 'token' in token_data - return token_data["token"] - -def get_ws_version(token: str) -> None: - """get the current workspace version""" - ws = Workspace(WS_URL, token=token) - assert ws.ver() == WORKSPACE_VERSION - -def create_read_workspace(token: str) -> None: - """create a new workspace and then get the workspace information""" - ws = Workspace(WS_URL, token=token) - new_ws = ws.create_workspace({'workspace': WS_NAME}) - assert new_ws[1] == WS_NAME - assert new_ws[2] == USER_NAME - assert ws.get_workspace_info({ "id": new_ws[0] }) == new_ws - -def test_get_docs() -> None: - """check that the workspace documentation can be accessed""" - response = requests.get(WS_URL + "/docs/") - assert response.status_code == 200 - assert response.text.find("KBase Workspace Service Manual") != -1 - assert response.text.find("KBase Workspace " + WORKSPACE_VERSION + " documentation") != -1 diff --git a/test/README.md b/test/README.md new file mode 100644 index 000000000..ad44c76c4 --- /dev/null +++ b/test/README.md @@ -0,0 +1,2 @@ +This directory contains tests not part of the standard java suite. Currently it has a very small +test suite that runs against the workspace in a docker container. \ No newline at end of file diff --git a/test/run_tests.sh b/test/run_tests.sh new file mode 100644 index 000000000..af873e9f5 --- /dev/null +++ b/test/run_tests.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# +# Script to run the python workspace_container_test.py locally or on GitHub Actions. +# Builds and mounts auth2, workspace, and mongo docker containers, and then calls +# the python script. +# +# See .github/workflows/test.yml for GitHub Actions implementation. + +# build and start the containers +docker compose up -d --build +compose_up_exit_code=$? +if [ $compose_up_exit_code -ne 0 ]; then + echo "Error: docker-compose up -d --build command failed with exit code $compose_up_exit_code." + exit $compose_up_exit_code +fi + +# get the path to the current directory and add it to the python execution path +current_dir="$( dirname -- "$( readlink -f -- "$0"; )"; )" +PYTHONPATH="$current_dir":$PYTHONPATH python -m pytest test/workspace_container_test.py +exit_code=$? + +docker compose down +exit $exit_code diff --git a/test/workspace_container_test.py b/test/workspace_container_test.py new file mode 100644 index 000000000..d53a15ca3 --- /dev/null +++ b/test/workspace_container_test.py @@ -0,0 +1,116 @@ +from lib.biokbase.workspace.client import Workspace +import pytest +import requests +import json +import time + +""" workspace_container_test.py + +Very simple tests to ensure that local workspace and auth2 servers are functioning correctly. +Requires the python libraries `pytest` and `requests` to be installed. + +Assumes that the workspace and auth2 are running locally on ports 8080 and 7058 respectively. + +Use the wrapper shell script, `run_tests.sh`, to create the necessary set up and run the tests: + +sh scripts/run_tests.sh + +""" + +WORKSPACE_VERSION = "0.14.3" + +AUTH_URL = "http://localhost:8080" +WS_URL = "http://localhost:7058" +USER_NAME = "some_dull_user" +WS_NAME = "my_cool_new_workspace" +WAIT_TIMES = [1, 2, 5, 10, 30] + + +@pytest.fixture(scope="module") +def ready(): + wait_for_auth() + wait_for_ws() + + yield + +def wait_for_auth(): + print("waiting for auth service...") + for t in WAIT_TIMES: + try: + res = requests.get(AUTH_URL) + res.raise_for_status() + return + except Exception as e: + print(f"Failed to connect to auth, waiting {t} sec and trying again:\n\t{e}") + time.sleep(t) + raise Exception(f"Couldn't connect to the auth after {len(WAIT_TIMES)} attempts") + + +def wait_for_ws(): + print("waiting for workspace service...") + ws = Workspace(WS_URL) + for t in WAIT_TIMES: + try: + ws.ver() + return + except Exception as e: + print(f"Failed to connect to workspace, waiting {t} sec and trying again:\n\t{e}") + time.sleep(t) + raise Exception(f"Couldn't connect to the workspace after {len(WAIT_TIMES)} attempts") + + +def test_create_user_create_workspace(ready): + """create a user and then create a workspace for that user""" + token = create_auth2_user_token() + get_ws_version(token) + create_read_workspace(token) + + +def create_auth2_user_token() -> str: + """create a user and generate a token for that user""" + # create a new user + user_json = json.dumps({"user": USER_NAME, "display": "Blah blah"}) + response = requests.post( + AUTH_URL + "/testmode/api/V2/testmodeonly/user", + data=user_json, + headers={"content-type":"application/json"} + ) + assert response.status_code == 200 + user_data = response.json() + assert 'created' in user_data + + # create the toke + token_json = json.dumps({ "user": USER_NAME, "type": "Login" }) + response = requests.post( + AUTH_URL + "/testmode/api/V2/testmodeonly/token", + data=token_json, + headers={"content-type":"application/json"} + ) + assert response.status_code == 200 + token_data = response.json() + assert 'created' in token_data + assert 'token' in token_data + return token_data["token"] + + +def get_ws_version(token: str) -> None: + """get the current workspace version""" + ws = Workspace(WS_URL, token=token) + assert ws.ver() == WORKSPACE_VERSION + + +def create_read_workspace(token: str) -> None: + """create a new workspace and then get the workspace information""" + ws = Workspace(WS_URL, token=token) + new_ws = ws.create_workspace({'workspace': WS_NAME}) + assert new_ws[1] == WS_NAME + assert new_ws[2] == USER_NAME + assert ws.get_workspace_info({ "id": new_ws[0] }) == new_ws + + +def test_get_docs(ready) -> None: + """check that the workspace documentation can be accessed""" + response = requests.get(WS_URL + "/docs/") + assert response.status_code == 200 + assert response.text.find("KBase Workspace Service Manual") != -1 + assert response.text.find("KBase Workspace " + WORKSPACE_VERSION + " documentation") != -1