Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MySQL Router Docker #531

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docker-image-tests/percona-mysql-router/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Before running set environment variables, eg.:

export DOCKER_ACC="percona"
export PS_VERSION="8.0.32-24"
export ROUTER_VERSION="8.0.32"
export TESTING_BRANCH="master"
This is based on: https://testinfra.readthedocs.io/en/latest/examples.html#test-docker-images
5 changes: 5 additions & 0 deletions docker-image-tests/percona-mysql-router/cleanup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
rm -f report.xml
rm -rf .pytest_cache
rm -rf __pycache__
rm -rf tests/__pycache__
15 changes: 15 additions & 0 deletions docker-image-tests/percona-mysql-router/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
atomicwrites==1.3.0
attrs==19.3.0
importlib-metadata==0.23
more-itertools==7.2.0
packaging==19.2
pluggy==0.13.0
py==1.10.0
pyparsing==2.4.2
pytest==5.2.1
six==1.12.0
testinfra==3.2.0
wcwidth==0.1.7
zipp==0.6.0
requests==2.27.1
docker==5.0.3
2 changes: 2 additions & 0 deletions docker-image-tests/percona-mysql-router/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env bash
pytest -v --junit-xml report.xml $@
14 changes: 14 additions & 0 deletions docker-image-tests/percona-mysql-router/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import os

router_version = os.getenv('ROUTER_VERSION')
docker_tag = os.getenv('ROUTER_VERSION')
docker_acc = os.getenv('DOCKER_ACC')

docker_product = 'percona-mysql-router'
docker_image = docker_acc + "/" + docker_product + ":" + docker_tag
ps_pwd = 'inno'

RHEL_DISTS = ["redhat", "centos", "rhel", "oracleserver", "ol", "amzn"]

DEB_DISTS = ["debian", "ubuntu"]

Empty file.
38 changes: 38 additions & 0 deletions docker-image-tests/percona-mysql-router/tests/test_router_attr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env python3
import pytest
import subprocess
import testinfra
import json
from settings import *

container_name = 'router-docker-test-inspect'

@pytest.fixture(scope='module')
def inspect_data():
docker_id = subprocess.check_output(
['docker', 'run', '--name', container_name, '-d', docker_image], stderr=subprocess.STDOUT ).decode().strip()
inspect_data = json.loads(subprocess.check_output(['docker','inspect',container_name]))
yield inspect_data[0]
subprocess.check_call(['docker', 'rm', '-f', docker_id])


class TestContainerAttributes:
def test_status(self, inspect_data):
assert inspect_data['State']['Status'] == 'running'
assert inspect_data['State']['Running'] == True

def test_config(self, inspect_data):
assert len(inspect_data['Config']['Cmd']) == 1
assert inspect_data['Config']['Cmd'][0] == 'mysqlrouter'

def test_image_name(self, inspect_data):
assert inspect_data['Config']['Image'] == docker_image

def test_volumes(self, inspect_data):
assert len(inspect_data['Config']['Volumes']) == 1
assert '/var/lib/mysqlrouter' in inspect_data['Config']['Volumes']

def test_entrypoint(self, inspect_data):
assert len(inspect_data['Config']['Entrypoint']) == 1
assert inspect_data['Config']['Entrypoint'][0] == '/entrypoint.sh'

141 changes: 141 additions & 0 deletions docker-image-tests/percona-mysql-router/tests/test_router_static.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#!/usr/bin/env python3
import subprocess
import time
import json
import os
import pytest
import testinfra

container_name_mysql_router = 'mysql-router'
network_name = 'innodbnet'
docker_tag = os.getenv('ROUTER_VERSION')
docker_acc = os.getenv('DOCKER_ACC')
ps_version = os.getenv('PS_VERSION')
router_docker_image = f"{docker_acc}/percona-mysql-router:{docker_tag}"
percona_docker_image = f"{docker_acc}/percona-server:{ps_version}"

def create_network():
subprocess.run(['docker', 'network', 'create', network_name], check=True)

def create_mysql_config():
for N in range(1, 5):
with open(f'my{N}.cnf', 'w') as file:
file.write(
f"[mysqld]\n"
f"plugin_load_add='group_replication.so'\n"
f"server_id={(hash(str(time.time()) + str(N))) % 40 + 10}\n"
f"binlog_checksum=NONE\n"
f"enforce_gtid_consistency=ON\n"
f"gtid_mode=ON\n"
f"relay_log=mysql{N}-relay-bin\n"
f"innodb_dedicated_server=ON\n"
f"binlog_transaction_dependency_tracking=WRITESET\n"
f"slave_preserve_commit_order=ON\n"
f"slave_parallel_type=LOGICAL_CLOCK\n"
f"transaction_write_set_extraction=XXHASH64\n"
)

