Skip to content

Commit

Permalink
Add a check for updateGraph values in config
Browse files Browse the repository at this point in the history
The new check verifies that only allowed values are used in the config
for updateGraph field and in case the value is missing the Warning is
raised with an info that a default is used.

JIRA: ISV-4197

Signed-off-by: Ales Raszka <[email protected]>
  • Loading branch information
Allda committed Oct 31, 2023
1 parent 127933b commit 5b08bab
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 11 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ jobs:

- name: Install dependencies
run: |
pdm sync -dG operator-pipelines-dev
pdm sync -dG tox
- name: Run Tests
run: |
pdm run -v tox
run: tox
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ def check_dangling_bundles(bundle: Bundle) -> Iterator[CheckResult]:
for channel in sorted(all_channels):
channel_bundles = operator.channel_bundles(channel)
channel_head = operator.head(channel)
graph = operator.update_graph(channel)
try:
graph = operator.update_graph(channel)
except NotImplementedError as exc:
yield Fail(str(exc))
return
dangling_bundles = {
x for x in channel_bundles if x not in graph and x != channel_head
}
Expand Down Expand Up @@ -175,7 +179,11 @@ def check_upgrade_graph_loop(bundle: Bundle) -> Iterator[CheckResult]:
visited: List[Bundle] = []
try:
channel_bundles = operator.channel_bundles(channel)
graph = operator.update_graph(channel)
try:
graph = operator.update_graph(channel)
except NotImplementedError as exc:
yield Fail(str(exc))
return
follow_graph(graph, channel_bundles[0], visited)
except GraphLoopException as exc:
yield Fail(str(exc))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,27 @@
from collections.abc import Iterator

from operator_repo import Operator
from operator_repo.checks import CheckResult, Fail
from operator_repo.checks import CheckResult, Fail, Warn


def check_operator_name(operator: Operator) -> Iterator[CheckResult]:
"""Ensure all operator's bundles use the same operator name in their CSV"""
names = {bundle.csv_operator_name for bundle in operator}
if len(names) > 1:
yield Fail(f"Bundles use multiple operator names: {names}")


def check_ci_upgrade_graph(operator: Operator) -> Iterator[CheckResult]:
"""Ensure the operator has a valid upgrade graph for ci.yaml"""
upgrade_graph = operator.config.get("updateGraph")
if not upgrade_graph:
yield Warn(
"The 'updateGraph' option is missing in ci.yaml. "
"The default upgrade graph 'replaces-mode' will be used."
)
else:
allowed_graphs = ["replaces-mode", "semver-mode"]
if upgrade_graph not in allowed_graphs:
yield Fail(
f"The 'updateGraph' option in ci.yaml must be one of {allowed_graphs}"
)
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,9 @@ def test_required_fields(
assert expected_successes.intersection(collected_results.keys()) == set()


def test_check_dangling_bundles(tmp_path: Path) -> None:
@patch("operator_repo.core.Operator.config")
def test_check_dangling_bundles(mock_config: MagicMock, tmp_path: Path) -> None:
mock_config.get.return_value = "replaces-mode"
create_files(
tmp_path,
bundle_files("hello", "0.0.1"),
Expand All @@ -217,6 +219,13 @@ def test_check_dangling_bundles(tmp_path: Path) -> None:
failures = list(check_dangling_bundles(bundle3))
assert failures == []

mock_config.get.return_value = "unknown-mode"
is_loop = list(check_dangling_bundles(bundle3))
assert is_loop == [
Fail("Operator(hello): unsupported updateGraph value: unknown-mode")
]

mock_config.get.return_value = "replaces-mode"
# Bundle 0.0.2 is not referenced by any bundle and it is not a HEAD of channel
create_files(
tmp_path,
Expand All @@ -234,7 +243,9 @@ def test_check_dangling_bundles(tmp_path: Path) -> None:
)


def test_check_upgrade_graph_loop(tmp_path: Path) -> None:
@patch("operator_repo.core.Operator.config")
def test_check_upgrade_graph_loop(mock_config: MagicMock, tmp_path: Path) -> None:
mock_config.get.return_value = "replaces-mode"
create_files(
tmp_path,
bundle_files("hello", "0.0.1"),
Expand All @@ -247,6 +258,13 @@ def test_check_upgrade_graph_loop(tmp_path: Path) -> None:
is_loop = list(check_upgrade_graph_loop(bundle))
assert is_loop == []

mock_config.get.return_value = "unknown-mode"
is_loop = list(check_upgrade_graph_loop(bundle))
assert is_loop == [
Fail("Operator(hello): unsupported updateGraph value: unknown-mode")
]

mock_config.get.return_value = "replaces-mode"
# Both bundles replace each other
create_files(
tmp_path,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
from pathlib import Path
from typing import Any

import pytest
import yaml
from operator_repo import Repo

from operatorcert.static_tests.community.operator import check_operator_name
from tests.utils import create_files, bundle_files
from operator_repo.checks import Fail, Warn
from operatorcert.static_tests.community.operator import (
check_ci_upgrade_graph,
check_operator_name,
)
from tests.utils import bundle_files, create_files


def test_check_operator_name(tmp_path: Path) -> None:
Expand All @@ -20,3 +26,54 @@ def test_check_operator_name(tmp_path: Path) -> None:
),
)
assert [x.kind for x in check_operator_name(operator)] == ["failure"]


@pytest.mark.parametrize(
"graph_mode, expected",
[
pytest.param(
"",
{
Warn(
"The 'updateGraph' option is missing in ci.yaml. The default upgrade graph 'replaces-mode' will be used."
)
},
id="empty",
),
pytest.param(
"replaces-mode",
set(),
id="replaces",
),
pytest.param(
"semver-mode",
set(),
id="semver",
),
pytest.param(
"unknown-mode",
{
Fail(
"The 'updateGraph' option in ci.yaml must be one of ['replaces-mode', 'semver-mode']",
)
},
id="unknown",
),
],
)
def test_check_ci_upgrade_graph(graph_mode: str, expected: Any, tmp_path: Path) -> None:
create_files(
tmp_path,
bundle_files(
"test-operator",
"0.0.1",
other_files={
"operators/test-operator/ci.yaml": {"updateGraph": graph_mode}
},
),
)
repo = Repo(tmp_path)
operator = repo.operator("test-operator")
result = check_ci_upgrade_graph(operator)

assert set(result) == expected

0 comments on commit 5b08bab

Please sign in to comment.