-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add basic sanity test for upgrade
Signed-off-by: Niladri Halder <[email protected]>
- Loading branch information
Showing
12 changed files
with
518 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,5 +22,6 @@ __pycache__ | |
/kubectl-plugin | ||
|
||
# Pytest assets | ||
/test-bin-* | ||
/test-dir-* | ||
tests/bdd/venv | ||
pytest.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[pytest] | ||
log_cli = true | ||
log_cli_level = INFO | ||
log_cli_format = %(asctime)s [%(levelname)s] %(message)s | ||
log_cli_date_format = %Y-%m-%d %H:%M:%S | ||
log_file = pytest.log | ||
log_file_level = DEBUG |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import logging | ||
import os | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def get_env(variable: str): | ||
try: | ||
value = os.getenv(variable) | ||
if len(value) == 0: | ||
raise ValueError("Env {variable} is empty") | ||
logger.info(f"Found env {variable}={value}") | ||
return value | ||
|
||
except Exception as e: | ||
logger.error(f"Failed to get env {variable}: {e}") | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,305 @@ | ||
import json | ||
import logging | ||
import os | ||
import subprocess | ||
from enum import Enum | ||
from shutil import which | ||
|
||
from common import repo | ||
from common.environment import get_env | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
helm_bin = which("helm") | ||
|
||
|
||
def repo_ls(): | ||
try: | ||
result = subprocess.run( | ||
[helm_bin, "repo", "ls", "-o", "json"], | ||
capture_output=True, | ||
check=True, | ||
text=True, | ||
) | ||
return json.loads(result.stdout.strip()) | ||
|
||
except subprocess.CalledProcessError as e: | ||
logger.error( | ||
f"Error: command 'helm repo ls -o json' failed with exit code {e.returncode}" | ||
) | ||
logger.error(f"Error Output: {e.stderr}") | ||
return None | ||
|
||
except Exception as e: | ||
logger.error(f"An unexpected error occurred: {e}") | ||
return None | ||
|
||
|
||
def repo_add_mayastor(): | ||
repos = repo_ls() | ||
if repos is not None: | ||
for r in repos: | ||
if r["url"] == "https://openebs.github.io/mayastor-extensions": | ||
return r["name"] | ||
|
||
try: | ||
repo_name = "mayastor" | ||
subprocess.run( | ||
[ | ||
helm_bin, | ||
"repo", | ||
"add", | ||
repo_name, | ||
"https://openebs.github.io/mayastor-extensions", | ||
], | ||
capture_output=True, | ||
check=True, | ||
text=True, | ||
) | ||
|
||
subprocess.run( | ||
[ | ||
helm_bin, | ||
"repo", | ||
"update", | ||
], | ||
capture_output=True, | ||
check=True, | ||
text=True, | ||
) | ||
return repo_name | ||
|
||
except subprocess.CalledProcessError as e: | ||
logger.error( | ||
f"Error: command 'helm repo add mayastor https://openebs.github.io/mayastor-extensions' failed with exit code {e.returncode}" | ||
) | ||
logger.error(f"Error Output: {e.stderr}") | ||
return None | ||
|
||
except Exception as e: | ||
logger.error(f"An unexpected error occurred: {e}") | ||
return None | ||
|
||
|
||
def latest_chart_so_far(version=None): | ||
if version is None: | ||
v = get_env("UPGRADE_TARGET_VERSION") | ||
if v is None: | ||
version = generate_test_tag() | ||
else: | ||
version = v | ||
|
||
repo_name = repo_add_mayastor() | ||
assert repo_name is not None | ||
|
||
helm_search_command = [ | ||
helm_bin, | ||
"search", | ||
"repo", | ||
repo_name + "/mayastor", | ||
"--version", | ||
"<" + version, | ||
"-o", | ||
"json", | ||
] | ||
try: | ||
result = subprocess.run( | ||
helm_search_command, | ||
capture_output=True, | ||
check=True, | ||
text=True, | ||
) | ||
result_chart_info = json.loads(result.stdout.strip()) | ||
return result_chart_info[0]["version"] | ||
|
||
except subprocess.CalledProcessError as e: | ||
logger.error( | ||
f"Error: command {helm_search_command} failed with exit code {e.returncode}" | ||
) | ||
logger.error(f"Error Output: {e.stderr}") | ||
return None | ||
|
||
except Exception as e: | ||
logger.error(f"An unexpected error occurred: {e}") | ||
return None | ||
|
||
|
||
class ChartSource(Enum): | ||
HOSTED = "mayastor" | ||
LOCAL = [ | ||
"/bin/bash", | ||
"-c", | ||
os.path.join(repo.root_dir(), "scripts/helm/install.sh") | ||
+ " --dep-update --wait", | ||
] | ||
|
||
|
||
class HelmReleaseClient: | ||
""" | ||
A client for interacting with Helm releases in a specified Kubernetes namespace. | ||
Attributes: | ||
namespace (str): The Kubernetes namespace where the Helm releases are managed. | ||
""" | ||
|
||
def __init__(self): | ||
""" | ||
Initializes the HelmReleaseClient. | ||
""" | ||
self.namespace = "mayastor" | ||
|
||
def get_metadata_mayastor(self): | ||
command = [ | ||
helm_bin, | ||
"get", | ||
"metadata", | ||
"mayastor", | ||
"-n", | ||
self.namespace, | ||
"-o", | ||
"json", | ||
] | ||
try: | ||
result = subprocess.run( | ||
command, | ||
capture_output=True, | ||
check=True, | ||
text=True, | ||
) | ||
return json.loads(result.stdout.strip()) | ||
|
||
except subprocess.CalledProcessError as e: | ||
logger.error( | ||
f"Error: command '{command}' failed with exit code {e.returncode}" | ||
) | ||
logger.error(f"Error Output: {e.stderr}") | ||
return None | ||
|
||
except Exception as e: | ||
logger.error(f"An unexpected error occurred: {e}") | ||
return None | ||
|
||
def list(self): | ||
""" | ||
Lists the deployed Helm releases in the specified namespace. | ||
Executes the 'helm ls' command to retrieve a list of deployed releases. | ||
Returns: | ||
str: A newline-separated string of deployed release names, or None if an error occurs. | ||
""" | ||
try: | ||
result = subprocess.run( | ||
[ | ||
helm_bin, | ||
"ls", | ||
"-n", | ||
self.namespace, | ||
"--deployed", | ||
"--short", | ||
], | ||
capture_output=True, | ||
check=True, | ||
text=True, | ||
) | ||
return result.stdout.strip() | ||
|
||
except subprocess.CalledProcessError as e: | ||
logger.error( | ||
f"Error: command 'helm ls -n {self.namespace} --deployed --short' failed with exit code {e.returncode}" | ||
) | ||
logger.error(f"Error Output: {e.stderr}") | ||
return None | ||
|
||
except Exception as e: | ||
logger.error(f"An unexpected error occurred: {e}") | ||
return None | ||
|
||
def release_is_deployed(self, release_name: str): | ||
releases = self.list() | ||
if releases is not None: | ||
for release in releases: | ||
if release == release_name: | ||
return True | ||
return False | ||
|
||
def install_mayastor(self, source: ChartSource, version=None): | ||
if self.release_is_deployed("mayastor"): | ||
logger.error( | ||
f"WARN: Helm release 'mayastor' already exists in the 'mayastor' namespace." | ||
) | ||
return | ||
|
||
install_command = [] | ||
if source == ChartSource.HOSTED: | ||
repo_name = repo_add_mayastor() | ||
assert repo_name is not None | ||
|
||
install_command += [ | ||
helm_bin, | ||
"install", | ||
"mayastor", | ||
repo_name + "/" + source.value, | ||
"--namespace=" + self.namespace, | ||
"--create-namespace", | ||
"--set", | ||
"obs.callhome.sendReport=false,localpv-provisioner.analytics.enabled=false,etcd.livenessProbe.initialDelaySeconds=5,etcd.readinessProbe.initialDelaySeconds=5,etcd.replicaCount=1,eventing.enabled=false", | ||
] | ||
if version is not None: | ||
install_command += ["--version=" + version] | ||
install_command += ["--wait"] | ||
logger.info( | ||
f"Installing mayastor helm chart from hosted registry, version='{version}'" | ||
) | ||
|
||
if source == ChartSource.LOCAL: | ||
install_command = source.value | ||
logger.info("Installing mayastor helm chart from local directory") | ||
|
||
try: | ||
result = subprocess.run( | ||
install_command, | ||
capture_output=True, | ||
check=True, | ||
text=True, | ||
) | ||
logger.info("Installation succeeded") | ||
return result.stdout.strip() | ||
|
||
except subprocess.CalledProcessError as e: | ||
logger.error( | ||
f"Error: command {install_command} failed with exit code {e.returncode}" | ||
) | ||
logger.error(f"Error Output: {e.stderr}") | ||
return None | ||
|
||
except Exception as e: | ||
logger.error(f"An unexpected error occurred: {e}") | ||
return None | ||
|
||
|
||
def generate_test_tag(): | ||
generate_test_tag_script = [ | ||
"/bin/bash", | ||
"-c", | ||
os.path.join(repo.root_dir(), "scripts/python/generate-test-tag.sh"), | ||
] | ||
try: | ||
result = subprocess.run( | ||
generate_test_tag_script, | ||
capture_output=True, | ||
check=True, | ||
text=True, | ||
) | ||
return result.stdout.strip() | ||
|
||
except subprocess.CalledProcessError as e: | ||
logger.error( | ||
f"Error: command {generate_test_tag_script} failed with exit code {e.returncode}" | ||
) | ||
logger.error(f"Error Output: {e.stderr}") | ||
return None | ||
|
||
except Exception as e: | ||
logger.error(f"An unexpected error occurred: {e}") | ||
return None |
Oops, something went wrong.