Merge pull request #107 from thedac/mysql8-actions
MySQL 8 specific tests
This commit is contained in:
@@ -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.")
|
||||
|
||||
Reference in New Issue
Block a user