From ba5995e7158980bb143814374cb1c22e79ac8759 Mon Sep 17 00:00:00 2001 From: Ales Raszka Date: Mon, 26 Aug 2024 15:03:11 +0200 Subject: [PATCH] Fix: Recognize operator bundle directory A detect changes task wasn't able to recognize bundle directories in the operator directory. It marked all directories as a bundle no matter its content. This caused issue when introducing a catalog-templates directory which is operator sub-directory but not a bundle. This commit makes a parser more clever and uses a OperatorRepo probes to detect operator bundle dir. In case it is not recognized as a bundle it is automatically marked as "other" files owner by the operator. This commit also simplifies a unit tests to reduce amount of fixtures objects size. JIRA: ISV-5168 Signed-off-by: Ales Raszka --- .../entrypoints/detect_changed_operators.py | 94 +++++- .../tests/data/test-repo.tar | Bin 296960 -> 317440 bytes .../test_detect_changed_operators.py | 285 +++++------------- 3 files changed, 153 insertions(+), 226 deletions(-) diff --git a/operator-pipeline-images/operatorcert/entrypoints/detect_changed_operators.py b/operator-pipeline-images/operatorcert/entrypoints/detect_changed_operators.py index e50f56481..6705a5728 100644 --- a/operator-pipeline-images/operatorcert/entrypoints/detect_changed_operators.py +++ b/operator-pipeline-images/operatorcert/entrypoints/detect_changed_operators.py @@ -94,8 +94,68 @@ def github_pr_affected_files(pr_url: str) -> set[str]: return {x.filename for x in gh_pr.get_files()} +def is_operator_bundle_dir( + operator_name: str, + bundle_version: str, + head_repo: OperatorRepo, + base_repo: OperatorRepo, +) -> tuple[bool, bool]: + """ + Check if provided operator and bundle exist in either the head or base repo + + Returns a tuple of two booleans, the first indicating if the operator exists + and the second indicating if the bundle exists. + + Args: + operator_name (str): Operator name given by the directory name + bundle_version (str): A bundle version given by the directory name + head_repo (OperatorRepo): Git repository with the head state + base_repo (OperatorRepo): Git repository with the base state + + Returns: + tuple[bool, bool]: A tuple of two booleans indicating if the operator + and bundle exist in either the head or base repo + """ + # Check if the operator and bundle exist in either the head or base repo + is_operator = False + is_bundle = False + for repo in [head_repo, base_repo]: + if repo.has(operator_name): + is_operator = True + if repo.operator(operator_name).has(bundle_version): + is_bundle = True + return is_operator, is_bundle + + +def is_catalog_operator_dir( + catalog_name: str, + catalog_operator: str, + head_repo: OperatorRepo, + base_repo: OperatorRepo, +) -> bool: + """ + Check if provided catalog and operator exist in either the head or base repo + + Args: + catalog_name (str): A catalog name given by the directory name + catalog_operator (str): A catalog operator given by the directory name + head_repo (OperatorRepo): Git repository with the head state + base_repo (OperatorRepo): Git repository with the base state + + Returns: + bool: A boolean indicating if the catalog and operator exist in either + the head or base repo + """ + # Check if the catalog and operator exist in either the head or base repo + for repo in [head_repo, base_repo]: + if repo.has_catalog(catalog_name): + if repo.catalog(catalog_name).has(catalog_operator): + return True + return False + + def _find_directory_owner( - path: str, + path: str, head_repo: OperatorRepo, base_repo: OperatorRepo ) -> tuple[Optional[str], Optional[str], Optional[str], Optional[str]]: """ Given a relative file name within an operator repo, return a tuple @@ -106,6 +166,8 @@ def _find_directory_owner( If the file is outside an operator or catalog directory, all returns will be None. Args: path: Path to the file + head_repo: OperatorRepo object representing the head state of the repo + base_repo: OperatorRepo object representing the base state of the repo Returns: (operator_name, bundle_version, catalog_name, catalog_operator) Operator/bundle, Catalog/operator the files belongs to @@ -115,22 +177,26 @@ def _find_directory_owner( filename_parts = pathlib.Path(path).parts if len(filename_parts) >= 3 and filename_parts[0] == "operators": # inside an operator directory - _, detected_operator_name, detected_bundle_version, *rest = filename_parts - if len(rest) < 1: - # inside an operator but not in a bundle (i.e.: the ci.yaml file) - return detected_operator_name, None, None, None - return detected_operator_name, detected_bundle_version, None, None + is_operator, is_bundle = is_operator_bundle_dir( + filename_parts[1], filename_parts[2], head_repo, base_repo + ) + if is_operator and is_bundle: + return filename_parts[1], filename_parts[2], None, None + if is_operator: + # path is inside an operator but outside a bundle + # (i.e.: ci.yaml, catalog-templates, Makefile) + return filename_parts[1], None, None, None if len(filename_parts) >= 3 and filename_parts[0] == "catalogs": - # inside a catalog directory - _, detected_catalog_name, catalog_operator, *rest = filename_parts - if len(rest) >= 1: - return None, None, detected_catalog_name, catalog_operator + if is_catalog_operator_dir( + filename_parts[1], filename_parts[2], head_repo, base_repo + ): + return None, None, filename_parts[1], filename_parts[2] # path is outside an operator or catalog directory return None, None, None, None def _affected_bundles_and_operators_from_files( - affected_files: set[str], + affected_files: set[str], head_repo: OperatorRepo, base_repo: OperatorRepo ) -> tuple[dict[str, set[Optional[str]]], dict[str, set[Optional[str]]], set[str]]: """ Group a given set of file names depending on the operator, bundle, @@ -138,6 +204,8 @@ def _affected_bundles_and_operators_from_files( Args: affected_files: set of files names to parse + head_repo: OperatorRepo object representing the head state of the repo + base_repo: OperatorRepo object representing the base state of the repo Returns: A tuple containing: @@ -159,7 +227,7 @@ def _affected_bundles_and_operators_from_files( bundle_version, catalog_name, catalog_operator, - ) = _find_directory_owner(filename) + ) = _find_directory_owner(filename, head_repo, base_repo) if operator_name is None and catalog_name is None: extra_files.add(filename) elif operator_name is not None: @@ -396,7 +464,7 @@ def detect_changes( all_affected_bundles, all_affected_catalog_operators, non_operator_files, - ) = _affected_bundles_and_operators_from_files(pr_files) + ) = _affected_bundles_and_operators_from_files(pr_files, head_repo, base_repo) operators = detect_changed_operators(head_repo, base_repo, all_affected_bundles) bundles = detect_changed_operator_bundles( diff --git a/operator-pipeline-images/tests/data/test-repo.tar b/operator-pipeline-images/tests/data/test-repo.tar index eb6d770b48d6bbfeb5d08a486d83835f0a061164..e0320926d1416a2ebe5be42001f4ae524650ced2 100644 GIT binary patch delta 4383 zcmd^Cdsr0Z8lP`xm766O6ZMF0UP`>M-`r{K?5_h z;B?4vCOgoweN~jg)C2cK5OUsTKUDU(*W_M?oMeFhWeRv*N;QPLJe(&%7 zz3=y%g5vOks)*uc5iCnVhK3A*L4trBfti>xB2uma;ANmMLRwqoDCk@42xf)%;@r9W0^mPyxU@12uFsXl0@WXclNF(F$ed zc-~4fkYPoOC|V%oX-On`k)R1H&00#r23J($Mn~#F&?}O{2--uJ#s~>H5=D2VR09qK zfXV7iNI(dmfG4OE6b)xq?fWgW!hCFRkEtyIR)Xjnv-xvlxoKc&L_)az=I3(~lIxe@a%E}S6f;XvW@F83zFA#;@>FcXE73ciPdR^jk|WW-Eog`A&94A&Q$crh5-DC6 zC8{6*VF^d;6O*BMqN(Y!0gHItP^95H07^_TwWAHoc6*>voYoK&2YtjhX~^y%WCLWz zEE5tW1<13!00pZ=P!vKVavZ4$qG%OZD<#rI8PPCA(^gsP*>k>5Gw%n>=F}^g= zKWUa^yglwx+j86(&GKeS<}9>T;V4EHdB!4(lFV4NL}^J8Xba8Lim1@uYRGt>wsA>< zCeiG0^^yvB}TCbJVPM}oGb}6%lJ?(X^)bC zI!dIMKma`rKY%(((O-PpFess+eu7w6wY?=jGjHph8>_b7-afr?;+fBGejkL{w@1i& z27wiW4WWR(7c)!f^r~Qxp)(jjn`xQnECPwTR^&*UQD_29EDKanJ8=>(2#UnB6z64j zo57!1G^KPY)qraTkl#3J(jgccFP<8H_85PgZjO9h2U&?#oB}r?i;2CA_tC$*#)E+tVg}uqn3wcbGq-bzJs=4l`56YP^jH zrL}&XA%(d5kR^P5xXVQuPok?#5*c2GGD|U}6%9UuV+e~v3up?mkR?fm@K9EkdbC$0 zr#GNGC<)Qk?#Fq%kFjRl5N7>!1Qj%SSY$r3bj+y~0gyJD~M4(43x-N4yiq#}ZwZh@U)l_zlPS?7W+g_n8y2 zcX8RJ4{A@JoBkPpqABEjf%E#BeLsD%f5(+^mFExj#FY0hIyaV2k2N}+3ue{NGgmEN zRlVY;q-|$%oI_uZOIg<6UjAmu;n?XZyQdX|%{tnhDT<~4U=m+AajgTF_xZWwn?I|0 zZGO*yv*WHv!VlL%_SA)sZeUL~R_}WILQzEPyjN@EBd+D13`+UK1h?3_4ZRJU@7~FZ zJNK({#&Kiwh^*$wkeM@LG(p6H+8ubIp*yOxf8o##LFyN+=8kHs@x+Hq-yRTcBIyTf ze@D`Xc)xrS`4g5Up=l5r<}gUIWn?^;Gt?x?vgx_ZTrvGQ*(8ZMV!G|w;0FzCdQhWg z8kO#t@*(~xt%2as?ROs#IZDRtbTLOUS#8-SG{3ywpiDHURvf{@N(__TcVZn>Uq6Un z$Gf9!+Hu7&$b0ylWNjTD-|7F1tE^H(fEsWLUl7IX6)u% zI))&Ic%)>u+H5gtc3UP2hT<-JC~@RB@|2jjnM6M3g2{TqC)Z`J>~HI6%fv0Cd`{w+S! zefH@W1=;`X9*6M~o|haCbZ5Qp;dZPVe{eJjAC({P67e2v=zHOrmlS9lOy$#VT6eY-gi*gvUSn9^Ie>SpWahMc6p&beu`fy(JmOAI&6O873OTw zhufMC3?0+Ba%bW9mvm%yOh9o0zjn^vZYmV}+MZsWQ5iq5F{rkvT;Jld_dJ4gKa219 z;u5}L_&uq)o;zl7=z>kJJ|rdoXLV%K{&BxFckGiCG;(R$&c4%D792TNfA+TOtY7jr zrA^R504d)Q(2OtWp}mo|6Fv?7-Z7)Jxu?^3&&Y8^T*XN>IoJ3;dbTkv!LEyx=W`47Q7B}1yvAI6TsIJT z&q-JNQVyHZNNW)^$h{(IokPMM2RTgLE~?-*jsuONJ0Lhl7pA=gr1%4%kadRy$!b$a zrwD+qx&-~FMhTeE?li5v=P{5)7ohKS)csF;W=>gXWt=Ys?|V5alNO6*C_M%3GF1~% TjlB3fVWSG!5o2MI|& z-}m``KA)HO#xB*3P1a6k>!K1b3X&L&P#n*5vP_|9j_1`p0B-<0dzJQkd0FJvzHSD2 zFC0JZLRFh(Nm!5Myl2PDgfd46MJXath;s>Z0Ib>v?$SG)gXiHzFom9;p7rPbAD-M? zq!MJlLY1!u`M{;jq?3Jzo&e_pdw}EwMnI;+&VC01P%ITX;0mbTiMoxpRR%$%LQ?g>C5r{wQz7xvLETtjEZin>K18l|`hCkw=KLAL|C zJzn7Wrs-2Yo9L-TT`j@S4g^AG@4s~@=6ribg#52JUIzC=n-2e7R0so6N*J5=?8hU#40cRpZPp`h;xhOPUo%n)&Y3|yiw_e{(w#48} zGaPRw>l9hHaE>XL%oKg^(9bRNowRnCuulJIwDJVNsF}>R(CP2 zkEjLJ>Mle^Nwpasa!rIQk@DdZ!X7nsLP#hNYnGw(y^2-TpG;xXWwNkog$z8PM_A&h zP!(Dmxt{JSh&tL)?qGN0C}G&EBTctZT33_(!-!;K;Iux33vN;*7}wnpCXP_o5H^Ob z1c`{KPwB@{(t0=`mLV+tC=`klOexFV(8y@K-~{#lXJxUFDWy~}>q^Fm{6>-}GD%Iv z#}T(vl5xMtvRrX6#P`3+2$uU60}Td)D6Hb4ur`=VF|im5@hHf(aVQpJLYL>^GhpTk z=y&{&!;{d?wv)p?D)Qwc(g9~60#lw&_jIxovygRWcEF<(c{H~G{>SYMngf3W;V}WI diff --git a/operator-pipeline-images/tests/entrypoints/test_detect_changed_operators.py b/operator-pipeline-images/tests/entrypoints/test_detect_changed_operators.py index 58e2186c4..07ee1ddbb 100644 --- a/operator-pipeline-images/tests/entrypoints/test_detect_changed_operators.py +++ b/operator-pipeline-images/tests/entrypoints/test_detect_changed_operators.py @@ -22,6 +22,8 @@ @pytest.mark.parametrize( # The tar file contains an operator repository with the following # commits (last to first): + # 8a40093 Add catalog template to operator-e2e + # 244d87b Add invalid catalog file # 1ca2aa1 Delete 4.15 catalog # 8500957 Remove operator-2 from v4.15 # ff7cdcd Update operator-1 in 4.15 catalog @@ -40,92 +42,51 @@ # db1a066 Empty repo "head_commit, base_commit, expected", [ - ( + pytest.param( "6a75661", # Add operator-e2e/0.0.100 # Empty repo "db1a066", { - "extra_files": [], "affected_operators": ["operator-e2e"], "added_operators": ["operator-e2e"], - "modified_operators": [], - "deleted_operators": [], "affected_bundles": ["operator-e2e/0.0.100"], "added_bundles": ["operator-e2e/0.0.100"], - "modified_bundles": [], - "deleted_bundles": [], - "affected_catalog_operators": [], - "added_catalog_operators": [], - "modified_catalog_operators": [], - "deleted_catalog_operators": [], - "affected_catalogs": [], - "added_catalogs": [], - "modified_catalogs": [], - "added_or_modified_catalogs": [], - "deleted_catalogs": [], - "catalogs_with_added_or_modified_operators": [], }, + id="Add new bundle for new operator", ), - ( + pytest.param( "32e0f85", # Add operator-e2e/0.0.101 # Add operator-e2e/0.0.100 "6a75661", { - "extra_files": [], "affected_operators": ["operator-e2e"], - "added_operators": [], "modified_operators": ["operator-e2e"], - "deleted_operators": [], "affected_bundles": ["operator-e2e/0.0.101"], "added_bundles": ["operator-e2e/0.0.101"], - "modified_bundles": [], - "deleted_bundles": [], - "affected_catalog_operators": [], - "added_catalog_operators": [], - "modified_catalog_operators": [], - "deleted_catalog_operators": [], - "affected_catalogs": [], - "added_catalogs": [], - "modified_catalogs": [], - "added_or_modified_catalogs": [], - "deleted_catalogs": [], - "catalogs_with_added_or_modified_operators": [], }, + id="Add new bundle for existing operator", ), - ( + pytest.param( "6626c9a", # Add operator-clone-e2e/0.0.100 # Add operator-e2e/0.0.101 # Add operator-e2e/0.0.100 "6a75661", { - "extra_files": [], "affected_operators": ["operator-e2e", "operator-clone-e2e"], "added_operators": ["operator-clone-e2e"], "modified_operators": ["operator-e2e"], - "deleted_operators": [], "affected_bundles": [ "operator-e2e/0.0.101", "operator-clone-e2e/0.0.100", ], "added_bundles": ["operator-e2e/0.0.101", "operator-clone-e2e/0.0.100"], - "modified_bundles": [], - "deleted_bundles": [], - "affected_catalog_operators": [], - "added_catalog_operators": [], - "modified_catalog_operators": [], - "deleted_catalog_operators": [], - "affected_catalogs": [], - "added_catalogs": [], - "modified_catalogs": [], - "added_or_modified_catalogs": [], - "deleted_catalogs": [], - "catalogs_with_added_or_modified_operators": [], }, + id="Add bundles for multiple operators", ), - ( + pytest.param( "2d55a2e", # Add extra files # Modify operator-e2e/0.0.101 @@ -135,32 +96,19 @@ { "extra_files": ["empty.txt", "operators/empty.txt"], "affected_operators": ["operator-e2e", "operator-clone-e2e"], - "added_operators": [], "modified_operators": ["operator-e2e", "operator-clone-e2e"], - "deleted_operators": [], "affected_bundles": [ "operator-e2e/0.0.101", "operator-clone-e2e/0.0.100", ], - "added_bundles": [], "modified_bundles": [ "operator-e2e/0.0.101", "operator-clone-e2e/0.0.100", ], - "deleted_bundles": [], - "affected_catalog_operators": [], - "added_catalog_operators": [], - "modified_catalog_operators": [], - "deleted_catalog_operators": [], - "affected_catalogs": [], - "added_catalogs": [], - "modified_catalogs": [], - "added_or_modified_catalogs": [], - "deleted_catalogs": [], - "catalogs_with_added_or_modified_operators": [], }, + id="Modify bundles for multiple operators and add extra files", ), - ( + pytest.param( "2c06647", # Remove extra files # Remove operator-e2e/0.0.101 @@ -169,254 +117,142 @@ { "extra_files": ["empty.txt", "operators/empty.txt"], "affected_operators": ["operator-e2e"], - "added_operators": [], "modified_operators": ["operator-e2e"], - "deleted_operators": [], "affected_bundles": ["operator-e2e/0.0.101"], - "added_bundles": [], - "modified_bundles": [], "deleted_bundles": ["operator-e2e/0.0.101"], - "affected_catalog_operators": [], - "added_catalog_operators": [], - "modified_catalog_operators": [], - "deleted_catalog_operators": [], - "affected_catalogs": [], - "added_catalogs": [], - "modified_catalogs": [], - "added_or_modified_catalogs": [], - "deleted_catalogs": [], - "catalogs_with_added_or_modified_operators": [], }, + id="Delete a bundle and remove extra files", ), - ( + pytest.param( "a5501e2", # Add ci.yaml to operator-clone-e2e # Remove extra files "2c06647", { - "extra_files": [], "affected_operators": ["operator-clone-e2e"], - "added_operators": [], "modified_operators": ["operator-clone-e2e"], - "deleted_operators": [], - "affected_bundles": [], - "added_bundles": [], - "modified_bundles": [], - "deleted_bundles": [], - "affected_catalog_operators": [], - "added_catalog_operators": [], - "modified_catalog_operators": [], - "deleted_catalog_operators": [], - "affected_catalogs": [], - "added_catalogs": [], - "modified_catalogs": [], - "added_or_modified_catalogs": [], - "deleted_catalogs": [], - "catalogs_with_added_or_modified_operators": [], }, + id="Add ci.yaml to an operator", ), - ( + pytest.param( "2e9eae2", # Remove operator-clone-e2e # Add ci.yaml to operator-clone-e2e "a5501e2", { - "extra_files": [], "affected_operators": ["operator-clone-e2e"], - "added_operators": [], - "modified_operators": [], "deleted_operators": ["operator-clone-e2e"], "affected_bundles": ["operator-clone-e2e/0.0.100"], - "added_bundles": [], - "modified_bundles": [], "deleted_bundles": ["operator-clone-e2e/0.0.100"], - "affected_catalog_operators": [], - "added_catalog_operators": [], - "modified_catalog_operators": [], - "deleted_catalog_operators": [], - "affected_catalogs": [], - "added_catalogs": [], - "modified_catalogs": [], - "added_or_modified_catalogs": [], - "deleted_catalogs": [], - "catalogs_with_added_or_modified_operators": [], }, + id="Delete an operator", ), - ( + pytest.param( "c8d3509f", # Add v4.15/operator-1 "2e9eae2", { - "extra_files": [], - "affected_operators": [], - "added_operators": [], - "modified_operators": [], - "deleted_operators": [], - "affected_bundles": [], - "added_bundles": [], - "modified_bundles": [], - "deleted_bundles": [], "affected_catalog_operators": ["v4.15/operator-1"], "added_catalog_operators": ["v4.15/operator-1"], - "modified_catalog_operators": [], - "deleted_catalog_operators": [], "affected_catalogs": ["v4.15"], "added_catalogs": ["v4.15"], - "modified_catalogs": [], "added_or_modified_catalogs": ["v4.15"], - "deleted_catalogs": [], "catalogs_with_added_or_modified_operators": ["v4.15"], }, + id="Add new catalog with new operator", ), - ( + pytest.param( "4db21de1", # Add v4.15/operator-2 "c8d3509f", { - "extra_files": [], - "affected_operators": [], - "added_operators": [], - "modified_operators": [], - "deleted_operators": [], - "affected_bundles": [], - "added_bundles": [], - "modified_bundles": [], - "deleted_bundles": [], "affected_catalog_operators": ["v4.15/operator-2"], "added_catalog_operators": ["v4.15/operator-2"], - "modified_catalog_operators": [], - "deleted_catalog_operators": [], "affected_catalogs": ["v4.15"], - "added_catalogs": [], "modified_catalogs": ["v4.15"], "added_or_modified_catalogs": ["v4.15"], - "deleted_catalogs": [], "catalogs_with_added_or_modified_operators": ["v4.15"], }, + id="Add new operator to existing catalog", ), - ( + pytest.param( "ff7cdcd6", # Modify v4.15/operator-1 "4db21de1", { - "extra_files": [], - "affected_operators": [], - "added_operators": [], - "modified_operators": [], - "deleted_operators": [], - "affected_bundles": [], - "added_bundles": [], - "modified_bundles": [], - "deleted_bundles": [], "affected_catalog_operators": ["v4.15/operator-1"], - "added_catalog_operators": [], "modified_catalog_operators": ["v4.15/operator-1"], - "deleted_catalog_operators": [], "affected_catalogs": ["v4.15"], - "added_catalogs": [], "modified_catalogs": ["v4.15"], "added_or_modified_catalogs": ["v4.15"], - "deleted_catalogs": [], "catalogs_with_added_or_modified_operators": ["v4.15"], }, + id="Modify operator in existing catalog", ), - ( + pytest.param( "85009570", # Delete v4.15/operator-2 "ff7cdcd6", { - "extra_files": [], - "affected_operators": [], - "added_operators": [], - "modified_operators": [], - "deleted_operators": [], - "affected_bundles": [], - "added_bundles": [], - "modified_bundles": [], - "deleted_bundles": [], "affected_catalog_operators": ["v4.15/operator-2"], - "added_catalog_operators": [], - "modified_catalog_operators": [], "deleted_catalog_operators": ["v4.15/operator-2"], "affected_catalogs": ["v4.15"], - "added_catalogs": [], "modified_catalogs": ["v4.15"], "added_or_modified_catalogs": ["v4.15"], - "deleted_catalogs": [], - "catalogs_with_added_or_modified_operators": [], }, + id="Delete operator in existing catalog", ), - ( + pytest.param( "1ca2aa12", # Delete v4.15 catalog "85009570", { - "extra_files": [], - "affected_operators": [], - "added_operators": [], - "modified_operators": [], - "deleted_operators": [], - "affected_bundles": [], - "added_bundles": [], - "modified_bundles": [], - "deleted_bundles": [], "affected_catalog_operators": ["v4.15/operator-1"], - "added_catalog_operators": [], - "modified_catalog_operators": [], "deleted_catalog_operators": ["v4.15/operator-1"], "affected_catalogs": ["v4.15"], - "added_catalogs": [], - "modified_catalogs": [], - "added_or_modified_catalogs": [], "deleted_catalogs": ["v4.15"], - "catalogs_with_added_or_modified_operators": [], }, + id="Delete catalog", ), - ( + pytest.param( "ff7cdcd", # Modify v4.15/operator-1 # Add v4.15/operator-2 - # Empty repo "c8d3509", { - "affected_operators": [], - "added_operators": [], - "modified_operators": [], - "deleted_operators": [], - "affected_bundles": [], - "added_bundles": [], - "modified_bundles": [], - "deleted_bundles": [], "affected_catalogs": ["v4.15"], - "added_catalogs": [], "modified_catalogs": ["v4.15"], "added_or_modified_catalogs": ["v4.15"], - "deleted_catalogs": [], "catalogs_with_added_or_modified_operators": ["v4.15"], "affected_catalog_operators": ["v4.15/operator-1", "v4.15/operator-2"], "added_catalog_operators": ["v4.15/operator-2"], "modified_catalog_operators": ["v4.15/operator-1"], - "deleted_catalog_operators": [], - "extra_files": [], }, + id="Modify operator in existing catalog and add new operator", + ), + pytest.param( + "244d87b", + # Delete v4.15 catalog + # Add invalid catalog file + "1ca2aa12", + { + "extra_files": ["catalogs/v4.11-invalid/foo.json"], + }, + id="Add invalid catalog file", + ), + pytest.param( + "8a40093eff", + # Add catalog template to operator-e2e + # Add invalid catalog file + "244d87b92", + { + "affected_operators": ["operator-e2e"], + "modified_operators": ["operator-e2e"], + }, + id="Add catalog template to operator-e2e", ), ], indirect=False, - ids=[ - "Add new bundle for new operator", - "Add new bundle for existing operator", - "Add bundles for multiple operators", - "Modify bundles for multiple operators and add extra files", - "Delete a bundle and remove extra files", - "Add ci.yaml to an operator", - "Delete an operator", - "Add new catalog with new operator", - "Add new operator to existing catalog", - "Modify operator in existing catalog", - "Delete operator in existing catalog", - "Delete catalog", - "Modify operator in existing catalog and add new operator", - ], ) @patch("operatorcert.entrypoints.detect_changed_operators.ParserResults.enrich_result") @patch("operatorcert.entrypoints.detect_changed_operators.github_pr_affected_files") @@ -456,6 +292,29 @@ def test_detect_changes( "https://example.com/foo/bar/pull/1", ) + default_expected: dict[str, Any] = { + "extra_files": [], + "affected_operators": [], + "added_operators": [], + "modified_operators": [], + "deleted_operators": [], + "affected_bundles": [], + "added_bundles": [], + "modified_bundles": [], + "deleted_bundles": [], + "affected_catalog_operators": [], + "added_catalog_operators": [], + "modified_catalog_operators": [], + "deleted_catalog_operators": [], + "affected_catalogs": [], + "added_catalogs": [], + "modified_catalogs": [], + "added_or_modified_catalogs": [], + "deleted_catalogs": [], + "catalogs_with_added_or_modified_operators": [], + } + expected = {**default_expected, **expected} + result_dict = result.to_dict() for key in set(result_dict.keys()) | set(expected.keys()):