diff --git a/repos/system_upgrade/cloudlinux/actors/clmysqlrepositorysetup/tests/conftest.py b/repos/system_upgrade/cloudlinux/actors/clmysqlrepositorysetup/tests/conftest.py new file mode 100644 index 0000000000..c722da46d1 --- /dev/null +++ b/repos/system_upgrade/cloudlinux/actors/clmysqlrepositorysetup/tests/conftest.py @@ -0,0 +1,92 @@ +"""Shared fixtures for clmysqlrepositorysetup actor tests. + +Leapp injects the actor context during pytest collection, so the actor's +private modules (leapp.libraries.common.clmysql, ...) are not importable at +conftest import time. Imports therefore live inside the fixture bodies. +""" + +import pytest + + +_MARIADB106_META_BASEURL = "http://repo.cloudlinux.com/other/cl$releasever/mysqlmeta/cl-mariadb-10.6/x86_64/" +_MYSQLCLIENT_BASEURL = "http://repo.cloudlinux.com/other/cl$releasever/mysqlmeta/mysqlclient/x86_64/" + + +@pytest.fixture +def patch_env(monkeypatch): + """ + Return a callable that patches clmysql_cloudlinux dependencies. + + Defaults to a healthy mariadb106 OK detection targeting CL9. Pass + ``clmysql_result`` to exercise a different status (e.g. MISMATCH), or + override ``clmysql_type`` / ``target_major`` / ``source_major`` to vary the + scenario. + """ + from leapp import reporting + from leapp.libraries.common.clmysql import ClMysqlTypeResult, ClMysqlTypeStatus + from leapp.libraries.common.testutils import ( + create_report_mocked, + logger_mocked, + produce_mocked, + ) + from leapp.libraries.stdlib import api + + def _apply(clmysql_result=None, clmysql_type="mariadb106", target_major="9", source_major="8"): + if clmysql_result is None: + clmysql_result = ClMysqlTypeResult( + status=ClMysqlTypeStatus.OK, + governor_type=clmysql_type, + pkg_type=clmysql_type, + ) + monkeypatch.setattr( + "leapp.libraries.actor.clmysql_cloudlinux.get_clmysql_type", + lambda: clmysql_result, + ) + monkeypatch.setattr( + "leapp.libraries.actor.clmysql_cloudlinux.get_target_major_version", + lambda: target_major, + ) + monkeypatch.setattr( + "leapp.libraries.common.clmysql.get_target_major_version", + lambda: target_major, + ) + monkeypatch.setattr( + "leapp.libraries.common.clmysql.get_source_major_version", + lambda: source_major, + ) + monkeypatch.setattr( + "leapp.libraries.actor.clmysql_cloudlinux.create_leapp_repofile_copy", + lambda *a, **kw: "/tmp/cl-mysql-leapp.repo", + ) + monkeypatch.setattr(api, "produce", produce_mocked()) + monkeypatch.setattr(api, "current_logger", logger_mocked()) + monkeypatch.setattr(reporting, "create_report", create_report_mocked()) + + return _apply + + +@pytest.fixture +def make_cl_mysql_repofile(): + """Return a factory that builds a Governor-style cl-mysql.repo RepositoryFile.""" + from leapp.models import RepositoryData, RepositoryFile + + def _make(cl_mysql_meta_enabled=True, mysqlclient_enabled=False): + return RepositoryFile( + file="cl-mysql.repo", + data=[ + RepositoryData( + repoid="cl-mysql-meta", + name="cl-mysql", + baseurl=_MARIADB106_META_BASEURL, + enabled=cl_mysql_meta_enabled, + ), + RepositoryData( + repoid="mysqclient", + name="mysqlclient", + baseurl=_MYSQLCLIENT_BASEURL, + enabled=mysqlclient_enabled, + ), + ], + ) + + return _make diff --git a/repos/system_upgrade/cloudlinux/actors/clmysqlrepositorysetup/tests/test_clmysql_cloudlinux.py b/repos/system_upgrade/cloudlinux/actors/clmysqlrepositorysetup/tests/test_clmysql_cloudlinux.py new file mode 100644 index 0000000000..02bd3a5cc1 --- /dev/null +++ b/repos/system_upgrade/cloudlinux/actors/clmysqlrepositorysetup/tests/test_clmysql_cloudlinux.py @@ -0,0 +1,94 @@ +""" +Regression tests for clmysql_cloudlinux.py - Governor-managed DB handler. + +Key scenario (CLOS-2882): Governor writes cl-mysql.repo with both repos +disabled (enabled=0). The handler must still force-enable cl-mysql-meta-N +and mysqclient-N for the target userspace so DNF can resolve the +mariadb:cl-MariaDB106 (or equivalent) module stream and upgrade the packages. + +Without the fix the module metadata is absent from the target userspace DNF +cache, which causes: + Error: Problems in request: missing groups or modules: mariadb:cl-MariaDB106 +""" + +from leapp.libraries.actor.clmysql_cloudlinux import clmysql_process +from leapp.libraries.actor.clmysqlrepositorysetup import MySqlRepositorySetupLibrary + + +class TestDisabledReposForceEnabled: + """ + CLOS-2882 regression: disabled cl-mysql repos must appear in the + target userspace for the module stream to be resolvable. + """ + + def test_both_repos_disabled_still_in_target(self, patch_env, make_cl_mysql_repofile): + """Disabled cl-mysql-meta and mysqclient repos must both be force-enabled.""" + patch_env() + + lib = MySqlRepositorySetupLibrary() + clmysql_process( + lib, + "cl-mysql", + make_cl_mysql_repofile(cl_mysql_meta_enabled=False, mysqlclient_enabled=False), + ) + + repoids = {msg.repoid for msg in lib.custom_repo_msgs} + assert "cl-mysql-meta-9" in repoids + assert "mysqclient-9" in repoids + + def test_target_repos_enabled_true(self, patch_env, make_cl_mysql_repofile): + """Target repo messages must have enabled=True regardless of source state.""" + patch_env() + + lib = MySqlRepositorySetupLibrary() + clmysql_process( + lib, + "cl-mysql", + make_cl_mysql_repofile(cl_mysql_meta_enabled=False, mysqlclient_enabled=False), + ) + + for msg in lib.custom_repo_msgs: + assert msg.enabled, "target repo {} must be enabled=True".format(msg.repoid) + + def test_cloudlinux_type_always_registered(self, patch_env, make_cl_mysql_repofile): + """'cloudlinux' must be added to mysql_types even when all repos are disabled.""" + patch_env() + + lib = MySqlRepositorySetupLibrary() + clmysql_process( + lib, + "cl-mysql", + make_cl_mysql_repofile(cl_mysql_meta_enabled=False, mysqlclient_enabled=False), + ) + + assert "cloudlinux" in lib.mysql_types + + def test_releasever_substituted_in_target_baseurl(self, patch_env, make_cl_mysql_repofile): + """Target repo baseurls must have $releasever replaced with the target major version.""" + patch_env(target_major="9") + + lib = MySqlRepositorySetupLibrary() + clmysql_process( + lib, + "cl-mysql", + make_cl_mysql_repofile(cl_mysql_meta_enabled=False, mysqlclient_enabled=False), + ) + + for msg in lib.custom_repo_msgs: + assert "$releasever" not in msg.baseurl + assert "/cl9/" in msg.baseurl + + def test_enabled_repos_also_pass_through(self, patch_env, make_cl_mysql_repofile): + """Normal case: enabled cl-mysql-meta still appears in target repos.""" + patch_env() + + lib = MySqlRepositorySetupLibrary() + clmysql_process( + lib, + "cl-mysql", + make_cl_mysql_repofile(cl_mysql_meta_enabled=True, mysqlclient_enabled=False), + ) + + repoids = {msg.repoid for msg in lib.custom_repo_msgs} + assert "cl-mysql-meta-9" in repoids + assert "cloudlinux" in lib.mysql_types diff --git a/repos/system_upgrade/cloudlinux/actors/clmysqlrepositorysetup/tests/test_clmysql_mismatch.py b/repos/system_upgrade/cloudlinux/actors/clmysqlrepositorysetup/tests/test_clmysql_mismatch.py new file mode 100644 index 0000000000..62161ce780 --- /dev/null +++ b/repos/system_upgrade/cloudlinux/actors/clmysqlrepositorysetup/tests/test_clmysql_mismatch.py @@ -0,0 +1,32 @@ +""" +Tests for the Governor/RPM mismatch inhibitor in clmysql_cloudlinux. + +When MySQL Governor's recorded type does not match the installed mysqld +binary, the handler must inhibit the upgrade and not register any target +repos (a wrong module stream would otherwise be enabled). +""" + +from leapp import reporting +from leapp.libraries.actor.clmysql_cloudlinux import clmysql_process +from leapp.libraries.actor.clmysqlrepositorysetup import MySqlRepositorySetupLibrary +from leapp.libraries.common.clmysql import ClMysqlTypeResult, ClMysqlTypeStatus + + +class TestMismatchInhibitor: + """Governor/RPM type mismatch must create an inhibitor and skip repo setup.""" + + def test_mismatch_inhibits_and_adds_no_repos(self, patch_env, make_cl_mysql_repofile): + patch_env( + clmysql_result=ClMysqlTypeResult( + status=ClMysqlTypeStatus.MISMATCH, + governor_type="mariadb106", + pkg_type="mysql80", + ) + ) + + lib = MySqlRepositorySetupLibrary() + clmysql_process(lib, "cl-mysql", make_cl_mysql_repofile()) + + assert "cloudlinux" not in lib.mysql_types + assert lib.custom_repo_msgs == [] + assert reporting.create_report.called == 1