Skip to content

Commit

Permalink
feat: add logging and robustness checks to test_charm_with_profile.py (
Browse files Browse the repository at this point in the history
…#147)

Adds logic to give a new Profile enough time to be initialized before we try
to use it, as well as better logging to make it clear what is happening.

Fixes #136
  • Loading branch information
ca-scribner committed Nov 22, 2023
1 parent 55dcd5a commit 8b2e666
Showing 1 changed file with 32 additions and 4 deletions.
36 changes: 32 additions & 4 deletions tests/integration/test_charm_with_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@
# See LICENSE file for licensing details.
import glob
import logging
import time
from pathlib import Path

import lightkube
import pytest
import yaml
from lightkube import codecs
from lightkube.generic_resource import create_global_resource
from lightkube.resources.core_v1 import ServiceAccount
from lightkube.resources.rbac_authorization_v1 import RoleBinding
from pytest_operator.plugin import OpsTest
from tenacity import RetryError, Retrying, stop_after_attempt, stop_after_delay, wait_exponential
from tenacity import (
RetryError,
Retrying,
before_sleep_log,
stop_after_attempt,
stop_after_delay,
wait_exponential,
)

basedir = Path("./").absolute()
PROFILE_NAMESPACE = "profile-example"
Expand Down Expand Up @@ -60,6 +70,7 @@ async def test_authorization_for_creating_resources(
# Set up for creating an object of kind *Job
job_yaml = yaml.safe_load(Path(example).read_text())
training_job = job_yaml["kind"]
log.info(f"Checking `kubectl can-i create` for {training_job}")
_, stdout, _ = await ops_test.run(
"kubectl",
"auth",
Expand Down Expand Up @@ -112,18 +123,35 @@ def apply_profile(lightkube_client):

# Apply Profile first
apply_manifests(lightkube_client, PROFILE_FILE_PATH)
log.info(f"Profile from {PROFILE_FILE_PATH} applied.")

# Allow time for the Profile to be created
# Ensure the Profile is fully initialized
try:
for attempt in Retrying(
stop=(stop_after_attempt(10) | stop_after_delay(30)),
wait=wait_exponential(multiplier=1, min=5, max=10),
reraise=True,
before_sleep=before_sleep_log(log, logging.INFO),
):
with attempt:
lightkube_client.get(profile_resource, name=PROFILE_NAME)
# Look for the Profile and some of the objects expected in an instantiated
# Profile (to avoid https://github.com/canonical/training-operator/issues/136)
for resource, name, namespace in (
(profile_resource, PROFILE_NAME, None),
(ServiceAccount, "default-editor", PROFILE_NAME),
(RoleBinding, "default-editor", PROFILE_NAME),
):
log.info(f"Looking for {resource} of name {name}")
lightkube_client.get(resource, name=name, namespace=namespace)
log.info(f"Found {resource} of name {name}")
except RetryError:
log.info(f"Profile {PROFILE_NAME} not found.")
log.info(f"Profile {PROFILE_NAME} not found or found to be incomplete.")

# Wait a few seconds more just in case the profile-controller is still creating the Profile
# to avoid https://github.com/canonical/training-operator/issues/136
sleeptime = 5
log.info(f"Waiting {sleeptime}s to ensure Profile is fully initialized")
time.sleep(sleeptime)

yield

Expand Down

0 comments on commit 8b2e666

Please sign in to comment.