Skip to content

Commit

Permalink
Add minimum release for upgrade tests (#769)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Homayoon Alimohammadi <homayoon.alimohammadi@canonical.com>
  • Loading branch information
bschimke95 and HomayoonAlimohammadi authored Nov 8, 2024
1 parent d6de281 commit 953f4dd
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 12 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/nightly-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ jobs:
# Test the latest (up to) 6 releases for the flavour
# TODO(ben): upgrade nightly to run all flavours
TEST_VERSION_UPGRADE_CHANNELS: "recent 6 classic"
# Upgrading from 1.30 is not supported.
TEST_VERSION_UPGRADE_MIN_RELEASE: "1.31"
TEST_STRICT_INTERFACE_CHANNELS: "recent 6 strict"
run: |
export PATH="/home/runner/.local/bin:$PATH"
Expand Down
5 changes: 5 additions & 0 deletions tests/integration/tests/test_util/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@
VERSION_UPGRADE_CHANNELS = (
os.environ.get("TEST_VERSION_UPGRADE_CHANNELS", "").strip().split()
)

# The minimum Kubernetes release to upgrade from (e.g. "1.31")
# Only relevant when using 'recent' in VERSION_UPGRADE_CHANNELS.
VERSION_UPGRADE_MIN_RELEASE = os.environ.get("TEST_VERSION_UPGRADE_MIN_RELEASE")

# A list of space-separated channels for which the strict interface tests should be run in sequential order.
# Alternatively, use 'recent <num> strict' to get the latest <num> channels for strict.
STRICT_INTERFACE_CHANNELS = (
Expand Down
15 changes: 13 additions & 2 deletions tests/integration/tests/test_util/snap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import re
import urllib.error
import urllib.request
from typing import List
from typing import List, Optional

from test_util.util import major_minor

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -60,7 +62,11 @@ def filter_arch_and_flavor(channels: List[dict], arch: str, flavor: str) -> List


def get_most_stable_channels(
num_of_channels: int, flavor: str, arch: str, include_latest=True
num_of_channels: int,
flavor: str,
arch: str,
include_latest: bool = True,
min_release: Optional[str] = None,
) -> List[str]:
"""Get an ascending list of latest channels based on the number of channels
flavour and architecture."""
Expand All @@ -76,6 +82,11 @@ def get_most_stable_channels(
for channel, major, minor, risk in arch_flavor_channels:
version_key = (int(major), int(minor))

if min_release is not None:
_min_release = major_minor(min_release)
if _min_release is not None and version_key < _min_release:
continue

if version_key not in channel_map or RISK_LEVELS.index(
risk
) < RISK_LEVELS.index(channel_map[version_key][1]):
Expand Down
27 changes: 18 additions & 9 deletions tests/integration/tests/test_util/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,21 @@ def tracks_least_risk(track: str, arch: str) -> str:
return channel


def major_minor(version: str) -> Optional[tuple]:
"""Determine the major and minor version of a Kubernetes version string.
Args:
version: the version string to determine the major and minor version for
Returns:
a tuple containing the major and minor version or None if the version string is invalid
"""
if match := TRACK_RE.match(version):
maj, min, _ = match.groups()
return int(maj), int(min)
return None


def previous_track(snap_version: str) -> str:
"""Determine the snap track preceding the provided version.
Expand All @@ -392,12 +407,6 @@ def previous_track(snap_version: str) -> str:
"""
LOG.debug("Determining previous track for %s", snap_version)

def _maj_min(version: str):
if match := TRACK_RE.match(version):
maj, min, _ = match.groups()
return int(maj), int(min)
return None

if not snap_version:
assumed = "latest"
LOG.info(
Expand All @@ -414,20 +423,20 @@ def _maj_min(version: str):
)
return assumed

if maj_min := _maj_min(snap_version):
if maj_min := major_minor(snap_version):
maj, min = maj_min
if min == 0:
with urllib.request.urlopen(
f"https://dl.k8s.io/release/stable-{maj - 1}.txt"
) as r:
stable = r.read().decode().strip()
maj_min = _maj_min(stable)
maj_min = major_minor(stable)
else:
maj_min = (maj, min - 1)
elif snap_version.startswith("latest") or "/" not in snap_version:
with urllib.request.urlopen("https://dl.k8s.io/release/stable.txt") as r:
stable = r.read().decode().strip()
maj_min = _maj_min(stable)
maj_min = major_minor(stable)

flavor_track = {"": "classic", "strict": ""}.get(config.FLAVOR, config.FLAVOR)
track = f"{maj_min[0]}.{maj_min[1]}" + (flavor_track and f"-{flavor_track}")
Expand Down
11 changes: 10 additions & 1 deletion tests/integration/tests/test_version_upgrades.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,16 @@ def test_version_upgrades(instances: List[harness.Instance], tmp_path):
"'recent' requires the number of releases as second argument and the flavour as third argument"
)
_, num_channels, flavour = channels
channels = snap.get_most_stable_channels(int(num_channels), flavour, cp.arch)
channels = snap.get_most_stable_channels(
int(num_channels),
flavour,
cp.arch,
min_release=config.VERSION_UPGRADE_MIN_RELEASE,
)
if len(channels) < 2:
pytest.fail(
f"Need at least 2 channels to upgrade, got {len(channels)} for flavour {flavour}"
)
current_channel = channels[0]

LOG.info(
Expand Down

0 comments on commit 953f4dd

Please sign in to comment.