Skip to content

Commit

Permalink
Improve waits in integration tests (#1322)
Browse files Browse the repository at this point in the history
* Use wait_for_task util where possible
* Add a wait_for_url util to better poll 404s

No-Issue
  • Loading branch information
awcrosby authored Jun 22, 2022
1 parent 75f4a98 commit 9d23bf6
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 107 deletions.
43 changes: 6 additions & 37 deletions galaxy_ng/tests/integration/api/test_artifact_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
import logging
import os
import re
import time
from unittest.mock import patch
from urllib.parse import urljoin

import pytest
from orionutils.generator import build_collection, randstr

from galaxy_ng.tests.integration.constants import SLEEP_SECONDS_POLLING, USERNAME_PUBLISHER
from galaxy_ng.tests.integration.constants import USERNAME_PUBLISHER

from ..utils import (
CapturingGalaxyError,
Expand Down Expand Up @@ -105,12 +103,7 @@ def test_api_publish_invalid_tarball(ansible_config, artifact, upload_artifact):
f.write(randstr(1024).encode("utf8"))

resp = upload_artifact(config, api_client, artifact)

ready = False
url = urljoin(config["url"], resp["task"])
while not ready:
resp = api_client(url)
ready = resp["state"] not in ("running", "waiting")
resp = wait_for_task(api_client, resp)

assert resp["state"] == "failed"

Expand Down Expand Up @@ -344,13 +337,7 @@ def test_ansible_lint_exception(ansible_config, upload_artifact):
)

resp = upload_artifact(config, api_client, artifact)

ready = False
url = urljoin(config["url"], resp["task"])
while not ready:
resp = api_client(url)
ready = resp["state"] not in ("running", "waiting")
time.sleep(SLEEP_SECONDS_POLLING)
resp = wait_for_task(api_client, resp)

log_messages = [item["message"] for item in resp["messages"]]

Expand Down Expand Up @@ -392,13 +379,7 @@ def test_api_publish_log_missing_ee_deps(ansible_config, upload_artifact):
)

resp = upload_artifact(config, api_client, artifact)

ready = False
url = urljoin(config["url"], resp["task"])
while not ready:
resp = api_client(url)
ready = resp["state"] not in ("running", "waiting")
time.sleep(SLEEP_SECONDS_POLLING)
resp = wait_for_task(api_client, resp)

log_messages = [item["message"] for item in resp["messages"]]

Expand Down Expand Up @@ -435,13 +416,7 @@ def test_api_publish_ignore_files_logged(ansible_config, upload_artifact):
)

resp = upload_artifact(config, api_client, artifact)

ready = False
url = urljoin(config["url"], resp["task"])
while not ready:
resp = api_client(url)
ready = resp["state"] not in ("running", "waiting")
time.sleep(SLEEP_SECONDS_POLLING)
resp = wait_for_task(api_client, resp)

log_messages = [item["message"] for item in resp["messages"]]

Expand Down Expand Up @@ -473,13 +448,7 @@ def test_publish_fail_required_tag(ansible_config, upload_artifact):
)

resp = upload_artifact(config, api_client, artifact)

ready = False
url = urljoin(config["url"], resp["task"])
while not ready:
resp = api_client(url)
ready = resp["state"] not in ("running", "waiting")
time.sleep(SLEEP_SECONDS_POLLING)
resp = wait_for_task(api_client, resp)

