import time import pymysql.cursors import pytest from helpers.cluster import ( ClickHouseCluster, ClickHouseInstance, get_docker_compose_path, ) import logging from . import materialized_with_ddl DOCKER_COMPOSE_PATH = get_docker_compose_path() cluster = ClickHouseCluster(__file__) mysql_node = None mysql8_node = None node_db = cluster.add_instance( "node1", main_configs=["configs/timezone_config.xml"], user_configs=["configs/users.xml"], with_mysql=True, with_mysql8=True, stay_alive=True, ) node_disable_bytes_settings = cluster.add_instance( "node2", main_configs=["configs/timezone_config.xml"], user_configs=["configs/users_disable_bytes_settings.xml"], with_mysql=False, stay_alive=True, ) node_disable_rows_settings = cluster.add_instance( "node3", main_configs=["configs/timezone_config.xml"], user_configs=["configs/users_disable_rows_settings.xml"], with_mysql=False, stay_alive=True, ) @pytest.fixture(scope="module") def started_cluster(): try: cluster.start() yield cluster finally: node_db.stop_clickhouse() # ensures that coverage report is written to disk, even if cluster.shutdown() times out. cluster.shutdown() class MySQLConnection: def __init__( self, port, user="root", password="clickhouse", ip_address=None, ): self.user = user self.port = port self.ip_address = ip_address self.password = password self.mysql_connection = None # lazy init def alloc_connection(self): errors = [] for _ in range(5): try: if self.mysql_connection is None: self.mysql_connection = pymysql.connect( user=self.user, password=self.password, host=self.ip_address, port=self.port, autocommit=True, ) else: self.mysql_connection.ping(reconnect=True) logging.debug( "MySQL Connection established: {}:{}".format( self.ip_address, self.port ) ) return self.mysql_connection except Exception as e: errors += [str(e)] time.sleep(1) raise Exception("Connection not established, {}".format(errors)) def query(self, execution_query): with self.alloc_connection().cursor() as cursor: cursor.execute(execution_query) def create_min_priv_user(self, user, password): self.query("CREATE USER '" + user + "'@'%' IDENTIFIED BY '" + password + "'") self.grant_min_priv_for_user(user) def grant_min_priv_for_user(self, user, db="priv_err_db"): self.query( "GRANT REPLICATION SLAVE, REPLICATION CLIENT, RELOAD ON *.* TO '" + user + "'@'%'" ) self.query("GRANT SELECT ON " + db + ".* TO '" + user + "'@'%'") def result(self, execution_query): with self.alloc_connection().cursor() as cursor: result = cursor.execute(execution_query) if result is not None: print(cursor.fetchall()) def query_and_get_data(self, execution_query): with self.alloc_connection().cursor() as cursor: cursor.execute(execution_query) return cursor.fetchall() def close(self): if self.mysql_connection is not None: self.mysql_connection.close() @pytest.fixture(scope="module") def started_mysql_5_7(): mysql_node = MySQLConnection( cluster.mysql_port, "root", "clickhouse", cluster.mysql_ip ) yield mysql_node @pytest.fixture(scope="module") def started_mysql_8_0(): mysql8_node = MySQLConnection( cluster.mysql8_port, "root", "clickhouse", cluster.mysql8_ip ) yield mysql8_node @pytest.fixture(scope="module") def clickhouse_node(): yield node_db def test_materialized_database_dml_with_mysql_5_7( started_cluster, started_mysql_5_7, clickhouse_node: ClickHouseInstance ): materialized_with_ddl.dml_with_materialized_mysql_database( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.materialized_mysql_database_with_views( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.materialized_mysql_database_with_datetime_and_decimal( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.move_to_prewhere_and_column_filtering( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_materialized_database_dml_with_mysql_8_0( started_cluster, started_mysql_8_0, clickhouse_node ): materialized_with_ddl.dml_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.materialized_mysql_database_with_views( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.materialized_mysql_database_with_datetime_and_decimal( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.move_to_prewhere_and_column_filtering( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_materialized_database_ddl_with_mysql_5_7( started_cluster, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.drop_table_with_materialized_mysql_database( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.create_table_with_materialized_mysql_database( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.rename_table_with_materialized_mysql_database( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.alter_add_column_with_materialized_mysql_database( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.alter_drop_column_with_materialized_mysql_database( clickhouse_node, started_mysql_5_7, "mysql57" ) # mysql 5.7 cannot support alter rename column # materialized_with_ddl.alter_rename_column_with_materialized_mysql_database(clickhouse_node, started_mysql_5_7, "mysql57") materialized_with_ddl.alter_rename_table_with_materialized_mysql_database( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.alter_modify_column_with_materialized_mysql_database( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.create_table_like_with_materialized_mysql_database( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_materialized_database_ddl_with_mysql_8_0( started_cluster, started_mysql_8_0, clickhouse_node ): materialized_with_ddl.drop_table_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.create_table_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.rename_table_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.alter_add_column_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.alter_drop_column_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.alter_rename_table_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.alter_rename_column_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.alter_modify_column_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.create_table_like_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_materialized_database_ddl_with_empty_transaction_5_7( started_cluster, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.query_event_with_empty_transaction( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_materialized_database_ddl_with_empty_transaction_8_0( started_cluster, started_mysql_8_0, clickhouse_node ): materialized_with_ddl.query_event_with_empty_transaction( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_text_blob_charset(started_cluster, started_mysql_8_0, clickhouse_node): materialized_with_ddl.text_blob_with_charset_test( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_select_without_columns_5_7( started_cluster, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.select_without_columns( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_select_without_columns_8_0( started_cluster, started_mysql_8_0, clickhouse_node ): materialized_with_ddl.select_without_columns( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_insert_with_modify_binlog_checksum_5_7( started_cluster, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.insert_with_modify_binlog_checksum( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_insert_with_modify_binlog_checksum_8_0( started_cluster, started_mysql_8_0, clickhouse_node ): materialized_with_ddl.insert_with_modify_binlog_checksum( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_materialized_database_err_sync_user_privs_5_7( started_cluster, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.err_sync_user_privs_with_materialized_mysql_database( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_materialized_database_err_sync_user_privs_8_0( started_cluster, started_mysql_8_0, clickhouse_node ): materialized_with_ddl.err_sync_user_privs_with_materialized_mysql_database( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_network_partition_5_7(started_cluster, started_mysql_5_7, clickhouse_node): materialized_with_ddl.network_partition_test( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_network_partition_8_0(started_cluster, started_mysql_8_0, clickhouse_node): materialized_with_ddl.network_partition_test( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_mysql_kill_sync_thread_restore_5_7( started_cluster, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.mysql_kill_sync_thread_restore_test( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_mysql_kill_sync_thread_restore_8_0( started_cluster, started_mysql_8_0, clickhouse_node ): materialized_with_ddl.mysql_kill_sync_thread_restore_test( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_mysql_killed_while_insert_5_7( started_cluster, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.mysql_killed_while_insert( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_mysql_killed_while_insert_8_0( started_cluster, started_mysql_8_0, clickhouse_node ): materialized_with_ddl.mysql_killed_while_insert( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_clickhouse_killed_while_insert_5_7( started_cluster, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.clickhouse_killed_while_insert( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_clickhouse_killed_while_insert_8_0( started_cluster, started_mysql_8_0, clickhouse_node ): materialized_with_ddl.clickhouse_killed_while_insert( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_utf8mb4( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.utf8mb4_test(clickhouse_node, started_mysql_5_7, "mysql57") materialized_with_ddl.utf8mb4_test(clickhouse_node, started_mysql_8_0, "mysql80") materialized_with_ddl.utf8mb4_column_test( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.utf8mb4_name_test( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_system_parts_table(started_cluster, started_mysql_8_0, clickhouse_node): materialized_with_ddl.system_parts_test( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_multi_table_update( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.multi_table_update_test( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.multi_table_update_test( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_system_tables_table( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.system_tables_test( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.system_tables_test( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_materialized_with_column_comments( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.materialized_with_column_comments_test( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.materialized_with_column_comments_test( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_double_quoted_comment(started_cluster, started_mysql_8_0, clickhouse_node): materialized_with_ddl.double_quoted_comment( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_default_values(started_cluster, started_mysql_8_0, clickhouse_node): materialized_with_ddl.default_values(clickhouse_node, started_mysql_8_0, "mysql80") def test_materialized_with_enum( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.materialized_with_enum8_test( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.materialized_with_enum16_test( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.alter_enum8_to_enum16_test( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.materialized_with_enum8_test( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.materialized_with_enum16_test( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.alter_enum8_to_enum16_test( clickhouse_node, started_mysql_8_0, "mysql80" ) @pytest.mark.parametrize( ("clickhouse_node"), [node_disable_bytes_settings, node_disable_rows_settings] ) def test_mysql_settings( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.mysql_settings_test( clickhouse_node, started_mysql_5_7, "mysql57" ) materialized_with_ddl.mysql_settings_test( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_large_transaction( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.materialized_mysql_large_transaction( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.materialized_mysql_large_transaction( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_table_table( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.table_table(clickhouse_node, started_mysql_8_0, "mysql80") materialized_with_ddl.table_table(clickhouse_node, started_mysql_5_7, "mysql57") def test_table_overrides( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.table_overrides(clickhouse_node, started_mysql_5_7, "mysql57") materialized_with_ddl.table_overrides(clickhouse_node, started_mysql_8_0, "mysql80") def test_materialized_database_support_all_kinds_of_mysql_datatype( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.materialized_database_support_all_kinds_of_mysql_datatype( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.materialized_database_support_all_kinds_of_mysql_datatype( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_materialized_database_settings_materialized_mysql_tables_list( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.materialized_database_settings_materialized_mysql_tables_list( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.materialized_database_settings_materialized_mysql_tables_list( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_materialized_database_mysql_date_type_to_date32( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.materialized_database_mysql_date_type_to_date32( clickhouse_node, started_mysql_8_0, "mysql80" ) materialized_with_ddl.materialized_database_mysql_date_type_to_date32( clickhouse_node, started_mysql_5_7, "mysql57" ) def test_savepoint_query( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.savepoint(clickhouse_node, started_mysql_8_0, "mysql80") materialized_with_ddl.savepoint(clickhouse_node, started_mysql_5_7, "mysql57") def test_materialized_database_mysql_drop_ddl( started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node ): materialized_with_ddl.dropddl(clickhouse_node, started_mysql_8_0, "mysql80") materialized_with_ddl.dropddl(clickhouse_node, started_mysql_5_7, "mysql57") def test_named_collections(started_cluster, started_mysql_8_0, clickhouse_node): materialized_with_ddl.named_collections( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_create_table_as_select(started_cluster, started_mysql_8_0, clickhouse_node): materialized_with_ddl.create_table_as_select( clickhouse_node, started_mysql_8_0, "mysql80" ) def test_table_with_indexes(started_cluster, started_mysql_8_0, clickhouse_node): materialized_with_ddl.table_with_indexes( clickhouse_node, started_mysql_8_0, "mysql80" )