Skip to content

Commit

Permalink
MySQL Router Docker
Browse files Browse the repository at this point in the history
  • Loading branch information
kaushikpuneet07 committed Sep 8, 2023
1 parent 8a9d8d1 commit 6adf3e0
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 90 deletions.
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"]

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

container_name = 'router-docker-test-static'

@pytest.fixture(scope='module')
def host():
docker_id = subprocess.check_output(
['docker', 'run', '--name', container_name, '-d', docker_image ], stderr=subprocess.STDOUT ).decode().strip()
time.sleep(20)
subprocess.check_call(['docker','exec','--user','root',container_name,'microdnf','install', '-y', 'net-tools'])
time.sleep(20)
yield testinfra.get_host("docker://root@" + docker_id)
subprocess.check_call(['docker', 'rm', '-f', docker_id])


class TestRouterEnvironment:
def test_packages(self, host):
pkg = host.package("percona-mysql-router")
dist = host.system_info.distribution
assert pkg.is_installed
if dist.lower() in RHEL_DISTS:
assert router_version in pkg.version+'-'+pkg.release, pkg.version+'-'+pkg.release
else:
assert router_version in pkg.version, pkg.version

def test_binaries_exist(self, host):
router_binary="/tmp/mysqlrouter"
assert host.file(router_binary).exists
assert oct(host.file(router_binary).mode) == '0o755'

def test_binaries_version(self, host):
assert router_version in host.check_output("/tmp/mysqlrouter --version")

# def test_process_running(self, host):
# assert host.process.get(user="mysql", comm="orchestrator")

def test_http_port_6446(self, host):
assert host.socket('tcp://127.0.0.1:6446').is_listening

def test_raft_port_6447(self, host):
assert host.socket('tcp://127.0.0.1:6447').is_listening

def test_mysql_user(self, host):
assert host.user('mysql').exists
assert host.user('mysql').uid == 1001
assert host.user('mysql').gid == 1001
assert 'mysql' in host.user('mysql').groups

def test_mysql_group(self, host):
assert host.group('mysql').exists
assert host.group('mysql').gid == 1001

def test_router_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_mysqlrouter_version(self, host):
cmd = host.run("mysqlrouter --version")
assert router_version in cmd.stdout


def test_mysqlsh_version(self, host):
cmd = host.run("mysqlsh --version")
assert PS_VERSION in cmd.stdout
Binary file not shown.
Binary file not shown.
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'

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
import pytest
import subprocess
import testinfra
import time
from settings import *
import json
import os
import requests
import docker

container_name = 'mysql-router-test'
network_name = 'innodbnet1'

@pytest.fixture(scope='module')
def host():
docker_client = docker.from_env()
docker_client.networks.create(network_name)
docker_id = subprocess.check_output(
['docker', 'run', '--name', container_name, '--net', network_name, '--MYSQL_PASSWORD', '+ps_pwd+', '--MYSQL_INNODB_CLUSTER_MEMBERS', '4', '-d', docker_image ], stderr=subprocess.STDOUT ).decode().strip()
time.sleep(20)
subprocess.check_call(['docker','exec','--user','root',container_name,'microdnf','install', '-y', 'net-tools'])
time.sleep(20)
yield testinfra.get_host("docker://root@" + docker_id)
subprocess.check_call(['docker', 'rm', '-f', docker_id])


class TestRouterEnvironment:
def test_mysqlsh_version(self, host):
assert host.check_output("mysqlsh --version") == 'mysqlsh Ver '+ROUTER_VERSION+' for Linux on x86_64 - for MySQL '+PS_VERSION+' (Source distribution)'

def test_mysqlrouter_version(self, host):
assert host.check_output("mysqlrouter --version") == 'MySQL Router Ver '+PS_VERSION+' for Linux on x86_64 (Percona Server (GPL), Release 25, Revision '+Revision+')'

def test_binaries_exist(self, host):
router_binary="/tmp/mysqlrouter"
assert host.file(router_binary).exists
assert oct(host.file(router_binary).mode) == '0o755'

def test_http_port_6447(self, host):
assert host.socket('tcp://127.0.0.1:6447').is_listening

def test_raft_port_6446(self, host):
assert host.socket('tcp://127.0.0.1:6446').is_listening

def test_mysql_user(self, host):
assert host.user('mysql').exists
assert host.user('mysql').uid == 1001
assert host.user('mysql').gid == 1001
assert 'mysql' in host.user('mysql').groups

def test_mysql_group(self, host):
assert host.group('mysql').exists
assert host.group('mysql').gid == 1001

def test_router_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'
105 changes: 15 additions & 90 deletions router-docker_test.sh
Original file line number Diff line number Diff line change
@@ -1,31 +1,4 @@
#!/bin/bash

