Merge pull request #107 from thedac/mysql8-actions

MySQL 8 specific tests
This commit is contained in:
Alex Kavanagh
2019-11-07 16:00:29 +00:00
committed by GitHub

View File

@@ -14,6 +14,7 @@
"""MySQL/Percona Cluster Testing."""
import json
import logging
import os
import re
@@ -27,31 +28,17 @@ import zaza.openstack.utilities.openstack as openstack_utils
import zaza.openstack.utilities.generic as generic_utils
class MySQLTest(test_utils.OpenStackBaseTest):
class MySQLBaseTest(test_utils.OpenStackBaseTest):
"""Base for mysql charm tests."""
@classmethod
def setUpClass(cls):
"""Run class setup for running mysql tests."""
super(MySQLTest, cls).setUpClass()
super(MySQLBaseTest, cls).setUpClass()
cls.application = "mysql"
cls.services = ["mysqld"]
class PerconaClusterTest(test_utils.OpenStackBaseTest):
"""Base for percona-cluster charm tests."""
@classmethod
def setUpClass(cls):
"""Run class setup for running percona-cluster tests."""
super(PerconaClusterTest, cls).setUpClass()
cls.application = "percona-cluster"
# This is the service pidof will attempt to find
# rather than what systemctl uses
cls.services = ["mysqld"]
cls.vip = os.environ.get("OS_VIP00")
cls.leader = None
cls.non_leaders = []
# Config file affected by juju set config change
cls.conf_file = "/etc/mysql/mysql.conf.d/mysqld.cnf"
def get_root_password(self):
"""Get the MySQL root password.
@@ -63,6 +50,76 @@ class PerconaClusterTest(test_utils.OpenStackBaseTest):
self.application,
"leader-get root-password")["Stdout"].strip()
def get_leaders_and_non_leaders(self):
"""Get leader node and non-leader nodes of percona.
Update and set on the object the leader node and list of non-leader
nodes.
:returns: None
:rtype: None
"""
status = zaza.model.get_status().applications[self.application]
# Reset
self.leader = None
self.non_leaders = []
for unit in status["units"]:
if status["units"][unit].get("leader"):
self.leader = unit
else:
self.non_leaders.append(unit)
return self.leader, self.non_leaders
class MySQLCommonTests(MySQLBaseTest):
"""Common mysql charm tests."""
def test_910_restart_on_config_change(self):
"""Checking restart happens on config change.
Change disk format and assert then change propagates to the correct
file and that services are restarted as a result
"""
# Expected default and alternate values
set_default = {"max-connections": "600"}
set_alternate = {"max-connections": "1000"}
# Make config change, check for service restarts
logging.debug("Setting peer timeout ...")
self.restart_on_changed(
self.conf_file,
set_default,
set_alternate,
{}, {},
self.services)
logging.info("Passed restart on changed test.")
def test_920_pause_resume(self):
"""Run pause and resume tests.
Pause service and check services are stopped then resume and check
they are started
"""
with self.pause_resume(self.services):
logging.info("Testing pause resume")
logging.info("Passed pause and resume test.")
class PerconaClusterBaseTest(MySQLBaseTest):
"""Base for percona-cluster charm tests."""
@classmethod
def setUpClass(cls):
"""Run class setup for running percona-cluster tests."""
super().setUpClass()
cls.application = "percona-cluster"
# This is the service pidof will attempt to find
# rather than what systemctl uses
cls.services = ["mysqld"]
cls.vip = os.environ.get("TEST_VIP00")
# Config file affected by juju set config change
cls.conf_file = "/etc/mysql/percona-xtradb-cluster.conf.d/mysqld.cnf"
def get_wsrep_value(self, attr):
"""Get wsrrep value from the DB.
@@ -123,39 +180,13 @@ class PerconaClusterTest(test_utils.OpenStackBaseTest):
)
return unit.entity_id
def update_leaders_and_non_leaders(self):
"""Get leader node and non-leader nodes of percona.
Update and set on the object the leader node and list of non-leader
nodes.
:returns: None
:rtype: None
"""
status = zaza.model.get_status().applications[self.application]
# Reset
self.leader = None
self.non_leaders = []
for unit in status["units"]:
if status["units"][unit].get("leader"):
self.leader = unit
else:
self.non_leaders.append(unit)
class PerconaClusterCharmTests(PerconaClusterTest):
"""Base for percona-cluster charm tests.
class PerconaClusterCharmTests(MySQLCommonTests, PerconaClusterBaseTest):
"""Percona-cluster charm tests.
.. note:: these have tests have been ported from amulet tests
"""
@classmethod
def setUpClass(cls):
"""Run class setup for running percona-cluster tests."""
super(PerconaClusterTest, cls).setUpClass()
cls.application = "percona-cluster"
cls.services = ["mysqld"]
def test_100_bootstrapped_and_clustered(self):
"""Ensure PXC is bootstrapped and that peer units are clustered."""
self.units = zaza.model.get_application_config(
@@ -170,38 +201,6 @@ class PerconaClusterCharmTests(PerconaClusterTest):
" (wanted=%s, cluster_size=%s)" % (self.units, cluster_size))
assert cluster_size >= self.units, msg
def test_110_restart_on_config_change(self):
"""Checking restart happens on config change.
Change disk format and assert then change propagates to the correct
file and that services are restarted as a result
"""
# Expected default and alternate values
set_default = {"peer-timeout": "PT3S"}
set_alternate = {"peer-timeout": "PT15S"}
# Config file affected by juju set config change
conf_file = "/etc/mysql/percona-xtradb-cluster.conf.d/mysqld.cnf"
# Make config change, check for service restarts
logging.debug("Setting peer timeout ...")
self.restart_on_changed(
conf_file,
set_default,
set_alternate,
{}, {},
self.services)
logging.info("Passed restart on changed")
def test_120_pause_resume(self):
"""Run pause and resume tests.
Pause service and check services are stopped then resume and check
they are started
"""
with self.pause_resume(self.services):
logging.info("Testing pause resume")
def test_130_change_root_password(self):
"""Change root password.
@@ -232,7 +231,7 @@ class PerconaClusterCharmTests(PerconaClusterTest):
assert code == "0", output
class PerconaClusterColdStartTest(PerconaClusterTest):
class PerconaClusterColdStartTest(PerconaClusterBaseTest):
"""Percona Cluster cold start tests."""
@classmethod
@@ -317,14 +316,14 @@ class PerconaClusterColdStartTest(PerconaClusterTest):
zaza.model.wait_for_application_states(states=states)
# Update which node is the leader and which are not
self.update_leaders_and_non_leaders()
_leader, _non_leaders = self.get_leaders_and_non_leaders()
# We want to test the worst possible scenario which is the
# non-leader with the highest sequence number. We will use the leader
# for the notify-bootstrapped after. They just need to be different
# units.
logging.info("Execute bootstrap-pxc action after cold boot ...")
zaza.model.run_action(
self.non_leaders[0],
_non_leaders[0],
"bootstrap-pxc",
action_params={})
logging.debug("Wait for application states ...")
@@ -349,17 +348,9 @@ class PerconaClusterColdStartTest(PerconaClusterTest):
states=test_config.get("target_deploy_status", {}))
class PerconaClusterScaleTests(PerconaClusterTest):
class PerconaClusterScaleTests(PerconaClusterBaseTest):
"""Percona Cluster scale tests."""
@classmethod
def setUpClass(cls):
"""Run class setup for running percona scale tests.
.. note:: these have tests have been ported from amulet tests
"""
super(PerconaClusterScaleTests, cls).setUpClass()
def test_100_kill_crm_master(self):
"""Ensure VIP failover.
@@ -398,3 +389,35 @@ class PerconaClusterScaleTests(PerconaClusterTest):
# always true.
assert generic_utils.is_port_open("3306", self.vip), \
"Cannot connect to vip"
class MySQLInnoDBClusterTests(MySQLCommonTests):
"""Mysql-innodb-cluster charm tests.
Note: The restart on changed and pause/resume tests also validate the
changing of the R/W primary. On each mysqld shutodown a new R/W primary is
elected automatically by MySQL.
"""
@classmethod
def setUpClass(cls):
"""Run class setup for running mysql-innodb-cluster tests."""
super().setUpClass()
cls.application = "mysql-innodb-cluster"
def test_100_cluster_status(self):
"""Checking cluster status.
Run the cluster-status action.
"""
# Update which node is the leader and which are not
_leaders, _non_leaders = self.get_leaders_and_non_leaders()
logging.info("Execute cluster-status action")
action = zaza.model.run_action(
_non_leaders[0],
"cluster-status",
action_params={})
cluster_status = json.loads(action.data["results"]["cluster-status"])
assert "OK" in cluster_status["defaultReplicaSet"]["status"], (
"Cluster status action failed.")
logging.info("Passed cluster-status action test.")