def start_mysql_containers():
for N in range(1, 5):
subprocess.run([
'docker', 'run', '-d',
f'--name=mysql{N}',
f'--hostname=mysql{N}',
'--net=innodbnet',
'-v', f"{os.getcwd()}/my{N}.cnf:/etc/my.cnf",
'-e', 'MYSQL_ROOT_PASSWORD=root', percona_docker_image
], check=True)
time.sleep(60)

def create_new_user():
for N in range(1, 5):
subprocess.run([
'docker', 'exec', f'mysql{N}',
'mysql', '-uroot', '-proot',
'-e', "CREATE USER 'inno'@'%' IDENTIFIED BY 'inno'; GRANT ALL privileges ON *.* TO 'inno'@'%' with grant option; FLUSH PRIVILEGES;"
], check=True)

def verify_new_user():
for N in range(1, 5):
subprocess.run([
'docker', 'exec', f'mysql{N}',
'mysql', '-uinno', '-pinno',
'-e', "SHOW VARIABLES WHERE Variable_name = 'hostname';",
'-e', "SELECT user FROM mysql.user WHERE user = 'inno';"
], check=True)
time.sleep(30)

def docker_restart():
subprocess.run(['docker', 'restart', 'mysql1', 'mysql2', 'mysql3', 'mysql4'], check=True)
time.sleep(10)

def create_cluster():
subprocess.run([
'docker', 'exec', 'mysql1',
'mysqlsh', '-uinno', '-pinno', '--', 'dba', 'create-cluster', 'testCluster'
], check=True)

def add_slave():
subprocess.run([
'docker', 'exec', 'mysql1',
'mysqlsh', '-uinno', '-pinno', '--',
'cluster', 'add-instance', '--uri=inno@mysql2', '--recoveryMethod=clone'
], check=True)
time.sleep(120)
subprocess.run(['docker', 'exec', mysql2 , 'service', 'mysql', 'restart'], check=True)
shell.options["dba.restartWaitTimeout"] = 300
subprocess.run([
'docker', 'exec', 'mysql1',
'mysqlsh', '-uinno', '-pinno', '--',
'cluster', 'add-instance', '--uri=inno@mysql3', '--recoveryMethod=clone'
], check=True)
time.sleep(120)
subprocess.run([
'docker', 'exec', 'mysql1',
'mysqlsh', '-uinno', '-pinno', '--',
'cluster', 'add-instance', '--uri=inno@mysql4', '--recoveryMethod=clone'
], check=True)
time.sleep(120)

create_network()
create_mysql_config()
start_mysql_containers()
create_new_user()
verify_new_user()
docker_restart()
create_cluster()
add_slave()

class TestRouterEnvironment:
def test_mysqlrouter_version(self, host):
command = "mysqlrouter --version"
output = host.check_output(command)
assert docker_tag in output

def test_mysqlsh_version(self, host):
command = "mysqlsh --version"
output = host.check_output(command)
assert ps_version in output

def test_mysqlrouter_directory_permissions(self, host):
assert host.file('/var/lib/mysqlrouter').user == 'mysql'
assert host.file('/var/lib/mysqlrouter').group == 'mysql'
assert oct(host.file('/var/lib/mysqlrouter').mode) == '0o755'

def test_mysql_user(self, host):
mysql_user = host.user('mysql')
print(f"Username: {mysql_user.name}, UID: {mysql_user.uid}")
assert mysql_user.exists
assert mysql_user.uid == 1001

def test_mysqlrouter_ports(self, host):
host.socket("tcp://6446").is_listening
host.socket("tcp://6447").is_listening
host.socket("tcp://64460").is_listening
host.socket("tcp://64470").is_listening

def test_mysqlrouter_config(self, host):
assert host.file("/etc/mysqlrouter/mysqlrouter.conf").exists
assert host.file("/etc/mysqlrouter/mysqlrouter.conf").user == "root"
assert host.file("/etc/mysqlrouter/mysqlrouter.conf").group == "root"
assert oct(host.file("/etc/mysqlrouter/mysqlrouter.conf").mode) == "0o644"