From 8e81f483a1622f4cfa2a65884d0921cebbb6f97d Mon Sep 17 00:00:00 2001 From: "Petr \"Stone\" Hracek" Date: Mon, 24 Nov 2025 13:28:30 +0100 Subject: [PATCH 1/3] Container PyTest suite for mysql-container Migration matrix is here: - run_container_creation_tests -> test_container_configuration.py - run_configuration_tests -> test_container_configuration.py - run_general_tests -> test_container_general.py - run_change_password_test -> test_container_password.py - run_change_password_new_user_test -> test_container_password.py - run_replication_test -> Not Yet - run_s2i_test -> test_container_basics.py - run_ssl_test -> test_container_ssl.py - run_datadir_actions_test -> test_container_general.py Signed-off-by: Petr "Stone" Hracek --- test/conftest.py | 45 ++++ test/constants.py | 5 - test/run-pytest | 17 ++ test/test_container_basics.py | 113 +++++++++ test/test_container_configuration.py | 250 ++++++++++++++++++++ test/test_container_general.py | 207 ++++++++++++++++ test/test_container_password.py | 127 ++++++++++ test/test_container_ssl.py | 82 +++++++ test/test_ocp_mysql_latest_imagestreams.py | 4 +- test/test_ocp_mysql_local_template.py | 22 +- test/test_ocp_mysql_shared_helm_template.py | 32 +-- 11 files changed, 864 insertions(+), 40 deletions(-) create mode 100644 test/conftest.py delete mode 100644 test/constants.py create mode 100755 test/run-pytest create mode 100644 test/test_container_basics.py create mode 100644 test/test_container_configuration.py create mode 100644 test/test_container_general.py create mode 100644 test/test_container_password.py create mode 100644 test/test_container_ssl.py diff --git a/test/conftest.py b/test/conftest.py new file mode 100644 index 0000000..d7cb40b --- /dev/null +++ b/test/conftest.py @@ -0,0 +1,45 @@ +import os +import sys + +from pathlib import Path +from collections import namedtuple + +from container_ci_suite.utils import check_variables + +if not check_variables(): + sys.exit(1) + +TAGS = { + "rhel8": "-el8", + "rhel9": "-el9", + "rhel10": "-el10", +} +TEST_DIR = Path(__file__).parent.absolute() +Vars = namedtuple( + "Vars", + [ + "OS", + "VERSION", + "IMAGE_NAME", + "TEST_DIR", + "TAG", + "TEST_APP", + "VERY_LONG_DB_NAME", + "VERY_LONG_USER_NAME", + ], +) +VERSION = os.getenv("VERSION") +OS = os.getenv("TARGET").lower() +TEST_APP = TEST_DIR / "test-app" +VERY_LONG_DB_NAME = "very_long_database_name_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +VERY_LONG_USER_NAME = "very_long_user_name_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +VARS = Vars( + OS=OS, + VERSION=VERSION, + IMAGE_NAME=os.getenv("IMAGE_NAME"), + TEST_DIR=Path(__file__).parent.absolute(), + TAG=TAGS.get(OS), + TEST_APP=TEST_APP, + VERY_LONG_DB_NAME=VERY_LONG_DB_NAME, + VERY_LONG_USER_NAME=VERY_LONG_USER_NAME, +) diff --git a/test/constants.py b/test/constants.py deleted file mode 100644 index 26eb71a..0000000 --- a/test/constants.py +++ /dev/null @@ -1,5 +0,0 @@ -TAGS = { - "rhel8": "-el8", - "rhel9": "-el9", - "rhel10": "-el10", -} diff --git a/test/run-pytest b/test/run-pytest new file mode 100755 index 0000000..cc76ee7 --- /dev/null +++ b/test/run-pytest @@ -0,0 +1,17 @@ +#!/bin/bash +# +# IMAGE_NAME specifies a name of the candidate image used for testing. +# The image has to be available before this script is executed. +# VERSION specifies the major version of the MariaDB in format of X.Y +# OS specifies RHEL version (e.g. OS=rhel10) +# + +THISDIR=$(dirname ${BASH_SOURCE[0]}) + +git show -s + +PYTHON_VERSION="3.12" +if [[ ! -f "/usr/bin/python$PYTHON_VERSION" ]]; then + PYTHON_VERSION="3.13" +fi +cd "${THISDIR}" && "python${PYTHON_VERSION}" -m pytest -s -rA --showlocals -vv test_container_*.py diff --git a/test/test_container_basics.py b/test/test_container_basics.py new file mode 100644 index 0000000..ae034fb --- /dev/null +++ b/test/test_container_basics.py @@ -0,0 +1,113 @@ +import shutil +import tempfile + +from container_ci_suite.container_lib import ContainerTestLib +from container_ci_suite.container_lib import ContainerTestLibUtils +from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper +from pathlib import Path + +from conftest import VARS + + +def build_s2i_app(app_path: Path) -> ContainerTestLib: + container_lib = ContainerTestLib(VARS.IMAGE_NAME) + app_name = app_path.name + s2i_app = container_lib.build_as_df( + app_path=app_path, + s2i_args="--pull-policy=never", + src_image=VARS.IMAGE_NAME, + dst_image=f"{VARS.IMAGE_NAME}-{app_name}", + ) + return s2i_app + + +class TestMySqlBasicsContainer: + """ + Test MySQL container configuration. + """ + + def setup_method(self): + self.s2i_db = build_s2i_app(app_path=VARS.TEST_DIR / "test-app") + self.s2i_db.set_new_db_type(db_type="mysql") + + def teardown_method(self): + self.s2i_db.cleanup() + + def test_s2i_usage(self): + """ + Test container creation fails with invalid combinations of arguments. + """ + cid_config_build = "s2i_config_build" + self.s2i_db.assert_container_creation_fails( + cid_file_name=cid_config_build, + command="", + container_args=[ + "-e MYSQL_USER=root", + "-e MYSQL_PASSWORD=pass", + "-e MYSQL_DATABASE=db", + "-e MYSQL_ROOT_PASSWORD=pass", + ], + ) + assert self.s2i_db.create_container( + cid_file_name=cid_config_build, + container_args=[ + "-e MYSQL_USER=config_test_user", + "-e MYSQL_PASSWORD=config_test_user", + "-e MYSQL_DATABASE=db", + "-e MYSQL_OPERATIONS_USER=operations_user", + "-e MYSQL_OPERATIONS_PASSWORD=operations_user", + ], + ) + cip = self.s2i_db.get_cip(cid_file_name=cid_config_build) + assert cip + assert self.s2i_db.test_db_connection( + container_ip=cip, username="operations_user", password="operations_user" + ) + cid = self.s2i_db.get_cid(cid_file_name=cid_config_build) + db_configuration = PodmanCLIWrapper.podman_exec_shell_command( + cid_file_name=cid, + cmd="cat /etc/my.cnf /etc/my.cnf.d/*", + ) + assert db_configuration + PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") + + def test_s2i_usage_with_mount(self): + """ + Test container creation fails with invalid combinations of arguments. + """ + data_dir = tempfile.mkdtemp(prefix="/tmp/mysql-test_data") + shutil.copytree(VARS.TEST_DIR / "test-app", f"{data_dir}/test-app") + assert ContainerTestLibUtils.commands_to_run( + commands_to_run=[ + f"chown -R 27:27 {data_dir}/test-app", + ] + ) + cid_s2i_test_mount = "s2i_test_mount" + self.s2i_db.create_container( + cid_file_name=cid_s2i_test_mount, + container_args=[ + "-e MYSQL_USER=config_test_user", + "-e MYSQL_PASSWORD=config_test_user", + "-e MYSQL_DATABASE=db", + "-e MYSQL_OPERATIONS_USER=operations_user", + "-e MYSQL_OPERATIONS_PASSWORD=operations_pass", + f"-v {data_dir}/test-app:/opt/app-root/src/:z", + ], + ) + cip_test_mount = self.s2i_db.get_cip(cid_file_name=cid_s2i_test_mount) + assert cip_test_mount + assert self.s2i_db.test_db_connection( + container_ip=cip_test_mount, + username="operations_user", + password="operations_pass", + max_attempts=10, + ) + cid = self.s2i_db.get_cid(cid_file_name=cid_s2i_test_mount) + assert cid + db_configuration = PodmanCLIWrapper.podman_exec_shell_command( + cid_file_name=cid, + cmd="cat /etc/my.cnf /etc/my.cnf.d/*", + ) + assert db_configuration + PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") + shutil.rmtree(data_dir) diff --git a/test/test_container_configuration.py b/test/test_container_configuration.py new file mode 100644 index 0000000..db2eadd --- /dev/null +++ b/test/test_container_configuration.py @@ -0,0 +1,250 @@ +import re + +import pytest + +from container_ci_suite.container_lib import ContainerTestLib +from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper + +from conftest import VARS + + +class TestMySqlConfigurationContainer: + """ + Test MySQL container configuration. + """ + + def setup_method(self): + self.db = ContainerTestLib(image_name=VARS.IMAGE_NAME) + + def teardown_method(self): + self.db.cleanup() + + def test_container_creation_fails(self): + """ + Test container creation fails with no arguments. + """ + cid_config_test = "container_creation_fails" + assert self.db.assert_container_creation_fails( + cid_file_name=cid_config_test, container_args=[], command="" + ) + + @pytest.mark.parametrize( + "container_args", + [ + ["-e MYSQL_USER=user", "-e MYSQL_DATABASE=db"], + ["-e MYSQL_PASSWORD=pass", "-e MYSQL_DATABASE=db"], + ], + ) + def test_try_image_invalid_combinations(self, container_args): + """ + Test container creation fails with invalid combinations of arguments. + """ + cid_file_name = "try_image_invalid_combinations" + assert self.db.assert_container_creation_fails( + cid_file_name=cid_file_name, container_args=container_args, command="" + ) + + @pytest.mark.parametrize( + "container_args", + [ + ["-e", "MYSQL_USER=user", "-e", "MYSQL_PASSWORD=pass"], + [ + "-e MYSQL_USER=$invalid", + "-e MYSQL_PASSWORD=pass", + "-e MYSQL_DATABASE=db", + "-e MYSQL_ROOT_PASSWORD=root_pass", + ], + [ + f"-e MYSQL_USER={VARS.VERY_LONG_USER_NAME}", + "-e MYSQL_PASSWORD=pass", + "-e MYSQL_DATABASE=db", + "-e MYSQL_ROOT_PASSWORD=root_pass", + ], + [ + "-e MYSQL_USER=user", + "-e MYSQL_PASSWORD=", + "-e MYSQL_DATABASE=db", + "-e MYSQL_ROOT_PASSWORD=root_pass", + ], + [ + "-e MYSQL_USER=user", + "-e MYSQL_PASSWORD=pass", + "-e MYSQL_DATABASE=$invalid", + "-e MYSQL_ROOT_PASSWORD=root_pass", + ], + [ + "-e MYSQL_USER=user", + "-e MYSQL_PASSWORD=pass", + f"-e MYSQL_DATABASE={VARS.VERY_LONG_DB_NAME}", + "-e MYSQL_ROOT_PASSWORD=root_pass", + ], + [ + "-e MYSQL_USER=user", + "-e MYSQL_PASSWORD=pass", + "-e MYSQL_DATABASE=db", + "-e MYSQL_ROOT_PASSWORD=", + ], + [ + "-e MYSQL_USER=root", + "-e MYSQL_PASSWORD=pass", + "-e MYSQL_DATABASE=db", + "-e MYSQL_ROOT_PASSWORD=pass", + ], + ], + ) + def test_invalid_configuration_tests(self, container_args): + """ + Test invalid configuration combinations for MySQL container. + """ + cid_config_test = "invalid_configuration_tests" + assert self.db.assert_container_creation_fails( + cid_file_name=cid_config_test, container_args=container_args, command="" + ) + + +class TestMySqlConfigurationTests: + """ + Test MySQL container configuration tests. + """ + + def setup_method(self): + self.db = ContainerTestLib(image_name=VARS.IMAGE_NAME) + self.db.set_new_db_type(db_type="mysql") + + def teardown_method(self): + self.db.cleanup() + + def test_configuration_auto_calculated_settings(self): + """ + Test MySQL container configuration auto-calculated settings. + """ + cid_config_test = "auto-config_test" + assert self.db.create_container( + cid_file_name=cid_config_test, + container_args=[ + "--env MYSQL_COLLATION=latin2_czech_cs", + "--env MYSQL_CHARSET=latin2", + "--env MYSQL_USER=config_test_user", + "--env MYSQL_PASSWORD=config_test", + "--env MYSQL_DATABASE=db", + ], + docker_args="--memory=512m", + ) + cip = self.db.get_cip(cid_file_name=cid_config_test) + assert cip + return_value = self.db.test_db_connection( + container_ip=cip, + username="config_test_user", + password="config_test", + max_attempts=10, + ) + assert return_value + cid = self.db.get_cid(cid_file_name=cid_config_test) + db_configuration = PodmanCLIWrapper.podman_exec_shell_command( + cid_file_name=cid, + cmd="cat /etc/my.cnf /etc/my.cnf.d/*", + ) + assert db_configuration + assert re.search( + r"key_buffer_size\s*=\s*51M", + db_configuration, + ) + assert re.search( + r"read_buffer_size\s*=\s*25M", + db_configuration, + ) + assert re.search( + r"innodb_buffer_pool_size\s*=\s*256M", + db_configuration, + ) + assert re.search( + r"innodb_log_file_size\s*=\s*76M", + db_configuration, + ) + assert re.search( + r"innodb_log_buffer_size\s*=\s*76M", + db_configuration, + ) + assert re.search( + r"authentication_policy\s*=\s*'caching_sha2_password,,'", + db_configuration, + ) + + def test_configuration_options_settings(self): + """ + Test MySQL container configuration options. + """ + cid_config_test = "config_test" + assert self.db.create_container( + cid_file_name=cid_config_test, + container_args=[ + "--env MYSQL_USER=config_test_user", + "--env MYSQL_PASSWORD=config_test", + "--env MYSQL_DATABASE=db", + "--env MYSQL_LOWER_CASE_TABLE_NAMES=1", + "--env MYSQL_LOG_QUERIES_ENABLED=1", + "--env MYSQL_MAX_CONNECTIONS=1337", + "--env MYSQL_FT_MIN_WORD_LEN=8", + "--env MYSQL_FT_MAX_WORD_LEN=15", + "--env MYSQL_MAX_ALLOWED_PACKET=10M", + "--env MYSQL_TABLE_OPEN_CACHE=100", + "--env MYSQL_SORT_BUFFER_SIZE=256K", + "--env MYSQL_KEY_BUFFER_SIZE=16M", + "--env MYSQL_READ_BUFFER_SIZE=16M", + "--env MYSQL_INNODB_BUFFER_POOL_SIZE=16M", + "--env MYSQL_INNODB_LOG_FILE_SIZE=4M", + "--env MYSQL_INNODB_LOG_BUFFER_SIZE=4M", + "--env MYSQL_AUTHENTICATION_POLICY=sha256_password", + ], + ) + cip = self.db.get_cip(cid_file_name=cid_config_test) + assert cip + assert self.db.test_db_connection( + container_ip=cip, username="config_test_user", password="config_test" + ) + cip = self.db.get_cip(cid_file_name=cid_config_test) + assert cip + return_value = self.db.test_db_connection( + container_ip=cip, + username="config_test_user", + password="config_test", + max_attempts=10, + ) + assert return_value + cid = self.db.get_cid(cid_file_name=cid_config_test) + db_configuration = PodmanCLIWrapper.podman_exec_shell_command( + cid_file_name=cid, + cmd="cat /etc/my.cnf /etc/my.cnf.d/*", + ) + assert db_configuration + assert re.search( + r"lower_case_table_names\s*=\s*1", + db_configuration, + ) + assert re.search( + r"general_log\s*=\s*1", + db_configuration, + ) + assert re.search( + r"max_connections\s*=\s*1337", + db_configuration, + re.MULTILINE | re.IGNORECASE, + ) + assert re.search(r"ft_min_word_len\s*=\s*8", db_configuration) + assert re.search( + r"ft_max_word_len\s*=\s*15", + db_configuration, + ) + assert re.search(r"max_allowed_packet\s*=\s*10M", db_configuration) + assert re.search(r"table_open_cache\s*=\s*100", db_configuration) + assert re.search(r"sort_buffer_size\s*=\s*256K", db_configuration) + assert re.search(r"key_buffer_size\s*=\s*16M", db_configuration) + assert re.search(r"read_buffer_size\s*=\s*16M", db_configuration) + assert re.search(r"innodb_buffer_pool_size\s*=\s*16M", db_configuration) + assert re.search(r"innodb_log_file_size\s*=\s*4M", db_configuration) + assert re.search(r"innodb_log_buffer_size\s*=\s*4M", db_configuration) + assert re.search( + r"authentication_policy\s*=\s*'sha256_password'", + db_configuration, + re.MULTILINE, + ) diff --git a/test/test_container_general.py b/test/test_container_general.py new file mode 100644 index 0000000..4685305 --- /dev/null +++ b/test/test_container_general.py @@ -0,0 +1,207 @@ +import re +import pytest +import tempfile + +from container_ci_suite.container_lib import ContainerTestLib +from container_ci_suite.container_lib import ContainerTestLibUtils +from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper + +from conftest import VARS + + +class TestMySqlGeneralContainer: + """ + Test MySQL container configuration. + """ + + def setup_method(self): + self.s2i_db = ContainerTestLib(image_name=VARS.IMAGE_NAME) + self.s2i_db.set_new_db_type(db_type="mysql") + + def teardown_method(self): + self.s2i_db.cleanup() + + @pytest.mark.parametrize( + "docker_args, username, password, root_password", + [ + ("", "user", "pass", ""), + ("", "user1", "pass1", "r00t"), + ("--user 12345", "user", "pass", ""), + ("--user 12345", "user1", "pass1", "r00t"), + ], + ) + def test_run(self, docker_args, username, password, root_password): + """ + Test container creation fails with invalid combinations of arguments. + """ + root_password_arg = ( + f"-e MYSQL_ROOT_PASSWORD={root_password}" if root_password else "" + ) + cid_file_name = f"test_{username}_{password}_{root_password}" + assert self.s2i_db.create_container( + cid_file_name=cid_file_name, + container_args=[ + f"-e MYSQL_USER={username}", + f"-e MYSQL_PASSWORD={password}", + "-e MYSQL_DATABASE=db", + f"{root_password_arg}", + f"{docker_args}", + ], + command="run-mysqld --innodb_buffer_pool_size=5242880", + ) + cip = self.s2i_db.get_cip(cid_file_name=cid_file_name) + assert cip + assert self.s2i_db.test_db_connection( + container_ip=cip, username=username, password=password + ) + cid = self.s2i_db.get_cid(cid_file_name=cid_file_name) + output = PodmanCLIWrapper.podman_exec_shell_command( + cid_file_name=cid, + cmd="mysql --version", + ) + assert VARS.VERSION in output + self.s2i_db.db_lib.assert_login_access( + container_ip=cip, + username=username, + password=password, + expected_success=True, + ) + self.s2i_db.db_lib.assert_login_access( + container_ip=cip, + username=username, + password=f"{password}_foo", + expected_success=False, + ) + if root_password: + self.s2i_db.db_lib.assert_login_access( + container_ip=cip, + username="root", + password=root_password, + expected_success=True, + ) + self.s2i_db.db_lib.assert_login_access( + container_ip=cip, + username="root", + password=f"{root_password}_foo", + expected_success=False, + ) + else: + self.s2i_db.db_lib.assert_login_access( + container_ip=cip, + username="root", + password="foo", + expected_success=False, + ) + self.s2i_db.db_lib.assert_login_access( + container_ip=cip, + username="root", + password="", + expected_success=False, + ) + output = self.s2i_db.db_lib.assert_local_access(container_id=cid) + assert output + podman_cmd = ( + f"--rm {VARS.IMAGE_NAME} mysql --host {cip} -u{username} -p{password}" + ) + assert PodmanCLIWrapper.podman_run_command( + cmd=f"{podman_cmd} -e 'CREATE TABLE tbl (col1 VARCHAR(20), col2 VARCHAR(20));' db", + ) + values = 'INSERT INTO tbl VALUES ("foo1", "bar1");' + assert PodmanCLIWrapper.podman_run_command( + cmd=f"{podman_cmd} -e '{values}' db", + ) + values = 'INSERT INTO tbl VALUES ("foo2", "bar2");' + assert PodmanCLIWrapper.podman_run_command( + cmd=f"{podman_cmd} -e '{values}' db", + ) + values = 'INSERT INTO tbl VALUES ("foo3", "bar3");' + assert PodmanCLIWrapper.podman_run_command( + cmd=f"{podman_cmd} -e '{values}' db", + ) + output = PodmanCLIWrapper.podman_run_command( + cmd=f"{podman_cmd} -e 'SELECT * FROM tbl;' db", + ) + assert re.search(r"foo1\t*bar1", output) + assert re.search(r"foo2\t*bar2", output) + assert re.search(r"foo3\t*bar3", output) + PodmanCLIWrapper.podman_run_command( + cmd=f"{podman_cmd} -e 'DROP TABLE tbl;' db", + ) + + def test_datadir_actions(self): + """ + Test container creation fails with invalid combinations of arguments. + """ + cid_testupg1 = "testupg1" + datadir = tempfile.mkdtemp(prefix="/tmp/mysql-datadir-actions") + assert ContainerTestLibUtils.commands_to_run( + commands_to_run=[ + f"mkdir -p {datadir}/data", + f"chmod -R a+rwx {datadir}", + ] + ) + assert self.s2i_db.create_container( + cid_file_name=cid_testupg1, + container_args=[ + "-e MYSQL_USER=user", + "-e MYSQL_PASSWORD=foo", + "-e MYSQL_DATABASE=db", + f"-v {datadir}/data:/var/lib/mysql/data:Z", + ], + ) + cip = self.s2i_db.get_cip(cid_file_name=cid_testupg1) + assert cip + assert self.s2i_db.test_db_connection( + container_ip=cip, username="user", password="foo" + ) + cid = self.s2i_db.get_cid(cid_file_name=cid_testupg1) + assert cid + PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") + + cid_testupg5 = "testupg5" + assert self.s2i_db.create_container( + cid_file_name=cid_testupg5, + container_args=[ + "-e MYSQL_USER=user", + "-e MYSQL_PASSWORD=foo", + "-e MYSQL_DATABASE=db", + f"-v {datadir}/data:/var/lib/mysql/data:Z", + "-e MYSQL_DATADIR_ACTION=analyze", + ], + ) + cip = self.s2i_db.get_cip(cid_file_name=cid_testupg5) + assert cip + assert self.s2i_db.test_db_connection( + container_ip=cip, username="user", password="foo" + ) + cid = self.s2i_db.get_cid(cid_file_name=cid_testupg5) + assert cid + output = PodmanCLIWrapper.podman_logs( + container_id=cid, + ) + assert re.search(r"--analyze --all-databases", output) + PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") + + cid_testupg6 = "testupg6" + assert self.s2i_db.create_container( + cid_file_name=cid_testupg6, + container_args=[ + "-e MYSQL_USER=user", + "-e MYSQL_PASSWORD=foo", + "-e MYSQL_DATABASE=db", + f"-v {datadir}/data:/var/lib/mysql/data:Z", + "-e MYSQL_DATADIR_ACTION=optimize", + ], + ) + cip = self.s2i_db.get_cip(cid_file_name=cid_testupg6) + assert cip + assert self.s2i_db.test_db_connection( + container_ip=cip, username="user", password="foo" + ) + cid = self.s2i_db.get_cid(cid_file_name=cid_testupg6) + assert cid + output = PodmanCLIWrapper.podman_logs( + container_id=cid, + ) + assert re.search(r"--optimize --all-databases", output) + PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") diff --git a/test/test_container_password.py b/test/test_container_password.py new file mode 100644 index 0000000..89bfaf5 --- /dev/null +++ b/test/test_container_password.py @@ -0,0 +1,127 @@ +import tempfile + +from container_ci_suite.container_lib import ContainerTestLib, DatabaseWrapper +from container_ci_suite.container_lib import ContainerTestLibUtils +from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper + +from conftest import VARS + + +class TestMySqlPasswordContainer: + """ + Test MySQL container configuration. + """ + + def setup_method(self): + self.ssl_db = ContainerTestLib(image_name=VARS.IMAGE_NAME) + self.ssl_db.set_new_db_type(db_type="mysql") + self.db_connector = DatabaseWrapper(image_name=VARS.IMAGE_NAME, db_type="mysql") + + def teardown_method(self): + self.ssl_db.cleanup() + + def test_password_change(self): + """ """ + cid_file_name = "test_password_change" + pwd_dir = tempfile.mkdtemp(prefix="/tmp/mysql-pwd") + username = "user" + password = "foo" + assert ContainerTestLibUtils.commands_to_run( + commands_to_run=[ + f"chmod -R a+rwx {pwd_dir}", + ] + ) + assert self.ssl_db.create_container( + cid_file_name=cid_file_name, + container_args=[ + f"-e MYSQL_USER={username}", + f"-e MYSQL_PASSWORD={password}", + "-e MYSQL_DATABASE=db", + f"-v {pwd_dir}:/var/lib/mysql/data:Z", + ], + ) + cip = self.ssl_db.get_cip(cid_file_name=cid_file_name) + assert cip + assert self.ssl_db.test_db_connection( + container_ip=cip, username=username, password=password + ) + cid = self.ssl_db.get_cid(cid_file_name=cid_file_name) + assert cid + PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") + cid_file_name = "test_password_change_2" + new_password = "bar" + assert self.ssl_db.create_container( + cid_file_name=cid_file_name, + container_args=[ + f"-e MYSQL_USER={username}", + f"-e MYSQL_PASSWORD={new_password}", + "-e MYSQL_DATABASE=db", + f"-v {pwd_dir}:/var/lib/mysql/data:Z", + ], + ) + podman_cmd = ( + f"--rm {VARS.IMAGE_NAME} mysql --host {cip} -u{username} -p{password}" + ) + output = PodmanCLIWrapper.podman_run_command( + cmd=f"{podman_cmd} -e 'SELECT 1;' db", + ) + assert output == "1" + + def test_password_change_new_user_test(self): + """ """ + cid_file_name = "test_password_change1" + pwd_dir = tempfile.mkdtemp(prefix="/tmp/mysql-pwd") + username1 = "user" + password1 = "foo" + assert ContainerTestLibUtils.commands_to_run( + commands_to_run=[ + f"chmod -R a+rwx {pwd_dir}", + ] + ) + assert self.ssl_db.create_container( + cid_file_name=cid_file_name, + container_args=[ + f"-e MYSQL_USER={username1}", + f"-e MYSQL_PASSWORD={password1}", + "-e MYSQL_DATABASE=db", + f"-v {pwd_dir}:/var/lib/mysql/data:Z", + ], + ) + cip = self.ssl_db.get_cip(cid_file_name=cid_file_name) + assert cip + assert self.ssl_db.test_db_connection( + container_ip=cip, username=username1, password=password1 + ) + cid = self.ssl_db.get_cid(cid_file_name=cid_file_name) + assert cid + PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") + cid_file_name = "test_password_change2" + username2 = "user2" + password2 = "bar" + # Create second container with changed password + assert self.ssl_db.create_container( + cid_file_name=cid_file_name, + container_args=[ + f"-e MYSQL_USER={username2}", + f"-e MYSQL_PASSWORD={password2}", + "-e MYSQL_DATABASE=db", + f"-v {pwd_dir}:/var/lib/mysql/data:Z", + ], + ) + cip2 = self.ssl_db.get_cip(cid_file_name=cid_file_name) + assert cip2 + assert self.ssl_db.test_db_connection( + container_ip=cip2, username=username1, password=password1 + ) + cid2 = self.ssl_db.get_cid(cid_file_name=cid_file_name) + mysql_logs = PodmanCLIWrapper.podman_logs( + conatiner_id=cid2, + ) + assert "User user2 does not exist in database" in mysql_logs + podman_cmd = ( + f"--rm {VARS.IMAGE_NAME} mysql --host {cip2} -u{username1} -p{password2}" + ) + output = PodmanCLIWrapper.podman_run_command( + cmd=f"{podman_cmd} -e 'SELECT 1;' db", + ) + assert output == "1" diff --git a/test/test_container_ssl.py b/test/test_container_ssl.py new file mode 100644 index 0000000..02ef17b --- /dev/null +++ b/test/test_container_ssl.py @@ -0,0 +1,82 @@ +import tempfile +import re + +from container_ci_suite.container_lib import ContainerTestLib +from container_ci_suite.container_lib import ContainerTestLibUtils +from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper + +from conftest import VARS + + +class TestMySqlGeneralContainer: + """ + Test MySQL container configuration. + """ + + def setup_method(self): + self.ssl_db = ContainerTestLib(image_name=VARS.IMAGE_NAME) + self.ssl_db.set_new_db_type(db_type="mysql") + + def teardown_method(self): + self.ssl_db.cleanup() + + def test_ssl(self): + """ """ + ssl_dir = tempfile.mkdtemp(prefix="/tmp/mysql-ssl_data") + username = "ssl_test_user" + password = "ssl_test" + with open(f"{ssl_dir}/ssl.cnf", mode="wt+") as f: + lines = [ + "[mysqld]", + "ssl-key=${APP_DATA}/mysql-certs/server-key.pem", + "ssl-cert=${APP_DATA}/mysql-certs/server-cert-selfsigned.pem", + ] + f.write("\n".join(lines)) + server_key_pem = f"{ssl_dir}/server-key.pem" + server_req_pem = f"{ssl_dir}/server-req.pem" + server_cert_selfsigned_pem = f"{ssl_dir}/server-cert-selfsigned.pem" + ContainerTestLibUtils.run_command( + cmd=f"openssl req -newkey rsa:2048 -nodes -keyout {server_key_pem} -subj " + + f"/C=GB/ST=Berkshire/L=Newbury/O=My Server Company' > {server_req_pem}" + ) + ContainerTestLibUtils.run_command( + cmd=f"openssl req -new -x509 -nodes -key {server_key_pem} -batch > " + + f"{server_cert_selfsigned_pem}" + ) + assert ContainerTestLibUtils.commands_to_run( + commands_to_run=[ + f"mkdir -p {ssl_dir}/mysql-certs {ssl_dir}/mysql-cfg", + f"cp {ssl_dir}/server-cert-selfsigned.pem {ssl_dir}/mysql-certs/server-cert-selfsigned.pem", + f"cp {ssl_dir}/server-key.pem {ssl_dir}/mysql-certs/server-key.pem", + f"cp {ssl_dir}/ssl.cnf {ssl_dir}/mysql-cfg/ssl.cnf", + f"chown -R 27:27 {ssl_dir}", + ] + ) + + ca_cert_path = "/opt/app-root/src/mysql-certs/server-cert-selfsigned.pem" + cid_file_name = "s2i_test_ssl" + assert self.ssl_db.create_container( + cid_file_name=cid_file_name, + container_args=[ + f"-e MYSQL_USER={username}", + f"-e MYSQL_PASSWORD={password}", + "-e MYSQL_DATABASE=db", + f"-v {ssl_dir}:/opt/app-root/src/:z", + ], + ) + cip = self.ssl_db.get_cip(cid_file_name=cid_file_name) + assert cip + assert self.ssl_db.test_db_connection( + container_ip=cip, username=username, password=password + ) + cid = self.ssl_db.get_cid(cid_file_name=cid_file_name) + assert cid + + mysql_cmd = ( + f"mysql --host {cip} -u{username} -p{password} --ssl-ca={ca_cert_path}" + + "-e 'show status like \"Ssl_cipher\" \\G' db" + ) + ssl_output = PodmanCLIWrapper.podman_run_command( + cmd=f"--rm -v {ssl_dir}:/opt/app-root/src/:z {VARS.IMAGE_NAME} {mysql_cmd}", + ) + assert re.search(r"Value: [A-Z][A-Z0-9-]*", ssl_output) diff --git a/test/test_ocp_mysql_latest_imagestreams.py b/test/test_ocp_mysql_latest_imagestreams.py index b30c384..fa46034 100644 --- a/test/test_ocp_mysql_latest_imagestreams.py +++ b/test/test_ocp_mysql_latest_imagestreams.py @@ -1,6 +1,5 @@ import os import sys -import pytest from pathlib import Path @@ -15,11 +14,10 @@ class TestLatestImagestreams: - def setup_method(self): self.isc = ImageStreamChecker(working_dir=TEST_DIR.parent) def test_latest_imagestream(self): self.latest_version = self.isc.get_latest_version() - assert self.latest_version != "" + assert self.latest_version self.isc.check_imagestreams(self.latest_version) diff --git a/test/test_ocp_mysql_local_template.py b/test/test_ocp_mysql_local_template.py index fee611e..6beb487 100644 --- a/test/test_ocp_mysql_local_template.py +++ b/test/test_ocp_mysql_local_template.py @@ -7,6 +7,7 @@ from container_ci_suite.utils import check_variables from constants import TAGS + if not check_variables(): print("At least one variable from IMAGE_NAME, OS, VERSION is missing.") sys.exit(1) @@ -21,20 +22,17 @@ class TestMySQLDeployTemplate: - def setup_method(self): - self.oc_api = OpenShiftAPI(pod_name_prefix="mysql-testing", version=VERSION, shared_cluster=True) + self.oc_api = OpenShiftAPI( + pod_name_prefix="mysql-testing", version=VERSION, shared_cluster=True + ) self.oc_api.import_is("imagestreams/mysql-rhel.json", "", skip_check=True) def teardown_method(self): self.oc_api.delete_project() @pytest.mark.parametrize( - "template", - [ - "mysql-ephemeral-template.json", - "mysql-persistent-template.json" - ] + "template", ["mysql-ephemeral-template.json", "mysql-persistent-template.json"] ) def test_template_inside_cluster(self, template): short_version = VERSION.replace(".", "") @@ -45,10 +43,10 @@ def test_template_inside_cluster(self, template): openshift_args=[ f"MYSQL_VERSION={VERSION}{TAG}", f"DATABASE_SERVICE_NAME={self.oc_api.pod_name_prefix}", - f"MYSQL_USER=testu", - f"MYSQL_PASSWORD=testp", - f"MYSQL_DATABASE=testdb" - ] + "MYSQL_USER=testu", + "MYSQL_PASSWORD=testp", + "MYSQL_DATABASE=testdb", + ], ) assert self.oc_api.is_pod_running(pod_name_prefix=self.oc_api.pod_name_prefix) @@ -56,5 +54,5 @@ def test_template_inside_cluster(self, template): image_name=f"registry.redhat.io/{OS}/mysql-{short_version}", service_name=self.oc_api.pod_name_prefix, cmd="echo 'SELECT 42 as testval\\g' | mysql --connect-timeout=15 -h testdb -utestu -ptestp", - expected_output="42" + expected_output="42", ) diff --git a/test/test_ocp_mysql_shared_helm_template.py b/test/test_ocp_mysql_shared_helm_template.py index c80d0e1..31c5046 100644 --- a/test/test_ocp_mysql_shared_helm_template.py +++ b/test/test_ocp_mysql_shared_helm_template.py @@ -1,29 +1,21 @@ -import os - -import pytest -from pathlib import Path - from container_ci_suite.helm import HelmChartsAPI -from constants import TAGS -test_dir = Path(os.path.abspath(os.path.dirname(__file__))) - -VERSION = os.getenv("VERSION") -IMAGE_NAME = os.getenv("IMAGE_NAME") -OS = os.getenv("TARGET") +from conftest import VARS -TAG = TAGS.get(OS) - class TestHelmMySQLDBPersistent: - def setup_method(self): package_name = "redhat-mysql-persistent" - path = test_dir - self.hc_api = HelmChartsAPI(path=path, package_name=package_name, tarball_dir=test_dir, shared_cluster=True) + self.hc_api = HelmChartsAPI( + path=VARS.TEST_DIR, + package_name=package_name, + tarball_dir=VARS.TEST_DIR, + shared_cluster=True, + ) self.hc_api.clone_helm_chart_repo( - repo_url="https://github.com/sclorg/helm-charts", repo_name="helm-charts", - subdir="charts/redhat" + repo_url="https://github.com/sclorg/helm-charts", + repo_name="helm-charts", + subdir="charts/redhat", ) def teardown_method(self): @@ -37,9 +29,9 @@ def test_package_persistent(self): assert self.hc_api.helm_package() assert self.hc_api.helm_installation( values={ - "mysql_version": f"{VERSION}{TAG}", + "mysql_version": f"{VARS.VERSION}{VARS.TAG}", "namespace": self.hc_api.namespace, - "database_service_name": "mysql" + "database_service_name": "mysql", } ) assert self.hc_api.is_pod_running(pod_name_prefix="mysql") From c21c4ac676594e04563e2c01deb4528c7406b4c7 Mon Sep 17 00:00:00 2001 From: "Petr \"Stone\" Hracek" Date: Mon, 1 Dec 2025 12:59:17 +0100 Subject: [PATCH 2/3] Add container tests including replication Signed-off-by: Petr "Stone" Hracek --- test/run | 1 - test/test_container_password.py | 73 +++++++++++--------- test/test_container_replication.py | 104 +++++++++++++++++++++++++++++ test/test_container_ssl.py | 17 ++--- 4 files changed, 155 insertions(+), 40 deletions(-) create mode 100644 test/test_container_replication.py diff --git a/test/run b/test/run index d233e10..1664318 100755 --- a/test/run +++ b/test/run @@ -8,7 +8,6 @@ set -o nounset shopt -s nullglob - THISDIR=$(dirname ${BASH_SOURCE[0]}) source ${THISDIR}/test-lib.sh diff --git a/test/test_container_password.py b/test/test_container_password.py index 89bfaf5..a18be6d 100644 --- a/test/test_container_password.py +++ b/test/test_container_password.py @@ -13,16 +13,15 @@ class TestMySqlPasswordContainer: """ def setup_method(self): - self.ssl_db = ContainerTestLib(image_name=VARS.IMAGE_NAME) - self.ssl_db.set_new_db_type(db_type="mysql") - self.db_connector = DatabaseWrapper(image_name=VARS.IMAGE_NAME, db_type="mysql") + self.pwd_change = ContainerTestLib(image_name=VARS.IMAGE_NAME) + self.pwd_change.set_new_db_type(db_type="mysql") def teardown_method(self): - self.ssl_db.cleanup() + self.pwd_change.cleanup() def test_password_change(self): """ """ - cid_file_name = "test_password_change" + cid_file_name1 = "test_password_change" pwd_dir = tempfile.mkdtemp(prefix="/tmp/mysql-pwd") username = "user" password = "foo" @@ -31,8 +30,8 @@ def test_password_change(self): f"chmod -R a+rwx {pwd_dir}", ] ) - assert self.ssl_db.create_container( - cid_file_name=cid_file_name, + assert self.pwd_change.create_container( + cid_file_name=cid_file_name1, container_args=[ f"-e MYSQL_USER={username}", f"-e MYSQL_PASSWORD={password}", @@ -40,18 +39,18 @@ def test_password_change(self): f"-v {pwd_dir}:/var/lib/mysql/data:Z", ], ) - cip = self.ssl_db.get_cip(cid_file_name=cid_file_name) - assert cip - assert self.ssl_db.test_db_connection( - container_ip=cip, username=username, password=password + cip1 = self.pwd_change.get_cip(cid_file_name=cid_file_name1) + assert cip1 + assert self.pwd_change.test_db_connection( + container_ip=cip1, username=username, password=password ) - cid = self.ssl_db.get_cid(cid_file_name=cid_file_name) - assert cid - PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") - cid_file_name = "test_password_change_2" + cid1 = self.pwd_change.get_cid(cid_file_name=cid_file_name1) + assert cid1 + PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid1}") + cid_file_name2 = "test_password_change_2" new_password = "bar" - assert self.ssl_db.create_container( - cid_file_name=cid_file_name, + assert self.pwd_change.create_container( + cid_file_name=cid_file_name2, container_args=[ f"-e MYSQL_USER={username}", f"-e MYSQL_PASSWORD={new_password}", @@ -59,13 +58,22 @@ def test_password_change(self): f"-v {pwd_dir}:/var/lib/mysql/data:Z", ], ) + cip2 = self.pwd_change.get_cip(cid_file_name=cid_file_name2) + assert cip2 + assert self.pwd_change.test_db_connection( + container_ip=cip2, username=username, password=new_password + ) podman_cmd = ( - f"--rm {VARS.IMAGE_NAME} mysql --host {cip} -u{username} -p{password}" + f"--rm {VARS.IMAGE_NAME} mysql --host {cip2} -u{username} -p{password}" ) output = PodmanCLIWrapper.podman_run_command( cmd=f"{podman_cmd} -e 'SELECT 1;' db", + ignore_error=True, + ) + print(output) + assert f"Access denied for user '{username}'@" in output, ( + f"The old password {password} should not work, but it does" ) - assert output == "1" def test_password_change_new_user_test(self): """ """ @@ -78,7 +86,7 @@ def test_password_change_new_user_test(self): f"chmod -R a+rwx {pwd_dir}", ] ) - assert self.ssl_db.create_container( + assert self.pwd_change.create_container( cid_file_name=cid_file_name, container_args=[ f"-e MYSQL_USER={username1}", @@ -87,19 +95,19 @@ def test_password_change_new_user_test(self): f"-v {pwd_dir}:/var/lib/mysql/data:Z", ], ) - cip = self.ssl_db.get_cip(cid_file_name=cid_file_name) - assert cip - assert self.ssl_db.test_db_connection( - container_ip=cip, username=username1, password=password1 + cip1 = self.pwd_change.get_cip(cid_file_name=cid_file_name) + assert cip1 + assert self.pwd_change.test_db_connection( + container_ip=cip1, username=username1, password=password1 ) - cid = self.ssl_db.get_cid(cid_file_name=cid_file_name) + cid = self.pwd_change.get_cid(cid_file_name=cid_file_name) assert cid PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") cid_file_name = "test_password_change2" username2 = "user2" password2 = "bar" # Create second container with changed password - assert self.ssl_db.create_container( + assert self.pwd_change.create_container( cid_file_name=cid_file_name, container_args=[ f"-e MYSQL_USER={username2}", @@ -108,14 +116,14 @@ def test_password_change_new_user_test(self): f"-v {pwd_dir}:/var/lib/mysql/data:Z", ], ) - cip2 = self.ssl_db.get_cip(cid_file_name=cid_file_name) + cip2 = self.pwd_change.get_cip(cid_file_name=cid_file_name) assert cip2 - assert self.ssl_db.test_db_connection( + assert self.pwd_change.test_db_connection( container_ip=cip2, username=username1, password=password1 ) - cid2 = self.ssl_db.get_cid(cid_file_name=cid_file_name) + cid2 = self.pwd_change.get_cid(cid_file_name=cid_file_name) mysql_logs = PodmanCLIWrapper.podman_logs( - conatiner_id=cid2, + container_id=cid2, ) assert "User user2 does not exist in database" in mysql_logs podman_cmd = ( @@ -123,5 +131,8 @@ def test_password_change_new_user_test(self): ) output = PodmanCLIWrapper.podman_run_command( cmd=f"{podman_cmd} -e 'SELECT 1;' db", + ignore_error=True, + ) + assert f"Access denied for user '{username1}'@" in output, ( + f"The new password {password2} should not work, but it does" ) - assert output == "1" diff --git a/test/test_container_replication.py b/test/test_container_replication.py new file mode 100644 index 0000000..5873723 --- /dev/null +++ b/test/test_container_replication.py @@ -0,0 +1,104 @@ +import tempfile +import re +from time import sleep + +from container_ci_suite.container_lib import ContainerTestLib, DatabaseWrapper +from container_ci_suite.container_lib import ContainerTestLibUtils +from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper + +from conftest import VARS + + +class TestMySqlReplicationContainer: + """ + Test MySQL container configuration. + """ + + def setup_method(self): + self.replication_db = ContainerTestLib(image_name=VARS.IMAGE_NAME) + self.replication_db.set_new_db_type(db_type="mysql") + + def teardown_method(self): + self.replication_db.cleanup() + + def test_replication(self): + """ """ + cluster_args = "-e MYSQL_SOURCE_USER=source -e MYSQL_SOURCE_PASSWORD=source -e MYSQL_DATABASE=db" + source_cid = "source.cid" + username = "user" + password = "foo" + # Run the MySQL source + assert self.replication_db.create_container( + cid_file_name=source_cid, + container_args=[ + f"-e MYSQL_USER={username}", + f"-e MYSQL_PASSWORD={password}", + "-e MYSQL_ROOT_PASSWORD=root", + "-e MYSQL_INNODB_BUFFER_POOL_SIZE=5M", + ], + docker_args=cluster_args, + command="run-mysqld-source", + ) + source_cip = self.replication_db.get_cip(cid_file_name=source_cid) + print(f"Source IP: {source_cip}") + source_cid = self.replication_db.get_cid(cid_file_name=source_cid) + assert source_cid + # Run the MySQL replica + replica_cid = "replica.cid" + assert self.replication_db.create_container( + cid_file_name=replica_cid, + container_args=[ + f"-e MYSQL_SOURCE_SERVICE_NAME={source_cip}", + "-e MYSQL_INNODB_BUFFER_POOL_SIZE=5M", + ], + docker_args=cluster_args, + command="run-mysqld-replica", + ) + replica_cip = self.replication_db.get_cip(cid_file_name=replica_cid) + assert replica_cip + replica_cid = self.replication_db.get_cid(cid_file_name=replica_cid) + assert replica_cid + print(f"Replica IP: {replica_cip}") + # Now wait till the SOURCE will see the REPLICA + result = self.replication_db.test_db_connection( + container_ip=replica_cip, + username=username, + password=password, + ) + result = PodmanCLIWrapper.call_podman_command( + cmd=f"exec {source_cid} mysql -e 'SHOW REPLICAS;' db", + ignore_error=True, + debug=True, + ) + print(f"Showing replicas: {result}") + assert replica_cip in result, ( + f"Replica {replica_cip} not found in SOURCE {source_cip}" + ) + # do some real work to test replication in practice + result = self.replication_db.test_db_connection( + container_ip=source_cip, + username=username, + password=password, + max_attempts=120, + sql_cmd="-e 'CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (24);'", + ) + print(f"Creating table: {result}") + # let's wait for the table to be created and available for replication + sleep(3) + + result = self.replication_db.test_db_connection( + container_ip=replica_cip, + username=username, + password=password, + max_attempts=120, + sql_cmd="-e 'select * from t1;'", + ) + assert result + podman_cmd = f"--rm {VARS.IMAGE_NAME} mysql --host {replica_cip} -u{username} -p{password}" + table_output = PodmanCLIWrapper.podman_run_command( + cmd=f"{podman_cmd} -e 'select * from t1;' db", + ) + print(f"Selecting from table: {table_output}") + assert re.search(r"^a\n^24", table_output.strip(), re.MULTILINE), ( + f"Replica {replica_cip} did not get value from SOURCE {source_cip}" + ) diff --git a/test/test_container_ssl.py b/test/test_container_ssl.py index 02ef17b..5aa1f55 100644 --- a/test/test_container_ssl.py +++ b/test/test_container_ssl.py @@ -32,16 +32,17 @@ def test_ssl(self): "ssl-cert=${APP_DATA}/mysql-certs/server-cert-selfsigned.pem", ] f.write("\n".join(lines)) - server_key_pem = f"{ssl_dir}/server-key.pem" - server_req_pem = f"{ssl_dir}/server-req.pem" - server_cert_selfsigned_pem = f"{ssl_dir}/server-cert-selfsigned.pem" + srv_key_pem = f"{ssl_dir}/server-key.pem" + srv_req_pem = f"{ssl_dir}/server-req.pem" + srv_self_pem = f"{ssl_dir}/server-cert-selfsigned.pem" + openssl_cmd = "openssl req -newkey rsa:2048 -nodes" + openssl_cmd_new = "openssl req -new -x509 -nodes" + subj = "/C=GB/ST=Berkshire/L=Newbury/O=My Server Company" ContainerTestLibUtils.run_command( - cmd=f"openssl req -newkey rsa:2048 -nodes -keyout {server_key_pem} -subj " - + f"/C=GB/ST=Berkshire/L=Newbury/O=My Server Company' > {server_req_pem}" + cmd=f"{openssl_cmd} -keyout {srv_key_pem} -subj '{subj}' > {srv_req_pem}" ) ContainerTestLibUtils.run_command( - cmd=f"openssl req -new -x509 -nodes -key {server_key_pem} -batch > " - + f"{server_cert_selfsigned_pem}" + cmd=f"{openssl_cmd_new} -key {srv_key_pem} -batch > {srv_self_pem}" ) assert ContainerTestLibUtils.commands_to_run( commands_to_run=[ @@ -74,7 +75,7 @@ def test_ssl(self): mysql_cmd = ( f"mysql --host {cip} -u{username} -p{password} --ssl-ca={ca_cert_path}" - + "-e 'show status like \"Ssl_cipher\" \\G' db" + + " -e 'show status like \"Ssl_cipher\" \\G' db" ) ssl_output = PodmanCLIWrapper.podman_run_command( cmd=f"--rm -v {ssl_dir}:/opt/app-root/src/:z {VARS.IMAGE_NAME} {mysql_cmd}", From 5639d0eca756b9c56a52bb7fb13e3ea38c01ca2c Mon Sep 17 00:00:00 2001 From: "Petr \"Stone\" Hracek" Date: Fri, 12 Dec 2025 12:49:27 +0100 Subject: [PATCH 3/3] Use class DatabaseWrapper to call sql commands directly Check configuration files in one command instead of several ones. Signed-off-by: Petr "Stone" Hracek --- test/test_container_basics.py | 5 - test/test_container_configuration.py | 169 ++++++++++++++------------- test/test_container_general.py | 142 ++++++++++++---------- test/test_container_password.py | 39 ++++--- test/test_container_replication.py | 61 +++++----- test/test_container_ssl.py | 12 +- 6 files changed, 238 insertions(+), 190 deletions(-) diff --git a/test/test_container_basics.py b/test/test_container_basics.py index ae034fb..e17edca 100644 --- a/test/test_container_basics.py +++ b/test/test_container_basics.py @@ -104,10 +104,5 @@ def test_s2i_usage_with_mount(self): ) cid = self.s2i_db.get_cid(cid_file_name=cid_s2i_test_mount) assert cid - db_configuration = PodmanCLIWrapper.podman_exec_shell_command( - cid_file_name=cid, - cmd="cat /etc/my.cnf /etc/my.cnf.d/*", - ) - assert db_configuration PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") shutil.rmtree(data_dir) diff --git a/test/test_container_configuration.py b/test/test_container_configuration.py index db2eadd..0809488 100644 --- a/test/test_container_configuration.py +++ b/test/test_container_configuration.py @@ -3,6 +3,7 @@ import pytest from container_ci_suite.container_lib import ContainerTestLib +from container_ci_suite.engines.database import DatabaseWrapper from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper from conftest import VARS @@ -14,9 +15,15 @@ class TestMySqlConfigurationContainer: """ def setup_method(self): + """ + Setup the test environment. + """ self.db = ContainerTestLib(image_name=VARS.IMAGE_NAME) def teardown_method(self): + """ + Teardown the test environment. + """ self.db.cleanup() def test_container_creation_fails(self): @@ -108,78 +115,95 @@ class TestMySqlConfigurationTests: """ def setup_method(self): - self.db = ContainerTestLib(image_name=VARS.IMAGE_NAME) - self.db.set_new_db_type(db_type="mysql") + """ + Setup the test environment. + """ + self.db_config = ContainerTestLib(image_name=VARS.IMAGE_NAME) + self.db_config.set_new_db_type(db_type="mysql") + self.db_api = DatabaseWrapper(image_name=VARS.IMAGE_NAME) def teardown_method(self): - self.db.cleanup() + """ + Teardown the test environment. + """ + self.db_config.cleanup() def test_configuration_auto_calculated_settings(self): """ Test MySQL container configuration auto-calculated settings. """ cid_config_test = "auto-config_test" - assert self.db.create_container( + username = "config_test_user" + password = "config_test" + assert self.db_config.create_container( cid_file_name=cid_config_test, container_args=[ "--env MYSQL_COLLATION=latin2_czech_cs", "--env MYSQL_CHARSET=latin2", - "--env MYSQL_USER=config_test_user", - "--env MYSQL_PASSWORD=config_test", + f"--env MYSQL_USER={username}", + f"--env MYSQL_PASSWORD={password}", "--env MYSQL_DATABASE=db", ], docker_args="--memory=512m", ) - cip = self.db.get_cip(cid_file_name=cid_config_test) + cip = self.db_config.get_cip(cid_file_name=cid_config_test) assert cip - return_value = self.db.test_db_connection( + assert self.db_config.test_db_connection( container_ip=cip, - username="config_test_user", - password="config_test", + username=username, + password=password, max_attempts=10, ) - assert return_value - cid = self.db.get_cid(cid_file_name=cid_config_test) + cid = self.db_config.get_cid(cid_file_name=cid_config_test) db_configuration = PodmanCLIWrapper.podman_exec_shell_command( cid_file_name=cid, cmd="cat /etc/my.cnf /etc/my.cnf.d/*", ) - assert db_configuration - assert re.search( - r"key_buffer_size\s*=\s*51M", - db_configuration, - ) - assert re.search( - r"read_buffer_size\s*=\s*25M", - db_configuration, - ) - assert re.search( - r"innodb_buffer_pool_size\s*=\s*256M", - db_configuration, - ) - assert re.search( - r"innodb_log_file_size\s*=\s*76M", - db_configuration, - ) - assert re.search( - r"innodb_log_buffer_size\s*=\s*76M", - db_configuration, + words = [ + "key_buffer_size\\s*=\\s*51M", + "read_buffer_size\\s*=\\s*25M", + "innodb_buffer_pool_size\\s*=\\s*256M", + "innodb_log_file_size\\s*=\\s*76M", + "innodb_log_buffer_size\\s*=\\s*76M", + "authentication_policy\\s*=\\s*'caching_sha2_password,,'", + ] + for word in words: + assert re.search(word, db_configuration), ( + f"Word {word} not found in {db_configuration}" + ) + # do some real work to test replication in practice + self.db_api.run_sql_command( + container_ip=cip, + username=username, + password=password, + container_id=cid, + sql_cmd="CREATE TABLE tbl (col VARCHAR(20));", + podman_run_command="exec", ) - assert re.search( - r"authentication_policy\s*=\s*'caching_sha2_password,,'", - db_configuration, + show_table_output = self.db_api.run_sql_command( + container_ip=cip, + username=username, + password=password, + container_id=cid, + sql_cmd="SHOW CREATE TABLE tbl;", + podman_run_command="exec", ) + assert "CHARSET=latin2" in show_table_output + assert "COLLATE=latin2_czech_cs" in show_table_output + PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") def test_configuration_options_settings(self): """ Test MySQL container configuration options. """ cid_config_test = "config_test" - assert self.db.create_container( + username = "config_test_user" + password = "config_test" + assert self.db_config.create_container( cid_file_name=cid_config_test, container_args=[ - "--env MYSQL_USER=config_test_user", - "--env MYSQL_PASSWORD=config_test", + f"--env MYSQL_USER={username}", + f"--env MYSQL_PASSWORD={password}", "--env MYSQL_DATABASE=db", "--env MYSQL_LOWER_CASE_TABLE_NAMES=1", "--env MYSQL_LOG_QUERIES_ENABLED=1", @@ -197,54 +221,41 @@ def test_configuration_options_settings(self): "--env MYSQL_AUTHENTICATION_POLICY=sha256_password", ], ) - cip = self.db.get_cip(cid_file_name=cid_config_test) + cip = self.db_config.get_cip(cid_file_name=cid_config_test) assert cip - assert self.db.test_db_connection( - container_ip=cip, username="config_test_user", password="config_test" + assert self.db_config.test_db_connection( + container_ip=cip, username=username, password=password ) - cip = self.db.get_cip(cid_file_name=cid_config_test) + cip = self.db_config.get_cip(cid_file_name=cid_config_test) assert cip - return_value = self.db.test_db_connection( + assert self.db_config.test_db_connection( container_ip=cip, - username="config_test_user", - password="config_test", + username=username, + password=password, max_attempts=10, ) - assert return_value - cid = self.db.get_cid(cid_file_name=cid_config_test) + cid = self.db_config.get_cid(cid_file_name=cid_config_test) db_configuration = PodmanCLIWrapper.podman_exec_shell_command( cid_file_name=cid, cmd="cat /etc/my.cnf /etc/my.cnf.d/*", ) - assert db_configuration - assert re.search( - r"lower_case_table_names\s*=\s*1", - db_configuration, - ) - assert re.search( - r"general_log\s*=\s*1", - db_configuration, - ) - assert re.search( - r"max_connections\s*=\s*1337", - db_configuration, - re.MULTILINE | re.IGNORECASE, - ) - assert re.search(r"ft_min_word_len\s*=\s*8", db_configuration) - assert re.search( - r"ft_max_word_len\s*=\s*15", - db_configuration, - ) - assert re.search(r"max_allowed_packet\s*=\s*10M", db_configuration) - assert re.search(r"table_open_cache\s*=\s*100", db_configuration) - assert re.search(r"sort_buffer_size\s*=\s*256K", db_configuration) - assert re.search(r"key_buffer_size\s*=\s*16M", db_configuration) - assert re.search(r"read_buffer_size\s*=\s*16M", db_configuration) - assert re.search(r"innodb_buffer_pool_size\s*=\s*16M", db_configuration) - assert re.search(r"innodb_log_file_size\s*=\s*4M", db_configuration) - assert re.search(r"innodb_log_buffer_size\s*=\s*4M", db_configuration) - assert re.search( - r"authentication_policy\s*=\s*'sha256_password'", - db_configuration, - re.MULTILINE, - ) + words = [ + "lower_case_table_names\\s*=\\s*1", + "general_log\\s*=\\s*1", + "max_connections\\s*=\\s*1337", + "ft_min_word_len\\s*=\\s*8", + "ft_max_word_len\\s*=\\s*15", + "max_allowed_packet\\s*=\\s*10M", + "table_open_cache\\s*=\\s*100", + "sort_buffer_size\\s*=\\s*256K", + "key_buffer_size\\s*=\\s*16M", + "read_buffer_size\\s*=\\s*16M", + "innodb_log_file_size\\s*=\\s*4M", + "innodb_log_buffer_size\\s*=\\s*4M", + "authentication_policy\\s*=\\s*'sha256_password'", + ] + for word in words: + assert re.search(word, db_configuration), ( + f"Word {word} not found in {db_configuration}" + ) + PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") diff --git a/test/test_container_general.py b/test/test_container_general.py index 4685305..504a631 100644 --- a/test/test_container_general.py +++ b/test/test_container_general.py @@ -4,6 +4,7 @@ from container_ci_suite.container_lib import ContainerTestLib from container_ci_suite.container_lib import ContainerTestLibUtils +from container_ci_suite.engines.database import DatabaseWrapper from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper from conftest import VARS @@ -15,11 +16,12 @@ class TestMySqlGeneralContainer: """ def setup_method(self): - self.s2i_db = ContainerTestLib(image_name=VARS.IMAGE_NAME) - self.s2i_db.set_new_db_type(db_type="mysql") + self.db_image = ContainerTestLib(image_name=VARS.IMAGE_NAME) + self.db_image.set_new_db_type(db_type="mysql") + self.db_api = DatabaseWrapper(image_name=VARS.IMAGE_NAME) def teardown_method(self): - self.s2i_db.cleanup() + self.db_image.cleanup() @pytest.mark.parametrize( "docker_args, username, password, root_password", @@ -38,7 +40,7 @@ def test_run(self, docker_args, username, password, root_password): f"-e MYSQL_ROOT_PASSWORD={root_password}" if root_password else "" ) cid_file_name = f"test_{username}_{password}_{root_password}" - assert self.s2i_db.create_container( + assert self.db_image.create_container( cid_file_name=cid_file_name, container_args=[ f"-e MYSQL_USER={username}", @@ -49,83 +51,96 @@ def test_run(self, docker_args, username, password, root_password): ], command="run-mysqld --innodb_buffer_pool_size=5242880", ) - cip = self.s2i_db.get_cip(cid_file_name=cid_file_name) + cip = self.db_image.get_cip(cid_file_name=cid_file_name) assert cip - assert self.s2i_db.test_db_connection( + assert self.db_image.test_db_connection( container_ip=cip, username=username, password=password ) - cid = self.s2i_db.get_cid(cid_file_name=cid_file_name) + cid = self.db_image.get_cid(cid_file_name=cid_file_name) output = PodmanCLIWrapper.podman_exec_shell_command( cid_file_name=cid, cmd="mysql --version", ) assert VARS.VERSION in output - self.s2i_db.db_lib.assert_login_access( + self.db_image.db_lib.assert_login_access( container_ip=cip, username=username, password=password, expected_success=True, ) - self.s2i_db.db_lib.assert_login_access( + self.db_image.db_lib.assert_login_access( container_ip=cip, username=username, password=f"{password}_foo", expected_success=False, ) if root_password: - self.s2i_db.db_lib.assert_login_access( + self.db_image.db_lib.assert_login_access( container_ip=cip, username="root", password=root_password, expected_success=True, ) - self.s2i_db.db_lib.assert_login_access( + self.db_image.db_lib.assert_login_access( container_ip=cip, username="root", password=f"{root_password}_foo", expected_success=False, ) else: - self.s2i_db.db_lib.assert_login_access( + self.db_image.db_lib.assert_login_access( container_ip=cip, username="root", password="foo", expected_success=False, ) - self.s2i_db.db_lib.assert_login_access( + self.db_image.db_lib.assert_login_access( container_ip=cip, username="root", password="", expected_success=False, ) - output = self.s2i_db.db_lib.assert_local_access(container_id=cid) - assert output - podman_cmd = ( - f"--rm {VARS.IMAGE_NAME} mysql --host {cip} -u{username} -p{password}" - ) - assert PodmanCLIWrapper.podman_run_command( - cmd=f"{podman_cmd} -e 'CREATE TABLE tbl (col1 VARCHAR(20), col2 VARCHAR(20));' db", - ) - values = 'INSERT INTO tbl VALUES ("foo1", "bar1");' - assert PodmanCLIWrapper.podman_run_command( - cmd=f"{podman_cmd} -e '{values}' db", - ) - values = 'INSERT INTO tbl VALUES ("foo2", "bar2");' - assert PodmanCLIWrapper.podman_run_command( - cmd=f"{podman_cmd} -e '{values}' db", - ) - values = 'INSERT INTO tbl VALUES ("foo3", "bar3");' - assert PodmanCLIWrapper.podman_run_command( - cmd=f"{podman_cmd} -e '{values}' db", + assert self.db_image.db_lib.assert_local_access(container_id=cid) + self.db_api.run_sql_command( + container_ip=cip, + username=username, + password=password, + container_id=VARS.IMAGE_NAME, + sql_cmd=[ + "CREATE TABLE tbl (col1 VARCHAR(20), col2 VARCHAR(20));", + ], ) - output = PodmanCLIWrapper.podman_run_command( - cmd=f"{podman_cmd} -e 'SELECT * FROM tbl;' db", + self.db_api.run_sql_command( + container_ip=cip, + username=username, + password=password, + container_id=VARS.IMAGE_NAME, + sql_cmd=[ + 'INSERT INTO tbl VALUES ("foo1", "bar1");', + 'INSERT INTO tbl VALUES ("foo2", "bar2");', + 'INSERT INTO tbl VALUES ("foo3", "bar3");', + ], ) - assert re.search(r"foo1\t*bar1", output) - assert re.search(r"foo2\t*bar2", output) - assert re.search(r"foo3\t*bar3", output) - PodmanCLIWrapper.podman_run_command( - cmd=f"{podman_cmd} -e 'DROP TABLE tbl;' db", + output = self.db_api.run_sql_command( + container_ip=cip, + username=username, + password=password, + container_id=VARS.IMAGE_NAME, + sql_cmd="SELECT * FROM tbl;", + ) + words = [ + "foo1\t*bar1", + "foo2\t*bar2", + "foo3\t*bar3", + ] + for word in words: + assert re.search(word, output), f"Word {word} not found in {output}" + self.db_api.run_sql_command( + container_ip=cip, + username=username, + password=password, + container_id=VARS.IMAGE_NAME, + sql_cmd="DROP TABLE tbl;", ) def test_datadir_actions(self): @@ -140,41 +155,44 @@ def test_datadir_actions(self): f"chmod -R a+rwx {datadir}", ] ) - assert self.s2i_db.create_container( + mysql_user = "user" + mysql_password = "foo" + mysql_database = "db" + assert self.db_image.create_container( cid_file_name=cid_testupg1, container_args=[ - "-e MYSQL_USER=user", - "-e MYSQL_PASSWORD=foo", - "-e MYSQL_DATABASE=db", + f"-e MYSQL_USER={mysql_user}", + f"-e MYSQL_PASSWORD={mysql_password}", + f"-e MYSQL_DATABASE={mysql_database}", f"-v {datadir}/data:/var/lib/mysql/data:Z", ], ) - cip = self.s2i_db.get_cip(cid_file_name=cid_testupg1) + cip = self.db_image.get_cip(cid_file_name=cid_testupg1) assert cip - assert self.s2i_db.test_db_connection( + assert self.db_image.test_db_connection( container_ip=cip, username="user", password="foo" ) - cid = self.s2i_db.get_cid(cid_file_name=cid_testupg1) + cid = self.db_image.get_cid(cid_file_name=cid_testupg1) assert cid PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") cid_testupg5 = "testupg5" - assert self.s2i_db.create_container( + assert self.db_image.create_container( cid_file_name=cid_testupg5, container_args=[ - "-e MYSQL_USER=user", - "-e MYSQL_PASSWORD=foo", - "-e MYSQL_DATABASE=db", + f"-e MYSQL_USER={mysql_user}", + f"-e MYSQL_PASSWORD={mysql_password}", + f"-e MYSQL_DATABASE={mysql_database}", f"-v {datadir}/data:/var/lib/mysql/data:Z", "-e MYSQL_DATADIR_ACTION=analyze", ], ) - cip = self.s2i_db.get_cip(cid_file_name=cid_testupg5) + cip = self.db_image.get_cip(cid_file_name=cid_testupg5) assert cip - assert self.s2i_db.test_db_connection( - container_ip=cip, username="user", password="foo" + assert self.db_image.test_db_connection( + container_ip=cip, username=mysql_user, password=mysql_password ) - cid = self.s2i_db.get_cid(cid_file_name=cid_testupg5) + cid = self.db_image.get_cid(cid_file_name=cid_testupg5) assert cid output = PodmanCLIWrapper.podman_logs( container_id=cid, @@ -183,22 +201,22 @@ def test_datadir_actions(self): PodmanCLIWrapper.call_podman_command(cmd=f"stop {cid}") cid_testupg6 = "testupg6" - assert self.s2i_db.create_container( + assert self.db_image.create_container( cid_file_name=cid_testupg6, container_args=[ - "-e MYSQL_USER=user", - "-e MYSQL_PASSWORD=foo", - "-e MYSQL_DATABASE=db", + f"-e MYSQL_USER={mysql_user}", + f"-e MYSQL_PASSWORD={mysql_password}", + f"-e MYSQL_DATABASE={mysql_database}", f"-v {datadir}/data:/var/lib/mysql/data:Z", "-e MYSQL_DATADIR_ACTION=optimize", ], ) - cip = self.s2i_db.get_cip(cid_file_name=cid_testupg6) + cip = self.db_image.get_cip(cid_file_name=cid_testupg6) assert cip - assert self.s2i_db.test_db_connection( - container_ip=cip, username="user", password="foo" + assert self.db_image.test_db_connection( + container_ip=cip, username=mysql_user, password=mysql_password ) - cid = self.s2i_db.get_cid(cid_file_name=cid_testupg6) + cid = self.db_image.get_cid(cid_file_name=cid_testupg6) assert cid output = PodmanCLIWrapper.podman_logs( container_id=cid, diff --git a/test/test_container_password.py b/test/test_container_password.py index a18be6d..cf0a321 100644 --- a/test/test_container_password.py +++ b/test/test_container_password.py @@ -1,7 +1,8 @@ import tempfile -from container_ci_suite.container_lib import ContainerTestLib, DatabaseWrapper +from container_ci_suite.container_lib import ContainerTestLib from container_ci_suite.container_lib import ContainerTestLibUtils +from container_ci_suite.engines.database import DatabaseWrapper from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper from conftest import VARS @@ -13,14 +14,23 @@ class TestMySqlPasswordContainer: """ def setup_method(self): + """ + Setup the test environment. + """ self.pwd_change = ContainerTestLib(image_name=VARS.IMAGE_NAME) self.pwd_change.set_new_db_type(db_type="mysql") + self.dw_api = DatabaseWrapper(image_name=VARS.IMAGE_NAME) def teardown_method(self): + """ + Teardown the test environment. + """ self.pwd_change.cleanup() def test_password_change(self): - """ """ + """ + Test password change. + """ cid_file_name1 = "test_password_change" pwd_dir = tempfile.mkdtemp(prefix="/tmp/mysql-pwd") username = "user" @@ -63,20 +73,21 @@ def test_password_change(self): assert self.pwd_change.test_db_connection( container_ip=cip2, username=username, password=new_password ) - podman_cmd = ( - f"--rm {VARS.IMAGE_NAME} mysql --host {cip2} -u{username} -p{password}" - ) - output = PodmanCLIWrapper.podman_run_command( - cmd=f"{podman_cmd} -e 'SELECT 1;' db", + output = self.dw_api.run_sql_command( + container_ip=cip2, + username=username, + password=password, + container_id=VARS.IMAGE_NAME, ignore_error=True, ) - print(output) assert f"Access denied for user '{username}'@" in output, ( f"The old password {password} should not work, but it does" ) def test_password_change_new_user_test(self): - """ """ + """ + Test password change for new user. + """ cid_file_name = "test_password_change1" pwd_dir = tempfile.mkdtemp(prefix="/tmp/mysql-pwd") username1 = "user" @@ -126,11 +137,11 @@ def test_password_change_new_user_test(self): container_id=cid2, ) assert "User user2 does not exist in database" in mysql_logs - podman_cmd = ( - f"--rm {VARS.IMAGE_NAME} mysql --host {cip2} -u{username1} -p{password2}" - ) - output = PodmanCLIWrapper.podman_run_command( - cmd=f"{podman_cmd} -e 'SELECT 1;' db", + output = self.dw_api.run_sql_command( + container_ip=cip2, + username=username1, + password=password2, + container_id=VARS.IMAGE_NAME, ignore_error=True, ) assert f"Access denied for user '{username1}'@" in output, ( diff --git a/test/test_container_replication.py b/test/test_container_replication.py index 5873723..68a33c1 100644 --- a/test/test_container_replication.py +++ b/test/test_container_replication.py @@ -2,8 +2,8 @@ import re from time import sleep -from container_ci_suite.container_lib import ContainerTestLib, DatabaseWrapper -from container_ci_suite.container_lib import ContainerTestLibUtils +from container_ci_suite.container_lib import ContainerTestLib +from container_ci_suite.engines.database import DatabaseWrapper from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper from conftest import VARS @@ -15,14 +15,23 @@ class TestMySqlReplicationContainer: """ def setup_method(self): + """ + Setup the test environment. + """ self.replication_db = ContainerTestLib(image_name=VARS.IMAGE_NAME) self.replication_db.set_new_db_type(db_type="mysql") + self.db_wrapper_api = DatabaseWrapper(image_name=VARS.IMAGE_NAME) def teardown_method(self): + """ + Teardown the test environment. + """ self.replication_db.cleanup() def test_replication(self): - """ """ + """ + Test replication. + """ cluster_args = "-e MYSQL_SOURCE_USER=source -e MYSQL_SOURCE_PASSWORD=source -e MYSQL_DATABASE=db" source_cid = "source.cid" username = "user" @@ -40,7 +49,6 @@ def test_replication(self): command="run-mysqld-source", ) source_cip = self.replication_db.get_cip(cid_file_name=source_cid) - print(f"Source IP: {source_cip}") source_cid = self.replication_db.get_cid(cid_file_name=source_cid) assert source_cid # Run the MySQL replica @@ -58,47 +66,42 @@ def test_replication(self): assert replica_cip replica_cid = self.replication_db.get_cid(cid_file_name=replica_cid) assert replica_cid - print(f"Replica IP: {replica_cip}") # Now wait till the SOURCE will see the REPLICA result = self.replication_db.test_db_connection( container_ip=replica_cip, - username=username, - password=password, + username="root", + password="root", ) - result = PodmanCLIWrapper.call_podman_command( - cmd=f"exec {source_cid} mysql -e 'SHOW REPLICAS;' db", - ignore_error=True, - debug=True, + result = self.db_wrapper_api.run_sql_command( + container_ip=source_cip, + username="root", + password="root", + container_id=source_cid, + sql_cmd="SHOW REPLICAS;", + podman_run_command="exec", ) - print(f"Showing replicas: {result}") assert replica_cip in result, ( f"Replica {replica_cip} not found in SOURCE {source_cip}" ) # do some real work to test replication in practice - result = self.replication_db.test_db_connection( + table_output = self.db_wrapper_api.run_sql_command( container_ip=source_cip, - username=username, - password=password, - max_attempts=120, - sql_cmd="-e 'CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (24);'", + username="root", + password="root", + container_id=source_cid, + sql_cmd="CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (24);", + podman_run_command="exec", ) - print(f"Creating table: {result}") # let's wait for the table to be created and available for replication sleep(3) - result = self.replication_db.test_db_connection( + table_output = self.db_wrapper_api.run_sql_command( container_ip=replica_cip, - username=username, - password=password, - max_attempts=120, - sql_cmd="-e 'select * from t1;'", - ) - assert result - podman_cmd = f"--rm {VARS.IMAGE_NAME} mysql --host {replica_cip} -u{username} -p{password}" - table_output = PodmanCLIWrapper.podman_run_command( - cmd=f"{podman_cmd} -e 'select * from t1;' db", + username="root", + password="root", + container_id=VARS.IMAGE_NAME, + sql_cmd="select * from t1;", ) - print(f"Selecting from table: {table_output}") assert re.search(r"^a\n^24", table_output.strip(), re.MULTILINE), ( f"Replica {replica_cip} did not get value from SOURCE {source_cip}" ) diff --git a/test/test_container_ssl.py b/test/test_container_ssl.py index 5aa1f55..1e77b3e 100644 --- a/test/test_container_ssl.py +++ b/test/test_container_ssl.py @@ -3,6 +3,7 @@ from container_ci_suite.container_lib import ContainerTestLib from container_ci_suite.container_lib import ContainerTestLibUtils +from container_ci_suite.engines.database import DatabaseWrapper from container_ci_suite.engines.podman_wrapper import PodmanCLIWrapper from conftest import VARS @@ -14,14 +15,23 @@ class TestMySqlGeneralContainer: """ def setup_method(self): + """ + Setup the test environment. + """ self.ssl_db = ContainerTestLib(image_name=VARS.IMAGE_NAME) self.ssl_db.set_new_db_type(db_type="mysql") + self.db_api = DatabaseWrapper(image_name=VARS.IMAGE_NAME) def teardown_method(self): + """ + Teardown the test environment. + """ self.ssl_db.cleanup() def test_ssl(self): - """ """ + """ + Test SSL. + """ ssl_dir = tempfile.mkdtemp(prefix="/tmp/mysql-ssl_data") username = "ssl_test_user" password = "ssl_test"