Improve rebuild test
Change-Id: I8addc9eb5a6109116ff0d088c0b69d6865856970
This commit is contained in:
parent
23ac0ee82b
commit
4922ec75db
@ -13,8 +13,10 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from urllib import parse as urlparse
|
||||
|
||||
from oslo_serialization import jsonutils as json
|
||||
from six.moves.urllib import parse as urlparse
|
||||
import tenacity
|
||||
|
||||
from tempest.lib.common import rest_client
|
||||
from tempest.lib import exceptions
|
||||
@ -50,6 +52,12 @@ class TroveClient(rest_client.RestClient):
|
||||
|
||||
return rest_client.ResponseBody(resp, json.loads(body))
|
||||
|
||||
@tenacity.retry(
|
||||
wait=tenacity.wait_fixed(5),
|
||||
stop=tenacity.stop_after_attempt(2),
|
||||
retry=tenacity.retry_if_exception_type(),
|
||||
reraise=True
|
||||
)
|
||||
def delete_resource(self, obj, id, ignore_notfound=False):
|
||||
try:
|
||||
resp, _ = self.delete('/{obj}/{id}'.format(obj=obj, id=id))
|
||||
|
@ -521,3 +521,49 @@ class BaseTroveTest(test.BaseTestCase):
|
||||
def get_root_pass(cls, instance_id):
|
||||
resp = cls.client.create_resource(f"instances/{instance_id}/root", {})
|
||||
return resp['user']['password']
|
||||
|
||||
@classmethod
|
||||
def rebuild_instance(cls, instance_id, image_id):
|
||||
rebuild_req = {
|
||||
"rebuild": {
|
||||
"image_id": image_id
|
||||
}
|
||||
}
|
||||
cls.admin_client.create_resource(
|
||||
f"mgmt/instances/{instance_id}/action",
|
||||
rebuild_req, expected_status_code=202,
|
||||
need_response=False)
|
||||
cls.wait_for_instance_status(instance_id)
|
||||
|
||||
@classmethod
|
||||
def create_config(cls, name, values, datastore, datastore_version):
|
||||
create_config = {
|
||||
"configuration": {
|
||||
"datastore": {
|
||||
"type": datastore,
|
||||
"version": datastore_version
|
||||
},
|
||||
"values": values,
|
||||
"name": name
|
||||
}
|
||||
}
|
||||
config = cls.client.create_resource('configurations', create_config)
|
||||
return config
|
||||
|
||||
@classmethod
|
||||
def attach_config(cls, instance_id, config_id):
|
||||
attach_config = {
|
||||
"instance": {
|
||||
"configuration": config_id
|
||||
}
|
||||
}
|
||||
cls.client.put_resource(f'instances/{instance_id}', attach_config)
|
||||
|
||||
@classmethod
|
||||
def detach_config(cls, instance_id):
|
||||
detach_config = {
|
||||
"instance": {
|
||||
"configuration": None
|
||||
}
|
||||
}
|
||||
cls.client.put_resource(f'instances/{instance_id}', detach_config)
|
||||
|
@ -40,6 +40,9 @@ class TestInstanceActionsBase(trove_base.BaseTroveTest):
|
||||
def get_db_version(self):
|
||||
pass
|
||||
|
||||
def get_config_value(self, ip, option, **kwargs):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(TestInstanceActionsBase, cls).resource_setup()
|
||||
@ -143,22 +146,43 @@ class TestInstanceActionsBase(trove_base.BaseTroveTest):
|
||||
ret = self.client.get_resource('instances', self.instance_id)
|
||||
self.assertEqual(2, ret['instance']['volume']['size'])
|
||||
|
||||
def rebuild_test(self):
|
||||
def rebuild_test(self, config_values, config_need_restart=False):
|
||||
LOG.info(f"Inserting data on {self.instance_ip} before rebuilding")
|
||||
self.insert_data_before_rebuild(self.instance_ip)
|
||||
|
||||
# Create configuration before rebuild
|
||||
config_name = self.get_resource_name('config')
|
||||
LOG.info(f"Creating new configuration {config_name} for rebuild")
|
||||
config = self.create_config(
|
||||
config_name, config_values, self.datastore,
|
||||
self.instance['datastore']['version'])
|
||||
config_id = config['configuration']['id']
|
||||
self.addCleanup(self.client.delete_resource, 'configurations',
|
||||
config_id, ignore_notfound=True)
|
||||
# Attach the configuration
|
||||
LOG.info(f"Attaching config {config_id} to instance "
|
||||
f"{self.instance_id}")
|
||||
self.attach_config(self.instance_id, config_id)
|
||||
self.addCleanup(self.detach_config, self.instance_id)
|
||||
if config_need_restart:
|
||||
LOG.info(f"Restarting instance {self.instance_id}")
|
||||
self.restart_instance(self.instance_id)
|
||||
# Verify the config before rebuild
|
||||
key = list(config_values.keys())[0]
|
||||
value = list(config_values.values())[0]
|
||||
LOG.info(f"Getting config value for {key} on {self.instance_ip}")
|
||||
cur_value = self.get_config_value(self.instance_ip, key)
|
||||
self.assertEqual(value, cur_value)
|
||||
|
||||
LOG.info(f"Rebuilding instance {self.instance_id} with image "
|
||||
f"{CONF.database.rebuild_image_id}")
|
||||
rebuild_req = {
|
||||
"rebuild": {
|
||||
"image_id": CONF.database.rebuild_image_id
|
||||
}
|
||||
}
|
||||
self.admin_client.create_resource(
|
||||
f"mgmt/instances/{self.instance_id}/action",
|
||||
rebuild_req, expected_status_code=202,
|
||||
need_response=False)
|
||||
self.wait_for_instance_status(self.instance_id)
|
||||
self.rebuild_instance(self.instance_id, CONF.database.rebuild_image_id)
|
||||
|
||||
LOG.info(f"Verifying data on {self.instance_ip} after rebuilding")
|
||||
self.verify_data_after_rebuild(self.instance_ip)
|
||||
|
||||
# Verify configuration before rebuild
|
||||
LOG.info(f"Verifying config {key} on {self.instance_ip} after "
|
||||
f"rebuilding")
|
||||
cur_value = self.get_config_value(self.instance_ip, key)
|
||||
self.assertEqual(value, cur_value)
|
||||
|
@ -36,21 +36,14 @@ class TestInstanceBasicBase(trove_base.BaseTroveTest):
|
||||
value should be in type int.
|
||||
"""
|
||||
# Create new configuration
|
||||
config_name = 'test_config'
|
||||
config_name = self.get_resource_name('config')
|
||||
key = list(create_values.keys())[0]
|
||||
value = list(create_values.values())[0]
|
||||
create_config = {
|
||||
"configuration": {
|
||||
"datastore": {
|
||||
"type": self.datastore,
|
||||
"version": self.instance['datastore']['version']
|
||||
},
|
||||
"values": create_values,
|
||||
"name": config_name
|
||||
}
|
||||
}
|
||||
|
||||
LOG.info(f"Creating new configuration {config_name}")
|
||||
config = self.client.create_resource('configurations', create_config)
|
||||
config = self.create_config(
|
||||
config_name, create_values, self.datastore,
|
||||
self.instance['datastore']['version'])
|
||||
config_id = config['configuration']['id']
|
||||
self.addCleanup(self.client.delete_resource, 'configurations',
|
||||
config_id, ignore_notfound=True)
|
||||
@ -61,15 +54,9 @@ class TestInstanceBasicBase(trove_base.BaseTroveTest):
|
||||
self.assertEqual(0, len(ret['instances']))
|
||||
|
||||
# Attach the configuration to the existing instance
|
||||
attach_config = {
|
||||
"instance": {
|
||||
"configuration": config_id
|
||||
}
|
||||
}
|
||||
LOG.info(f"Attaching config {config_id} to instance "
|
||||
f"{self.instance_id}")
|
||||
self.client.put_resource(f'instances/{self.instance_id}',
|
||||
attach_config)
|
||||
self.attach_config(self.instance_id, config_id)
|
||||
|
||||
if need_restart:
|
||||
LOG.info(f"Restarting instance {self.instance_id}")
|
||||
@ -107,13 +94,7 @@ class TestInstanceBasicBase(trove_base.BaseTroveTest):
|
||||
|
||||
# Detach the configuration from the instance
|
||||
LOG.info(f"Detaching from instance {self.instance_id}")
|
||||
detach_config = {
|
||||
"instance": {
|
||||
"configuration": None
|
||||
}
|
||||
}
|
||||
self.client.put_resource(f'instances/{self.instance_id}',
|
||||
detach_config)
|
||||
self.detach_config(self.instance_id)
|
||||
|
||||
if need_restart:
|
||||
LOG.info(f"Restarting instance {self.instance_id}")
|
||||
|
@ -209,3 +209,15 @@ class TestReplicationBase(trove_base.BaseTroveTest):
|
||||
ret = self.client.get_resource('instances', self.instance_id)
|
||||
self.assertIsNone(ret['instance'].get('replicas'))
|
||||
self.assertIsNone(ret['instance'].get('replica_of'))
|
||||
|
||||
# Rebuild test for replication cluster, now replica1 is the primary
|
||||
if CONF.database.rebuild_image_id:
|
||||
LOG.info(f"Rebuilding primary {replica1_id}")
|
||||
self.rebuild_instance(replica1_id, CONF.database.rebuild_image_id)
|
||||
LOG.info(f"Verifying data after rebuild {replica1_id}")
|
||||
self.verify_data_after_promote(replica1_ip)
|
||||
|
||||
LOG.info(f"Rebuilding replica {replica2_id}")
|
||||
self.rebuild_instance(replica2_id, CONF.database.rebuild_image_id)
|
||||
LOG.info(f"Verifying data after rebuild {replica2_id}")
|
||||
self.verify_data_after_promote(replica2_ip)
|
||||
|
@ -98,6 +98,16 @@ class InstanceActionsMySQLBase(base_actions.TestInstanceActionsBase):
|
||||
ret = db_client.mysql_execute(cmd)
|
||||
return ret.first()[0]
|
||||
|
||||
def get_config_value(self, ip, option, username=constants.DB_USER,
|
||||
password=constants.DB_PASS):
|
||||
db_url = f'mysql+pymysql://{username}:{password}@{ip}:3306'
|
||||
with utils.SQLClient(db_url) as db_client:
|
||||
cmd = f"show variables where Variable_name in ('{option}');"
|
||||
ret = db_client.mysql_execute(cmd)
|
||||
rows = ret.fetchall()
|
||||
self.assertEqual(1, len(rows))
|
||||
return int(rows[0][1])
|
||||
|
||||
|
||||
class TestInstanceActionsMySQL(InstanceActionsMySQLBase):
|
||||
datastore = 'mysql'
|
||||
@ -117,7 +127,8 @@ class TestInstanceActionsMySQL(InstanceActionsMySQLBase):
|
||||
@testtools.skipUnless(CONF.database.rebuild_image_id,
|
||||
'Image for rebuild not configured.')
|
||||
def test_rebuild(self):
|
||||
self.rebuild_test()
|
||||
config_values = {"max_connections": 555}
|
||||
self.rebuild_test(config_values)
|
||||
|
||||
|
||||
class TestInstanceActionsMariaDB(InstanceActionsMySQLBase):
|
||||
@ -138,7 +149,8 @@ class TestInstanceActionsMariaDB(InstanceActionsMySQLBase):
|
||||
@testtools.skipUnless(CONF.database.rebuild_image_id,
|
||||
'Image for rebuild not configured.')
|
||||
def test_rebuild(self):
|
||||
self.rebuild_test()
|
||||
config_values = {"max_connections": 555}
|
||||
self.rebuild_test(config_values)
|
||||
|
||||
|
||||
class TestInstanceActionsPostgreSQL(base_actions.TestInstanceActionsBase):
|
||||
@ -223,6 +235,17 @@ class TestInstanceActionsPostgreSQL(base_actions.TestInstanceActionsBase):
|
||||
|
||||
return version.split(' ')[0]
|
||||
|
||||
def get_config_value(self, ip, option):
|
||||
db_url = (f'postgresql+psycopg2://root:{self.password}@'
|
||||
f'{ip}:5432/postgres')
|
||||
with utils.SQLClient(db_url) as db_client:
|
||||
cmd = f"SELECT setting FROM pg_settings WHERE name='{option}';"
|
||||
ret = db_client.pgsql_execute(cmd)
|
||||
rows = ret.fetchall()
|
||||
|
||||
self.assertEqual(1, len(rows))
|
||||
return int(rows[0][0])
|
||||
|
||||
@decorators.idempotent_id("97f1e7ca-f415-11ea-a950-00224d6b7bc1")
|
||||
@testtools.skipUnless(
|
||||
'postgresql' in CONF.database.pre_upgrade_datastore_versions,
|
||||
@ -238,4 +261,5 @@ class TestInstanceActionsPostgreSQL(base_actions.TestInstanceActionsBase):
|
||||
@testtools.skipUnless(CONF.database.rebuild_image_id,
|
||||
'Image for rebuild not configured.')
|
||||
def test_rebuild(self):
|
||||
self.rebuild_test()
|
||||
config_values = {"max_connections": 101}
|
||||
self.rebuild_test(config_values, config_need_restart=True)
|
||||
|
Loading…
x
Reference in New Issue
Block a user