1
0
Fork 0
operator-repo/tests/checks/test_bundle.py

189 lines
5.8 KiB
Python

from pathlib import Path
from typing import Any, Union
import pytest
from operator_repo import Repo
from operator_repo.checks.bundle import check_image, check_operator_name, check_semver
from tests import bundle_files, create_files, make_nested_dict
@pytest.mark.parametrize(
"base_bundle_files, extra_files, expected_results",
[
(
bundle_files("hello", "0.0.1"),
{},
set(),
),
(
bundle_files(
"hello",
"0.0.1",
annotations={"operators.operatorframework.io.bundle.package.v1": "foo"},
),
{},
{
"Operator name from annotations.yaml (foo) does not match the operator's directory name (hello)",
"Operator name from annotations.yaml (foo) does not match the name defined in the CSV (hello)",
},
),
(
bundle_files("hello", "0.0.1"),
{"operators/hello/0.0.1/metadata/annotations.yaml": {"annotations": {}}},
{
"Bundle does not define the operator name in annotations.yaml",
},
),
],
indirect=False,
ids=["Names ok", "Wrong annotations.yaml", "Empty annotations.yaml"],
)
def test_operator_name(
tmp_path: Path,
base_bundle_files: dict[str, Any],
extra_files: dict[str, Any],
expected_results: set[str],
) -> None:
create_files(tmp_path, base_bundle_files, extra_files)
repo = Repo(tmp_path)
operator = next(repo.all_operators())
bundle = next(operator.all_bundles())
assert {x.reason for x in check_operator_name(bundle)} == expected_results
@pytest.mark.parametrize(
"base_bundle_files, extra_files, expected_results",
[
(
bundle_files("hello", "0.0.1"),
{},
{"CSV doesn't define .metadata.annotations.containerImage"},
),
(
bundle_files(
"hello",
"0.0.1",
csv=make_nested_dict(
{
"metadata.annotations.containerImage": "example.com/namespace/image:tag",
}
),
),
{},
{"CSV doesn't define .spec.install.spec.deployments"},
),
(
bundle_files(
"hello",
"0.0.1",
csv=make_nested_dict(
{
"metadata.annotations.containerImage": "example.com/namespace/image:tag",
"spec.install.spec.deployments": [
make_nested_dict(
{
"spec.template.spec.containers": [
{"image": "example.com/namespace/image:tag"}
]
}
),
],
}
),
),
{},
set(),
),
(
bundle_files(
"hello",
"0.0.1",
csv=make_nested_dict(
{
"metadata.annotations.containerImage": "example.com/namespace/image:tag",
"spec.install.spec.deployments": [
make_nested_dict(
{
"spec.template.spec.containers": [
{
"image": "example.com/namespace/image:othertag"
}
]
}
),
],
}
),
),
{},
{
"container image example.com/namespace/image:tag not used by any deployment"
},
),
(
bundle_files("hello", "0.0.1"),
{"operators/hello/0.0.1/manifests/hello.clusterserviceversion.yaml": ""},
"Invalid CSV contents ",
),
],
indirect=False,
ids=[
"Missing containerImage",
"Missing deployments",
"Matching images",
"Mismatched images",
"Empty CSV",
],
)
def test_image(
tmp_path: Path,
base_bundle_files: dict[str, Any],
extra_files: dict[str, Any],
expected_results: Union[set[str], str],
) -> None:
create_files(tmp_path, base_bundle_files, extra_files)
repo = Repo(tmp_path)
operator = next(repo.all_operators())
bundle = next(operator.all_bundles())
reasons = {x.reason for x in check_image(bundle)}
if isinstance(expected_results, str):
assert len(reasons) == 1
reason = reasons.pop()
assert expected_results in reason
else:
assert reasons == expected_results
@pytest.mark.parametrize(
"base_bundle_files, extra_files, expected_results",
[
(
bundle_files("hello", "0.0.1"),
{},
set(),
),
(
bundle_files("hello", "latest"),
{},
{
"Version from CSV (latest) is not valid semver",
"Version from filesystem (latest) is not valid semver",
},
),
],
indirect=False,
ids=["All versions ok", "Both versions invalid"],
)
def test_semver(
tmp_path: Path,
base_bundle_files: dict[str, Any],
extra_files: dict[str, Any],
expected_results: set[str],
) -> None:
create_files(tmp_path, base_bundle_files, extra_files)
repo = Repo(tmp_path)
operator = next(repo.all_operators())
bundle = next(operator.all_bundles())
assert {x.reason for x in check_semver(bundle)} == expected_results