Skip to content

Commit b433b39

Browse files
authored
[ISV-4831] Improve bundle name checks (#650)
* [ISV-4831] Improve bundle name checks --------- Signed-off-by: Maurizio Porrato <[email protected]>
1 parent 7ad50c0 commit b433b39

File tree

4 files changed

+257
-42
lines changed

4 files changed

+257
-42
lines changed

operator-pipeline-images/operatorcert/static_tests/common/bundle.py

Lines changed: 71 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,78 @@
33
from collections.abc import Iterator
44

55
from operator_repo import Bundle
6-
from operator_repo.checks import CheckResult, Warn
6+
from operator_repo.checks import CheckResult, Fail, Warn
77

88

9-
def check_operator_name(bundle: Bundle) -> Iterator[CheckResult]:
10-
"""
11-
Ensure that the operator name matches the CSV name
9+
def _check_consistency(
10+
my_name: str, all_names: set[str], other_names: set[str], result_description: str
11+
) -> Iterator[CheckResult]:
12+
"""Helper function for check_operator_name"""
13+
if len(other_names) == 1:
14+
# Operator names are consistent across other bundles
15+
common_name = other_names.pop()
16+
if common_name != my_name:
17+
# The new bundle has a different operator name
18+
msg = (
19+
f"Operator name {result_description} ({my_name})"
20+
f" does not match the name defined in other"
21+
f" bundles ({common_name})"
22+
)
23+
yield Fail(msg)
24+
else:
25+
# Other bundles have inconsistent operator names: let's just issue a warning
26+
msg = (
27+
f"Operator name {result_description} is not consistent across bundles:"
28+
f" {sorted(all_names)}"
29+
)
30+
yield Warn(msg)
1231

13-
Args:
14-
bundle (Bundle): Tested operator bundle
15-
"""
16-
annotation_package = bundle.annotations.get(
17-
"operators.operatorframework.io.bundle.package.v1"
18-
)
19-
if annotation_package != bundle.csv_operator_name:
20-
yield Warn(
21-
f"Bundle package annotation is set to '{annotation_package}'. "
22-
f"Expected value is '{bundle.csv_operator_name}' based on the CSV name. "
23-
"To fix this issue define the annotation in "
24-
"'metadata/annotations.yaml' file that matches the CSV name."
32+
33+
def check_operator_name(bundle: Bundle) -> Iterator[CheckResult]:
34+
"""Check if the operator names used in CSV, metadata and filesystem are consistent
35+
in the bundle and across other operator's bundles"""
36+
if not bundle.metadata_operator_name:
37+
yield Fail("Bundle does not define the operator name in annotations.yaml")
38+
return
39+
all_bundles = set(bundle.operator.all_bundles())
40+
all_metadata_operator_names = {x.metadata_operator_name for x in all_bundles}
41+
all_csv_operator_names = {x.csv_operator_name for x in all_bundles}
42+
other_bundles = all_bundles - {bundle}
43+
other_metadata_operator_names = {x.metadata_operator_name for x in other_bundles}
44+
other_csv_operator_names = {x.csv_operator_name for x in other_bundles}
45+
# Count how many unique names are in use in the CSV and annotations.yaml across
46+
# all other bundles. Naming is consistent if the count is zero (when the bundle
47+
# under test is the only bundle for its operator) or one
48+
consistent_metadata_names = len(other_metadata_operator_names) < 2
49+
consistent_csv_names = len(other_csv_operator_names) < 2
50+
if other_bundles:
51+
yield from _check_consistency(
52+
bundle.metadata_operator_name,
53+
all_metadata_operator_names,
54+
other_metadata_operator_names,
55+
"from annotations.yaml",
56+
)
57+
yield from _check_consistency(
58+
bundle.csv_operator_name,
59+
all_csv_operator_names,
60+
other_csv_operator_names,
61+
"from the CSV",
62+
)
63+
if bundle.metadata_operator_name != bundle.csv_operator_name:
64+
msg = (
65+
f"Operator name from annotations.yaml ({bundle.metadata_operator_name})"
66+
f" does not match the name defined in the CSV ({bundle.csv_operator_name})"
67+
)
68+
if consistent_metadata_names and consistent_csv_names:
69+
yield Fail(msg)
70+
else:
71+
yield Warn(msg)
72+
if bundle.metadata_operator_name != bundle.operator_name:
73+
msg = (
74+
f"Operator name from annotations.yaml ({bundle.metadata_operator_name})"
75+
f" does not match the operator's directory name ({bundle.operator_name})"
2576
)
77+
if consistent_metadata_names:
78+
yield Fail(msg)
79+
else:
80+
yield Warn(msg)

operator-pipeline-images/tests/static_tests/common/test_bundle.py

Lines changed: 181 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,193 @@
1010

1111

1212
@pytest.mark.parametrize(
13-
"annotation_package,csv_package,expected",
13+
"files, bundle_to_check, expected_results",
1414
[
15-
pytest.param("foo", "foo", set(), id="Name matches"),
1615
pytest.param(
17-
"foo",
18-
"bar",
16+
[
17+
bundle_files("hello", "0.0.1"),
18+
],
19+
("hello", "0.0.1"),
20+
set(),
21+
id="Names ok",
22+
),
23+
pytest.param(
24+
[
25+
bundle_files(
26+
"hello",
27+
"0.0.1",
28+
annotations={
29+
"operators.operatorframework.io.bundle.package.v1": "foo"
30+
},
31+
),
32+
],
33+
("hello", "0.0.1"),
34+
{
35+
(
36+
Fail,
37+
"Operator name from annotations.yaml (foo) does not match"
38+
" the operator's directory name (hello)",
39+
),
40+
(
41+
Fail,
42+
"Operator name from annotations.yaml (foo) does not match"
43+
" the name defined in the CSV (hello)",
44+
),
45+
},
46+
id="Wrong annotations.yaml name",
47+
),
48+
pytest.param(
49+
[
50+
bundle_files("hello", "0.0.1"),
51+
{
52+
"operators/hello/0.0.1/metadata/annotations.yaml": {
53+
"annotations": {}
54+
}
55+
},
56+
],
57+
("hello", "0.0.1"),
58+
{
59+
(Fail, "Bundle does not define the operator name in annotations.yaml"),
60+
},
61+
id="Empty annotations.yaml",
62+
),
63+
pytest.param(
64+
[
65+
bundle_files("hello", "0.0.1"),
66+
bundle_files(
67+
"hello",
68+
"0.0.2",
69+
annotations={
70+
"operators.operatorframework.io.bundle.package.v1": "foo"
71+
},
72+
),
73+
bundle_files(
74+
"hello",
75+
"0.0.3",
76+
annotations={
77+
"operators.operatorframework.io.bundle.package.v1": "foo"
78+
},
79+
),
80+
],
81+
("hello", "0.0.3"),
82+
{
83+
(
84+
Warn,
85+
"Operator name from annotations.yaml (foo) does not match"
86+
" the operator's directory name (hello)",
87+
),
88+
(
89+
Warn,
90+
"Operator name from annotations.yaml (foo) does not match"
91+
" the name defined in the CSV (hello)",
92+
),
93+
(
94+
Warn,
95+
"Operator name from annotations.yaml is not consistent"
96+
" across bundles: ['foo', 'hello']",
97+
),
98+
},
99+
id="Wrong annotations.yaml name, inconsistent bundles",
100+
),
101+
pytest.param(
102+
[
103+
bundle_files("hello", "0.0.1"),
104+
bundle_files(
105+
"hello",
106+
"0.0.2",
107+
csv={"metadata": {"name": "foo.v0.0.2"}},
108+
),
109+
bundle_files(
110+
"hello",
111+
"0.0.3",
112+
csv={"metadata": {"name": "foo.v0.0.3"}},
113+
),
114+
],
115+
("hello", "0.0.3"),
116+
{
117+
(
118+
Warn,
119+
"Operator name from annotations.yaml (hello) does not match"
120+
" the name defined in the CSV (foo)",
121+
),
122+
(
123+
Warn,
124+
"Operator name from the CSV is not consistent across bundles: ['foo', 'hello']",
125+
),
126+
},
127+
id="Wrong CSV name, inconsistent bundles",
128+
),
129+
pytest.param(
130+
[
131+
bundle_files("hello", "0.0.1"),
132+
bundle_files("hello", "0.0.2"),
133+
bundle_files(
134+
"hello",
135+
"0.0.3",
136+
annotations={
137+
"operators.operatorframework.io.bundle.package.v1": "foo"
138+
},
139+
),
140+
],
141+
("hello", "0.0.3"),
19142
{
20-
Warn(
21-
"Bundle package annotation is set to 'foo'. Expected value "
22-
"is 'bar' based on the CSV name. To fix this issue define "
23-
"the annotation in 'metadata/annotations.yaml' file that "
24-
"matches the CSV name."
25-
)
143+
(
144+
Fail,
145+
"Operator name from annotations.yaml (foo) does not match"
146+
" the operator's directory name (hello)",
147+
),
148+
(
149+
Fail,
150+
"Operator name from annotations.yaml (foo) does not match"
151+
" the name defined in the CSV (hello)",
152+
),
153+
(
154+
Fail,
155+
"Operator name from annotations.yaml (foo) does not match"
156+
" the name defined in other bundles (hello)",
157+
),
26158
},
27-
id="Name does not match",
159+
id="Wrong annotations.yaml name, consistent bundles",
160+
),
161+
pytest.param(
162+
[
163+
bundle_files("hello", "0.0.1"),
164+
bundle_files("hello", "0.0.2"),
165+
bundle_files(
166+
"hello",
167+
"0.0.3",
168+
csv={"metadata": {"name": "foo.v0.0.3"}},
169+
),
170+
],
171+
("hello", "0.0.3"),
172+
{
173+
(
174+
Fail,
175+
"Operator name from annotations.yaml (hello) does not match"
176+
" the name defined in the CSV (foo)",
177+
),
178+
(
179+
Fail,
180+
"Operator name from the CSV (foo) does not match the name"
181+
" defined in other bundles (hello)",
182+
),
183+
},
184+
id="Wrong CSV name, consistent bundles",
28185
),
29186
],
187+
indirect=False,
30188
)
31-
def test_check_operator_name(
32-
annotation_package: str, csv_package: str, expected: Any, tmp_path: Path
189+
def test_operator_name(
190+
tmp_path: Path,
191+
files: list[dict[str, Any]],
192+
bundle_to_check: tuple[str, str],
193+
expected_results: set[tuple[type, str]],
33194
) -> None:
34-
annotations = {
35-
"operators.operatorframework.io.bundle.package.v1": annotation_package,
36-
}
37-
create_files(tmp_path, bundle_files(csv_package, "0.0.1", annotations=annotations))
38-
195+
create_files(tmp_path, *files)
39196
repo = Repo(tmp_path)
40-
bundle = repo.operator(csv_package).bundle("0.0.1")
41-
42-
assert set(check_operator_name(bundle)) == expected
197+
operator_name, bundle_version = bundle_to_check
198+
operator = repo.operator(operator_name)
199+
bundle = operator.bundle(bundle_version)
200+
assert {
201+
(x.__class__, x.reason) for x in check_operator_name(bundle)
202+
} == expected_results

pdm.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ dependencies = [
4848
"PyGithub<2.0,>=1.59.0",
4949
"GitPython>=3.1.37",
5050
"semver>=3.0.1",
51-
"operator-repo @ git+https://github.com/mporrato/[email protected].2",
51+
"operator-repo @ git+https://github.com/mporrato/[email protected].3",
5252
"urllib3>=2.0.7",
5353
]
5454

0 commit comments

Comments
 (0)