assert resp["state"] == "failed"
assert (
Expand Down
20 changes: 9 additions & 11 deletions galaxy_ng/tests/integration/api/test_collection_signing.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@
import tarfile
import time
from tempfile import TemporaryDirectory
from urllib.parse import urljoin

import pytest
import requests
from orionutils.generator import build_collection

from galaxy_ng.tests.integration.constants import SLEEP_SECONDS_ONETIME, SLEEP_SECONDS_POLLING

from ..utils import get_all_collections_by_repo, get_all_namespaces, get_client, set_certification
from galaxy_ng.tests.integration.constants import SLEEP_SECONDS_ONETIME
from galaxy_ng.tests.integration.utils import (
get_all_collections_by_repo,
get_all_namespaces,
get_client,
set_certification,
wait_for_task,
)

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -52,13 +56,7 @@ def namespace(api_client):
def import_and_wait(api_client, artifact, upload_artifact, config):
# import and wait ...
resp = upload_artifact(config, api_client, artifact)
ready = False
url = urljoin(config["url"], resp["task"])
log.info("Waiting for collection to be imported: %s", url)
while not ready:
resp = api_client(url)
ready = resp["state"] not in ("running", "waiting")
time.sleep(SLEEP_SECONDS_POLLING)
resp = wait_for_task(api_client, resp)
assert resp["state"] == "completed"
return resp

Expand Down
25 changes: 7 additions & 18 deletions galaxy_ng/tests/integration/api/test_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,11 @@
See: https://issues.redhat.com/browse/AAH-1268
"""
import time
from urllib.parse import urljoin

import pytest
from orionutils.generator import build_collection

from galaxy_ng.tests.integration.constants import SLEEP_SECONDS_ONETIME, SLEEP_SECONDS_POLLING

from ..constants import USERNAME_PUBLISHER
from ..utils import get_client, set_certification
from ..utils import get_client, set_certification, wait_for_task, wait_for_url

pytestmark = pytest.mark.qa # noqa: F821

Expand Down Expand Up @@ -60,16 +55,13 @@ def get_all_collections():

# import and wait ...
resp = upload_artifact(config, api_client, artifact)
ready = False
url = urljoin(config["url"], resp["task"])
while not ready:
resp = api_client(url)
ready = resp["state"] not in ("running", "waiting")
time.sleep(SLEEP_SECONDS_POLLING)
resp = wait_for_task(api_client, resp)
assert resp['state'] == 'completed'

# wait for move task from `inbound-<namespace>` repo to `staging` repo
time.sleep(SLEEP_SECONDS_ONETIME)
dest_url = (
f"content/staging/v3/collections/{artifact.namespace}/"
f"{artifact.name}/versions/{artifact.version}/"
)
wait_for_url(api_client, dest_url)

# Make sure it ended up in staging but not in published ...
before = get_all_collections()
Expand All @@ -84,9 +76,6 @@ def get_all_collections():
assert cert_result['href'] is not None
assert cert_result['metadata']['tags'] == ['tools']

# wait for move task from `staging` repo to `published` repo
time.sleep(SLEEP_SECONDS_ONETIME)

# Make sure it's moved to the right place ...
after = get_all_collections()
assert ckey not in after['staging']
Expand Down
64 changes: 23 additions & 41 deletions galaxy_ng/tests/integration/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,25 @@ def wait_for_task(api_client, resp, timeout=300):
return resp


def wait_for_url(api_client, url, timeout_sec=30):
"""Wait until url stops returning a 404."""
ready = False
res = None
wait_until = time.time() + timeout_sec
while not ready:
if wait_until < time.time():
raise TaskWaitingTimeout()
try:
res = api_client(url, method="GET")
except GalaxyError as e:
if "404" not in str(e):
raise
time.sleep(0.5)
else:
ready = True
return res


@contextmanager
def modify_artifact(artifact):
filename = artifact.filename
Expand All @@ -284,28 +303,6 @@ def modify_artifact(artifact):
tf.close()


def approve_collection(client, collection):
"""Approve a collection version by moving it from the staging to published repository."""
move_collection(client, collection, "staging", "published")


def reject_collection(client, collection):
"""Reject a collection version by moving it from the staging to published repository."""
move_collection(client, collection, "staging", "rejected")


def move_collection(client, collection, source, destination):
"""Move a collection version between repositories.
For use in versions of the API that implement repository-based approval.
"""
namespace = collection.namespace
name = collection.name
version = collection.version
url = f"/v3/collections/{namespace}/{name}/versions/{version}/move/{source}/{destination}"
client(url, method="PUT")


def uuid4():
"""Return a random UUID4 as a string."""
return str(uuid.uuid4())
Expand Down Expand Up @@ -396,27 +393,12 @@ def set_certification(client, collection):
task_result = wait_for_task(client, ds)
assert task_result['state'] == 'completed', task_result

# give extra time for the backend to settle and "hidden" tasks to finish
# callers expect response as part of this method, ensure artifact is there
dest_url = (
f"v3/collections/{collection.namespace}/"
f"{collection.name}/versions/{collection.version}/"
"content/published/v3/plugin/ansible/content/published/collections/index/"
f"{collection.namespace}/{collection.name}/versions/{collection.version}/"
)
ready = False
timeout = SLEEP_SECONDS_POLLING * 5
res = None
while not ready:
try:
res = client(dest_url, method="GET")
# if we aren't done publishing, GalaxyError gets thrown and we skip
# past the below line and directly to the `except GalaxyError` line.
ready = True
except GalaxyError:
time.sleep(SLEEP_SECONDS_POLLING)
timeout = timeout - 1
if timeout < 0:
raise

return res
return wait_for_url(client, dest_url)


def generate_namespace(exclude=None):
Expand Down

0 comments on commit 9d23bf6

Please sign in to comment.