Fix inconsistent usage of mount_point
Reasons: - multiple datastores; - inconsistent usage of mount_point at taskmanager and guestagent; Changes: - oslo groups; - mount point per datastore; - guest API not changed. Change-Id: I8044789c6ab2ed837ff0e1b16183dfeafbf955bb Closes-Bug: #1248212
This commit is contained in:
parent
89f517f736
commit
ea51b7e625
@ -69,3 +69,4 @@ backup_aes_cbc_key = "default_aes_cbc_key"
|
||||
backup_use_snet = False
|
||||
backup_chunk_size = 65536
|
||||
backup_segment_max_size = 2147483648
|
||||
|
||||
|
@ -59,7 +59,6 @@ network_label_regex = ^private$
|
||||
trove_volume_support = True
|
||||
block_device_mapping = vdb
|
||||
device_path = /dev/vdb
|
||||
mount_point = /var/lib/mysql
|
||||
# Maximum volume size for an instance
|
||||
max_accepted_volume_size = 10
|
||||
max_instances_per_user = 5
|
||||
|
@ -84,7 +84,6 @@ trove_volume_support = True
|
||||
nova_volume_service_type = volume
|
||||
nova_volume_service_name = Volume Service
|
||||
device_path = /dev/vdb
|
||||
mount_point = /var/lib/mysql
|
||||
max_accepted_volume_size = 25
|
||||
max_instances_per_user = 55
|
||||
max_volumes_per_user = 100
|
||||
@ -180,4 +179,3 @@ paste.app_factory = trove.common.api:app_factory
|
||||
#Add this filter to log request and response for debugging
|
||||
[filter:debug]
|
||||
paste.filter_factory = trove.common.wsgi:Debug
|
||||
|
||||
|
@ -116,7 +116,6 @@ common_opts = [
|
||||
cfg.BoolOpt('use_nova_server_volume', default=False),
|
||||
cfg.BoolOpt('use_heat', default=False),
|
||||
cfg.StrOpt('device_path', default='/dev/vdb'),
|
||||
cfg.StrOpt('mount_point', default='/var/lib/mysql'),
|
||||
cfg.StrOpt('default_datastore', default=None,
|
||||
help="The default datastore id or name to use if one is not "
|
||||
"provided by the user. If the default value is None, the field "
|
||||
@ -276,7 +275,10 @@ mysql_opts = [
|
||||
' in the security group (only applicable '
|
||||
'if trove_security_groups_support is True)'),
|
||||
cfg.StrOpt('backup_strategy', default='InnoBackupEx',
|
||||
help='Default strategy to perform backups.')
|
||||
help='Default strategy to perform backups.'),
|
||||
cfg.StrOpt('mount_point', default='/var/lib/mysql',
|
||||
help="Filesystem path for mounting "
|
||||
"volumes if volume support is enabled"),
|
||||
]
|
||||
|
||||
# Percona
|
||||
@ -293,7 +295,10 @@ percona_opts = [
|
||||
' in the security group (only applicable '
|
||||
'if trove_security_groups_support is True)'),
|
||||
cfg.StrOpt('backup_strategy', default='InnoBackupEx',
|
||||
help='Default strategy to perform backups.')
|
||||
help='Default strategy to perform backups.'),
|
||||
cfg.StrOpt('mount_point', default='/var/lib/mysql',
|
||||
help="Filesystem path for mounting "
|
||||
"volumes if volume support is enabled"),
|
||||
]
|
||||
|
||||
# Redis
|
||||
@ -309,6 +314,11 @@ redis_opts = [
|
||||
help='List of UDP ports and/or port ranges to open'
|
||||
' in the security group (only applicable '
|
||||
'if trove_security_groups_support is True)'),
|
||||
cfg.StrOpt('backup_strategy', default=None,
|
||||
help='Default strategy to perform backups.'),
|
||||
cfg.StrOpt('mount_point', default='/var/lib/redis',
|
||||
help="Filesystem path for mounting "
|
||||
"volumes if volume support is enabled"),
|
||||
]
|
||||
|
||||
# Cassandra
|
||||
@ -326,6 +336,9 @@ cassandra_opts = [
|
||||
'if trove_security_groups_support is True)'),
|
||||
cfg.StrOpt('backup_strategy', default=None,
|
||||
help='Default strategy to perform backups.'),
|
||||
cfg.StrOpt('mount_point', default='/var/lib/cassandra',
|
||||
help="Filesystem path for mounting "
|
||||
"volumes if volume support is enabled"),
|
||||
]
|
||||
|
||||
#Couchbase
|
||||
@ -345,6 +358,9 @@ couchbase_opts = [
|
||||
'if trove_security_groups_support is True)'),
|
||||
cfg.StrOpt('backup_strategy', default=None,
|
||||
help='Default strategy to perform backups.'),
|
||||
cfg.StrOpt('mount_point', default='/var/lib/couchbase',
|
||||
help="Filesystem path for mounting "
|
||||
"volumes if volume support is enabled"),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
@ -268,7 +268,7 @@ class API(proxy.RpcProxy):
|
||||
LOG.debug(_("Check Volume Info on Instance %s"), self.id)
|
||||
# self._check_for_hearbeat()
|
||||
return self._call("get_filesystem_stats", AGENT_LOW_TIMEOUT,
|
||||
fs_path=CONF.mount_point)
|
||||
fs_path=None)
|
||||
|
||||
def update_guest(self):
|
||||
"""Make a synchronous call to update the guest agent."""
|
||||
|
@ -86,7 +86,9 @@ class BackupAgent(object):
|
||||
})
|
||||
|
||||
# Store the size of the filesystem before the backup.
|
||||
stats = get_filesystem_volume_stats(CONF.mount_point)
|
||||
mount_point = CONF.get('mysql' if not CONF.datastore_manager
|
||||
else CONF.datastore_manager).mount_point
|
||||
stats = get_filesystem_volume_stats(mount_point)
|
||||
backup = {
|
||||
'backup_id': backup_id,
|
||||
'size': stats.get('used', 0.0),
|
||||
|
@ -19,7 +19,6 @@ from trove.common import cfg
|
||||
from trove.common import exception
|
||||
from trove.guestagent import volume
|
||||
from trove.guestagent.datastore.cassandra import service
|
||||
from trove.guestagent.datastore.cassandra import system
|
||||
from trove.openstack.common import periodic_task
|
||||
from trove.openstack.common import log as logging
|
||||
from trove.openstack.common.gettextutils import _
|
||||
@ -30,6 +29,7 @@ LOG = logging.getLogger(__name__)
|
||||
USAGE_SLEEP_TIME = CONF.usage_sleep_time # seconds.
|
||||
USAGE_TIMEOUT = CONF.usage_timeout # seconds.
|
||||
ERROR_MSG = _("Not supported")
|
||||
MANAGER = CONF.datastore_manager
|
||||
|
||||
|
||||
class Manager(periodic_task.PeriodicTasks):
|
||||
@ -48,8 +48,9 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
|
||||
def get_filesystem_stats(self, context, fs_path):
|
||||
"""Gets the filesystem stats for the path given. """
|
||||
return dbaas.get_filesystem_volume_stats(
|
||||
system.CASSANDRA_MOUNT_POINT)
|
||||
mount_point = CONF.get(
|
||||
'mysql' if not MANAGER else MANAGER).mount_point
|
||||
return dbaas.get_filesystem_volume_stats(mount_point)
|
||||
|
||||
def start_db_with_conf_changes(self, context, config_contents):
|
||||
self.app.start_db_with_conf_changes(config_contents)
|
||||
@ -67,7 +68,7 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
self.appStatus.begin_install()
|
||||
LOG.info("Installing cassandra")
|
||||
self.app.install_if_needed(packages)
|
||||
self.app.init_storage_structure()
|
||||
self.app.init_storage_structure(mount_point)
|
||||
if config_contents:
|
||||
LOG.info(_("Config processing"))
|
||||
self.app.write_config(config_contents)
|
||||
@ -75,11 +76,11 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
if device_path:
|
||||
device = volume.VolumeDevice(device_path)
|
||||
device.format()
|
||||
if os.path.exists(system.CASSANDRA_MOUNT_POINT):
|
||||
if os.path.exists(mount_point):
|
||||
#rsync exiting data
|
||||
device.migrate_data(system.CASSANDRA_MOUNT_POINT)
|
||||
device.migrate_data(mount_point)
|
||||
#mount the volume
|
||||
device.mount(system.CASSANDRA_MOUNT_POINT)
|
||||
device.mount(mount_point)
|
||||
LOG.debug(_("Mounting new volume."))
|
||||
self.app.restart()
|
||||
|
||||
|
@ -58,8 +58,13 @@ class CassandraApp(object):
|
||||
utils.execute_with_timeout(system.DISABLE_CASSANDRA_ON_BOOT,
|
||||
shell=True)
|
||||
|
||||
def init_storage_structure(self):
|
||||
utils.execute_with_timeout(system.INIT_FS, shell=True)
|
||||
def init_storage_structure(self, mount_point):
|
||||
try:
|
||||
cmd = system.INIT_FS % mount_point
|
||||
utils.execute_with_timeout(cmd, shell=True)
|
||||
except exception.ProcessExecutionError as e:
|
||||
LOG.error(_("Error while initiating storage structure."))
|
||||
LOG.error(e)
|
||||
|
||||
def start_db(self, update_db=False):
|
||||
self._enable_db_on_boot()
|
||||
|
@ -20,13 +20,11 @@ LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
|
||||
CASSANDRA_DATA_DIR = "/var/lib/cassandra/data"
|
||||
CASSANDRA_MOUNT_POINT = "/var/lib/cassandra"
|
||||
CASSANDRA_CONF = "/etc/cassandra/cassandra.yaml"
|
||||
CASSANDRA_TEMP_CONF = "/tmp/cassandra.yaml"
|
||||
CASSANDRA_TEMP_DIR = "/tmp/cassandra"
|
||||
|
||||
INIT_FS = "sudo mkdir -p %s" % CASSANDRA_MOUNT_POINT
|
||||
|
||||
INIT_FS = "sudo mkdir -p %s"
|
||||
ENABLE_CASSANDRA_ON_BOOT = "sudo update-rc.d cassandra enable"
|
||||
DISABLE_CASSANDRA_ON_BOOT = "sudo update-rc.d cassandra disable"
|
||||
|
||||
|
@ -17,7 +17,6 @@ from trove.common import cfg
|
||||
from trove.common import exception
|
||||
from trove.guestagent import dbaas
|
||||
from trove.guestagent import volume
|
||||
from trove.guestagent.datastore.couchbase import system
|
||||
from trove.guestagent.datastore.couchbase import service
|
||||
from trove.openstack.common import log as logging
|
||||
from trove.openstack.common import periodic_task
|
||||
@ -27,6 +26,7 @@ from trove.openstack.common.gettextutils import _
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
ERROR_MSG = _("Not supported")
|
||||
MANAGER = CONF.datastore_manager
|
||||
|
||||
|
||||
class Manager(periodic_task.PeriodicTasks):
|
||||
@ -64,7 +64,7 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
if device_path:
|
||||
device = volume.VolumeDevice(device_path)
|
||||
device.format()
|
||||
device.mount(system.COUCHBASE_MOUNT_POINT)
|
||||
device.mount(mount_point)
|
||||
LOG.debug(_('Mounted the volume.'))
|
||||
self.app.install_if_needed(packages)
|
||||
LOG.info(_('Securing couchbase now.'))
|
||||
@ -91,10 +91,10 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
self.app.stop_db(do_not_start_on_reboot=do_not_start_on_reboot)
|
||||
|
||||
def get_filesystem_stats(self, context, fs_path):
|
||||
"""
|
||||
Gets file system stats from the provided fs_path.
|
||||
"""
|
||||
return dbaas.get_filesystem_volume_stats(system.COUCHBASE_MOUNT_POINT)
|
||||
"""Gets the filesystem stats for the path given. """
|
||||
mount_point = CONF.get(
|
||||
'mysql' if not MANAGER else MANAGER).mount_point
|
||||
return dbaas.get_filesystem_volume_stats(mount_point)
|
||||
|
||||
def update_attributes(self, context, username, hostname, user_attrs):
|
||||
raise exception.TroveError(ERROR_MSG)
|
||||
|
@ -58,12 +58,13 @@ class CouchbaseApp(object):
|
||||
|
||||
def initial_setup(self):
|
||||
self.ip_address = operating_system.get_ip_address()
|
||||
mount_point = CONF.get('couchbase').mount_point
|
||||
try:
|
||||
LOG.info(_('Couchbase Server change data dir path'))
|
||||
utils.execute_with_timeout(system.cmd_own_data_dir, shell=True)
|
||||
utils.execute_with_timeout(
|
||||
(system.cmd_node_init
|
||||
% {'data_path': system.COUCHBASE_MOUNT_POINT,
|
||||
% {'data_path': mount_point,
|
||||
'IP': self.ip_address}), shell=True)
|
||||
utils.execute_with_timeout(
|
||||
system.cmd_rm_old_data_dir, shell=True)
|
||||
|
@ -12,10 +12,11 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from trove.common import cfg
|
||||
CONF = cfg.CONF
|
||||
|
||||
TIME_OUT = 1200
|
||||
COUCHBASE_CONF_DIR = '/etc/couchbase'
|
||||
COUCHBASE_MOUNT_POINT = '/var/lib/couchbase'
|
||||
SERVICE_CANDIDATES = ["couchbase-server"]
|
||||
cmd_couchbase_status = ('sudo /opt/couchbase/bin/couchbase-cli server-info '
|
||||
'-c %(IP)s:8091 -u Administrator -p password')
|
||||
@ -28,7 +29,7 @@ cmd_cluster_init = ('sudo /opt/couchbase/bin/couchbase-cli cluster-init '
|
||||
'--cluster-init-port=8091')
|
||||
cmd_kill = 'sudo pkill -9 couchbase-server'
|
||||
cmd_own_data_dir = ('sudo chown couchbase:couchbase %s' %
|
||||
COUCHBASE_MOUNT_POINT)
|
||||
CONF.get('couchbase').mount_point)
|
||||
cmd_rm_old_data_dir = 'sudo rm -rf /opt/couchbase/var/lib/couchbase/data'
|
||||
""" For optimal couchbase operations, swappiness of vm should be set to 0.
|
||||
Reference link: http://docs.couchbase.com/couchbase-manual-2
|
||||
|
@ -32,6 +32,7 @@ from trove.openstack.common import periodic_task
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
MANAGER = CONF.datastore_manager
|
||||
|
||||
|
||||
class Manager(periodic_task.PeriodicTasks):
|
||||
@ -116,16 +117,16 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
app.stop_db()
|
||||
device = volume.VolumeDevice(device_path)
|
||||
device.format()
|
||||
if os.path.exists(CONF.mount_point):
|
||||
if os.path.exists(mount_point):
|
||||
#rsync exiting data
|
||||
device.migrate_data(CONF.mount_point)
|
||||
device.migrate_data(mount_point)
|
||||
#mount the volume
|
||||
device.mount(mount_point)
|
||||
LOG.debug(_("Mounted the volume."))
|
||||
app.start_mysql()
|
||||
if backup_info:
|
||||
self._perform_restore(backup_info, context,
|
||||
CONF.mount_point, app)
|
||||
mount_point, app)
|
||||
LOG.info(_("Securing mysql now."))
|
||||
app.secure(config_contents, overrides)
|
||||
enable_root_on_restore = (backup_info and
|
||||
@ -161,8 +162,10 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
app.stop_db(do_not_start_on_reboot=do_not_start_on_reboot)
|
||||
|
||||
def get_filesystem_stats(self, context, fs_path):
|
||||
"""Gets the filesystem stats for the path given """
|
||||
return dbaas.get_filesystem_volume_stats(fs_path)
|
||||
"""Gets the filesystem stats for the path given. """
|
||||
mount_point = CONF.get(
|
||||
'mysql' if not MANAGER else MANAGER).mount_point
|
||||
return dbaas.get_filesystem_volume_stats(mount_point)
|
||||
|
||||
def create_backup(self, context, backup_info):
|
||||
"""
|
||||
|
@ -18,7 +18,6 @@ from trove.guestagent import dbaas
|
||||
from trove.guestagent import volume
|
||||
from trove.guestagent.datastore.redis.service import RedisAppStatus
|
||||
from trove.guestagent.datastore.redis.service import RedisApp
|
||||
from trove.guestagent.datastore.redis import system
|
||||
from trove.openstack.common import log as logging
|
||||
from trove.openstack.common.gettextutils import _
|
||||
from trove.openstack.common import periodic_task
|
||||
@ -26,6 +25,7 @@ from trove.openstack.common import periodic_task
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
MANAGER = CONF.datastore_manager
|
||||
|
||||
|
||||
class Manager(periodic_task.PeriodicTasks):
|
||||
@ -77,7 +77,7 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
if device_path:
|
||||
device = volume.VolumeDevice(device_path)
|
||||
device.format()
|
||||
device.mount(system.REDIS_BASE_DIR)
|
||||
device.mount(mount_point)
|
||||
LOG.debug(_('Mounted the volume.'))
|
||||
app.install_if_needed(packages)
|
||||
LOG.info(_('Securing redis now.'))
|
||||
@ -111,10 +111,10 @@ class Manager(periodic_task.PeriodicTasks):
|
||||
app.stop_db(do_not_start_on_reboot=do_not_start_on_reboot)
|
||||
|
||||
def get_filesystem_stats(self, context, fs_path):
|
||||
"""
|
||||
Gets file system stats from the provided fs_path.
|
||||
"""
|
||||
return dbaas.get_filesystem_volume_stats(fs_path)
|
||||
"""Gets the filesystem stats for the path given. """
|
||||
mount_point = CONF.get(
|
||||
'mysql' if not MANAGER else MANAGER).mount_point
|
||||
return dbaas.get_filesystem_volume_stats(mount_point)
|
||||
|
||||
def create_backup(self, context, backup_info):
|
||||
"""
|
||||
|
@ -29,7 +29,6 @@ REDIS_CMD_DISABLE = 'update-rc.d redis-server disable'
|
||||
REDIS_CMD_START = 'service redis-server start || /bin/true'
|
||||
REDIS_CMD_STOP = 'service redis-server stop || /bin/true'
|
||||
REDIS_PACKAGE = 'redis-server'
|
||||
REDIS_BASE_DIR = '/var/lib/redis'
|
||||
|
||||
if OS is 'redhat':
|
||||
REDIS_BIN = '/usr/libexec/redis-server'
|
||||
|
@ -369,7 +369,7 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
self._log_and_raise(e, msg, err)
|
||||
|
||||
device_path = CONF.device_path
|
||||
mount_point = CONF.mount_point
|
||||
mount_point = CONF.get(datastore_manager).mount_point
|
||||
volume_info = {'device_path': device_path, 'mount_point': mount_point}
|
||||
LOG.debug(_("end _create_server_volume for id: %s") % self.id)
|
||||
return volume_info
|
||||
@ -441,7 +441,7 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
self._log_and_raise(e, msg, err)
|
||||
|
||||
device_path = CONF.device_path
|
||||
mount_point = CONF.mount_point
|
||||
mount_point = CONF.get(datastore_manager).mount_point
|
||||
volume_info = {'device_path': device_path, 'mount_point': mount_point}
|
||||
|
||||
LOG.debug(_("end _create_server_volume_heat for id: %s") % self.id)
|
||||
@ -454,7 +454,8 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
LOG.debug(_("begin _create_server_volume_individually for id: %s") %
|
||||
self.id)
|
||||
server = None
|
||||
volume_info = self._build_volume_info(volume_size)
|
||||
volume_info = self._build_volume_info(datastore_manager,
|
||||
volume_size=volume_size)
|
||||
block_device_mapping = volume_info['block_device']
|
||||
try:
|
||||
server = self._create_server(flavor_id, image_id, security_groups,
|
||||
@ -472,24 +473,26 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
self.id)
|
||||
return volume_info
|
||||
|
||||
def _build_volume_info(self, volume_size=None):
|
||||
def _build_volume_info(self, datastore_manager, volume_size=None):
|
||||
volume_info = None
|
||||
volume_support = CONF.trove_volume_support
|
||||
LOG.debug(_("trove volume support = %s") % volume_support)
|
||||
if volume_support:
|
||||
try:
|
||||
volume_info = self._create_volume(volume_size)
|
||||
volume_info = self._create_volume(
|
||||
volume_size, datastore_manager)
|
||||
except Exception as e:
|
||||
msg = _("Error provisioning volume for instance: %s") % self.id
|
||||
err = inst_models.InstanceTasks.BUILDING_ERROR_VOLUME
|
||||
self._log_and_raise(e, msg, err)
|
||||
else:
|
||||
LOG.debug(_("device_path = %s") % CONF.device_path)
|
||||
LOG.debug(_("mount_point = %s") % CONF.mount_point)
|
||||
LOG.debug(_("mount_point = %s") %
|
||||
CONF.get(datastore_manager).mount_point)
|
||||
volume_info = {
|
||||
'block_device': None,
|
||||
'device_path': CONF.device_path,
|
||||
'mount_point': CONF.mount_point,
|
||||
'mount_point': CONF.get(datastore_manager).mount_point,
|
||||
'volumes': None,
|
||||
}
|
||||
return volume_info
|
||||
@ -501,7 +504,7 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
self.update_db(task_status=task_status)
|
||||
raise TroveError(message=message)
|
||||
|
||||
def _create_volume(self, volume_size):
|
||||
def _create_volume(self, volume_size, datastore_manager):
|
||||
LOG.info("Entering create_volume")
|
||||
LOG.debug(_("begin _create_volume for id: %s") % self.id)
|
||||
volume_client = create_cinder_client(self.context)
|
||||
@ -522,9 +525,9 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
if v_ref.status in ['error']:
|
||||
raise VolumeCreationFailure()
|
||||
LOG.debug(_("end _create_volume for id: %s") % self.id)
|
||||
return self._build_volume(v_ref)
|
||||
return self._build_volume(v_ref, datastore_manager)
|
||||
|
||||
def _build_volume(self, v_ref):
|
||||
def _build_volume(self, v_ref, datastore_manager):
|
||||
LOG.debug(_("Created volume %s") % v_ref)
|
||||
# The mapping is in the format:
|
||||
# <id>:[<type>]:[<size(GB)>]:[<delete_on_terminate>]
|
||||
@ -538,7 +541,7 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
LOG.debug("volume = %s" % created_volumes)
|
||||
|
||||
device_path = CONF.device_path
|
||||
mount_point = CONF.mount_point
|
||||
mount_point = CONF.get(datastore_manager).mount_point
|
||||
LOG.debug(_("device_path = %s") % device_path)
|
||||
LOG.debug(_("mount_point = %s") % mount_point)
|
||||
|
||||
@ -979,6 +982,11 @@ class ResizeVolumeAction(ConfigurationMixin):
|
||||
self.old_size = int(old_size)
|
||||
self.new_size = int(new_size)
|
||||
|
||||
def get_mount_point(self):
|
||||
mount_point = CONF.get(
|
||||
self.instance.datastore_version.manager).mount_point
|
||||
return mount_point
|
||||
|
||||
def _fail(self, orig_func):
|
||||
LOG.exception(_("%(func)s encountered an error when attempting to "
|
||||
"resize the volume for instance %(id)s. Setting service "
|
||||
@ -1023,8 +1031,9 @@ class ResizeVolumeAction(ConfigurationMixin):
|
||||
def _unmount_volume(self):
|
||||
LOG.debug(_("Unmounting the volume on instance %(id)s") % {
|
||||
'id': self.instance.id})
|
||||
mount_point = self.get_mount_point()
|
||||
self.instance.guest.unmount_volume(device_path=CONF.device_path,
|
||||
mount_point=CONF.mount_point)
|
||||
mount_point=mount_point)
|
||||
LOG.debug(_("Successfully unmounted the volume %(vol_id)s for "
|
||||
"instance %(id)s") % {'vol_id': self.instance.volume_id,
|
||||
'id': self.instance.id})
|
||||
@ -1073,8 +1082,9 @@ class ResizeVolumeAction(ConfigurationMixin):
|
||||
def _resize_fs(self):
|
||||
LOG.debug(_("Resizing the filesystem for instance %(id)s") % {
|
||||
'id': self.instance.id})
|
||||
mount_point = self.get_mount_point()
|
||||
self.instance.guest.resize_fs(device_path=CONF.device_path,
|
||||
mount_point=CONF.mount_point)
|
||||
mount_point=mount_point)
|
||||
LOG.debug(_("Successfully resized volume %(vol_id)s filesystem for "
|
||||
"instance %(id)s") % {'vol_id': self.instance.volume_id,
|
||||
'id': self.instance.id})
|
||||
@ -1083,8 +1093,9 @@ class ResizeVolumeAction(ConfigurationMixin):
|
||||
def _mount_volume(self):
|
||||
LOG.debug(_("Mount the volume on instance %(id)s") % {
|
||||
'id': self.instance.id})
|
||||
mount_point = self.get_mount_point()
|
||||
self.instance.guest.mount_volume(device_path=CONF.device_path,
|
||||
mount_point=CONF.mount_point)
|
||||
mount_point=mount_point)
|
||||
LOG.debug(_("Successfully mounted the volume %(vol_id)s on instance "
|
||||
"%(id)s") % {'vol_id': self.instance.volume_id,
|
||||
'id': self.instance.id})
|
||||
|
140
trove/tests/unittests/guestagent/test_cassandra_manager.py
Normal file
140
trove/tests/unittests/guestagent/test_cassandra_manager.py
Normal file
@ -0,0 +1,140 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
import testtools
|
||||
from mock import Mock
|
||||
from mockito import verify, when, unstub, any, mock
|
||||
from trove.common.context import TroveContext
|
||||
from trove.common.instance import ServiceStatuses
|
||||
from trove.guestagent import volume
|
||||
from trove.guestagent.common import operating_system
|
||||
from trove.guestagent.datastore.cassandra import service as cass_service
|
||||
from trove.guestagent.datastore.cassandra import manager as cass_manager
|
||||
from trove.guestagent import pkg
|
||||
|
||||
|
||||
class GuestAgentCassandraDBManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(GuestAgentCassandraDBManagerTest, self).setUp()
|
||||
self.real_status = cass_service.CassandraAppStatus.set_status
|
||||
|
||||
class FakeInstanceServiceStatus(object):
|
||||
status = ServiceStatuses.NEW
|
||||
|
||||
def save(self):
|
||||
pass
|
||||
|
||||
cass_service.CassandraAppStatus.set_status = Mock(
|
||||
return_value=FakeInstanceServiceStatus())
|
||||
self.context = TroveContext()
|
||||
self.manager = cass_manager.Manager()
|
||||
self.pkg = cass_service.packager
|
||||
self.real_db_app_status = cass_service.CassandraAppStatus
|
||||
self.origin_os_path_exists = os.path.exists
|
||||
self.origin_format = volume.VolumeDevice.format
|
||||
self.origin_migrate_data = volume.VolumeDevice.migrate_data
|
||||
self.origin_mount = volume.VolumeDevice.mount
|
||||
self.origin_stop_db = cass_service.CassandraApp.stop_db
|
||||
self.origin_start_db = cass_service.CassandraApp.start_db
|
||||
self.origin_install_db = cass_service.CassandraApp._install_db
|
||||
self.original_get_ip = operating_system.get_ip_address
|
||||
self.orig_make_host_reachable = (
|
||||
cass_service.CassandraApp.make_host_reachable)
|
||||
|
||||
def tearDown(self):
|
||||
super(GuestAgentCassandraDBManagerTest, self).tearDown()
|
||||
cass_service.packager = self.pkg
|
||||
cass_service.CassandraAppStatus.set_status = self.real_db_app_status
|
||||
os.path.exists = self.origin_os_path_exists
|
||||
volume.VolumeDevice.format = self.origin_format
|
||||
volume.VolumeDevice.migrate_data = self.origin_migrate_data
|
||||
volume.VolumeDevice.mount = self.origin_mount
|
||||
cass_service.CassandraApp.stop_db = self.origin_stop_db
|
||||
cass_service.CassandraApp.start_db = self.origin_start_db
|
||||
cass_service.CassandraApp._install_db = self.origin_install_db
|
||||
operating_system.get_ip_address = self.original_get_ip
|
||||
cass_service.CassandraApp.make_host_reachable = (
|
||||
self.orig_make_host_reachable)
|
||||
unstub()
|
||||
|
||||
def test_update_status(self):
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
self.manager.update_status(self.context)
|
||||
verify(mock_status).update()
|
||||
|
||||
def test_prepare_pkg(self):
|
||||
self._prepare_dynamic(['cassandra'])
|
||||
|
||||
def test_prepare_no_pkg(self):
|
||||
self._prepare_dynamic([])
|
||||
|
||||
def test_prepare_db_not_installed(self):
|
||||
self._prepare_dynamic([], is_db_installed=False)
|
||||
|
||||
def test_prepare_db_not_installed_no_package(self):
|
||||
self._prepare_dynamic([],
|
||||
is_db_installed=True)
|
||||
|
||||
def _prepare_dynamic(self, packages,
|
||||
config_content=any(), device_path='/dev/vdb',
|
||||
is_db_installed=True, backup_id=None,
|
||||
is_root_enabled=False,
|
||||
overrides=None):
|
||||
# covering all outcomes is starting to cause trouble here
|
||||
if not backup_id:
|
||||
backup_info = {'id': backup_id,
|
||||
'location': 'fake-location',
|
||||
'type': 'InnoBackupEx',
|
||||
'checksum': 'fake-checksum',
|
||||
}
|
||||
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
when(mock_status).begin_install().thenReturn(None)
|
||||
|
||||
mock_app = mock()
|
||||
self.manager.app = mock_app
|
||||
|
||||
when(mock_app).install_if_needed(packages).thenReturn(None)
|
||||
(when(pkg.Package).pkg_is_installed(any()).
|
||||
thenReturn(is_db_installed))
|
||||
when(mock_app).init_storage_structure(any()).thenReturn(None)
|
||||
when(mock_app).write_config(config_content).thenReturn(None)
|
||||
when(mock_app).make_host_reachable().thenReturn(None)
|
||||
when(mock_app).restart().thenReturn(None)
|
||||
when(os.path).exists(any()).thenReturn(True)
|
||||
|
||||
when(volume.VolumeDevice).format().thenReturn(None)
|
||||
when(volume.VolumeDevice).migrate_data(any()).thenReturn(None)
|
||||
when(volume.VolumeDevice).mount().thenReturn(None)
|
||||
|
||||
# invocation
|
||||
self.manager.prepare(context=self.context, packages=packages,
|
||||
config_contents=config_content,
|
||||
databases=None,
|
||||
memory_mb='2048', users=None,
|
||||
device_path=device_path,
|
||||
mount_point="/var/lib/cassandra",
|
||||
backup_info=backup_info,
|
||||
overrides=None)
|
||||
# verification/assertion
|
||||
verify(mock_status).begin_install()
|
||||
verify(mock_app).install_if_needed(packages)
|
||||
verify(mock_app).init_storage_structure(any())
|
||||
verify(mock_app).make_host_reachable()
|
||||
verify(mock_app).restart()
|
95
trove/tests/unittests/guestagent/test_couchbase_manager.py
Normal file
95
trove/tests/unittests/guestagent/test_couchbase_manager.py
Normal file
@ -0,0 +1,95 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import testtools
|
||||
from mock import Mock
|
||||
from mockito import verify, when, unstub, any, mock
|
||||
from trove.common.context import TroveContext
|
||||
from trove.guestagent import volume
|
||||
from trove.guestagent.common import operating_system
|
||||
from trove.guestagent.datastore.couchbase import service as couch_service
|
||||
from trove.guestagent.datastore.couchbase import manager as couch_manager
|
||||
|
||||
|
||||
class GuestAgentCouchbaseManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(GuestAgentCouchbaseManagerTest, self).setUp()
|
||||
self.context = TroveContext()
|
||||
self.manager = couch_manager.Manager()
|
||||
self.packages = 'couchbase-server'
|
||||
self.origin_CouchbaseAppStatus = couch_service.CouchbaseAppStatus
|
||||
self.origin_format = volume.VolumeDevice.format
|
||||
self.origin_mount = volume.VolumeDevice.mount
|
||||
self.origin_stop_db = couch_service.CouchbaseApp.stop_db
|
||||
self.origin_start_db = couch_service.CouchbaseApp.start_db
|
||||
operating_system.get_ip_address = Mock()
|
||||
|
||||
def tearDown(self):
|
||||
super(GuestAgentCouchbaseManagerTest, self).tearDown()
|
||||
couch_service.CouchbaseAppStatus = self.origin_CouchbaseAppStatus
|
||||
volume.VolumeDevice.format = self.origin_format
|
||||
volume.VolumeDevice.mount = self.origin_mount
|
||||
couch_service.CouchbaseApp.stop_db = self.origin_stop_db
|
||||
couch_service.CouchbaseApp.start_db = self.origin_start_db
|
||||
unstub()
|
||||
|
||||
def test_update_status(self):
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
self.manager.update_status(self.context)
|
||||
verify(mock_status).update()
|
||||
|
||||
def test_prepare_device_path_true(self):
|
||||
self._prepare_dynamic()
|
||||
|
||||
def _prepare_dynamic(self, device_path='/dev/vdb', is_db_installed=True,
|
||||
backup_info=None):
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
when(mock_status).begin_install().thenReturn(None)
|
||||
when(volume.VolumeDevice).format().thenReturn(None)
|
||||
when(volume.VolumeDevice).mount().thenReturn(None)
|
||||
when(couch_service.CouchbaseApp).install_if_needed().thenReturn(None)
|
||||
when(couch_service.CouchbaseApp).complete_install_or_restart(
|
||||
any()).thenReturn(None)
|
||||
#invocation
|
||||
self.manager.prepare(self.context, self.packages, None, 2048,
|
||||
None, device_path=device_path,
|
||||
mount_point='/var/lib/couchbase',
|
||||
backup_info=backup_info)
|
||||
#verification/assertion
|
||||
verify(mock_status).begin_install()
|
||||
verify(couch_service.CouchbaseApp).install_if_needed(self.packages)
|
||||
verify(couch_service.CouchbaseApp).complete_install_or_restart()
|
||||
|
||||
def test_restart(self):
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
when(couch_service.CouchbaseApp).restart().thenReturn(None)
|
||||
#invocation
|
||||
self.manager.restart(self.context)
|
||||
#verification/assertion
|
||||
verify(couch_service.CouchbaseApp).restart()
|
||||
|
||||
def test_stop_db(self):
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
when(couch_service.CouchbaseApp).stop_db(
|
||||
do_not_start_on_reboot=False).thenReturn(None)
|
||||
#invocation
|
||||
self.manager.stop_db(self.context)
|
||||
#verification/assertion
|
||||
verify(couch_service.CouchbaseApp).stop_db(
|
||||
do_not_start_on_reboot=False)
|
@ -25,7 +25,6 @@ from mockito import verify
|
||||
from mockito import contains
|
||||
from mockito import never
|
||||
from mockito import matchers
|
||||
from mockito import inorder, verifyNoMoreInteractions
|
||||
import sqlalchemy
|
||||
import testtools
|
||||
from testtools.matchers import Is
|
||||
@ -792,25 +791,6 @@ class MySqlAppMockTest(testtools.TestCase):
|
||||
super(MySqlAppMockTest, self).tearDown()
|
||||
unstub()
|
||||
|
||||
def test_secure_with_mycnf_error(self):
|
||||
mock_conn = mock_sql_connection()
|
||||
when(mock_conn).execute(any()).thenReturn(None)
|
||||
when(utils).execute_with_timeout("sudo", any(str), "stop").thenReturn(
|
||||
None)
|
||||
# skip writing the file for now
|
||||
when(os.path).isfile(any()).thenReturn(False)
|
||||
mock_status = mock()
|
||||
when(mock_status).wait_for_real_status_to_change_to(
|
||||
any(), any(), any()).thenReturn(True)
|
||||
app = MySqlApp(mock_status)
|
||||
when(dbaas).clear_expired_password().thenReturn(None)
|
||||
self.assertRaises(TypeError, app.secure, None, None)
|
||||
|
||||
verify(mock_conn, atleast=2).execute(any())
|
||||
inorder.verify(mock_status).wait_for_real_status_to_change_to(
|
||||
rd_instance.ServiceStatuses.SHUTDOWN, any(), any())
|
||||
verifyNoMoreInteractions(mock_status)
|
||||
|
||||
def test_secure_keep_root(self):
|
||||
mock_conn = mock_sql_connection()
|
||||
|
||||
|
@ -1,497 +0,0 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
import testtools
|
||||
from mock import Mock
|
||||
from mockito import verify, when, unstub, any, mock, never
|
||||
from testtools.matchers import Is, Equals, Not
|
||||
from trove.common.context import TroveContext
|
||||
from trove.common.instance import ServiceStatuses
|
||||
from trove.guestagent import volume
|
||||
from trove.guestagent.common import operating_system
|
||||
from trove.guestagent.datastore.cassandra import service as cass_service
|
||||
from trove.guestagent.datastore.cassandra import manager as cass_manager
|
||||
from trove.guestagent.datastore.mysql.manager import Manager
|
||||
import trove.guestagent.datastore.mysql.service as dbaas
|
||||
from trove.guestagent.datastore.couchbase import service as couch_service
|
||||
from trove.guestagent.datastore.couchbase import manager as couch_manager
|
||||
from trove.guestagent.datastore.redis.manager import Manager as RedisManager
|
||||
import trove.guestagent.datastore.redis.service as redis_service
|
||||
import trove.guestagent.datastore.redis.system as redis_system
|
||||
from trove.guestagent import backup
|
||||
from trove.guestagent.volume import VolumeDevice
|
||||
from trove.guestagent import pkg
|
||||
|
||||
|
||||
class GuestAgentManagerTest(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(GuestAgentManagerTest, self).setUp()
|
||||
self.context = TroveContext()
|
||||
self.manager = Manager()
|
||||
self.origin_MySqlAppStatus = dbaas.MySqlAppStatus
|
||||
self.origin_os_path_exists = os.path.exists
|
||||
self.origin_format = volume.VolumeDevice.format
|
||||
self.origin_migrate_data = volume.VolumeDevice.migrate_data
|
||||
self.origin_mount = volume.VolumeDevice.mount
|
||||
self.origin_stop_mysql = dbaas.MySqlApp.stop_db
|
||||
self.origin_start_mysql = dbaas.MySqlApp.start_mysql
|
||||
self.origin_pkg_is_installed = pkg.Package.pkg_is_installed
|
||||
self.origin_os_path_exists = os.path.exists
|
||||
|
||||
def tearDown(self):
|
||||
super(GuestAgentManagerTest, self).tearDown()
|
||||
dbaas.MySqlAppStatus = self.origin_MySqlAppStatus
|
||||
os.path.exists = self.origin_os_path_exists
|
||||
volume.VolumeDevice.format = self.origin_format
|
||||
volume.VolumeDevice.migrate_data = self.origin_migrate_data
|
||||
volume.VolumeDevice.mount = self.origin_mount
|
||||
dbaas.MySqlApp.stop_db = self.origin_stop_mysql
|
||||
dbaas.MySqlApp.start_mysql = self.origin_start_mysql
|
||||
pkg.Package.pkg_is_installed = self.origin_pkg_is_installed
|
||||
os.path.exists = self.origin_os_path_exists
|
||||
unstub()
|
||||
|
||||
def test_update_status(self):
|
||||
mock_status = mock()
|
||||
when(dbaas.MySqlAppStatus).get().thenReturn(mock_status)
|
||||
self.manager.update_status(self.context)
|
||||
verify(dbaas.MySqlAppStatus).get()
|
||||
verify(mock_status).update()
|
||||
|
||||
def test_create_database(self):
|
||||
when(dbaas.MySqlAdmin).create_database(['db1']).thenReturn(None)
|
||||
self.manager.create_database(self.context, ['db1'])
|
||||
verify(dbaas.MySqlAdmin).create_database(['db1'])
|
||||
|
||||
def test_create_user(self):
|
||||
when(dbaas.MySqlAdmin).create_user(['user1']).thenReturn(None)
|
||||
self.manager.create_user(self.context, ['user1'])
|
||||
verify(dbaas.MySqlAdmin).create_user(['user1'])
|
||||
|
||||
def test_delete_database(self):
|
||||
databases = ['db1']
|
||||
when(dbaas.MySqlAdmin).delete_database(databases).thenReturn(None)
|
||||
self.manager.delete_database(self.context, databases)
|
||||
verify(dbaas.MySqlAdmin).delete_database(databases)
|
||||
|
||||
def test_delete_user(self):
|
||||
user = ['user1']
|
||||
when(dbaas.MySqlAdmin).delete_user(user).thenReturn(None)
|
||||
self.manager.delete_user(self.context, user)
|
||||
verify(dbaas.MySqlAdmin).delete_user(user)
|
||||
|
||||
def test_grant_access(self):
|
||||
username = "test_user"
|
||||
hostname = "test_host"
|
||||
databases = ["test_database"]
|
||||
when(dbaas.MySqlAdmin).grant_access(username,
|
||||
hostname,
|
||||
databases).thenReturn(None)
|
||||
|
||||
self.manager.grant_access(self.context,
|
||||
username,
|
||||
hostname,
|
||||
databases)
|
||||
|
||||
verify(dbaas.MySqlAdmin).grant_access(username, hostname, databases)
|
||||
|
||||
def test_list_databases(self):
|
||||
when(dbaas.MySqlAdmin).list_databases(None, None,
|
||||
False).thenReturn(['database1'])
|
||||
databases = self.manager.list_databases(self.context)
|
||||
self.assertThat(databases, Not(Is(None)))
|
||||
self.assertThat(databases, Equals(['database1']))
|
||||
verify(dbaas.MySqlAdmin).list_databases(None, None, False)
|
||||
|
||||
def test_list_users(self):
|
||||
when(dbaas.MySqlAdmin).list_users(None, None,
|
||||
False).thenReturn(['user1'])
|
||||
users = self.manager.list_users(self.context)
|
||||
self.assertThat(users, Equals(['user1']))
|
||||
verify(dbaas.MySqlAdmin).list_users(None, None, False)
|
||||
|
||||
def test_get_users(self):
|
||||
username = ['user1']
|
||||
hostname = ['host']
|
||||
when(dbaas.MySqlAdmin).get_user(username,
|
||||
hostname).thenReturn(['user1'])
|
||||
users = self.manager.get_user(self.context, username, hostname)
|
||||
self.assertThat(users, Equals(['user1']))
|
||||
verify(dbaas.MySqlAdmin).get_user(username, hostname)
|
||||
|
||||
def test_enable_root(self):
|
||||
when(dbaas.MySqlAdmin).enable_root().thenReturn('user_id_stuff')
|
||||
user_id = self.manager.enable_root(self.context)
|
||||
self.assertThat(user_id, Is('user_id_stuff'))
|
||||
verify(dbaas.MySqlAdmin).enable_root()
|
||||
|
||||
def test_is_root_enabled(self):
|
||||
when(dbaas.MySqlAdmin).is_root_enabled().thenReturn(True)
|
||||
is_enabled = self.manager.is_root_enabled(self.context)
|
||||
self.assertThat(is_enabled, Is(True))
|
||||
verify(dbaas.MySqlAdmin).is_root_enabled()
|
||||
|
||||
def test_create_backup(self):
|
||||
when(backup).backup(self.context, 'backup_id_123').thenReturn(None)
|
||||
# entry point
|
||||
Manager().create_backup(self.context, 'backup_id_123')
|
||||
# assertions
|
||||
verify(backup).backup(self.context, 'backup_id_123')
|
||||
|
||||
def test_prepare_device_path_true(self):
|
||||
self._prepare_dynamic()
|
||||
|
||||
def test_prepare_device_path_false(self):
|
||||
self._prepare_dynamic(device_path=None)
|
||||
|
||||
def test_prepare_mysql_not_installed(self):
|
||||
self._prepare_dynamic(is_mysql_installed=False)
|
||||
|
||||
def test_prepare_mysql_from_backup(self):
|
||||
self._prepare_dynamic(backup_id='backup_id_123abc')
|
||||
|
||||
def test_prepare_mysql_from_backup_with_root(self):
|
||||
self._prepare_dynamic(backup_id='backup_id_123abc',
|
||||
is_root_enabled=True)
|
||||
|
||||
def _prepare_dynamic(self, device_path='/dev/vdb', is_mysql_installed=True,
|
||||
backup_id=None, is_root_enabled=False,
|
||||
overrides=None):
|
||||
# covering all outcomes is starting to cause trouble here
|
||||
COUNT = 1 if device_path else 0
|
||||
backup_info = None
|
||||
if backup_id is not None:
|
||||
backup_info = {'id': backup_id,
|
||||
'location': 'fake-location',
|
||||
'type': 'InnoBackupEx',
|
||||
'checksum': 'fake-checksum',
|
||||
}
|
||||
|
||||
# TODO(juice): this should stub an instance of the MySqlAppStatus
|
||||
mock_status = mock()
|
||||
when(dbaas.MySqlAppStatus).get().thenReturn(mock_status)
|
||||
when(mock_status).begin_install().thenReturn(None)
|
||||
when(VolumeDevice).format().thenReturn(None)
|
||||
when(VolumeDevice).migrate_data(any()).thenReturn(None)
|
||||
when(VolumeDevice).mount().thenReturn(None)
|
||||
when(dbaas.MySqlApp).stop_db().thenReturn(None)
|
||||
when(dbaas.MySqlApp).start_mysql().thenReturn(None)
|
||||
when(dbaas.MySqlApp).install_if_needed(any()).thenReturn(None)
|
||||
when(backup).restore(self.context,
|
||||
backup_info,
|
||||
'/var/lib/mysql').thenReturn(None)
|
||||
when(dbaas.MySqlApp).secure(any()).thenReturn(None)
|
||||
when(dbaas.MySqlApp).secure_root(any()).thenReturn(None)
|
||||
(when(pkg.Package).pkg_is_installed(any()).
|
||||
thenReturn(is_mysql_installed))
|
||||
when(dbaas.MySqlAdmin).is_root_enabled().thenReturn(is_root_enabled)
|
||||
when(dbaas.MySqlAdmin).create_user().thenReturn(None)
|
||||
when(dbaas.MySqlAdmin).create_database().thenReturn(None)
|
||||
|
||||
when(os.path).exists(any()).thenReturn(True)
|
||||
# invocation
|
||||
self.manager.prepare(context=self.context,
|
||||
packages=None,
|
||||
memory_mb='2048',
|
||||
databases=None,
|
||||
users=None,
|
||||
device_path=device_path,
|
||||
mount_point='/var/lib/mysql',
|
||||
backup_info=backup_info,
|
||||
overrides=overrides)
|
||||
# verification/assertion
|
||||
verify(mock_status).begin_install()
|
||||
|
||||
verify(VolumeDevice, times=COUNT).format()
|
||||
verify(dbaas.MySqlApp, times=COUNT).stop_db()
|
||||
verify(VolumeDevice, times=COUNT).migrate_data(
|
||||
any())
|
||||
if backup_info:
|
||||
verify(backup).restore(self.context, backup_info, '/var/lib/mysql')
|
||||
verify(dbaas.MySqlApp).install_if_needed(any())
|
||||
# We dont need to make sure the exact contents are there
|
||||
verify(dbaas.MySqlApp).secure(any(), overrides)
|
||||
verify(dbaas.MySqlAdmin, never).create_database()
|
||||
verify(dbaas.MySqlAdmin, never).create_user()
|
||||
verify(dbaas.MySqlApp).secure_root(secure_remote_root=any())
|
||||
|
||||
|
||||
class RedisGuestAgentManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(RedisGuestAgentManagerTest, self).setUp()
|
||||
self.context = TroveContext()
|
||||
self.manager = RedisManager()
|
||||
self.packages = 'redis-server'
|
||||
self.origin_RedisAppStatus = redis_service.RedisAppStatus
|
||||
self.origin_stop_redis = redis_service.RedisApp.stop_db
|
||||
self.origin_start_redis = redis_service.RedisApp.start_redis
|
||||
self.origin_install_redis = redis_service.RedisApp._install_redis
|
||||
|
||||
def tearDown(self):
|
||||
super(RedisGuestAgentManagerTest, self).tearDown()
|
||||
redis_service.RedisAppStatus = self.origin_RedisAppStatus
|
||||
redis_service.RedisApp.stop_db = self.origin_stop_redis
|
||||
redis_service.RedisApp.start_redis = self.origin_start_redis
|
||||
redis_service.RedisApp._install_redis = self.origin_install_redis
|
||||
unstub()
|
||||
|
||||
def test_update_status(self):
|
||||
mock_status = mock()
|
||||
when(redis_service.RedisAppStatus).get().thenReturn(mock_status)
|
||||
self.manager.update_status(self.context)
|
||||
verify(redis_service.RedisAppStatus).get()
|
||||
verify(mock_status).update()
|
||||
|
||||
def test_prepare_device_path_true(self):
|
||||
self._prepare_dynamic()
|
||||
|
||||
def test_prepare_device_path_false(self):
|
||||
self._prepare_dynamic(device_path=None)
|
||||
|
||||
def test_prepare_redis_not_installed(self):
|
||||
self._prepare_dynamic(is_redis_installed=False)
|
||||
|
||||
def _prepare_dynamic(self, device_path='/dev/vdb', is_redis_installed=True,
|
||||
backup_info=None, is_root_enabled=False):
|
||||
|
||||
# covering all outcomes is starting to cause trouble here
|
||||
dev_path = 1 if device_path else 0
|
||||
mock_status = mock()
|
||||
when(redis_service.RedisAppStatus).get().thenReturn(mock_status)
|
||||
when(mock_status).begin_install().thenReturn(None)
|
||||
when(VolumeDevice).format().thenReturn(None)
|
||||
when(VolumeDevice).mount().thenReturn(None)
|
||||
when(redis_service.RedisApp).start_redis().thenReturn(None)
|
||||
when(redis_service.RedisApp).install_if_needed().thenReturn(None)
|
||||
when(backup).restore(self.context, backup_info).thenReturn(None)
|
||||
when(redis_service.RedisApp).write_config(any()).thenReturn(None)
|
||||
when(redis_service.RedisApp).complete_install_or_restart(
|
||||
any()).thenReturn(None)
|
||||
self.manager.prepare(self.context, self.packages,
|
||||
None, '2048',
|
||||
None, device_path=device_path,
|
||||
mount_point='/var/lib/redis',
|
||||
backup_info=backup_info)
|
||||
verify(redis_service.RedisAppStatus, times=2).get()
|
||||
verify(mock_status).begin_install()
|
||||
verify(VolumeDevice, times=dev_path).mount(redis_system.REDIS_BASE_DIR)
|
||||
verify(redis_service.RedisApp).install_if_needed(self.packages)
|
||||
verify(redis_service.RedisApp).write_config(None)
|
||||
verify(redis_service.RedisApp).complete_install_or_restart()
|
||||
|
||||
def test_restart(self):
|
||||
mock_status = mock()
|
||||
when(redis_service.RedisAppStatus).get().thenReturn(mock_status)
|
||||
when(redis_service.RedisApp).restart().thenReturn(None)
|
||||
self.manager.restart(self.context)
|
||||
verify(redis_service.RedisAppStatus).get()
|
||||
verify(redis_service.RedisApp).restart()
|
||||
|
||||
def test_stop_db(self):
|
||||
mock_status = mock()
|
||||
when(redis_service.RedisAppStatus).get().thenReturn(mock_status)
|
||||
when(redis_service.RedisApp).stop_db(do_not_start_on_reboot=
|
||||
False).thenReturn(None)
|
||||
self.manager.stop_db(self.context)
|
||||
verify(redis_service.RedisAppStatus).get()
|
||||
verify(redis_service.RedisApp).stop_db(do_not_start_on_reboot=False)
|
||||
|
||||
|
||||
class GuestAgentCassandraDBManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(GuestAgentCassandraDBManagerTest, self).setUp()
|
||||
self.real_status = cass_service.CassandraAppStatus.set_status
|
||||
|
||||
class FakeInstanceServiceStatus(object):
|
||||
status = ServiceStatuses.NEW
|
||||
|
||||
def save(self):
|
||||
pass
|
||||
|
||||
cass_service.CassandraAppStatus.set_status = Mock(
|
||||
return_value=FakeInstanceServiceStatus())
|
||||
self.context = TroveContext()
|
||||
self.manager = cass_manager.Manager()
|
||||
self.pkg = cass_service.packager
|
||||
self.real_db_app_status = cass_service.CassandraAppStatus
|
||||
self.origin_os_path_exists = os.path.exists
|
||||
self.origin_format = volume.VolumeDevice.format
|
||||
self.origin_migrate_data = volume.VolumeDevice.migrate_data
|
||||
self.origin_mount = volume.VolumeDevice.mount
|
||||
self.origin_stop_db = cass_service.CassandraApp.stop_db
|
||||
self.origin_start_db = cass_service.CassandraApp.start_db
|
||||
self.origin_install_db = cass_service.CassandraApp._install_db
|
||||
self.original_get_ip = operating_system.get_ip_address
|
||||
self.orig_make_host_reachable = (
|
||||
cass_service.CassandraApp.make_host_reachable)
|
||||
|
||||
def tearDown(self):
|
||||
super(GuestAgentCassandraDBManagerTest, self).tearDown()
|
||||
cass_service.packager = self.pkg
|
||||
cass_service.CassandraAppStatus.set_status = self.real_db_app_status
|
||||
os.path.exists = self.origin_os_path_exists
|
||||
volume.VolumeDevice.format = self.origin_format
|
||||
volume.VolumeDevice.migrate_data = self.origin_migrate_data
|
||||
volume.VolumeDevice.mount = self.origin_mount
|
||||
cass_service.CassandraApp.stop_db = self.origin_stop_db
|
||||
cass_service.CassandraApp.start_db = self.origin_start_db
|
||||
cass_service.CassandraApp._install_db = self.origin_install_db
|
||||
operating_system.get_ip_address = self.original_get_ip
|
||||
cass_service.CassandraApp.make_host_reachable = (
|
||||
self.orig_make_host_reachable)
|
||||
|
||||
def test_update_status(self):
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
self.manager.update_status(self.context)
|
||||
verify(mock_status).update()
|
||||
|
||||
def test_prepare_pkg(self):
|
||||
self._prepare_dynamic(['cassandra'])
|
||||
|
||||
def test_prepare_no_pkg(self):
|
||||
self._prepare_dynamic([])
|
||||
|
||||
def test_prepare_db_not_installed(self):
|
||||
self._prepare_dynamic([], is_db_installed=False)
|
||||
|
||||
def test_prepare_db_not_installed_no_package(self):
|
||||
self._prepare_dynamic([],
|
||||
is_db_installed=True)
|
||||
|
||||
def _prepare_dynamic(self, packages,
|
||||
config_content=any(), device_path='/dev/vdb',
|
||||
is_db_installed=True, backup_id=None,
|
||||
is_root_enabled=False,
|
||||
overrides=None):
|
||||
# covering all outcomes is starting to cause trouble here
|
||||
if not backup_id:
|
||||
backup_info = {'id': backup_id,
|
||||
'location': 'fake-location',
|
||||
'type': 'InnoBackupEx',
|
||||
'checksum': 'fake-checksum',
|
||||
}
|
||||
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
when(mock_status).begin_install().thenReturn(None)
|
||||
|
||||
mock_app = mock()
|
||||
self.manager.app = mock_app
|
||||
|
||||
when(mock_app).install_if_needed(packages).thenReturn(None)
|
||||
(when(pkg.Package).pkg_is_installed(any()).
|
||||
thenReturn(is_db_installed))
|
||||
when(mock_app).init_storage_structure().thenReturn(None)
|
||||
when(mock_app).write_config(config_content).thenReturn(None)
|
||||
when(mock_app).make_host_reachable().thenReturn(None)
|
||||
when(mock_app).restart().thenReturn(None)
|
||||
when(os.path).exists(any()).thenReturn(True)
|
||||
|
||||
when(volume.VolumeDevice).format().thenReturn(None)
|
||||
when(volume.VolumeDevice).migrate_data(any()).thenReturn(None)
|
||||
when(volume.VolumeDevice).mount().thenReturn(None)
|
||||
|
||||
# invocation
|
||||
self.manager.prepare(context=self.context, packages=packages,
|
||||
config_contents=config_content,
|
||||
databases=None,
|
||||
memory_mb='2048', users=None,
|
||||
device_path=device_path,
|
||||
mount_point="/var/lib/cassandra",
|
||||
backup_info=backup_info,
|
||||
overrides=None)
|
||||
# verification/assertion
|
||||
verify(mock_status).begin_install()
|
||||
verify(mock_app).install_if_needed(packages)
|
||||
verify(mock_app).init_storage_structure()
|
||||
verify(mock_app).make_host_reachable()
|
||||
verify(mock_app).restart()
|
||||
|
||||
|
||||
class GuestAgentCouchbaseManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(GuestAgentCouchbaseManagerTest, self).setUp()
|
||||
self.context = TroveContext()
|
||||
self.manager = couch_manager.Manager()
|
||||
self.packages = 'couchbase-server'
|
||||
self.origin_CouchbaseAppStatus = couch_service.CouchbaseAppStatus
|
||||
self.origin_format = volume.VolumeDevice.format
|
||||
self.origin_mount = volume.VolumeDevice.mount
|
||||
self.origin_stop_db = couch_service.CouchbaseApp.stop_db
|
||||
self.origin_start_db = couch_service.CouchbaseApp.start_db
|
||||
operating_system.get_ip_address = Mock()
|
||||
|
||||
def tearDown(self):
|
||||
super(GuestAgentCouchbaseManagerTest, self).tearDown()
|
||||
couch_service.CouchbaseAppStatus = self.origin_CouchbaseAppStatus
|
||||
volume.VolumeDevice.format = self.origin_format
|
||||
volume.VolumeDevice.mount = self.origin_mount
|
||||
couch_service.CouchbaseApp.stop_db = self.origin_stop_db
|
||||
couch_service.CouchbaseApp.start_db = self.origin_start_db
|
||||
unstub()
|
||||
|
||||
def test_update_status(self):
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
self.manager.update_status(self.context)
|
||||
verify(mock_status).update()
|
||||
|
||||
def test_prepare_device_path_true(self):
|
||||
self._prepare_dynamic()
|
||||
|
||||
def _prepare_dynamic(self, device_path='/dev/vdb', is_db_installed=True,
|
||||
backup_info=None):
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
when(mock_status).begin_install().thenReturn(None)
|
||||
when(volume.VolumeDevice).format().thenReturn(None)
|
||||
when(volume.VolumeDevice).mount().thenReturn(None)
|
||||
when(couch_service.CouchbaseApp).install_if_needed().thenReturn(None)
|
||||
when(couch_service.CouchbaseApp).complete_install_or_restart(
|
||||
any()).thenReturn(None)
|
||||
#invocation
|
||||
self.manager.prepare(self.context, self.packages, None, 2048,
|
||||
None, device_path=device_path,
|
||||
mount_point='/var/lib/couchbase',
|
||||
backup_info=backup_info)
|
||||
#verification/assertion
|
||||
verify(mock_status).begin_install()
|
||||
verify(couch_service.CouchbaseApp).install_if_needed(self.packages)
|
||||
verify(couch_service.CouchbaseApp).complete_install_or_restart()
|
||||
|
||||
def test_restart(self):
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
when(couch_service.CouchbaseApp).restart().thenReturn(None)
|
||||
#invocation
|
||||
self.manager.restart(self.context)
|
||||
#verification/assertion
|
||||
verify(couch_service.CouchbaseApp).restart()
|
||||
|
||||
def test_stop_db(self):
|
||||
mock_status = mock()
|
||||
self.manager.appStatus = mock_status
|
||||
when(couch_service.CouchbaseApp).stop_db(
|
||||
do_not_start_on_reboot=False).thenReturn(None)
|
||||
#invocation
|
||||
self.manager.stop_db(self.context)
|
||||
#verification/assertion
|
||||
verify(couch_service.CouchbaseApp).stop_db(
|
||||
do_not_start_on_reboot=False)
|
219
trove/tests/unittests/guestagent/test_mysql_manager.py
Normal file
219
trove/tests/unittests/guestagent/test_mysql_manager.py
Normal file
@ -0,0 +1,219 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
import testtools
|
||||
from mockito import verify, when, unstub, any, mock, never
|
||||
from testtools.matchers import Is, Equals, Not
|
||||
from trove.common.context import TroveContext
|
||||
from trove.guestagent import volume
|
||||
from trove.guestagent.datastore.mysql.manager import Manager
|
||||
import trove.guestagent.datastore.mysql.service as dbaas
|
||||
from trove.guestagent import backup
|
||||
from trove.guestagent.volume import VolumeDevice
|
||||
from trove.guestagent import pkg
|
||||
|
||||
|
||||
class GuestAgentManagerTest(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(GuestAgentManagerTest, self).setUp()
|
||||
self.context = TroveContext()
|
||||
self.manager = Manager()
|
||||
self.origin_MySqlAppStatus = dbaas.MySqlAppStatus
|
||||
self.origin_os_path_exists = os.path.exists
|
||||
self.origin_format = volume.VolumeDevice.format
|
||||
self.origin_migrate_data = volume.VolumeDevice.migrate_data
|
||||
self.origin_mount = volume.VolumeDevice.mount
|
||||
self.origin_stop_mysql = dbaas.MySqlApp.stop_db
|
||||
self.origin_start_mysql = dbaas.MySqlApp.start_mysql
|
||||
self.origin_pkg_is_installed = pkg.Package.pkg_is_installed
|
||||
self.origin_os_path_exists = os.path.exists
|
||||
|
||||
def tearDown(self):
|
||||
super(GuestAgentManagerTest, self).tearDown()
|
||||
dbaas.MySqlAppStatus = self.origin_MySqlAppStatus
|
||||
os.path.exists = self.origin_os_path_exists
|
||||
volume.VolumeDevice.format = self.origin_format
|
||||
volume.VolumeDevice.migrate_data = self.origin_migrate_data
|
||||
volume.VolumeDevice.mount = self.origin_mount
|
||||
dbaas.MySqlApp.stop_db = self.origin_stop_mysql
|
||||
dbaas.MySqlApp.start_mysql = self.origin_start_mysql
|
||||
pkg.Package.pkg_is_installed = self.origin_pkg_is_installed
|
||||
os.path.exists = self.origin_os_path_exists
|
||||
unstub()
|
||||
|
||||
def test_update_status(self):
|
||||
mock_status = mock()
|
||||
when(dbaas.MySqlAppStatus).get().thenReturn(mock_status)
|
||||
self.manager.update_status(self.context)
|
||||
verify(dbaas.MySqlAppStatus).get()
|
||||
verify(mock_status).update()
|
||||
|
||||
def test_create_database(self):
|
||||
when(dbaas.MySqlAdmin).create_database(['db1']).thenReturn(None)
|
||||
self.manager.create_database(self.context, ['db1'])
|
||||
verify(dbaas.MySqlAdmin).create_database(['db1'])
|
||||
|
||||
def test_create_user(self):
|
||||
when(dbaas.MySqlAdmin).create_user(['user1']).thenReturn(None)
|
||||
self.manager.create_user(self.context, ['user1'])
|
||||
verify(dbaas.MySqlAdmin).create_user(['user1'])
|
||||
|
||||
def test_delete_database(self):
|
||||
databases = ['db1']
|
||||
when(dbaas.MySqlAdmin).delete_database(databases).thenReturn(None)
|
||||
self.manager.delete_database(self.context, databases)
|
||||
verify(dbaas.MySqlAdmin).delete_database(databases)
|
||||
|
||||
def test_delete_user(self):
|
||||
user = ['user1']
|
||||
when(dbaas.MySqlAdmin).delete_user(user).thenReturn(None)
|
||||
self.manager.delete_user(self.context, user)
|
||||
verify(dbaas.MySqlAdmin).delete_user(user)
|
||||
|
||||
def test_grant_access(self):
|
||||
username = "test_user"
|
||||
hostname = "test_host"
|
||||
databases = ["test_database"]
|
||||
when(dbaas.MySqlAdmin).grant_access(username,
|
||||
hostname,
|
||||
databases).thenReturn(None)
|
||||
|
||||
self.manager.grant_access(self.context,
|
||||
username,
|
||||
hostname,
|
||||
databases)
|
||||
|
||||
verify(dbaas.MySqlAdmin).grant_access(username, hostname, databases)
|
||||
|
||||
def test_list_databases(self):
|
||||
when(dbaas.MySqlAdmin).list_databases(None, None,
|
||||
False).thenReturn(['database1'])
|
||||
databases = self.manager.list_databases(self.context)
|
||||
self.assertThat(databases, Not(Is(None)))
|
||||
self.assertThat(databases, Equals(['database1']))
|
||||
verify(dbaas.MySqlAdmin).list_databases(None, None, False)
|
||||
|
||||
def test_list_users(self):
|
||||
when(dbaas.MySqlAdmin).list_users(None, None,
|
||||
False).thenReturn(['user1'])
|
||||
users = self.manager.list_users(self.context)
|
||||
self.assertThat(users, Equals(['user1']))
|
||||
verify(dbaas.MySqlAdmin).list_users(None, None, False)
|
||||
|
||||
def test_get_users(self):
|
||||
username = ['user1']
|
||||
hostname = ['host']
|
||||
when(dbaas.MySqlAdmin).get_user(username,
|
||||
hostname).thenReturn(['user1'])
|
||||
users = self.manager.get_user(self.context, username, hostname)
|
||||
self.assertThat(users, Equals(['user1']))
|
||||
verify(dbaas.MySqlAdmin).get_user(username, hostname)
|
||||
|
||||
def test_enable_root(self):
|
||||
when(dbaas.MySqlAdmin).enable_root().thenReturn('user_id_stuff')
|
||||
user_id = self.manager.enable_root(self.context)
|
||||
self.assertThat(user_id, Is('user_id_stuff'))
|
||||
verify(dbaas.MySqlAdmin).enable_root()
|
||||
|
||||
def test_is_root_enabled(self):
|
||||
when(dbaas.MySqlAdmin).is_root_enabled().thenReturn(True)
|
||||
is_enabled = self.manager.is_root_enabled(self.context)
|
||||
self.assertThat(is_enabled, Is(True))
|
||||
verify(dbaas.MySqlAdmin).is_root_enabled()
|
||||
|
||||
def test_create_backup(self):
|
||||
when(backup).backup(self.context, 'backup_id_123').thenReturn(None)
|
||||
# entry point
|
||||
Manager().create_backup(self.context, 'backup_id_123')
|
||||
# assertions
|
||||
verify(backup).backup(self.context, 'backup_id_123')
|
||||
|
||||
def test_prepare_device_path_true(self):
|
||||
self._prepare_dynamic()
|
||||
|
||||
def test_prepare_device_path_false(self):
|
||||
self._prepare_dynamic(device_path=None)
|
||||
|
||||
def test_prepare_mysql_not_installed(self):
|
||||
self._prepare_dynamic(is_mysql_installed=False)
|
||||
|
||||
def test_prepare_mysql_from_backup(self):
|
||||
self._prepare_dynamic(backup_id='backup_id_123abc')
|
||||
|
||||
def test_prepare_mysql_from_backup_with_root(self):
|
||||
self._prepare_dynamic(backup_id='backup_id_123abc',
|
||||
is_root_enabled=True)
|
||||
|
||||
def _prepare_dynamic(self, device_path='/dev/vdb', is_mysql_installed=True,
|
||||
backup_id=None, is_root_enabled=False,
|
||||
overrides=None):
|
||||
# covering all outcomes is starting to cause trouble here
|
||||
COUNT = 1 if device_path else 0
|
||||
backup_info = None
|
||||
if backup_id is not None:
|
||||
backup_info = {'id': backup_id,
|
||||
'location': 'fake-location',
|
||||
'type': 'InnoBackupEx',
|
||||
'checksum': 'fake-checksum',
|
||||
}
|
||||
|
||||
# TODO(juice): this should stub an instance of the MySqlAppStatus
|
||||
mock_status = mock()
|
||||
when(dbaas.MySqlAppStatus).get().thenReturn(mock_status)
|
||||
when(mock_status).begin_install().thenReturn(None)
|
||||
when(VolumeDevice).format().thenReturn(None)
|
||||
when(VolumeDevice).migrate_data(any()).thenReturn(None)
|
||||
when(VolumeDevice).mount().thenReturn(None)
|
||||
when(dbaas.MySqlApp).stop_db().thenReturn(None)
|
||||
when(dbaas.MySqlApp).start_mysql().thenReturn(None)
|
||||
when(dbaas.MySqlApp).install_if_needed(any()).thenReturn(None)
|
||||
when(backup).restore(self.context,
|
||||
backup_info,
|
||||
'/var/lib/mysql').thenReturn(None)
|
||||
when(dbaas.MySqlApp).secure(any()).thenReturn(None)
|
||||
when(dbaas.MySqlApp).secure_root(any()).thenReturn(None)
|
||||
(when(pkg.Package).pkg_is_installed(any()).
|
||||
thenReturn(is_mysql_installed))
|
||||
when(dbaas.MySqlAdmin).is_root_enabled().thenReturn(is_root_enabled)
|
||||
when(dbaas.MySqlAdmin).create_user().thenReturn(None)
|
||||
when(dbaas.MySqlAdmin).create_database().thenReturn(None)
|
||||
|
||||
when(os.path).exists(any()).thenReturn(True)
|
||||
# invocation
|
||||
self.manager.prepare(context=self.context,
|
||||
packages=None,
|
||||
memory_mb='2048',
|
||||
databases=None,
|
||||
users=None,
|
||||
device_path=device_path,
|
||||
mount_point='/var/lib/mysql',
|
||||
backup_info=backup_info,
|
||||
overrides=overrides)
|
||||
# verification/assertion
|
||||
verify(mock_status).begin_install()
|
||||
|
||||
verify(VolumeDevice, times=COUNT).format()
|
||||
verify(dbaas.MySqlApp, times=COUNT).stop_db()
|
||||
verify(VolumeDevice, times=COUNT).migrate_data(
|
||||
any())
|
||||
if backup_info:
|
||||
verify(backup).restore(self.context, backup_info, '/var/lib/mysql')
|
||||
verify(dbaas.MySqlApp).install_if_needed(any())
|
||||
# We dont need to make sure the exact contents are there
|
||||
verify(dbaas.MySqlApp).secure(any(), overrides)
|
||||
verify(dbaas.MySqlAdmin, never).create_database()
|
||||
verify(dbaas.MySqlAdmin, never).create_user()
|
||||
verify(dbaas.MySqlApp).secure_root(secure_remote_root=any())
|
@ -447,11 +447,6 @@ class PkgRPMRemoveTestCase(testtools.TestCase):
|
||||
self.assertRaises(pkg.PkgNotFoundError, self.pkg.pkg_remove,
|
||||
self.pkgName, 5000)
|
||||
|
||||
def test_success_remove(self):
|
||||
# test
|
||||
pexpect.spawn.expect = Mock(return_value=2)
|
||||
self.assertTrue(self.pkg.pkg_remove(self.pkgName, 5000) is None)
|
||||
|
||||
def test_timeout_error(self):
|
||||
# test timeout error
|
||||
pexpect.spawn.expect = Mock(side_effect=pexpect.
|
||||
|
97
trove/tests/unittests/guestagent/test_redis_manager.py
Normal file
97
trove/tests/unittests/guestagent/test_redis_manager.py
Normal file
@ -0,0 +1,97 @@
|
||||
# Copyright 2012 OpenStack Foundation
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import testtools
|
||||
from mockito import verify, when, unstub, any, mock
|
||||
from trove.common.context import TroveContext
|
||||
from trove.guestagent.datastore.redis.manager import Manager as RedisManager
|
||||
import trove.guestagent.datastore.redis.service as redis_service
|
||||
from trove.guestagent import backup
|
||||
from trove.guestagent.volume import VolumeDevice
|
||||
|
||||
|
||||
class RedisGuestAgentManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(RedisGuestAgentManagerTest, self).setUp()
|
||||
self.context = TroveContext()
|
||||
self.manager = RedisManager()
|
||||
self.packages = 'redis-server'
|
||||
self.origin_RedisAppStatus = redis_service.RedisAppStatus
|
||||
self.origin_stop_redis = redis_service.RedisApp.stop_db
|
||||
self.origin_start_redis = redis_service.RedisApp.start_redis
|
||||
self.origin_install_redis = redis_service.RedisApp._install_redis
|
||||
|
||||
def tearDown(self):
|
||||
super(RedisGuestAgentManagerTest, self).tearDown()
|
||||
redis_service.RedisAppStatus = self.origin_RedisAppStatus
|
||||
redis_service.RedisApp.stop_db = self.origin_stop_redis
|
||||
redis_service.RedisApp.start_redis = self.origin_start_redis
|
||||
redis_service.RedisApp._install_redis = self.origin_install_redis
|
||||
unstub()
|
||||
|
||||
def test_update_status(self):
|
||||
mock_status = mock()
|
||||
when(redis_service.RedisAppStatus).get().thenReturn(mock_status)
|
||||
self.manager.update_status(self.context)
|
||||
verify(redis_service.RedisAppStatus).get()
|
||||
verify(mock_status).update()
|
||||
|
||||
def test_prepare_redis_not_installed(self):
|
||||
self._prepare_dynamic(is_redis_installed=False)
|
||||
|
||||
def _prepare_dynamic(self, device_path='/dev/vdb', is_redis_installed=True,
|
||||
backup_info=None, is_root_enabled=False,
|
||||
mount_point='var/lib/redis'):
|
||||
|
||||
# covering all outcomes is starting to cause trouble here
|
||||
mock_status = mock()
|
||||
when(redis_service.RedisAppStatus).get().thenReturn(mock_status)
|
||||
when(mock_status).begin_install().thenReturn(None)
|
||||
when(VolumeDevice).format().thenReturn(None)
|
||||
when(VolumeDevice).mount().thenReturn(None)
|
||||
when(redis_service.RedisApp).start_redis().thenReturn(None)
|
||||
when(redis_service.RedisApp).install_if_needed().thenReturn(None)
|
||||
when(backup).restore(self.context, backup_info).thenReturn(None)
|
||||
when(redis_service.RedisApp).write_config(any()).thenReturn(None)
|
||||
when(redis_service.RedisApp).complete_install_or_restart(
|
||||
any()).thenReturn(None)
|
||||
self.manager.prepare(self.context, self.packages,
|
||||
None, '2048',
|
||||
None, device_path=device_path,
|
||||
mount_point='/var/lib/redis',
|
||||
backup_info=backup_info)
|
||||
verify(redis_service.RedisAppStatus, times=2).get()
|
||||
verify(mock_status).begin_install()
|
||||
verify(VolumeDevice).format()
|
||||
verify(redis_service.RedisApp).install_if_needed(self.packages)
|
||||
verify(redis_service.RedisApp).write_config(None)
|
||||
verify(redis_service.RedisApp).complete_install_or_restart()
|
||||
|
||||
def test_restart(self):
|
||||
mock_status = mock()
|
||||
when(redis_service.RedisAppStatus).get().thenReturn(mock_status)
|
||||
when(redis_service.RedisApp).restart().thenReturn(None)
|
||||
self.manager.restart(self.context)
|
||||
verify(redis_service.RedisAppStatus).get()
|
||||
verify(redis_service.RedisApp).restart()
|
||||
|
||||
def test_stop_db(self):
|
||||
mock_status = mock()
|
||||
when(redis_service.RedisAppStatus).get().thenReturn(mock_status)
|
||||
when(redis_service.RedisApp).stop_db(do_not_start_on_reboot=
|
||||
False).thenReturn(None)
|
||||
self.manager.stop_db(self.context)
|
||||
verify(redis_service.RedisAppStatus).get()
|
||||
verify(redis_service.RedisApp).stop_db(do_not_start_on_reboot=False)
|
@ -316,6 +316,11 @@ class ResizeVolumeTest(testtools.TestCase):
|
||||
self.old_vol_size,
|
||||
self.new_vol_size)
|
||||
|
||||
class FakeGroup():
|
||||
def __init__(self):
|
||||
self.mount_point = 'var/lib/mysql'
|
||||
taskmanager_models.CONF.get = Mock(return_value=FakeGroup())
|
||||
|
||||
def tearDown(self):
|
||||
super(ResizeVolumeTest, self).tearDown()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user