2019-04-02 22:21:44 +00:00
# coding: utf-8
import os
2019-04-07 10:29:30 +00:00
import docker
2019-04-02 22:21:44 +00:00
import pytest
2019-04-07 10:29:30 +00:00
import subprocess
2019-04-02 22:21:44 +00:00
import pymysql . connections
from docker . models . containers import Container
from helpers . cluster import ClickHouseCluster
SCRIPT_DIR = os . path . dirname ( os . path . realpath ( __file__ ) )
2019-04-29 06:05:30 +00:00
config_dir = os . path . join ( SCRIPT_DIR , ' ./configs ' )
cluster = ClickHouseCluster ( __file__ )
2019-07-19 17:50:42 +00:00
node = cluster . add_instance ( ' node ' , config_dir = config_dir , env_variables = { ' UBSAN_OPTIONS ' : ' print_stacktrace=1 ' } )
2019-04-02 22:21:44 +00:00
server_port = 9001
@pytest.fixture ( scope = " module " )
2019-04-07 10:29:30 +00:00
def server_address ( ) :
2019-04-02 22:21:44 +00:00
cluster . start ( )
try :
2019-04-07 10:29:30 +00:00
yield cluster . get_instance_ip ( ' node ' )
2019-04-02 22:21:44 +00:00
finally :
cluster . shutdown ( )
@pytest.fixture ( scope = ' module ' )
2019-04-07 10:29:30 +00:00
def mysql_client ( ) :
docker_compose = os . path . join ( SCRIPT_DIR , ' clients ' , ' mysql ' , ' docker_compose.yml ' )
subprocess . check_call ( [ ' docker-compose ' , ' -p ' , cluster . project_name , ' -f ' , docker_compose , ' up ' , ' --no-recreate ' , ' -d ' , ' --build ' ] )
yield docker . from_env ( ) . containers . get ( cluster . project_name + ' _mysql1_1 ' )
2019-04-02 22:21:44 +00:00
@pytest.fixture ( scope = ' module ' )
2019-04-07 10:29:30 +00:00
def golang_container ( ) :
docker_compose = os . path . join ( SCRIPT_DIR , ' clients ' , ' golang ' , ' docker_compose.yml ' )
subprocess . check_call ( [ ' docker-compose ' , ' -p ' , cluster . project_name , ' -f ' , docker_compose , ' up ' , ' --no-recreate ' , ' -d ' , ' --build ' ] )
yield docker . from_env ( ) . containers . get ( cluster . project_name + ' _golang1_1 ' )
2019-04-02 22:21:44 +00:00
2019-07-21 12:09:41 +00:00
@pytest.fixture ( scope = ' module ' )
def php_container ( ) :
docker_compose = os . path . join ( SCRIPT_DIR , ' clients ' , ' php-mysqlnd ' , ' docker_compose.yml ' )
subprocess . check_call ( [ ' docker-compose ' , ' -p ' , cluster . project_name , ' -f ' , docker_compose , ' up ' , ' --no-recreate ' , ' -d ' , ' --build ' ] )
yield docker . from_env ( ) . containers . get ( cluster . project_name + ' _php1_1 ' )
2019-07-28 13:12:26 +00:00
@pytest.fixture ( scope = ' module ' )
def nodejs_container ( ) :
docker_compose = os . path . join ( SCRIPT_DIR , ' clients ' , ' mysqljs ' , ' docker_compose.yml ' )
subprocess . check_call ( [ ' docker-compose ' , ' -p ' , cluster . project_name , ' -f ' , docker_compose , ' up ' , ' --no-recreate ' , ' -d ' , ' --build ' ] )
yield docker . from_env ( ) . containers . get ( cluster . project_name + ' _mysqljs1_1 ' )
2019-04-07 10:29:30 +00:00
def test_mysql_client ( mysql_client , server_address ) :
2019-04-02 22:21:44 +00:00
# type: (Container, str) -> None
2019-07-28 13:12:26 +00:00
code , ( stdout , stderr ) = mysql_client . exec_run ( '''
mysql - - protocol tcp - h { host } - P { port } default - u user_with_double_sha1 - - password = abacaba
- e " SELECT 1; "
''' .format(host=server_address, port=server_port), demux=True)
assert stdout == ' \n ' . join ( [ ' 1 ' , ' 1 ' , ' ' ] )
2019-04-07 10:29:30 +00:00
code , ( stdout , stderr ) = mysql_client . exec_run ( '''
2019-04-22 10:57:50 +00:00
mysql - - protocol tcp - h { host } - P { port } default - u default - - password = 123
2019-05-16 03:34:04 +00:00
- e " SELECT 1 as a; "
- e " SELECT ' тест ' as b; "
2019-04-02 22:21:44 +00:00
''' .format(host=server_address, port=server_port), demux=True)
2019-06-16 15:12:37 +00:00
assert stdout == ' \n ' . join ( [ ' a ' , ' 1 ' , ' b ' , ' тест ' , ' ' ] )
2019-04-02 22:21:44 +00:00
2019-04-07 10:29:30 +00:00
code , ( stdout , stderr ) = mysql_client . exec_run ( '''
2019-04-22 10:57:50 +00:00
mysql - - protocol tcp - h { host } - P { port } default - u default - - password = abc - e " select 1 as a; "
2019-04-02 22:21:44 +00:00
''' .format(host=server_address, port=server_port), demux=True)
assert stderr == ' mysql: [Warning] Using a password on the command line interface can be insecure. \n ' \
' ERROR 193 (00000): Wrong password for user default \n '
2019-04-07 10:29:30 +00:00
code , ( stdout , stderr ) = mysql_client . exec_run ( '''
2019-04-22 10:57:50 +00:00
mysql - - protocol tcp - h { host } - P { port } default - u default - - password = 123
2019-04-02 22:21:44 +00:00
- e " use system; "
- e " select count(*) from (select name from tables limit 1); "
- e " use system2; "
''' .format(host=server_address, port=server_port), demux=True)
assert stdout == ' count() \n 1 \n '
assert stderr == " mysql: [Warning] Using a password on the command line interface can be insecure. \n " \
" ERROR 81 (00000) at line 1: Database system2 doesn ' t exist \n "
2019-05-16 03:34:04 +00:00
code , ( stdout , stderr ) = mysql_client . exec_run ( '''
mysql - - protocol tcp - h { host } - P { port } default - u default - - password = 123
- e " CREATE DATABASE x; "
- e " USE x; "
2019-06-16 15:12:37 +00:00
- e " CREATE TABLE table1 (column UInt32) ENGINE = Memory; "
2019-05-16 03:34:04 +00:00
- e " INSERT INTO table1 VALUES (0), (1), (5); "
- e " INSERT INTO table1 VALUES (0), (1), (5); "
2019-06-16 15:12:37 +00:00
- e " SELECT * FROM table1 ORDER BY column; "
2019-06-16 07:55:14 +00:00
- e " DROP DATABASE x; "
2019-06-16 15:12:37 +00:00
- e " CREATE TEMPORARY TABLE tmp (tmp_column UInt32); "
- e " INSERT INTO tmp VALUES (0), (1); "
- e " SELECT * FROM tmp ORDER BY tmp_column; "
2019-05-16 03:34:04 +00:00
''' .format(host=server_address, port=server_port), demux=True)
2019-06-16 15:12:37 +00:00
assert stdout == ' \n ' . join ( [ ' column ' , ' 0 ' , ' 0 ' , ' 1 ' , ' 1 ' , ' 5 ' , ' 5 ' , ' tmp_column ' , ' 0 ' , ' 1 ' , ' ' ] )
2019-05-16 03:34:04 +00:00
2019-11-26 15:39:36 +00:00
def test_mysql_federated ( mysql_client , server_address ) :
node . query ( ''' DROP DATABASE IF EXISTS mysql_federated ''' , settings = { " password " : " 123 " } )
node . query ( ''' CREATE DATABASE mysql_federated ''' , settings = { " password " : " 123 " } )
node . query ( ''' CREATE TABLE mysql_federated.test (col UInt32) ENGINE = Log ''' , settings = { " password " : " 123 " } )
node . query ( ''' INSERT INTO mysql_federated.test VALUES (0), (1), (5) ''' , settings = { " password " : " 123 " } )
code , ( _ , stderr ) = mysql_client . exec_run ( '''
mysql
- e " DROP SERVER IF EXISTS clickhouse; "
- e " CREATE SERVER clickhouse FOREIGN DATA WRAPPER mysql OPTIONS (USER ' default ' , PASSWORD ' 123 ' , HOST ' {host} ' , PORT {port} , DATABASE ' mysql_federated ' ); "
- e " DROP DATABASE IF EXISTS mysql_federated; "
- e " CREATE DATABASE mysql_federated; "
''' .format(host=server_address, port=server_port), demux=True)
assert code == 0
code , ( stdout , stderr ) = mysql_client . exec_run ( '''
mysql
- e " CREATE TABLE mysql_federated.test(`col` int UNSIGNED) ENGINE=FEDERATED CONNECTION= ' clickhouse ' ; "
- e " SELECT * FROM mysql_federated.test ORDER BY col; "
''' .format(host=server_address, port=server_port), demux=True)
assert stdout == ' \n ' . join ( [ ' col ' , ' 0 ' , ' 1 ' , ' 5 ' , ' ' ] )
code , ( stdout , stderr ) = mysql_client . exec_run ( '''
mysql
- e " INSERT INTO mysql_federated.test VALUES (0), (1), (5); "
- e " SELECT * FROM mysql_federated.test ORDER BY col; "
''' .format(host=server_address, port=server_port), demux=True)
assert stdout == ' \n ' . join ( [ ' col ' , ' 0 ' , ' 0 ' , ' 1 ' , ' 1 ' , ' 5 ' , ' 5 ' , ' ' ] )
2019-05-16 03:34:04 +00:00
2019-04-02 22:21:44 +00:00
2019-04-07 10:29:30 +00:00
def test_python_client ( server_address ) :
2019-12-01 11:21:43 +00:00
client = pymysql . connections . Connection ( host = server_address , user = ' user_with_double_sha1 ' , password = ' abacaba ' , database = ' default ' , port = server_port )
with pytest . raises ( pymysql . InternalError ) as exc_info :
client . query ( ' select name from tables ' )
assert exc_info . value . args == ( 60 , " Table default.tables doesn ' t exist. " )
cursor = client . cursor ( pymysql . cursors . DictCursor )
cursor . execute ( " select 1 as a, ' тест ' as b " )
assert cursor . fetchall ( ) == [ { ' a ' : 1 , ' b ' : ' тест ' } ]
2019-04-02 22:21:44 +00:00
with pytest . raises ( pymysql . InternalError ) as exc_info :
pymysql . connections . Connection ( host = server_address , user = ' default ' , password = ' abacab ' , database = ' default ' , port = server_port )
assert exc_info . value . args == ( 193 , ' Wrong password for user default ' )
client = pymysql . connections . Connection ( host = server_address , user = ' default ' , password = ' 123 ' , database = ' default ' , port = server_port )
with pytest . raises ( pymysql . InternalError ) as exc_info :
client . query ( ' select name from tables ' )
assert exc_info . value . args == ( 60 , " Table default.tables doesn ' t exist. " )
cursor = client . cursor ( pymysql . cursors . DictCursor )
cursor . execute ( " select 1 as a, ' тест ' as b " )
2019-12-01 11:21:43 +00:00
assert cursor . fetchall ( ) == [ { ' a ' : 1 , ' b ' : ' тест ' } ]
2019-04-02 22:21:44 +00:00
client . select_db ( ' system ' )
with pytest . raises ( pymysql . InternalError ) as exc_info :
client . select_db ( ' system2 ' )
assert exc_info . value . args == ( 81 , " Database system2 doesn ' t exist " )
2019-04-07 10:29:30 +00:00
2019-05-16 03:34:04 +00:00
cursor = client . cursor ( pymysql . cursors . DictCursor )
2019-06-16 07:55:14 +00:00
cursor . execute ( ' CREATE DATABASE x ' )
client . select_db ( ' x ' )
cursor . execute ( " CREATE TABLE table1 (a UInt32) ENGINE = Memory " )
2019-05-16 03:34:04 +00:00
cursor . execute ( " INSERT INTO table1 VALUES (1), (3) " )
cursor . execute ( " INSERT INTO table1 VALUES (1), (4) " )
cursor . execute ( " SELECT * FROM table1 ORDER BY a " )
2019-12-01 11:21:43 +00:00
assert cursor . fetchall ( ) == [ { ' a ' : 1 } , { ' a ' : 1 } , { ' a ' : 3 } , { ' a ' : 4 } ]
2019-05-16 03:34:04 +00:00
2019-04-07 10:29:30 +00:00
def test_golang_client ( server_address , golang_container ) :
# type: (str, Container) -> None
2019-12-01 11:21:43 +00:00
with open ( os . path . join ( SCRIPT_DIR , ' clients ' , ' golang ' , ' 0.reference ' ) ) as fp :
reference = fp . read ( )
2019-04-07 10:29:30 +00:00
code , ( stdout , stderr ) = golang_container . exec_run ( ' ./main --host {host} --port {port} --user default --password 123 --database '
' abc ' . format ( host = server_address , port = server_port ) , demux = True )
assert code == 1
assert stderr == " Error 81: Database abc doesn ' t exist \n "
code , ( stdout , stderr ) = golang_container . exec_run ( ' ./main --host {host} --port {port} --user default --password 123 --database '
' default ' . format ( host = server_address , port = server_port ) , demux = True )
assert code == 0
2019-12-01 11:21:43 +00:00
assert stdout == reference
2019-04-07 10:29:30 +00:00
2019-12-01 11:21:43 +00:00
code , ( stdout , stderr ) = golang_container . exec_run ( ' ./main --host {host} --port {port} --user user_with_double_sha1 --password abacaba --database '
' default ' . format ( host = server_address , port = server_port ) , demux = True )
assert code == 0
assert stdout == reference
2019-07-21 12:09:41 +00:00
def test_php_client ( server_address , php_container ) :
# type: (str, Container) -> None
2019-07-28 13:12:26 +00:00
code , ( stdout , stderr ) = php_container . exec_run ( ' php -f test.php {host} {port} default 123 ' . format ( host = server_address , port = server_port ) , demux = True )
2019-07-21 12:09:41 +00:00
assert code == 0
assert stdout == ' tables \n '
2019-07-23 07:10:06 +00:00
2019-07-28 13:12:26 +00:00
code , ( stdout , stderr ) = php_container . exec_run ( ' php -f test_ssl.php {host} {port} default 123 ' . format ( host = server_address , port = server_port ) , demux = True )
2019-07-23 07:10:06 +00:00
assert code == 0
assert stdout == ' tables \n '
2019-12-01 11:21:43 +00:00
code , ( stdout , stderr ) = php_container . exec_run ( ' php -f test.php {host} {port} user_with_double_sha1 abacaba ' . format ( host = server_address , port = server_port ) , demux = True )
assert code == 0
assert stdout == ' tables \n '
code , ( stdout , stderr ) = php_container . exec_run ( ' php -f test_ssl.php {host} {port} user_with_double_sha1 abacaba ' . format ( host = server_address , port = server_port ) , demux = True )
assert code == 0
assert stdout == ' tables \n '
2019-07-28 13:12:26 +00:00
def test_mysqljs_client ( server_address , nodejs_container ) :
2019-07-28 14:17:33 +00:00
code , ( _ , stderr ) = nodejs_container . exec_run ( ' node test.js {host} {port} default 123 ' . format ( host = server_address , port = server_port ) , demux = True )
assert code == 1
assert ' MySQL is requesting the sha256_password authentication method, which is not supported. ' in stderr
2019-07-28 13:12:26 +00:00
2019-07-28 14:17:33 +00:00
code , ( _ , stderr ) = nodejs_container . exec_run ( ' node test.js {host} {port} user_with_empty_password " " ' . format ( host = server_address , port = server_port ) , demux = True )
assert code == 1
assert ' MySQL is requesting the sha256_password authentication method, which is not supported. ' in stderr
2019-07-28 13:12:26 +00:00
2019-07-28 14:17:33 +00:00
code , ( _ , _ ) = nodejs_container . exec_run ( ' node test.js {host} {port} user_with_double_sha1 abacaba ' . format ( host = server_address , port = server_port ) , demux = True )
2019-07-28 13:12:26 +00:00
assert code == 0
code , ( _ , _ ) = nodejs_container . exec_run ( ' node test.js {host} {port} user_with_empty_password 123 ' . format ( host = server_address , port = server_port ) , demux = True )
assert code == 1