2022-09-19 00:02:09 +00:00
import pytest
2022-10-26 22:02:17 +00:00
import random , string
2022-09-19 00:02:09 +00:00
from helpers . cluster import ClickHouseCluster
2022-11-14 17:42:46 +00:00
from helpers . test_tools import TSV
2022-09-19 00:02:09 +00:00
cluster = ClickHouseCluster ( __file__ )
2023-01-25 13:24:53 +00:00
node = cluster . add_instance (
" node " ,
main_configs = [
2023-07-08 19:06:00 +00:00
" configs/overrides.xml " ,
2023-01-25 13:24:53 +00:00
] ,
2023-06-15 10:33:24 +00:00
user_configs = [ " configs/users.xml " ] ,
2023-01-25 13:24:53 +00:00
with_zookeeper = True ,
2024-06-14 11:26:23 +00:00
with_azurite = True ,
2023-01-25 13:24:53 +00:00
)
2022-09-19 00:02:09 +00:00
@pytest.fixture ( scope = " module " , autouse = True )
def started_cluster ( ) :
try :
cluster . start ( )
yield cluster
finally :
cluster . shutdown ( )
2022-10-16 21:41:59 +00:00
def check_logs ( must_contain = [ ] , must_not_contain = [ ] ) :
2022-09-19 14:19:21 +00:00
node . query ( " SYSTEM FLUSH LOGS " )
for str in must_contain :
2023-01-25 00:26:44 +00:00
escaped_str = (
str . replace ( " ` " , " \\ ` " )
. replace ( " [ " , " \\ [ " )
. replace ( " ] " , " \\ ] " )
. replace ( " * " , " \\ * " )
)
2022-11-01 10:10:58 +00:00
assert node . contains_in_log ( escaped_str )
2022-10-16 21:41:59 +00:00
for str in must_not_contain :
2023-01-25 00:26:44 +00:00
escaped_str = (
str . replace ( " ` " , " \\ ` " )
. replace ( " [ " , " \\ [ " )
. replace ( " ] " , " \\ ] " )
. replace ( " * " , " \\ * " )
)
2022-11-01 10:10:58 +00:00
assert not node . contains_in_log ( escaped_str )
2022-10-16 21:41:59 +00:00
for str in must_contain :
escaped_str = str . replace ( " ' " , " \\ ' " )
2022-10-27 13:52:13 +00:00
assert system_query_log_contains_search_pattern ( escaped_str )
2022-09-19 14:19:21 +00:00
for str in must_not_contain :
2022-10-16 21:41:59 +00:00
escaped_str = str . replace ( " ' " , " \\ ' " )
2022-10-27 13:52:13 +00:00
assert not system_query_log_contains_search_pattern ( escaped_str )
# Returns true if "system.query_log" has a query matching a specified pattern.
def system_query_log_contains_search_pattern ( search_pattern ) :
return (
int (
node . query (
f " SELECT COUNT() FROM system.query_log WHERE query LIKE ' % { search_pattern } % ' "
) . strip ( )
2022-09-19 14:19:21 +00:00
)
2022-10-27 13:52:13 +00:00
> = 1
)
2022-10-26 22:02:17 +00:00
def new_password ( len = 16 ) :
return " " . join (
random . choice ( string . ascii_uppercase + string . digits ) for _ in range ( len )
)
2023-04-28 13:39:38 +00:00
show_secrets = " SETTINGS format_display_secrets_in_show_and_select "
2023-02-28 11:09:24 +00:00
2022-09-19 00:02:09 +00:00
def test_create_alter_user ( ) :
2022-10-26 22:02:17 +00:00
password = new_password ( )
node . query ( f " CREATE USER u1 IDENTIFIED BY ' { password } ' SETTINGS custom_a = ' a ' " )
node . query (
f " ALTER USER u1 IDENTIFIED BY ' { password } { password } ' SETTINGS custom_b = ' b ' "
)
2022-09-19 00:02:09 +00:00
node . query (
2022-10-26 22:02:17 +00:00
f " CREATE USER u2 IDENTIFIED WITH plaintext_password BY ' { password } ' SETTINGS custom_c = ' c ' "
2022-09-19 00:02:09 +00:00
)
2023-02-28 11:09:24 +00:00
assert (
node . query ( " SHOW CREATE USER u1 " )
== " CREATE USER u1 IDENTIFIED WITH sha256_password SETTINGS custom_b = \\ ' b \\ ' \n "
)
assert (
node . query ( " SHOW CREATE USER u2 " )
== " CREATE USER u2 IDENTIFIED WITH plaintext_password SETTINGS custom_c = \\ ' c \\ ' \n "
)
2023-02-17 10:36:58 +00:00
2023-02-28 11:09:24 +00:00
check_logs (
must_contain = [
2023-04-10 22:04:10 +00:00
" CREATE USER u1 IDENTIFIED " ,
" ALTER USER u1 IDENTIFIED " ,
2023-02-28 11:09:24 +00:00
" CREATE USER u2 IDENTIFIED WITH plaintext_password " ,
] ,
must_not_contain = [
password ,
2023-04-10 22:04:10 +00:00
" IDENTIFIED BY " ,
" IDENTIFIED BY " ,
2023-02-28 11:09:24 +00:00
" IDENTIFIED WITH plaintext_password BY " ,
] ,
)
2023-02-17 10:36:58 +00:00
2023-02-28 11:09:24 +00:00
assert " BY " in node . query ( f " SHOW CREATE USER u1 { show_secrets } =1 " )
assert " BY " in node . query ( f " SHOW CREATE USER u2 { show_secrets } =1 " )
2023-02-17 10:36:58 +00:00
2023-02-28 11:09:24 +00:00
node . query ( " DROP USER u1, u2 " )
2023-02-17 10:36:58 +00:00
2022-10-16 21:41:59 +00:00
2023-09-28 10:08:57 +00:00
def check_secrets_for_tables ( test_cases , password ) :
for table_name , query , error in test_cases :
if ( not error ) and ( password in query ) :
2023-02-28 11:09:24 +00:00
assert password in node . query (
f " SHOW CREATE TABLE { table_name } { show_secrets } =1 "
)
assert password in node . query (
f " SELECT create_table_query, engine_full FROM system.tables WHERE name = ' { table_name } ' "
f " { show_secrets } =1 "
)
2022-10-24 17:27:35 +00:00
2022-10-16 21:41:59 +00:00
2024-01-08 11:20:32 +00:00
def test_backup_table ( ) :
password = new_password ( )
setup_queries = [
" CREATE TABLE backup_test (x int) ENGINE = MergeTree ORDER BY x " ,
2024-01-08 11:47:58 +00:00
" INSERT INTO backup_test SELECT * FROM numbers(10) " ,
2024-01-08 11:20:32 +00:00
]
endpoints_with_credentials = [
(
f " S3( ' http://minio1:9001/root/data/backup_test_base ' , ' minio ' , ' { password } ' ) " ,
f " S3( ' http://minio1:9001/root/data/backup_test_incremental ' , ' minio ' , ' { password } ' ) " ,
)
]
for query in setup_queries :
node . query_and_get_answer_with_error ( query )
# Actually need to make two backups to have base_backup
def make_test_case ( endpoint_specs ) :
# Run ASYNC so it returns the backup id
return (
f " BACKUP TABLE backup_test TO { endpoint_specs [ 0 ] } ASYNC " ,
2024-01-08 11:47:58 +00:00
f " BACKUP TABLE backup_test TO { endpoint_specs [ 1 ] } SETTINGS async=1, base_backup= { endpoint_specs [ 0 ] } " ,
2024-01-08 11:20:32 +00:00
)
2024-01-08 11:47:58 +00:00
test_cases = [
make_test_case ( endpoint_spec ) for endpoint_spec in endpoints_with_credentials
]
2024-01-08 11:20:32 +00:00
for base_query , inc_query in test_cases :
node . query_and_get_answer_with_error ( base_query ) [ 0 ]
inc_backup_query_output = node . query_and_get_answer_with_error ( inc_query ) [ 0 ]
inc_backup_id = TSV . toMat ( inc_backup_query_output ) [ 0 ] [ 0 ]
names_in_system_backups_output , _ = node . query_and_get_answer_with_error (
f " SELECT base_backup_name, name FROM system.backups where id = ' { inc_backup_id } ' "
)
base_backup_name , name = TSV . toMat ( names_in_system_backups_output ) [ 0 ]
assert password not in base_backup_name
assert password not in name
2024-01-08 11:47:58 +00:00
2022-10-16 21:41:59 +00:00
def test_create_table ( ) :
2022-10-26 22:02:17 +00:00
password = new_password ( )
2022-10-16 21:41:59 +00:00
table_engines = [
2024-02-13 12:15:46 +00:00
f " MySQL( ' mysql80:3306 ' , ' mysql_db ' , ' mysql_table ' , ' mysql_user ' , ' { password } ' ) " ,
2022-10-26 22:02:17 +00:00
f " PostgreSQL( ' postgres1:5432 ' , ' postgres_db ' , ' postgres_table ' , ' postgres_user ' , ' { password } ' ) " ,
f " MongoDB( ' mongo1:27017 ' , ' mongo_db ' , ' mongo_col ' , ' mongo_user ' , ' { password } ' ) " ,
f " S3( ' http://minio1:9001/root/data/test1.csv ' ) " ,
f " S3( ' http://minio1:9001/root/data/test2.csv ' , ' CSV ' ) " ,
f " S3( ' http://minio1:9001/root/data/test3.csv.gz ' , ' CSV ' , ' gzip ' ) " ,
f " S3( ' http://minio1:9001/root/data/test4.csv ' , ' minio ' , ' { password } ' , ' CSV ' ) " ,
f " S3( ' http://minio1:9001/root/data/test5.csv.gz ' , ' minio ' , ' { password } ' , ' CSV ' , ' gzip ' ) " ,
2024-02-13 12:15:46 +00:00
f " MySQL(named_collection_1, host = ' mysql80 ' , port = 3306, database = ' mysql_db ' , table = ' mysql_table ' , user = ' mysql_user ' , password = ' { password } ' ) " ,
f " MySQL(named_collection_2, database = ' mysql_db ' , host = ' mysql80 ' , port = 3306, password = ' { password } ' , table = ' mysql_table ' , user = ' mysql_user ' ) " ,
f " MySQL(named_collection_3, database = ' mysql_db ' , host = ' mysql80 ' , port = 3306, table = ' mysql_table ' ) " ,
2023-01-25 13:24:53 +00:00
f " PostgreSQL(named_collection_4, host = ' postgres1 ' , port = 5432, database = ' postgres_db ' , table = ' postgres_table ' , user = ' postgres_user ' , password = ' { password } ' ) " ,
2023-03-02 18:04:33 +00:00
f " MongoDB(named_collection_5, host = ' mongo1 ' , port = 5432, db = ' mongo_db ' , collection = ' mongo_col ' , user = ' mongo_user ' , password = ' { password } ' ) " ,
2023-01-25 13:24:53 +00:00
f " S3(named_collection_6, url = ' http://minio1:9001/root/data/test8.csv ' , access_key_id = ' minio ' , secret_access_key = ' { password } ' , format = ' CSV ' ) " ,
2023-09-28 10:08:57 +00:00
f " S3( ' http://minio1:9001/root/data/test9.csv.gz ' , ' NOSIGN ' , ' CSV ' , ' gzip ' ) " ,
f " S3( ' http://minio1:9001/root/data/test10.csv.gz ' , ' minio ' , ' { password } ' ) " ,
(
f " DeltaLake( ' http://minio1:9001/root/data/test11.csv.gz ' , ' minio ' , ' { password } ' ) " ,
" DNS_ERROR " ,
) ,
2024-06-05 16:36:13 +00:00
f " S3Queue( ' http://minio1:9001/root/data/ ' , ' CSV ' ) settings mode = ' ordered ' " ,
f " S3Queue( ' http://minio1:9001/root/data/ ' , ' CSV ' , ' gzip ' ) settings mode = ' ordered ' " ,
f " S3Queue( ' http://minio1:9001/root/data/ ' , ' minio ' , ' { password } ' , ' CSV ' ) settings mode = ' ordered ' " ,
f " S3Queue( ' http://minio1:9001/root/data/ ' , ' minio ' , ' { password } ' , ' CSV ' , ' gzip ' ) settings mode = ' ordered ' " ,
2022-10-16 21:41:59 +00:00
]
2023-09-28 10:08:57 +00:00
def make_test_case ( i ) :
table_name = f " table { i } "
table_engine = table_engines [ i ]
error = None
if isinstance ( table_engine , tuple ) :
table_engine , error = table_engine
query = f " CREATE TABLE { table_name } (x int) ENGINE = { table_engine } "
return table_name , query , error
# Generate test cases as a list of tuples (table_name, query, error).
test_cases = [ make_test_case ( i ) for i in range ( len ( table_engines ) ) ]
for table_name , query , error in test_cases :
if error :
assert error in node . query_and_get_error ( query )
else :
node . query ( query )
2022-10-16 21:41:59 +00:00
2023-02-28 11:09:24 +00:00
for toggle , secret in enumerate ( [ " [HIDDEN] " , password ] ) :
2023-02-17 10:36:58 +00:00
assert (
2023-02-28 11:09:24 +00:00
node . query ( f " SHOW CREATE TABLE table0 { show_secrets } = { toggle } " )
== " CREATE TABLE default.table0 \\ n( \\ n `x` Int32 \\ n) \\ n "
2024-02-13 12:15:46 +00:00
" ENGINE = MySQL( \\ ' mysql80:3306 \\ ' , \\ ' mysql_db \\ ' , "
2023-02-28 11:09:24 +00:00
f " \\ ' mysql_table \\ ' , \\ ' mysql_user \\ ' , \\ ' { secret } \\ ' ) \n "
2023-02-17 10:36:58 +00:00
)
2022-11-14 17:42:46 +00:00
2023-02-17 10:36:58 +00:00
assert node . query (
2023-02-28 11:09:24 +00:00
f " SELECT create_table_query, engine_full FROM system.tables WHERE name = ' table0 ' { show_secrets } = { toggle } "
2023-02-17 10:36:58 +00:00
) == TSV (
2022-11-14 17:42:46 +00:00
[
2023-02-17 10:36:58 +00:00
[
2024-02-13 12:15:46 +00:00
" CREATE TABLE default.table0 (`x` Int32) ENGINE = MySQL( \\ ' mysql80:3306 \\ ' , \\ ' mysql_db \\ ' , "
2023-02-28 11:09:24 +00:00
f " \\ ' mysql_table \\ ' , \\ ' mysql_user \\ ' , \\ ' { secret } \\ ' ) " ,
2024-02-13 12:15:46 +00:00
f " MySQL( \\ ' mysql80:3306 \\ ' , \\ ' mysql_db \\ ' , \\ ' mysql_table \\ ' , \\ ' mysql_user \\ ' , \\ ' { secret } \\ ' ) " ,
2023-02-17 10:36:58 +00:00
] ,
]
)
2023-02-28 11:09:24 +00:00
check_logs (
must_contain = [
2024-02-13 12:15:46 +00:00
" CREATE TABLE table0 (`x` int) ENGINE = MySQL( ' mysql80:3306 ' , ' mysql_db ' , ' mysql_table ' , ' mysql_user ' , ' [HIDDEN] ' ) " ,
2023-02-28 11:09:24 +00:00
" CREATE TABLE table1 (`x` int) ENGINE = PostgreSQL( ' postgres1:5432 ' , ' postgres_db ' , ' postgres_table ' , ' postgres_user ' , ' [HIDDEN] ' ) " ,
" CREATE TABLE table2 (`x` int) ENGINE = MongoDB( ' mongo1:27017 ' , ' mongo_db ' , ' mongo_col ' , ' mongo_user ' , ' [HIDDEN] ' ) " ,
" CREATE TABLE table3 (x int) ENGINE = S3( ' http://minio1:9001/root/data/test1.csv ' ) " ,
" CREATE TABLE table4 (x int) ENGINE = S3( ' http://minio1:9001/root/data/test2.csv ' , ' CSV ' ) " ,
" CREATE TABLE table5 (x int) ENGINE = S3( ' http://minio1:9001/root/data/test3.csv.gz ' , ' CSV ' , ' gzip ' ) " ,
" CREATE TABLE table6 (`x` int) ENGINE = S3( ' http://minio1:9001/root/data/test4.csv ' , ' minio ' , ' [HIDDEN] ' , ' CSV ' ) " ,
" CREATE TABLE table7 (`x` int) ENGINE = S3( ' http://minio1:9001/root/data/test5.csv.gz ' , ' minio ' , ' [HIDDEN] ' , ' CSV ' , ' gzip ' ) " ,
2024-02-21 19:37:48 +00:00
" CREATE TABLE table8 (`x` int) ENGINE = MySQL(named_collection_1, host = ' mysql80 ' , port = 3306, database = ' mysql_db ' , `table` = ' mysql_table ' , user = ' mysql_user ' , password = ' [HIDDEN] ' ) " ,
" CREATE TABLE table9 (`x` int) ENGINE = MySQL(named_collection_2, database = ' mysql_db ' , host = ' mysql80 ' , port = 3306, password = ' [HIDDEN] ' , `table` = ' mysql_table ' , user = ' mysql_user ' ) " ,
2024-02-22 09:06:38 +00:00
" CREATE TABLE table10 (x int) ENGINE = MySQL(named_collection_3, database = ' mysql_db ' , host = ' mysql80 ' , port = 3306, table = ' mysql_table ' ) " ,
2024-02-21 18:23:52 +00:00
" CREATE TABLE table11 (`x` int) ENGINE = PostgreSQL(named_collection_4, host = ' postgres1 ' , port = 5432, database = ' postgres_db ' , `table` = ' postgres_table ' , user = ' postgres_user ' , password = ' [HIDDEN] ' ) " ,
2023-03-02 18:04:33 +00:00
" CREATE TABLE table12 (`x` int) ENGINE = MongoDB(named_collection_5, host = ' mongo1 ' , port = 5432, db = ' mongo_db ' , collection = ' mongo_col ' , user = ' mongo_user ' , password = ' [HIDDEN] ' " ,
2023-02-28 11:09:24 +00:00
" CREATE TABLE table13 (`x` int) ENGINE = S3(named_collection_6, url = ' http://minio1:9001/root/data/test8.csv ' , access_key_id = ' minio ' , secret_access_key = ' [HIDDEN] ' , format = ' CSV ' ) " ,
2023-09-28 10:08:57 +00:00
" CREATE TABLE table14 (x int) ENGINE = S3( ' http://minio1:9001/root/data/test9.csv.gz ' , ' NOSIGN ' , ' CSV ' , ' gzip ' ) " ,
" CREATE TABLE table15 (`x` int) ENGINE = S3( ' http://minio1:9001/root/data/test10.csv.gz ' , ' minio ' , ' [HIDDEN] ' ) " ,
" CREATE TABLE table16 (`x` int) ENGINE = DeltaLake( ' http://minio1:9001/root/data/test11.csv.gz ' , ' minio ' , ' [HIDDEN] ' ) " ,
2024-06-05 16:36:13 +00:00
" CREATE TABLE table17 (x int) ENGINE = S3Queue( ' http://minio1:9001/root/data/ ' , ' CSV ' ) settings mode = ' ordered ' " ,
" CREATE TABLE table18 (x int) ENGINE = S3Queue( ' http://minio1:9001/root/data/ ' , ' CSV ' , ' gzip ' ) settings mode = ' ordered ' " ,
2024-06-06 09:45:41 +00:00
# due to sensitive data substituion the query will be normalized, so not "settings" but "SETTINGS"
" CREATE TABLE table19 (`x` int) ENGINE = S3Queue( ' http://minio1:9001/root/data/ ' , ' minio ' , ' [HIDDEN] ' , ' CSV ' ) SETTINGS mode = ' ordered ' " ,
" CREATE TABLE table20 (`x` int) ENGINE = S3Queue( ' http://minio1:9001/root/data/ ' , ' minio ' , ' [HIDDEN] ' , ' CSV ' , ' gzip ' ) SETTINGS mode = ' ordered ' " ,
2023-02-28 11:09:24 +00:00
] ,
must_not_contain = [ password ] ,
)
2023-02-17 10:36:58 +00:00
2023-09-28 10:08:57 +00:00
check_secrets_for_tables ( test_cases , password )
2022-10-16 21:41:59 +00:00
2023-09-28 10:08:57 +00:00
for table_name , query , error in test_cases :
if not error :
node . query ( f " DROP TABLE { table_name } " )
2022-10-16 21:41:59 +00:00
def test_create_database ( ) :
2022-10-26 22:02:17 +00:00
password = new_password ( )
2022-10-16 21:41:59 +00:00
database_engines = [
2023-09-28 10:08:57 +00:00
(
f " MySQL( ' localhost:3306 ' , ' mysql_db ' , ' mysql_user ' , ' { password } ' ) SETTINGS connect_timeout=1, connection_max_tries=1 " ,
" ALL_CONNECTION_TRIES_FAILED " ,
) ,
(
f " MySQL(named_collection_1, host = ' localhost ' , port = 3306, database = ' mysql_db ' , user = ' mysql_user ' , password = ' { password } ' ) SETTINGS connect_timeout=1, connection_max_tries=1 " ,
" ALL_CONNECTION_TRIES_FAILED " ,
) ,
f " S3( ' http://minio1:9001/root/data ' , ' minio ' , ' { password } ' ) " ,
f " S3(named_collection_2, secret_access_key = ' { password } ' , access_key_id = ' minio ' ) " ,
2022-10-31 15:47:07 +00:00
# f"PostgreSQL('localhost:5432', 'postgres_db', 'postgres_user', '{password}')",
2022-10-16 21:41:59 +00:00
]
2023-09-28 10:08:57 +00:00
def make_test_case ( i ) :
database_name = f " database { i } "
database_engine = database_engines [ i ]
error = None
if isinstance ( database_engine , tuple ) :
database_engine , error = database_engine
query = f " CREATE DATABASE { database_name } ENGINE = { database_engine } "
return database_name , query , error
# Generate test cases as a list of tuples (database_name, query, error).
test_cases = [ make_test_case ( i ) for i in range ( len ( database_engines ) ) ]
for database_name , query , error in test_cases :
if error :
assert error in node . query_and_get_error ( query )
else :
node . query ( query )
2022-10-16 21:41:59 +00:00
2023-02-28 11:09:24 +00:00
check_logs (
must_contain = [
" CREATE DATABASE database0 ENGINE = MySQL( ' localhost:3306 ' , ' mysql_db ' , ' mysql_user ' , ' [HIDDEN] ' ) " ,
" CREATE DATABASE database1 ENGINE = MySQL(named_collection_1, host = ' localhost ' , port = 3306, database = ' mysql_db ' , user = ' mysql_user ' , password = ' [HIDDEN] ' ) " ,
2023-09-28 10:08:57 +00:00
" CREATE DATABASE database2 ENGINE = S3( ' http://minio1:9001/root/data ' , ' minio ' , ' [HIDDEN] ' ) " ,
" CREATE DATABASE database3 ENGINE = S3(named_collection_2, secret_access_key = ' [HIDDEN] ' , access_key_id = ' minio ' ) " ,
# "CREATE DATABASE database4 ENGINE = PostgreSQL('localhost:5432', 'postgres_db', 'postgres_user', '[HIDDEN]')",
2023-02-28 11:09:24 +00:00
] ,
must_not_contain = [ password ] ,
)
2022-10-16 21:41:59 +00:00
2023-09-28 10:08:57 +00:00
for database_name , query , error in test_cases :
if not error :
node . query ( f " DROP DATABASE { database_name } " )
2022-10-16 21:41:59 +00:00
def test_table_functions ( ) :
2022-10-26 22:02:17 +00:00
password = new_password ( )
2024-06-14 11:38:18 +00:00
azure_conn_string = cluster . env_variables [ " AZURITE_CONNECTION_STRING " ]
azure_storage_account_url = cluster . env_variables [ " AZURITE_STORAGE_ACCOUNT_URL " ]
2024-06-14 11:26:23 +00:00
azure_account_name = " devstoreaccount1 "
azure_account_key = " Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw== "
2022-10-26 22:02:17 +00:00
2022-10-16 21:41:59 +00:00
table_functions = [
2024-02-13 12:15:46 +00:00
f " mysql( ' mysql80:3306 ' , ' mysql_db ' , ' mysql_table ' , ' mysql_user ' , ' { password } ' ) " ,
2022-10-26 22:02:17 +00:00
f " postgresql( ' postgres1:5432 ' , ' postgres_db ' , ' postgres_table ' , ' postgres_user ' , ' { password } ' ) " ,
f " mongodb( ' mongo1:27017 ' , ' mongo_db ' , ' mongo_col ' , ' mongo_user ' , ' { password } ' , ' x int ' ) " ,
f " s3( ' http://minio1:9001/root/data/test1.csv ' ) " ,
f " s3( ' http://minio1:9001/root/data/test2.csv ' , ' CSV ' ) " ,
f " s3( ' http://minio1:9001/root/data/test3.csv ' , ' minio ' , ' { password } ' ) " ,
f " s3( ' http://minio1:9001/root/data/test4.csv ' , ' CSV ' , ' x int ' ) " ,
f " s3( ' http://minio1:9001/root/data/test5.csv.gz ' , ' CSV ' , ' x int ' , ' gzip ' ) " ,
f " s3( ' http://minio1:9001/root/data/test6.csv ' , ' minio ' , ' { password } ' , ' CSV ' ) " ,
f " s3( ' http://minio1:9001/root/data/test7.csv ' , ' minio ' , ' { password } ' , ' CSV ' , ' x int ' ) " ,
f " s3( ' http://minio1:9001/root/data/test8.csv.gz ' , ' minio ' , ' { password } ' , ' CSV ' , ' x int ' , ' gzip ' ) " ,
f " s3Cluster( ' test_shard_localhost ' , ' http://minio1:9001/root/data/test1.csv ' , ' minio ' , ' { password } ' ) " ,
f " s3Cluster( ' test_shard_localhost ' , ' http://minio1:9001/root/data/test2.csv ' , ' CSV ' , ' x int ' ) " ,
f " s3Cluster( ' test_shard_localhost ' , ' http://minio1:9001/root/data/test3.csv ' , ' minio ' , ' { password } ' , ' CSV ' ) " ,
f " remote( ' 127. {{ 2..11 }} ' , default.remote_table) " ,
f " remote( ' 127. {{ 2..11 }} ' , default.remote_table, rand()) " ,
f " remote( ' 127. {{ 2..11 }} ' , default.remote_table, ' remote_user ' ) " ,
f " remote( ' 127. {{ 2..11 }} ' , default.remote_table, ' remote_user ' , ' { password } ' ) " ,
f " remote( ' 127. {{ 2..11 }} ' , default.remote_table, ' remote_user ' , rand()) " ,
f " remote( ' 127. {{ 2..11 }} ' , default.remote_table, ' remote_user ' , ' { password } ' , rand()) " ,
f " remote( ' 127. {{ 2..11 }} ' , ' default.remote_table ' , ' remote_user ' , ' { password } ' , rand()) " ,
f " remote( ' 127. {{ 2..11 }} ' , ' default ' , ' remote_table ' , ' remote_user ' , ' { password } ' , rand()) " ,
f " remote( ' 127. {{ 2..11 }} ' , numbers(10), ' remote_user ' , ' { password } ' , rand()) " ,
f " remoteSecure( ' 127. {{ 2..11 }} ' , ' default ' , ' remote_table ' , ' remote_user ' , ' { password } ' ) " ,
f " remoteSecure( ' 127. {{ 2..11 }} ' , ' default ' , ' remote_table ' , ' remote_user ' , rand()) " ,
2024-02-13 12:15:46 +00:00
f " mysql(named_collection_1, host = ' mysql80 ' , port = 3306, database = ' mysql_db ' , table = ' mysql_table ' , user = ' mysql_user ' , password = ' { password } ' ) " ,
2023-01-25 13:24:53 +00:00
f " postgresql(named_collection_2, password = ' { password } ' , host = ' postgres1 ' , port = 5432, database = ' postgres_db ' , table = ' postgres_table ' , user = ' postgres_user ' ) " ,
2023-03-02 18:04:33 +00:00
f " s3(named_collection_2, url = ' http://minio1:9001/root/data/test4.csv ' , access_key_id = ' minio ' , secret_access_key = ' { password } ' ) " ,
2023-03-05 11:50:29 +00:00
f " remote(named_collection_6, addresses_expr = ' 127. {{ 2..11 }} ' , database = ' default ' , table = ' remote_table ' , user = ' remote_user ' , password = ' { password } ' , sharding_key = rand()) " ,
f " remoteSecure(named_collection_6, addresses_expr = ' 127. {{ 2..11 }} ' , database = ' default ' , table = ' remote_table ' , user = ' remote_user ' , password = ' { password } ' ) " ,
2023-09-28 10:08:57 +00:00
f " s3( ' http://minio1:9001/root/data/test9.csv.gz ' , ' NOSIGN ' , ' CSV ' ) " ,
f " s3( ' http://minio1:9001/root/data/test10.csv.gz ' , ' minio ' , ' { password } ' ) " ,
(
f " deltaLake( ' http://minio1:9001/root/data/test11.csv.gz ' , ' minio ' , ' { password } ' ) " ,
" DNS_ERROR " ,
) ,
2024-06-14 11:26:23 +00:00
f " azureBlobStorage( ' { azure_conn_string } ' , ' cont ' , ' test_simple.csv ' , ' CSV ' ) " ,
2024-06-20 12:51:49 +00:00
f " azureBlobStorage( ' { azure_conn_string } ' , ' cont ' , ' test_simple_1.csv ' , ' CSV ' , ' none ' ) " ,
f " azureBlobStorage( ' { azure_conn_string } ' , ' cont ' , ' test_simple_2.csv ' , ' CSV ' , ' none ' , ' auto ' ) " ,
f " azureBlobStorage( ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_3.csv ' , ' { azure_account_name } ' , ' { azure_account_key } ' ) " ,
f " azureBlobStorage( ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_4.csv ' , ' { azure_account_name } ' , ' { azure_account_key } ' , ' CSV ' ) " ,
f " azureBlobStorage( ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_5.csv ' , ' { azure_account_name } ' , ' { azure_account_key } ' , ' CSV ' , ' none ' ) " ,
f " azureBlobStorage( ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_6.csv ' , ' { azure_account_name } ' , ' { azure_account_key } ' , ' CSV ' , ' none ' , ' auto ' ) " ,
2024-06-26 12:07:38 +00:00
f " azureBlobStorage(named_collection_2, connection_string = ' { azure_conn_string } ' , container = ' cont ' , blob_path = ' test_simple_7.csv ' , format = ' CSV ' ) " ,
f " azureBlobStorage(named_collection_2, storage_account_url = ' { azure_storage_account_url } ' , container = ' cont ' , blob_path = ' test_simple_8.csv ' , account_name = ' { azure_account_name } ' , account_key = ' { azure_account_key } ' ) " ,
f " azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_conn_string } ' , ' cont ' , ' test_simple_9.csv ' , ' CSV ' ) " ,
f " azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_conn_string } ' , ' cont ' , ' test_simple_10.csv ' , ' CSV ' , ' none ' ) " ,
f " azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_conn_string } ' , ' cont ' , ' test_simple_11.csv ' , ' CSV ' , ' none ' , ' auto ' ) " ,
f " azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_12.csv ' , ' { azure_account_name } ' , ' { azure_account_key } ' ) " ,
f " azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_13.csv ' , ' { azure_account_name } ' , ' { azure_account_key } ' , ' CSV ' ) " ,
f " azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_14.csv ' , ' { azure_account_name } ' , ' { azure_account_key } ' , ' CSV ' , ' none ' ) " ,
f " azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_15.csv ' , ' { azure_account_name } ' , ' { azure_account_key } ' , ' CSV ' , ' none ' , ' auto ' ) " ,
f " azureBlobStorageCluster( ' test_shard_localhost ' , named_collection_2, connection_string = ' { azure_conn_string } ' , container = ' cont ' , blob_path = ' test_simple_16.csv ' , format = ' CSV ' ) " ,
f " azureBlobStorageCluster( ' test_shard_localhost ' , named_collection_2, storage_account_url = ' { azure_storage_account_url } ' , container = ' cont ' , blob_path = ' test_simple_17.csv ' , account_name = ' { azure_account_name } ' , account_key = ' { azure_account_key } ' ) " ,
2022-10-16 21:41:59 +00:00
]
2023-09-28 10:08:57 +00:00
def make_test_case ( i ) :
table_name = f " tablefunc { i } "
table_function = table_functions [ i ]
error = None
if isinstance ( table_function , tuple ) :
table_function , error = table_function
query = f " CREATE TABLE { table_name } (x int) AS { table_function } "
return table_name , query , error
# Generate test cases as a list of tuples (table_name, query, error).
test_cases = [ make_test_case ( i ) for i in range ( len ( table_functions ) ) ]
for table_name , query , error in test_cases :
node . query ( query )
2022-10-16 21:41:59 +00:00
2023-02-28 11:09:24 +00:00
for toggle , secret in enumerate ( [ " [HIDDEN] " , password ] ) :
assert (
node . query ( f " SHOW CREATE TABLE tablefunc0 { show_secrets } = { toggle } " )
== " CREATE TABLE default.tablefunc0 \\ n( \\ n `x` Int32 \\ n) AS "
2024-02-13 12:15:46 +00:00
" mysql( \\ ' mysql80:3306 \\ ' , \\ ' mysql_db \\ ' , \\ ' mysql_table \\ ' , "
2023-02-28 11:09:24 +00:00
f " \\ ' mysql_user \\ ' , \\ ' { secret } \\ ' ) \n "
)
2022-11-14 17:42:46 +00:00
2023-02-28 11:09:24 +00:00
assert node . query (
" SELECT create_table_query, engine_full FROM system.tables WHERE name = ' tablefunc0 ' "
f " { show_secrets } = { toggle } "
) == TSV (
2022-11-14 17:42:46 +00:00
[
2023-02-28 11:09:24 +00:00
[
2024-02-13 12:15:46 +00:00
" CREATE TABLE default.tablefunc0 (`x` Int32) AS mysql( \\ ' mysql80:3306 \\ ' , "
2023-02-28 11:09:24 +00:00
f " \\ ' mysql_db \\ ' , \\ ' mysql_table \\ ' , \\ ' mysql_user \\ ' , \\ ' { secret } \\ ' ) " ,
" " ,
] ,
]
)
2022-11-14 17:42:46 +00:00
2022-10-16 21:41:59 +00:00
check_logs (
must_contain = [
2024-02-13 12:15:46 +00:00
" CREATE TABLE tablefunc0 (`x` int) AS mysql( ' mysql80:3306 ' , ' mysql_db ' , ' mysql_table ' , ' mysql_user ' , ' [HIDDEN] ' ) " ,
2022-10-16 21:41:59 +00:00
" CREATE TABLE tablefunc1 (`x` int) AS postgresql( ' postgres1:5432 ' , ' postgres_db ' , ' postgres_table ' , ' postgres_user ' , ' [HIDDEN] ' ) " ,
" CREATE TABLE tablefunc2 (`x` int) AS mongodb( ' mongo1:27017 ' , ' mongo_db ' , ' mongo_col ' , ' mongo_user ' , ' [HIDDEN] ' , ' x int ' ) " ,
2022-10-31 15:47:07 +00:00
" CREATE TABLE tablefunc3 (x int) AS s3( ' http://minio1:9001/root/data/test1.csv ' ) " ,
" CREATE TABLE tablefunc4 (x int) AS s3( ' http://minio1:9001/root/data/test2.csv ' , ' CSV ' ) " ,
2022-10-16 21:41:59 +00:00
" CREATE TABLE tablefunc5 (`x` int) AS s3( ' http://minio1:9001/root/data/test3.csv ' , ' minio ' , ' [HIDDEN] ' ) " ,
2022-10-31 15:47:07 +00:00
" CREATE TABLE tablefunc6 (x int) AS s3( ' http://minio1:9001/root/data/test4.csv ' , ' CSV ' , ' x int ' ) " ,
" CREATE TABLE tablefunc7 (x int) AS s3( ' http://minio1:9001/root/data/test5.csv.gz ' , ' CSV ' , ' x int ' , ' gzip ' ) " ,
2022-10-16 21:41:59 +00:00
" CREATE TABLE tablefunc8 (`x` int) AS s3( ' http://minio1:9001/root/data/test6.csv ' , ' minio ' , ' [HIDDEN] ' , ' CSV ' ) " ,
" CREATE TABLE tablefunc9 (`x` int) AS s3( ' http://minio1:9001/root/data/test7.csv ' , ' minio ' , ' [HIDDEN] ' , ' CSV ' , ' x int ' ) " ,
" CREATE TABLE tablefunc10 (`x` int) AS s3( ' http://minio1:9001/root/data/test8.csv.gz ' , ' minio ' , ' [HIDDEN] ' , ' CSV ' , ' x int ' , ' gzip ' ) " ,
" CREATE TABLE tablefunc11 (`x` int) AS s3Cluster( ' test_shard_localhost ' , ' http://minio1:9001/root/data/test1.csv ' , ' minio ' , ' [HIDDEN] ' ) " ,
2022-10-31 15:47:07 +00:00
" CREATE TABLE tablefunc12 (x int) AS s3Cluster( ' test_shard_localhost ' , ' http://minio1:9001/root/data/test2.csv ' , ' CSV ' , ' x int ' ) " ,
2022-10-16 21:41:59 +00:00
" CREATE TABLE tablefunc13 (`x` int) AS s3Cluster( ' test_shard_localhost ' , ' http://minio1:9001/root/data/test3.csv ' , ' minio ' , ' [HIDDEN] ' , ' CSV ' ) " ,
2022-10-31 15:47:07 +00:00
" CREATE TABLE tablefunc14 (x int) AS remote( ' 127. { 2..11} ' , default.remote_table) " ,
" CREATE TABLE tablefunc15 (x int) AS remote( ' 127. { 2..11} ' , default.remote_table, rand()) " ,
" CREATE TABLE tablefunc16 (x int) AS remote( ' 127. { 2..11} ' , default.remote_table, ' remote_user ' ) " ,
2022-10-16 21:41:59 +00:00
" CREATE TABLE tablefunc17 (`x` int) AS remote( ' 127. { 2..11} ' , default.remote_table, ' remote_user ' , ' [HIDDEN] ' ) " ,
2022-10-31 15:47:07 +00:00
" CREATE TABLE tablefunc18 (x int) AS remote( ' 127. { 2..11} ' , default.remote_table, ' remote_user ' , rand()) " ,
2022-10-16 21:41:59 +00:00
" CREATE TABLE tablefunc19 (`x` int) AS remote( ' 127. { 2..11} ' , default.remote_table, ' remote_user ' , ' [HIDDEN] ' , rand()) " ,
" CREATE TABLE tablefunc20 (`x` int) AS remote( ' 127. { 2..11} ' , ' default.remote_table ' , ' remote_user ' , ' [HIDDEN] ' , rand()) " ,
" CREATE TABLE tablefunc21 (`x` int) AS remote( ' 127. { 2..11} ' , ' default ' , ' remote_table ' , ' remote_user ' , ' [HIDDEN] ' , rand()) " ,
" CREATE TABLE tablefunc22 (`x` int) AS remote( ' 127. { 2..11} ' , numbers(10), ' remote_user ' , ' [HIDDEN] ' , rand()) " ,
" CREATE TABLE tablefunc23 (`x` int) AS remoteSecure( ' 127. { 2..11} ' , ' default ' , ' remote_table ' , ' remote_user ' , ' [HIDDEN] ' ) " ,
2022-10-31 15:47:07 +00:00
" CREATE TABLE tablefunc24 (x int) AS remoteSecure( ' 127. { 2..11} ' , ' default ' , ' remote_table ' , ' remote_user ' , rand()) " ,
2024-02-21 19:38:22 +00:00
" CREATE TABLE tablefunc25 (`x` int) AS mysql(named_collection_1, host = ' mysql80 ' , port = 3306, database = ' mysql_db ' , `table` = ' mysql_table ' , user = ' mysql_user ' , password = ' [HIDDEN] ' ) " ,
2024-02-21 18:23:52 +00:00
" CREATE TABLE tablefunc26 (`x` int) AS postgresql(named_collection_2, password = ' [HIDDEN] ' , host = ' postgres1 ' , port = 5432, database = ' postgres_db ' , `table` = ' postgres_table ' , user = ' postgres_user ' ) " ,
2023-03-02 18:04:33 +00:00
" CREATE TABLE tablefunc27 (`x` int) AS s3(named_collection_2, url = ' http://minio1:9001/root/data/test4.csv ' , access_key_id = ' minio ' , secret_access_key = ' [HIDDEN] ' ) " ,
2024-02-21 18:23:52 +00:00
" CREATE TABLE tablefunc28 (`x` int) AS remote(named_collection_6, addresses_expr = ' 127. { 2..11} ' , database = ' default ' , `table` = ' remote_table ' , user = ' remote_user ' , password = ' [HIDDEN] ' , sharding_key = rand()) " ,
" CREATE TABLE tablefunc29 (`x` int) AS remoteSecure(named_collection_6, addresses_expr = ' 127. { 2..11} ' , database = ' default ' , `table` = ' remote_table ' , user = ' remote_user ' , password = ' [HIDDEN] ' ) " ,
2023-09-28 10:08:57 +00:00
" CREATE TABLE tablefunc30 (x int) AS s3( ' http://minio1:9001/root/data/test9.csv.gz ' , ' NOSIGN ' , ' CSV ' ) " ,
" CREATE TABLE tablefunc31 (`x` int) AS s3( ' http://minio1:9001/root/data/test10.csv.gz ' , ' minio ' , ' [HIDDEN] ' ) " ,
" CREATE TABLE tablefunc32 (`x` int) AS deltaLake( ' http://minio1:9001/root/data/test11.csv.gz ' , ' minio ' , ' [HIDDEN] ' ) " ,
2024-06-14 11:26:23 +00:00
f " CREATE TABLE tablefunc33 (x int) AS azureBlobStorage( ' { azure_conn_string } ' , ' cont ' , ' test_simple.csv ' , ' CSV ' ) " ,
2024-06-20 12:51:49 +00:00
f " CREATE TABLE tablefunc34 (x int) AS azureBlobStorage( ' { azure_conn_string } ' , ' cont ' , ' test_simple_1.csv ' , ' CSV ' , ' none ' ) " ,
f " CREATE TABLE tablefunc35 (x int) AS azureBlobStorage( ' { azure_conn_string } ' , ' cont ' , ' test_simple_2.csv ' , ' CSV ' , ' none ' , ' auto ' ) " ,
f " CREATE TABLE tablefunc36 (`x` int) AS azureBlobStorage( ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_3.csv ' , ' { azure_account_name } ' , ' [HIDDEN] ' ) " ,
f " CREATE TABLE tablefunc37 (`x` int) AS azureBlobStorage( ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_4.csv ' , ' { azure_account_name } ' , ' [HIDDEN] ' , ' CSV ' ) " ,
f " CREATE TABLE tablefunc38 (`x` int) AS azureBlobStorage( ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_5.csv ' , ' { azure_account_name } ' , ' [HIDDEN] ' , ' CSV ' , ' none ' ) " ,
f " CREATE TABLE tablefunc39 (`x` int) AS azureBlobStorage( ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_6.csv ' , ' { azure_account_name } ' , ' [HIDDEN] ' , ' CSV ' , ' none ' , ' auto ' ) " ,
2024-06-26 12:07:38 +00:00
f " CREATE TABLE tablefunc40 (x int) AS azureBlobStorage(named_collection_2, connection_string = ' { azure_conn_string } ' , container = ' cont ' , blob_path = ' test_simple_7.csv ' , format = ' CSV ' ) " ,
f " CREATE TABLE tablefunc41 (`x` int) AS azureBlobStorage(named_collection_2, storage_account_url = ' { azure_storage_account_url } ' , container = ' cont ' , blob_path = ' test_simple_8.csv ' , account_name = ' { azure_account_name } ' , account_key = ' [HIDDEN] ' ) " ,
f " CREATE TABLE tablefunc42 (x int) AS azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_conn_string } ' , ' cont ' , ' test_simple_9.csv ' , ' CSV ' ) " ,
f " CREATE TABLE tablefunc43 (x int) AS azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_conn_string } ' , ' cont ' , ' test_simple_10.csv ' , ' CSV ' , ' none ' ) " ,
f " CREATE TABLE tablefunc44 (x int) AS azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_conn_string } ' , ' cont ' , ' test_simple_11.csv ' , ' CSV ' , ' none ' , ' auto ' ) " ,
f " CREATE TABLE tablefunc45 (`x` int) AS azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_12.csv ' , ' { azure_account_name } ' , ' [HIDDEN] ' ) " ,
f " CREATE TABLE tablefunc46 (`x` int) AS azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_13.csv ' , ' { azure_account_name } ' , ' [HIDDEN] ' , ' CSV ' ) " ,
f " CREATE TABLE tablefunc47 (`x` int) AS azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_14.csv ' , ' { azure_account_name } ' , ' [HIDDEN] ' , ' CSV ' , ' none ' ) " ,
f " CREATE TABLE tablefunc48 (`x` int) AS azureBlobStorageCluster( ' test_shard_localhost ' , ' { azure_storage_account_url } ' , ' cont ' , ' test_simple_15.csv ' , ' { azure_account_name } ' , ' [HIDDEN] ' , ' CSV ' , ' none ' , ' auto ' ) " ,
f " CREATE TABLE tablefunc49 (x int) AS azureBlobStorageCluster( ' test_shard_localhost ' , named_collection_2, connection_string = ' { azure_conn_string } ' , container = ' cont ' , blob_path = ' test_simple_16.csv ' , format = ' CSV ' ) " ,
f " CREATE TABLE tablefunc50 (`x` int) AS azureBlobStorageCluster( ' test_shard_localhost ' , named_collection_2, storage_account_url = ' { azure_storage_account_url } ' , container = ' cont ' , blob_path = ' test_simple_17.csv ' , account_name = ' { azure_account_name } ' , account_key = ' [HIDDEN] ' ) " ,
2022-10-16 21:41:59 +00:00
] ,
2022-10-26 22:02:17 +00:00
must_not_contain = [ password ] ,
2022-10-16 21:41:59 +00:00
)
2023-09-28 10:08:57 +00:00
check_secrets_for_tables ( test_cases , password )
2023-02-28 11:09:24 +00:00
2023-09-28 10:08:57 +00:00
for table_name , query , error in test_cases :
if not error :
node . query ( f " DROP TABLE { table_name } " )
2022-10-16 21:41:59 +00:00
2023-01-25 00:26:44 +00:00
def test_table_function_ways_to_call ( ) :
password = new_password ( )
table_function = f " s3( ' http://minio1:9001/root/data/testfuncw.tsv.gz ' , ' minio ' , ' { password } ' , ' TSV ' , ' x int ' ) "
queries = [
" CREATE TABLE tablefuncw (`x` int) AS {} " ,
" INSERT INTO FUNCTION {} SELECT * FROM numbers(10) " ,
" DESCRIBE TABLE {} " ,
]
for query in queries :
# query_and_get_answer_with_error() is used here because we don't want to stop on error "Cannot connect to AWS".
# We test logging here and not actual work with AWS server.
node . query_and_get_answer_with_error ( query . format ( table_function ) )
table_function_with_hidden_arg = " s3( ' http://minio1:9001/root/data/testfuncw.tsv.gz ' , ' minio ' , ' [HIDDEN] ' , ' TSV ' , ' x int ' ) "
check_logs (
must_contain = [
query . format ( table_function_with_hidden_arg ) for query in queries
] ,
must_not_contain = [ password ] ,
)
node . query ( " DROP TABLE tablefuncw " )
2022-10-16 21:41:59 +00:00
def test_encryption_functions ( ) :
2022-10-26 22:02:17 +00:00
plaintext = new_password ( )
cipher = new_password ( )
key = new_password ( 32 )
iv8 = new_password ( 8 )
iv16 = new_password ( 16 )
add = new_password ( )
2022-10-16 21:41:59 +00:00
encryption_functions = [
2022-10-26 22:02:17 +00:00
f " encrypt( ' aes-256-ofb ' , ' { plaintext } ' , ' { key } ' ) " ,
f " encrypt( ' aes-256-ofb ' , ' { plaintext } ' , ' { key } ' , ' { iv16 } ' ) " ,
f " encrypt( ' aes-256-gcm ' , ' { plaintext } ' , ' { key } ' , ' { iv8 } ' ) " ,
f " encrypt( ' aes-256-gcm ' , ' { plaintext } ' , ' { key } ' , ' { iv8 } ' , ' { add } ' ) " ,
f " decrypt( ' aes-256-ofb ' , ' { cipher } ' , ' { key } ' , ' { iv16 } ' ) " ,
f " aes_encrypt_mysql( ' aes-256-ofb ' , ' { plaintext } ' , ' { key } ' , ' { iv16 } ' ) " ,
f " aes_decrypt_mysql( ' aes-256-ofb ' , ' { cipher } ' , ' { key } ' , ' { iv16 } ' ) " ,
f " tryDecrypt( ' aes-256-ofb ' , ' { cipher } ' , ' { key } ' , ' { iv16 } ' ) " ,
2022-10-16 21:41:59 +00:00
]
for encryption_function in encryption_functions :
node . query ( f " SELECT { encryption_function } " )
check_logs (
must_contain = [
" SELECT encrypt( ' aes-256-ofb ' , ' [HIDDEN] ' ) " ,
" SELECT encrypt( ' aes-256-gcm ' , ' [HIDDEN] ' ) " ,
" SELECT decrypt( ' aes-256-ofb ' , ' [HIDDEN] ' ) " ,
" SELECT aes_encrypt_mysql( ' aes-256-ofb ' , ' [HIDDEN] ' ) " ,
" SELECT aes_decrypt_mysql( ' aes-256-ofb ' , ' [HIDDEN] ' ) " ,
" SELECT tryDecrypt( ' aes-256-ofb ' , ' [HIDDEN] ' ) " ,
] ,
2022-10-26 22:02:17 +00:00
must_not_contain = [ plaintext , cipher , key , iv8 , iv16 , add ] ,
2022-10-16 21:41:59 +00:00
)
def test_create_dictionary ( ) :
2022-10-26 22:02:17 +00:00
password = new_password ( )
2022-10-16 21:41:59 +00:00
node . query (
2022-10-26 22:02:17 +00:00
f " CREATE DICTIONARY dict1 (n int DEFAULT 0, m int DEFAULT 1) PRIMARY KEY n "
f " SOURCE(CLICKHOUSE(HOST ' localhost ' PORT 9000 USER ' user1 ' TABLE ' test ' PASSWORD ' { password } ' DB ' default ' )) "
f " LIFETIME(MIN 0 MAX 10) LAYOUT(FLAT()) "
2022-10-16 21:41:59 +00:00
)
2023-02-28 11:09:24 +00:00
for toggle , secret in enumerate ( [ " [HIDDEN] " , password ] ) :
assert (
node . query ( f " SHOW CREATE TABLE dict1 { show_secrets } = { toggle } " )
== f " CREATE DICTIONARY default.dict1 \\ n( \\ n `n` int DEFAULT 0, \\ n `m` int DEFAULT 1 \\ n) \\ nPRIMARY KEY n \\ nSOURCE(CLICKHOUSE(HOST \\ ' localhost \\ ' PORT 9000 USER \\ ' user1 \\ ' TABLE \\ ' test \\ ' PASSWORD \\ ' { secret } \\ ' DB \\ ' default \\ ' )) \\ nLIFETIME(MIN 0 MAX 10) \\ nLAYOUT(FLAT()) \n "
)
2022-11-14 17:42:46 +00:00
2023-02-28 11:09:24 +00:00
assert (
node . query (
f " SELECT create_table_query FROM system.tables WHERE name = ' dict1 ' { show_secrets } = { toggle } "
)
== f " CREATE DICTIONARY default.dict1 (`n` int DEFAULT 0, `m` int DEFAULT 1) PRIMARY KEY n SOURCE(CLICKHOUSE(HOST \\ ' localhost \\ ' PORT 9000 USER \\ ' user1 \\ ' TABLE \\ ' test \\ ' PASSWORD \\ ' { secret } \\ ' DB \\ ' default \\ ' )) LIFETIME(MIN 0 MAX 10) LAYOUT(FLAT()) \n "
)
2022-11-14 17:42:46 +00:00
2022-10-16 21:41:59 +00:00
check_logs (
must_contain = [
" CREATE DICTIONARY dict1 (`n` int DEFAULT 0, `m` int DEFAULT 1) PRIMARY KEY n "
" SOURCE(CLICKHOUSE(HOST ' localhost ' PORT 9000 USER ' user1 ' TABLE ' test ' PASSWORD ' [HIDDEN] ' DB ' default ' )) "
" LIFETIME(MIN 0 MAX 10) LAYOUT(FLAT()) "
] ,
2022-10-26 22:02:17 +00:00
must_not_contain = [ password ] ,
2022-10-16 21:41:59 +00:00
)
2022-10-24 17:27:35 +00:00
node . query ( " DROP DICTIONARY dict1 " )
2022-10-16 21:41:59 +00:00
def test_backup_to_s3 ( ) :
node . query ( " CREATE TABLE temptbl (x int) ENGINE=Log " )
2022-10-26 22:02:17 +00:00
password = new_password ( )
2022-10-16 21:41:59 +00:00
queries = [
2022-10-26 22:02:17 +00:00
f " BACKUP TABLE temptbl TO S3( ' http://minio1:9001/root/data/backups/backup1 ' , ' minio ' , ' { password } ' ) " ,
f " RESTORE TABLE temptbl AS temptbl2 FROM S3( ' http://minio1:9001/root/data/backups/backup1 ' , ' minio ' , ' { password } ' ) " ,
2022-10-16 21:41:59 +00:00
]
for query in queries :
# query_and_get_answer_with_error() is used here because we don't want to stop on error "Cannot connect to AWS".
# We test logging here and not actual work with AWS server.
node . query_and_get_answer_with_error ( query )
check_logs (
must_contain = [
" BACKUP TABLE temptbl TO S3( ' http://minio1:9001/root/data/backups/backup1 ' , ' minio ' , ' [HIDDEN] ' ) " ,
" RESTORE TABLE temptbl AS temptbl2 FROM S3( ' http://minio1:9001/root/data/backups/backup1 ' , ' minio ' , ' [HIDDEN] ' ) " ,
] ,
2022-10-26 22:02:17 +00:00
must_not_contain = [ password ] ,
2022-10-16 21:41:59 +00:00
)
node . query ( " DROP TABLE IF EXISTS temptbl " )
node . query ( " DROP TABLE IF EXISTS temptbl2 " )
2022-10-24 17:27:35 +00:00
def test_on_cluster ( ) :
2022-10-26 22:02:17 +00:00
password = new_password ( )
2022-10-25 00:11:27 +00:00
node . query (
2024-02-13 12:15:46 +00:00
f " CREATE TABLE table_oncl ON CLUSTER ' test_shard_localhost ' (x int) ENGINE = MySQL( ' mysql80:3307 ' , ' mysql_db ' , ' mysql_table ' , ' mysql_user ' , ' { password } ' ) "
2022-10-25 00:11:27 +00:00
)
2022-10-24 17:27:35 +00:00
check_logs (
must_contain = [
2024-02-13 12:15:46 +00:00
" CREATE TABLE table_oncl ON CLUSTER test_shard_localhost (`x` int) ENGINE = MySQL( ' mysql80:3307 ' , ' mysql_db ' , ' mysql_table ' , ' mysql_user ' , ' [HIDDEN] ' ) " ,
2022-10-24 17:27:35 +00:00
] ,
2022-10-26 22:02:17 +00:00
must_not_contain = [ password ] ,
2022-10-24 17:27:35 +00:00
)
2022-10-27 13:52:13 +00:00
# Check logs of DDLWorker during executing of this query.
2022-11-01 10:10:58 +00:00
assert node . contains_in_log (
2024-02-13 12:15:46 +00:00
" DDLWorker: Processing task .*CREATE TABLE default \\ .table_oncl UUID ' [0-9a-fA-F-]* ' ( \\ `x \\ ` Int32) ENGINE = MySQL( ' mysql80:3307 ' , ' mysql_db ' , ' mysql_table ' , ' mysql_user ' , ' \\ [HIDDEN \\ ] ' ) "
2022-10-27 13:52:13 +00:00
)
2022-11-01 10:10:58 +00:00
assert node . contains_in_log (
2024-02-13 12:15:46 +00:00
" DDLWorker: Executing query: .*CREATE TABLE default \\ .table_oncl UUID ' [0-9a-fA-F-]* ' ( \\ `x \\ ` Int32) ENGINE = MySQL( ' mysql80:3307 ' , ' mysql_db ' , ' mysql_table ' , ' mysql_user ' , ' \\ [HIDDEN \\ ] ' ) "
2022-10-27 13:52:13 +00:00
)
2022-11-01 10:10:58 +00:00
assert node . contains_in_log (
2024-02-13 12:15:46 +00:00
" executeQuery: .*CREATE TABLE default \\ .table_oncl UUID ' [0-9a-fA-F-]* ' ( \\ `x \\ ` Int32) ENGINE = MySQL( ' mysql80:3307 ' , ' mysql_db ' , ' mysql_table ' , ' mysql_user ' , ' \\ [HIDDEN \\ ] ' ) "
2022-10-27 13:52:13 +00:00
)
2022-11-01 10:10:58 +00:00
assert node . contains_in_log (
2024-02-13 12:15:46 +00:00
" DDLWorker: Executed query: .*CREATE TABLE default \\ .table_oncl UUID ' [0-9a-fA-F-]* ' ( \\ `x \\ ` Int32) ENGINE = MySQL( ' mysql80:3307 ' , ' mysql_db ' , ' mysql_table ' , ' mysql_user ' , ' \\ [HIDDEN \\ ] ' ) "
2022-10-27 13:52:13 +00:00
)
assert system_query_log_contains_search_pattern (
2024-02-13 12:15:46 +00:00
" % CREATE TABLE default.table_oncl UUID \\ ' % \\ ' (`x` Int32) ENGINE = MySQL( \\ ' mysql80:3307 \\ ' , \\ ' mysql_db \\ ' , \\ ' mysql_table \\ ' , \\ ' mysql_user \\ ' , \\ ' [HIDDEN] \\ ' ) "
2022-10-27 13:52:13 +00:00
)
2023-02-28 11:09:24 +00:00
node . query ( " DROP TABLE table_oncl " )