if [ $# -eq 0 ];
then
echo "$0: Missing arguments"
exit 1
elif [ $# -gt 2 ];
then
echo "$0: Too many arguments: $@"
exit 1
else
echo "We got some argument(s)"

echo "==========================="

echo "Number of arguments.: $#"

echo "List of arguments...: $@"

echo "Arg #1..............: $1"

echo "Arg #2..............: $2"

echo "==========================="
fi


set -xe
#!/usr/bin/env bash

cleanup(){

Expand Down Expand Up @@ -78,7 +51,7 @@ start_mysql_containers(){

create_new_user(){
for N in 1 2 3 4
do sudo docker exec -it mysql$N mysql -uroot -proot \
do sudo docker exec mysql$N mysql -uroot -proot \
-e "CREATE USER 'inno'@'%' IDENTIFIED BY 'inno';" \
-e "GRANT ALL privileges ON *.* TO 'inno'@'%' with grant option;" \
-e "reset master;"
Expand All @@ -88,7 +61,7 @@ create_new_user(){

verify_new_user(){
for N in 1 2 3 4
do sudo docker exec -it mysql$N mysql -uinno -pinno \
do sudo docker exec mysql$N mysql -uinno -pinno \
-e "SHOW VARIABLES WHERE Variable_name = 'hostname';" \
-e "SELECT user FROM mysql.user where user = 'inno';"
done
Expand All @@ -104,19 +77,19 @@ docker_restart(){


create_cluster(){
sudo docker exec -it mysql1 mysqlsh -uinno -pinno -- dba create-cluster testCluster
sudo docker exec mysql1 mysqlsh -uinno -pinno -- dba create-cluster testCluster
}

add_slave(){
sudo docker exec -it mysql1 mysqlsh -uinno -pinno -- cluster add-instance --uri=inno@mysql2 --recoveryMethod=incremental
sudo docker exec mysql1 mysqlsh -uinno -pinno -- cluster add-instance --uri=inno@mysql2 --recoveryMethod=incremental

sleep 10

sudo docker exec -it mysql1 mysqlsh -uinno -pinno -- cluster add-instance --uri=inno@mysql3 --recoveryMethod=incremental
sudo docker exec mysql1 mysqlsh -uinno -pinno -- cluster add-instance --uri=inno@mysql3 --recoveryMethod=incremental

sleep 10

sudo docker exec -it mysql1 mysqlsh -uinno -pinno -- cluster add-instance --uri=inno@mysql4 --recoveryMethod=incremental
sudo docker exec mysql1 mysqlsh -uinno -pinno -- cluster add-instance --uri=inno@mysql4 --recoveryMethod=incremental

sleep 10
}
Expand All @@ -131,69 +104,24 @@ Router_Bootstrap(){
data_add(){

sudo docker run -d --name=mysql-client --hostname=mysql-client --net=innodbnet -e MYSQL_ROOT_PASSWORD=root $1

sleep 10

echo "Adding sbtest user"

sudo docker exec -it mysql-client mysql -h mysql-router -P 6446 -uinno -pinno \
sudo docker exec mysql-client mysql -h mysql-router -P 6446 -uinno -pinno \
-e "CREATE SCHEMA sbtest; CREATE USER sbtest@'%' IDENTIFIED with mysql_native_password by 'password';" \
-e "GRANT ALL PRIVILEGES ON sbtest.* to sbtest@'%';"

echo "Verify sbtest user"

sudo docker exec -it mysql-client mysql -h mysql-router -P 6447 -uinno -pinno -e "select host , user from mysql.user where user='sbtest';"

sleep 5

echo "sysbench run"

sudo docker run --rm=true --net=innodbnet --name=sb-prepare severalnines/sysbench sysbench --db-driver=mysql --table-size=10000 --tables=1 --threads=1 --mysql-host=mysql-router --mysql-port=6446--mysql-user=sbtest --mysql-password=password /usr/share/sysbench/oltp_insert.lua prepare

sleep 20

echo "verify if data is inserted or not"

sudo docker exec -it mysql-client mysql -h mysql-router -P 6447 -uinno -pinno -e "SELECT count(*) from sbtest.sbtest1;"
}

verify_replication(){

for N in 1 2 3 4;
do
sudo docker exec -it mysql$N mysql -uinno -pinno -e "SHOW VARIABLES WHERE Variable_name = 'hostname';" -e "SELECT count(*) from sbtest.sbtest1;";
done
}

Fault_tolerance(){
sudo docker exec mysql-client mysql -h mysql-router -P 6447 -uinno -pinno -e "select host , user from mysql.user where user='sbtest';"

echo "Stop One node"

sudo docker stop mysql1

sleep 10

echo "check status"

sudo docker exec -it mysql-client mysqlsh -h mysql-router -P 6446 -uinno -pinno -- cluster status >> cluster1.json

sed '1d' cluster1.json >> cluster.json

status=$(jq -r '.defaultReplicaSet.status' cluster.json)

echo $status
}

verify_status(){
sleep 5

if [[ "${status}" = "OK_PARTIAL" ]]; then
echo "Innodb cluster looks good"
exit 0
else
echo "Issue in Innodb Cluster"
exit 1
fi
echo "sysbench run"

sudo docker run --rm=true --net=innodbnet --name=sb-prepare severalnines/sysbench sysbench --db-driver=mysql --table-size=10000 --tables=1 --threads=1 --mysql-host=mysql-router --mysql-port=6446--mysql-user=sbtest --mysql-password=password /usr/share/sysbench/oltp_insert.lua prepare
}

cleanup
Expand All @@ -206,7 +134,4 @@ docker_restart
create_cluster
add_slave
Router_Bootstrap $2
data_add $1
verify_replication
Fault_tolerance
verify_status
data_add $1

0 comments on commit 6adf3e0

Please sign in to comment.