Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve waits in integration tests #1322

Merged
merged 5 commits into from
Jun 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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