231 lines
8.4 KiB
Python
231 lines
8.4 KiB
Python
#!/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
############################################################################
|
|
#
|
|
# @file test_sys_binlog_restart.py
|
|
# @date 2021/11/02 14:37:00
|
|
# @brief This file is a test file for doris binlog load.
|
|
#
|
|
#############################################################################
|
|
|
|
"""
|
|
binlog load be/fe 异常测试
|
|
MySQL需开启binlog功能
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import pymysql
|
|
sys.path.append("../")
|
|
from lib import node_op
|
|
from lib import palo_config
|
|
from lib import palo_client
|
|
from lib import palo_job
|
|
from lib import util
|
|
from data import binlog as DATA
|
|
client = None
|
|
config = palo_config.config
|
|
LOG = palo_client.LOG
|
|
L = palo_client.L
|
|
|
|
canal_ip = config.canal_ip
|
|
WAIT_TIME = 20
|
|
|
|
|
|
def setup_module():
|
|
"""
|
|
setUp
|
|
"""
|
|
global node_operator
|
|
node_operator = node_op.Node()
|
|
global client
|
|
master = node_operator.get_master()
|
|
client = palo_client.get_client(master, config.fe_query_port, user=config.fe_user,
|
|
password=config.fe_password, http_port=config.fe_http_port)
|
|
global connect
|
|
connect = pymysql.connect(host=config.mysql_host, port=config.mysql_port, user=config.canal_user, \
|
|
passwd=config.canal_password)
|
|
# client.set_frontend_config('enable_create_sync_job', 'true')
|
|
global destination
|
|
destination = 'example_' + str(config.fe_query_port)
|
|
|
|
|
|
def check_fe_be():
|
|
"""检查fe和be,是否有false,如果有则拉起来"""
|
|
ret = client.get_backend_list()
|
|
be_list = util.get_attr_condition_list(ret, palo_job.BackendProcInfo.Alive,
|
|
'false', palo_job.BackendProcInfo.Host)
|
|
if be_list is not None:
|
|
for be_host in be_list:
|
|
node_operator.start_be(be_host)
|
|
assert node_operator.is_be_alive(be_host)
|
|
ret = client.get_fe_list()
|
|
fe_list = util.get_attr_condition_list(ret, palo_job.FrontendInfo.Alive,
|
|
'false', palo_job.FrontendInfo.Host)
|
|
if fe_list is not None:
|
|
for fe_host in fe_list:
|
|
node_operator.start_fe(fe_host)
|
|
assert node_operator.is_fe_alive(fe_host)
|
|
|
|
|
|
def mysql_execute(sql):
|
|
"""
|
|
连接mysql执行语句
|
|
"""
|
|
cursor = connect.cursor()
|
|
try:
|
|
LOG.info(L('mysql check sql', sql=sql))
|
|
cursor.execute(sql)
|
|
cursor.close()
|
|
connect.commit()
|
|
except Exception as error:
|
|
assert False, "execute error. %s" % str(error)
|
|
LOG.error(L("mysql execute error", error=str(error)))
|
|
time.sleep(1)
|
|
return cursor.fetchall()
|
|
|
|
|
|
def create_mysql_table(mysql_table_name, mysql_database_name, columns, key='PRIMARY KEY (k1)', new_database=True):
|
|
"""
|
|
创建MySQL数据库和表
|
|
"""
|
|
if new_database:
|
|
mysql_clean(mysql_database_name)
|
|
sql = "CREATE DATABASE %s" % mysql_database_name
|
|
try:
|
|
mysql_execute(sql)
|
|
except Exception as error:
|
|
LOG.error(L("CREATE database error", host=config.canal_host, database_name=mysql_database_name, \
|
|
error=error))
|
|
connect.select_db(mysql_database_name)
|
|
sql = "DROP TABLE IF EXISTS %s" % mysql_table_name
|
|
mysql_execute(sql)
|
|
sql = ''
|
|
for column in columns:
|
|
column_sql = '%s %s' % (column[0], column[1])
|
|
if len(column) > 2:
|
|
if column[2]:
|
|
column_sql = '%s %s' % (column_sql, column[2])
|
|
if len(column) > 3:
|
|
column_sql = '%s DEFAULT "%s"' % (column_sql, column[3])
|
|
sql = '%s %s,' % (sql, column_sql)
|
|
sql = "CREATE table %s (%s %s)" % (mysql_table_name, sql, key)
|
|
LOG.info(L('mysql check sql', sql=sql))
|
|
try:
|
|
mysql_execute(sql)
|
|
except Exception as error:
|
|
LOG.error(L("CREATE TABLE error", host=config.canal_host, table_name=mysql_table_name, error=error))
|
|
return False
|
|
return True
|
|
|
|
|
|
def mysql_clean(mysql_database_name):
|
|
"""
|
|
mysql drop database
|
|
"""
|
|
sql = "DROP DATABASE IF EXISTS %s" % mysql_database_name
|
|
mysql_execute(sql)
|
|
|
|
|
|
def test_restart_be():
|
|
"""
|
|
{
|
|
"title": "test_sys_binlog_restart:test_restart_be",
|
|
"describe": "创建binlog load任务,be宕机,mysql执行导入语句,验证数据导入到doris",
|
|
"tag": "p0,system,fuzz"
|
|
}
|
|
"""
|
|
check_fe_be()
|
|
database_name, table_name, index_name = util.gen_num_format_name_list()
|
|
LOG.info(L('', database_name=database_name, table_name=table_name, index_name=index_name))
|
|
client.clean(database_name)
|
|
client.create_database(database_name)
|
|
client.use(database_name)
|
|
client.create_table(table_name, DATA.column_1, set_null=True, keys_desc='UNIQUE KEY(k1)')
|
|
mysql_database_name = 'm_' + database_name + '_' + str(config.fe_query_port)
|
|
mysql_table_name = 'mysql_' + table_name
|
|
create_mysql_table(mysql_table_name, mysql_database_name, DATA.column_1)
|
|
job_name = 'job_' + table_name
|
|
ret = client.create_sync_job(table_name, database_name, mysql_table_name, mysql_database_name,
|
|
job_name, canal_ip, destination=destination)
|
|
assert ret, 'create sync job failed'
|
|
assert client.get_sync_job_state(job_name) == 'RUNNING', 'sync job state error'
|
|
be_id = client.get_backend_id_list()[0]
|
|
be_host = client.get_be_hostname_by_id(be_id)
|
|
ret = node_operator.stop_be(be_host)
|
|
assert ret, 'stop be failed'
|
|
time.sleep(WAIT_TIME)
|
|
sql = open(DATA.binlog_sql_4, 'r').read().format(mysql_table_name)
|
|
mysql_execute(sql)
|
|
time.sleep(WAIT_TIME)
|
|
assert client.get_sync_job_state(job_name) == 'RUNNING', 'sync job state error'
|
|
assert client.verify(DATA.expected_file_3, table_name)
|
|
ret = node_operator.start_be(be_host)
|
|
assert ret, 'start be failed'
|
|
client.stop_sync_job(job_name)
|
|
client.clean(database_name)
|
|
mysql_clean(mysql_database_name)
|
|
check_fe_be()
|
|
|
|
|
|
def test_restart_fe():
|
|
"""
|
|
{
|
|
"title": "test_sys_binlog_restart:test_restart_fe",
|
|
"describe": "创建binlog load任务,fe master宕机,mysql执行导入语句,验证数据导入到doris",
|
|
"tag": "p0,system,fuzz"
|
|
}
|
|
"""
|
|
check_fe_be()
|
|
database_name, table_name, index_name = util.gen_num_format_name_list()
|
|
LOG.info(L('', database_name=database_name, table_name=table_name, index_name=index_name))
|
|
client.clean(database_name)
|
|
client.create_database(database_name)
|
|
client.use(database_name)
|
|
client.create_table(table_name, DATA.column_1, set_null=True, keys_desc='UNIQUE KEY(k1)')
|
|
mysql_database_name = 'm_' + database_name + '_' + str(config.fe_query_port)
|
|
mysql_table_name = 'mysql_' + table_name
|
|
create_mysql_table(mysql_table_name, mysql_database_name, DATA.column_1)
|
|
job_name = 'job_' + table_name
|
|
ret = client.create_sync_job(table_name, database_name, mysql_table_name, mysql_database_name,
|
|
job_name, canal_ip, destination=destination)
|
|
assert ret, 'create sync job failed'
|
|
assert client.get_sync_job_state(job_name) == 'RUNNING', 'sync job state error'
|
|
master_port = client.get_master()
|
|
master = master_port.split(':')[0]
|
|
ret = node_operator.stop_fe(master)
|
|
assert ret, 'stop fe failed'
|
|
time.sleep(WAIT_TIME)
|
|
sql = open(DATA.binlog_sql_4, 'r').read().format(mysql_table_name)
|
|
mysql_execute(sql)
|
|
time.sleep(WAIT_TIME)
|
|
ret = node_operator.start_fe(master)
|
|
assert ret, 'start fe failed'
|
|
time.sleep(WAIT_TIME)
|
|
client.connect()
|
|
client.use(database_name)
|
|
assert client.get_sync_job_state(job_name) == 'RUNNING', 'sync job state error'
|
|
assert client.verify(DATA.expected_file_3, table_name)
|
|
client.stop_sync_job(job_name)
|
|
client.clean(database_name)
|
|
mysql_clean(mysql_database_name)
|
|
check_fe_be()
|