summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2016-03-16 17:03:47 +0000
committerGerrit Code Review <review@openstack.org>2016-03-16 17:03:47 +0000
commit4e3ebd31411fd839085ebf12f78b91a83ac9dd08 (patch)
treefbf6b53315ee80c9b46280bf3bd460f376df89b9
parent1461ca14936821f327a2f1c8968fd3abdaf30a61 (diff)
parent2e51cdb3adc5084b62a18b54d03d716c13394091 (diff)
downloadtrove-4e3ebd31411fd839085ebf12f78b91a83ac9dd08.tar.gz
Merge "Vertica configuration groups"
-rw-r--r--trove/common/configurations.py11
-rw-r--r--trove/common/template.py1
-rw-r--r--trove/guestagent/common/configuration.py25
-rw-r--r--trove/guestagent/datastore/experimental/vertica/manager.py21
-rw-r--r--trove/guestagent/datastore/experimental/vertica/service.py168
-rw-r--r--trove/guestagent/datastore/experimental/vertica/system.py35
-rw-r--r--trove/templates/vertica/validation-rules.json1390
-rw-r--r--trove/tests/int_tests.py2
-rw-r--r--trove/tests/scenario/helpers/vertica_helper.py54
-rw-r--r--trove/tests/unittests/guestagent/test_dbaas.py163
-rw-r--r--trove/tests/unittests/guestagent/test_vertica_manager.py17
11 files changed, 1765 insertions, 122 deletions
diff --git a/trove/common/configurations.py b/trove/common/configurations.py
index 37c45054..423d3b0c 100644
--- a/trove/common/configurations.py
+++ b/trove/common/configurations.py
@@ -73,3 +73,14 @@ class CassandraConfParser(object):
def parse(self):
return self.CODEC.deserialize(self.config).items()
+
+
+class VerticaConfParser(object):
+
+ CODEC = stream_codecs.PropertiesCodec(delimiter='=')
+
+ def __init__(self, config):
+ self.config = config
+
+ def parse(self):
+ return self.CODEC.deserialize(self.config).items()
diff --git a/trove/common/template.py b/trove/common/template.py
index 6083f60b..a7a64398 100644
--- a/trove/common/template.py
+++ b/trove/common/template.py
@@ -36,6 +36,7 @@ SERVICE_PARSERS = {
'postgresql': configurations.PostgresqlConfParser,
'cassandra': configurations.CassandraConfParser,
'redis': configurations.RedisConfParser,
+ 'vertica': configurations.VerticaConfParser,
}
diff --git a/trove/guestagent/common/configuration.py b/trove/guestagent/common/configuration.py
index 911de41a..0e52bc0b 100644
--- a/trove/guestagent/common/configuration.py
+++ b/trove/guestagent/common/configuration.py
@@ -167,6 +167,10 @@ class ConfigurationManager(object):
"""
self._apply_override(self.USER_GROUP, change_id, options)
+ def get_user_override(self, change_id=DEFAULT_CHANGE_ID):
+ """Get the user overrides"""
+ return self._override_strategy.get(self.USER_GROUP, change_id)
+
def _apply_override(self, group_name, change_id, options):
if not isinstance(options, dict):
# Deserialize the options into a dict if not already.
@@ -240,6 +244,17 @@ class ConfigurationOverrideStrategy(object):
:type change_id string
"""
+ @abc.abstractmethod
+ def get(self, group_name, change_id=None):
+ """Return the contents of a given configuration override
+
+ :param group_name The group the override belongs to.
+ :type group_name string
+
+ :param change_id The name of the override within the group.
+ :type change_id string
+ """
+
def parse_updates(self):
"""Return all updates applied to the base revision as a single dict.
Return an empty dict if the base file is always the most current
@@ -359,6 +374,13 @@ class ImportOverrideStrategy(ConfigurationOverrideStrategy):
operating_system.remove(path, force=True,
as_root=self._requires_root)
+ def get(self, group_name, change_id):
+ revision_file = self._find_revision_file(group_name, change_id)
+
+ return operating_system.read_file(revision_file,
+ codec=self._codec,
+ as_root=self._requires_root)
+
def parse_updates(self):
parsed_options = {}
for path in self._collect_revision_files():
@@ -482,6 +504,9 @@ class OneFileOverrideStrategy(ConfigurationOverrideStrategy):
operating_system.remove(self._base_revision_file, force=True,
as_root=self._requires_root)
+ def get(self, group_name, change_id):
+ return self._import_strategy.get(group_name, change_id)
+
def _regenerate_base_configuration(self):
"""Gather all configuration changes and apply them in order on the base
revision. Write the results to the configuration file.
diff --git a/trove/guestagent/datastore/experimental/vertica/manager.py b/trove/guestagent/datastore/experimental/vertica/manager.py
index b668eb33..7fabeb01 100644
--- a/trove/guestagent/datastore/experimental/vertica/manager.py
+++ b/trove/guestagent/datastore/experimental/vertica/manager.py
@@ -38,6 +38,10 @@ class Manager(manager.Manager):
def status(self):
return self.appStatus
+ @property
+ def configuration_manager(self):
+ return self.app.configuration_manager
+
def do_prepare(self, context, packages, databases, memory_mb, users,
device_path, mount_point, backup_info,
config_contents, root_password, overrides,
@@ -60,6 +64,11 @@ class Manager(manager.Manager):
self.app.install_vertica()
self.app.create_db()
self.app.add_udls()
+
+ if config_contents:
+ self.app.configuration_manager.save_configuration(
+ config_contents)
+
elif cluster_config['instance_type'] not in ["member", "master"]:
raise RuntimeError(_("Bad cluster configuration: instance type "
"given as %s.") %
@@ -110,6 +119,18 @@ class Manager(manager.Manager):
self.appStatus.set_status(rd_ins.ServiceStatuses.FAILED)
raise
+ def update_overrides(self, context, overrides, remove=False):
+ LOG.debug("Updating overrides.")
+ if remove:
+ self.app.remove_overrides()
+ else:
+ self.app.update_overrides(context, overrides, remove)
+
+ def apply_overrides(self, context, overrides):
+ if overrides:
+ LOG.debug("Applying overrides: " + str(overrides))
+ self.app.apply_overrides(overrides)
+
def grow_cluster(self, context, members):
try:
LOG.debug("Growing cluster to members: %s." % members)
diff --git a/trove/guestagent/datastore/experimental/vertica/service.py b/trove/guestagent/datastore/experimental/vertica/service.py
index 8a052ac9..7fb6d715 100644
--- a/trove/guestagent/datastore/experimental/vertica/service.py
+++ b/trove/guestagent/datastore/experimental/vertica/service.py
@@ -24,7 +24,13 @@ from trove.common import exception
from trove.common.i18n import _
from trove.common.i18n import _LI
from trove.common import instance as rd_instance
+from trove.common.stream_codecs import PropertiesCodec
from trove.common import utils as utils
+from trove.guestagent.common.configuration import ConfigurationManager
+from trove.guestagent.common.configuration import ImportOverrideStrategy
+from trove.guestagent.common import guestagent_utils
+from trove.guestagent.common import operating_system
+from trove.guestagent.common.operating_system import FileMode
from trove.guestagent.datastore.experimental.vertica import system
from trove.guestagent.datastore import service
from trove.guestagent.db import models
@@ -36,6 +42,9 @@ CONF = cfg.CONF
packager = pkg.Package()
DB_NAME = 'db_srvr'
MOUNT_POINT = CONF.vertica.mount_point
+# We will use a fake configuration file for the options managed through
+# configuration groups that we apply directly with ALTER DB ... SET ...
+FAKE_CFG = os.path.join(MOUNT_POINT, "vertica.cfg.fake")
class VerticaAppStatus(service.BaseDbStatus):
@@ -44,7 +53,7 @@ class VerticaAppStatus(service.BaseDbStatus):
"""Get the status of dbaas and report it back."""
try:
out, err = system.shell_execute(system.STATUS_ACTIVE_DB,
- "dbadmin")
+ system.VERTICA_ADMIN)
if out.strip() == DB_NAME:
# UP status is confirmed
LOG.info(_("Service Status is RUNNING."))
@@ -63,10 +72,78 @@ class VerticaApp(object):
def __init__(self, status):
self.state_change_wait_time = CONF.state_change_wait_time
self.status = status
+ revision_dir = \
+ guestagent_utils.build_file_path(
+ os.path.join(MOUNT_POINT,
+ os.path.dirname(system.VERTICA_ADMIN)),
+ ConfigurationManager.DEFAULT_STRATEGY_OVERRIDES_SUB_DIR)
+
+ if not operating_system.exists(FAKE_CFG):
+ operating_system.write_file(FAKE_CFG, '', as_root=True)
+ operating_system.chown(FAKE_CFG, system.VERTICA_ADMIN,
+ system.VERTICA_ADMIN_GRP, as_root=True)
+ operating_system.chmod(FAKE_CFG, FileMode.ADD_GRP_RX_OTH_RX(),
+ as_root=True)
+ self.configuration_manager = \
+ ConfigurationManager(FAKE_CFG, system.VERTICA_ADMIN,
+ system.VERTICA_ADMIN_GRP,
+ PropertiesCodec(delimiter='='),
+ requires_root=True,
+ override_strategy=ImportOverrideStrategy(
+ revision_dir, "cnf"))
+
+ def update_overrides(self, context, overrides, remove=False):
+ if overrides:
+ self.apply_overrides(overrides)
+
+ def remove_overrides(self):
+ config = self.configuration_manager.get_user_override()
+ self._reset_config(config)
+ self.configuration_manager.remove_user_override()
+
+ def apply_overrides(self, overrides):
+ self.configuration_manager.apply_user_override(overrides)
+ self._apply_config(overrides)
+
+ def _reset_config(self, config):
+ try:
+ db_password = self._get_database_password()
+ for k, v in config.iteritems():
+ alter_db_cmd = system.ALTER_DB_RESET_CFG % (DB_NAME, str(k))
+ out, err = system.exec_vsql_command(db_password, alter_db_cmd)
+ if err:
+ if err.is_warning():
+ LOG.warning(err)
+ else:
+ LOG.error(err)
+ raise RuntimeError(_("Failed to remove config %s") % k)
+
+ except Exception:
+ LOG.exception(_("Vertica configuration remove failed."))
+ raise RuntimeError(_("Vertica configuration remove failed."))
+ LOG.info(_("Vertica configuration reset completed."))
+
+ def _apply_config(self, config):
+ try:
+ db_password = self._get_database_password()
+ for k, v in config.iteritems():
+ alter_db_cmd = system.ALTER_DB_CFG % (DB_NAME, str(k), str(v))
+ out, err = system.exec_vsql_command(db_password, alter_db_cmd)
+ if err:
+ if err.is_warning():
+ LOG.warning(err)
+ else:
+ LOG.error(err)
+ raise RuntimeError(_("Failed to apply config %s") % k)
+
+ except Exception:
+ LOG.exception(_("Vertica configuration apply failed"))
+ raise RuntimeError(_("Vertica configuration apply failed"))
+ LOG.info(_("Vertica config apply completed."))
def _enable_db_on_boot(self):
try:
- command = ["sudo", "su", "-", "dbadmin", "-c",
+ command = ["sudo", "su", "-", system.VERTICA_ADMIN, "-c",
(system.SET_RESTART_POLICY % (DB_NAME, "always"))]
subprocess.Popen(command)
command = ["sudo", "su", "-", "root", "-c",
@@ -79,7 +156,7 @@ class VerticaApp(object):
def _disable_db_on_boot(self):
try:
command = (system.SET_RESTART_POLICY % (DB_NAME, "never"))
- system.shell_execute(command, "dbadmin")
+ system.shell_execute(command, system.VERTICA_ADMIN)
command = (system.VERTICA_AGENT_SERVICE_COMMAND % "disable")
system.shell_execute(command)
except exception.ProcessExecutionError:
@@ -99,9 +176,10 @@ class VerticaApp(object):
# Using Vertica adminTools to stop db.
db_password = self._get_database_password()
stop_db_command = (system.STOP_DB % (DB_NAME, db_password))
- out, err = system.shell_execute(system.STATUS_ACTIVE_DB, "dbadmin")
+ out, err = system.shell_execute(system.STATUS_ACTIVE_DB,
+ system.VERTICA_ADMIN)
if out.strip() == DB_NAME:
- system.shell_execute(stop_db_command, "dbadmin")
+ system.shell_execute(stop_db_command, system.VERTICA_ADMIN)
if not self.status._is_restarting:
if not self.status.wait_for_real_status_to_change_to(
rd_instance.ServiceStatuses.SHUTDOWN,
@@ -127,14 +205,14 @@ class VerticaApp(object):
subprocess.Popen(command)
# Using Vertica adminTools to start db.
db_password = self._get_database_password()
- start_db_command = ["sudo", "su", "-", "dbadmin", "-c",
+ start_db_command = ["sudo", "su", "-", system.VERTICA_ADMIN, "-c",
(system.START_DB % (DB_NAME, db_password))]
subprocess.Popen(start_db_command)
if not self.status._is_restarting:
self.status.end_restart()
LOG.debug("Database started.")
- except Exception:
- raise RuntimeError("Could not start Vertica!")
+ except Exception as e:
+ raise RuntimeError(_("Could not start Vertica due to %s") % e)
def start_db_with_conf_changes(self, config_contents):
"""
@@ -142,6 +220,12 @@ class VerticaApp(object):
needs to be implemented to enable volume resize on guestagent side.
"""
LOG.info(_("Starting Vertica with configuration changes."))
+ if self.status.is_running:
+ format = 'Cannot start_db_with_conf_changes because status is %s.'
+ LOG.debug(format, self.status)
+ raise RuntimeError(format % self.status)
+ LOG.info(_("Initiating config."))
+ self.configuration_manager.save_configuration(config_contents)
self.start_db(True)
def restart(self):
@@ -199,7 +283,7 @@ class VerticaApp(object):
create_db_command = (system.CREATE_DB % (members, DB_NAME,
MOUNT_POINT, MOUNT_POINT,
db_password))
- system.shell_execute(create_db_command, "dbadmin")
+ system.shell_execute(create_db_command, system.VERTICA_ADMIN)
except Exception:
LOG.exception(_("Vertica database create failed."))
raise RuntimeError(_("Vertica database create failed."))
@@ -250,18 +334,24 @@ class VerticaApp(object):
system.CREATE_LIBRARY % (lib_name, path)
)
if err:
- LOG.error(err)
- raise RuntimeError(_("Failed to create library %s.")
- % lib_name)
+ if err.is_warning():
+ LOG.warning(err)
+ else:
+ LOG.error(err)
+ raise RuntimeError(_("Failed to create library %s.")
+ % lib_name)
out, err = system.exec_vsql_command(
password,
system.CREATE_SOURCE % (func_name, language,
factory, lib_name)
)
if err:
- LOG.error(err)
- raise RuntimeError(_("Failed to create source %s.")
- % func_name)
+ if err.is_warning():
+ LOG.warning(err)
+ else:
+ LOG.error(err)
+ raise RuntimeError(_("Failed to create source %s.")
+ % func_name)
loaded_udls.append(func_name)
else:
LOG.warning("Skipping %s as path %s not found." %
@@ -326,9 +416,10 @@ class VerticaApp(object):
"""This method executes preparatory methods before
executing install_vertica.
"""
- command = ("VERT_DBA_USR=dbadmin VERT_DBA_HOME=/home/dbadmin "
- "VERT_DBA_GRP=verticadba /opt/vertica/oss/python/bin/python"
- " -m vertica.local_coerce")
+ command = ("VERT_DBA_USR=%s VERT_DBA_HOME=/home/dbadmin "
+ "VERT_DBA_GRP=%s /opt/vertica/oss/python/bin/python"
+ " -m vertica.local_coerce" %
+ (system.VERTICA_ADMIN, system.VERTICA_ADMIN_GRP))
try:
self._set_readahead_for_disks()
system.shell_execute(command)
@@ -347,29 +438,39 @@ class VerticaApp(object):
LOG.error(err)
raise RuntimeError(_("Failed to set k-safety level %s.") % k)
- def _create_user(self, username, password, role):
+ def _create_user(self, username, password, role=None):
"""Creates a user, granting and enabling the given role for it."""
LOG.info(_("Creating user in Vertica database."))
out, err = system.exec_vsql_command(self._get_database_password(),
system.CREATE_USER %
(username, password))
- if not err:
- self._grant_role(username, role)
if err:
- LOG.error(err)
- raise RuntimeError(_("Failed to create user %s.") % username)
+ if err.is_warning():
+ LOG.warning(err)
+ else:
+ LOG.error(err)
+ raise RuntimeError(_("Failed to create user %s.") % username)
+ if role:
+ self._grant_role(username, role)
def _grant_role(self, username, role):
"""Grants a role to the user on the schema."""
out, err = system.exec_vsql_command(self._get_database_password(),
system.GRANT_TO_USER
% (role, username))
- if not err:
- out, err = system.exec_vsql_command(self._get_database_password(),
- system.ENABLE_FOR_USER
- % (username, role))
- if err:
+ if err:
+ if err.is_warning():
+ LOG.warning(err)
+ else:
LOG.error(err)
+ raise RuntimeError(_("Failed to grant role %(r)s to user "
+ "%(u)s.")
+ % {'r': role, 'u': username})
+ out, err = system.exec_vsql_command(self._get_database_password(),
+ system.ENABLE_FOR_USER
+ % (username, role))
+ if err:
+ LOG.warning(err)
def enable_root(self, root_password=None):
"""Resets the root password."""
@@ -387,9 +488,12 @@ class VerticaApp(object):
self._get_database_password(),
system.ALTER_USER_PASSWORD % (user.name, user.password))
if err:
- LOG.error(err)
- raise RuntimeError(_("Failed to update %s password.")
- % user.name)
+ if err.is_warning():
+ LOG.warning(err)
+ else:
+ LOG.error(err)
+ raise RuntimeError(_("Failed to update %s "
+ "password.") % user.name)
except exception.ProcessExecutionError:
LOG.error(_("Failed to update %s password.") % user.name)
raise RuntimeError(_("Failed to update %s password.")
@@ -402,7 +506,7 @@ class VerticaApp(object):
try:
out, err = system.shell_execute(system.USER_EXISTS %
(self._get_database_password(),
- 'root'), 'dbadmin')
+ 'root'), system.VERTICA_ADMIN)
if err:
LOG.error(err)
raise RuntimeError(_("Failed to query for root user."))
diff --git a/trove/guestagent/datastore/experimental/vertica/system.py b/trove/guestagent/datastore/experimental/vertica/system.py
index 534fcb6b..5ca9c689 100644
--- a/trove/guestagent/datastore/experimental/vertica/system.py
+++ b/trove/guestagent/datastore/experimental/vertica/system.py
@@ -11,8 +11,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import re
+
from trove.common import utils
+ALTER_DB_CFG = "ALTER DATABASE %s SET %s = %s"
+ALTER_DB_RESET_CFG = "ALTER DATABASE %s CLEAR %s"
ALTER_USER_PASSWORD = "ALTER USER %s IDENTIFIED BY '%s'"
ADD_DB_TO_NODE = ("/opt/vertica/bin/adminTools -t db_add_node -a"
" %s -d %s -p '%s'")
@@ -55,6 +59,8 @@ UPDATE_ADD = ("/opt/vertica/sbin/update_vertica --add-hosts %s "
USER_EXISTS = ("/opt/vertica/bin/vsql -w '%s' -c "
"\"select 1 from users where user_name = '%s'\" "
"| grep row | awk '{print $1}' | cut -c2-")
+VERTICA_ADMIN = "dbadmin"
+VERTICA_ADMIN_GRP = "verticadba"
VERTICA_AGENT_SERVICE_COMMAND = "service vertica_agent %s"
VERTICA_CONF = "/etc/vertica.cnf"
INSTALL_TIMEOUT = 1000
@@ -83,7 +89,32 @@ def shell_execute(command, command_executor="root"):
% command)
+class VSqlError(object):
+ def __init__(self, stderr):
+ """Parse the stderr part of the VSql output.
+ stderr looks like: "ERROR 3117: Division by zero"
+ :param stderr: string from executing statement via vsql
+ """
+ parse = re.match("^(ERROR|WARNING) (\d+): (.+)$", stderr)
+ if not parse:
+ raise ValueError("VSql stderr %(msg)s not recognized."
+ % {'msg': stderr})
+ self.type = parse.group(1)
+ self.code = int(parse.group(2))
+ self.msg = parse.group(3)
+
+ def is_warning(self):
+ return bool(self.type == "WARNING")
+
+ def __str__(self):
+ return "Vertica %s (%s): %s" % (self.type, self.code, self.msg)
+
+
def exec_vsql_command(dbadmin_password, command):
"""Executes a VSQL command with the given dbadmin password."""
- return shell_execute("/opt/vertica/bin/vsql -w \'%s\' -c \"%s\""
- % (dbadmin_password, command), "dbadmin")
+ out, err = shell_execute("/opt/vertica/bin/vsql -w \'%s\' -c \"%s\""
+ % (dbadmin_password, command),
+ VERTICA_ADMIN)
+ if err:
+ err = VSqlError(err)
+ return out, err
diff --git a/trove/templates/vertica/validation-rules.json b/trove/templates/vertica/validation-rules.json
new file mode 100644
index 00000000..2c71529a
--- /dev/null
+++ b/trove/templates/vertica/validation-rules.json
@@ -0,0 +1,1390 @@
+{
+ "configuration-parameters": [
+ {
+ "description": "No of active partitions",
+ "type": "integer",
+ "name": "ActivePartitionCount",
+ "restart_required": false
+ },
+ {
+ "description": "Interval between collection of nodes' addresses (seconds)",
+ "type": "integer",
+ "name": "AddressCollectorInterval",
+ "restart_required": false
+ },
+ {
+ "description": "Interval between advancing the AHM (seconds)",
+ "type": "integer",
+ "name": "AdvanceAHMInterval",
+ "restart_required": false
+ },
+ {
+ "description": "Consider backup epochs when setting new AHM",
+ "type": "integer",
+ "name": "AHMBackupManagement",
+ "restart_required": false
+ },
+ {
+ "description": "Allow names containing non-ASCII UTF-8 characters",
+ "type": "integer",
+ "name": "AllowNonAsciiNames",
+ "restart_required": false
+ },
+ {
+ "description": "Interval between Tuple Mover row count statistics updates (seconds)",
+ "type": "integer",
+ "name": "AnalyzeRowCountInterval",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum number of columns to analyze with each analyze stats plan",
+ "type": "integer",
+ "name": "AnalyzeStatsPlanMaxColumns",
+ "restart_required": false
+ },
+ {
+ "description": "Number of sampling bands to use when not using entire data set.",
+ "type": "integer",
+ "name": "AnalyzeStatsSampleBands",
+ "restart_required": false
+ },
+ {
+ "description": "ARC will commit only if the change is more than the percentage specified",
+ "type": "integer",
+ "name": "ARCCommitPercentage",
+ "restart_required": false
+ },
+ {
+ "description": "The confidence level at which to run audits of license size utilization. Represent 99.5% as 99.5.",
+ "type": "integer",
+ "name": "AuditConfidenceLevel",
+ "restart_required": false
+ },
+ {
+ "description": "The error tolerance for audits of license size utilization. Represent 4.5% as 4.5.",
+ "type": "integer",
+ "name": "AuditErrorTolerance",
+ "restart_required": false
+ },
+ {
+ "description": "Use as recommended by Technical Support",
+ "type": "integer",
+ "name": "BasicVerticaOptions",
+ "restart_required": false
+ },
+ {
+ "description": "size of memory managed by memory manager (in MB)",
+ "type": "integer",
+ "name": "BlockCacheSize",
+ "restart_required": true
+ },
+ {
+ "description": "Buffer query output to allow possible retry of the query. Values allowed: 0(never buffer), 1(always buffer), 2(default: vertica decides before query begins executing to buffer based on certain criteria)",
+ "type": "integer",
+ "name": "BufferQueryOutputForPossibleRetry",
+ "restart_required": false
+ },
+ {
+ "description": "If set to 1, position index will be cached",
+ "type": "integer",
+ "name": "CachePositionIndex",
+ "restart_required": true
+ },
+ {
+ "description": "If true, cascade to a target resource pool will always lead to replanning the query on the target pool",
+ "type": "integer",
+ "name": "CascadeResourcePoolAlwaysReplan",
+ "restart_required": false
+ },
+ {
+ "description": "Split catalog checkpoint into chunks of approximately this size",
+ "type": "integer",
+ "name": "CatalogCheckpointChunkSizeKB",
+ "restart_required": false
+ },
+ {
+ "description": "Minimum transaction log size before a new catalog checkpoint is created",
+ "type": "integer",
+ "name": "CatalogCheckpointMinLogSizeKB",
+ "restart_required": false
+ },
+ {
+ "description": "Transaction log size must be at least this fraction of the checkpoint size before a new catalog checkpoint is created",
+ "type": "integer",
+ "name": "CatalogCheckpointPercent",
+ "restart_required": false
+ },
+ {
+ "description": "Rename storage files during final cleanup upon removal from the catalog",
+ "type": "integer",
+ "name": "CatalogDeindexRename",
+ "restart_required": false
+ },
+ {
+ "description": "Check data integrity using CRCs (should be enabled unless performance is adversely impacted",
+ "type": "integer",
+ "name": "CheckCRCs",
+ "restart_required": false
+ },
+ {
+ "description": "Check data sortedness before writing to ROS",
+ "type": "integer",
+ "name": "CheckDataTargetSortOrder",
+ "restart_required": false
+ },
+ {
+ "description": "Seconds to wait for 'late' nodes to finish recovery actions and proceed with the cluster",
+ "type": "integer",
+ "name": "ClusterRecoveryWait",
+ "restart_required": false
+ },
+ {
+ "description": "The collation function column width is 4 plus its data column width times CollationExpansion octets",
+ "type": "integer",
+ "name": "CollationExpansion",
+ "restart_required": false
+ },
+ {
+ "description": "Catalog compression (0: off, 1: chkpt+systxnlogs, 2: chkpt+txnlogs)",
+ "type": "integer",
+ "name": "CompressCatalogOnDisk",
+ "restart_required": true
+ },
+ {
+ "description": "When enabled, control traffic will be compressed",
+ "type": "integer",
+ "name": "CompressDistCalls",
+ "restart_required": false
+ },
+ {
+ "description": "When enabled, data traffic will be compressed; this reduces data bandwidth at a cost of CPU time",
+ "type": "integer",
+ "name": "CompressNetworkData",
+ "restart_required": false
+ },
+ {
+ "description": "Compute APPROXCOUNTDISTINCTs when analyzing statistics. Default is false",
+ "type": "integer",
+ "name": "ComputeApproxNDVsDuringAnalyzeStats",
+ "restart_required": false
+ },
+ {
+ "description": "Number of ROS containers that are allowed before new ROSs are prevented (ROS pushback)",
+ "type": "integer",
+ "name": "ContainersPerProjectionLimit",
+ "restart_required": false
+ },
+ {
+ "description": "When doing a COPY FROM VERTICA without an explicit columns list, include IDENTITY columns in the implicit list",
+ "type": "integer",
+ "name": "CopyFromVerticaWithIdentity",
+ "restart_required": false
+ },
+ {
+ "description": "Time interval in seconds after which a node sends a heartbeat (Set to 0 to disable.)",
+ "type": "integer",
+ "name": "DatabaseHeartbeatInterval",
+ "restart_required": false
+ },
+ {
+ "description": "Number of rows to be sampled for correlation analysis during DBD design. Default: 4500",
+ "type": "integer",
+ "name": "DBDCorrelationSampleRowCount",
+ "restart_required": false
+ },
+ {
+ "description": "Percentage of rows to be sampled for correlation analysis during DBD design. Default: 0 Use DBDCorrelationSampleRowCount",
+ "type": "integer",
+ "name": "DBDCorrelationSampleRowPct",
+ "restart_required": false
+ },
+ {
+ "description": "Number of rows to be sampled for count distinct analysis during DBD design. Default: 0 Use DBDCountDistinctSampleRowPct",
+ "type": "integer",
+ "name": "DBDCountDistinctSampleRowCount",
+ "restart_required": false
+ },
+ {
+ "description": "Percentage of rows to be sampled for count distinct analysis during DBD design. Default: 100",
+ "type": "integer",
+ "name": "DBDCountDistinctSampleRowPct",
+ "restart_required": false
+ },
+ {
+ "description": "Concurrency setting for the deployment/rebalance process in the DBD. Default: 0",
+ "type": "integer",
+ "name": "DBDDeploymentParallelism",
+ "restart_required": false
+ },
+ {
+ "description": "Dynamic sampling scheme to be used for encoding analysis during DBD design. Default: true",
+ "type": "integer",
+ "name": "DBDDynamicSampling",
+ "restart_required": false
+ },
+ {
+ "description": "Number of rows to be sampled for encoding analysis during DBD design. Default: 1000000",
+ "type": "integer",
+ "name": "DBDEncodingSampleRowCount",
+ "restart_required": false
+ },
+ {
+ "description": "Percentage of rows to be sampled for encoding analysis during DBD design. Default: 0 Use DBDEncodingSampleRowCount",
+ "type": "integer",
+ "name": "DBDEncodingSampleRowPct",
+ "restart_required": false
+ },
+ {
+ "description": "Number of minimum rows expected in Fact Table, default 1M rows",
+ "type": "integer",
+ "name": "DBDLargestTableRowCountBoundary",
+ "restart_required": false
+ },
+ {
+ "description": "Log internal DBD design process in DC tables. Default: false DC logging of design process is turned OFF by default",
+ "type": "integer",
+ "name": "DBDLogInternalDesignProcess",
+ "restart_required": false
+ },
+ {
+ "description": "Concurrency setting for the parallelism in the Storage Optimization phase of Database Designer. Default: 0",
+ "type": "integer",
+ "name": "DBDMaxConcurrencyForEncodingExperiment",
+ "restart_required": false
+ },
+ {
+ "description": "If the largest fact table has more than <DBDLargestTableRowCountBoundary> rows, then use this percentage off the largest fact table to define the number of rows below which a table should be replicated Default: 1%",
+ "type": "integer",
+ "name": "DBDRepLargeRowCountPct",
+ "restart_required": false
+ },
+ {
+ "description": "If the largest fact table has less than <DBDLargestTableRowCountBoundary> rows, then use this percentage off the largest fact table to define the number of rows below which a table should be replicated Default: 10%",
+ "type": "integer",
+ "name": "DBDRepSmallRowCountPct",
+ "restart_required": false
+ },
+ {
+ "description": "Number of bands sampled using Dynamic Sampling Algorithm. Default: 100",
+ "type": "integer",
+ "name": "DBDSampleStorageBandCount",
+ "restart_required": false
+ },
+ {
+ "description": "Number of rows to be sampled for segmentation skew analysis during DBD design. Default: 8000",
+ "type": "integer",
+ "name": "DBDSkewDetectionSampleRowCount",
+ "restart_required": false
+ },
+ {
+ "description": "Percentage of rows to be sampled for segmentation skew analysis during DBD design. Default: 0 Use DBDSkewDetectionSampleRowCount",
+ "type": "integer",
+ "name": "DBDSkewDetectionSampleRowPct",
+ "restart_required": false
+ },
+ {
+ "description": "Determines source for resource allocation during a designer invocation. Default: false Uses user's resource pool",
+ "type": "integer",
+ "name": "DBDUseOnlyDesignerResourcePool",
+ "restart_required": false
+ },
+ {
+ "description": "Default setting for intervalstyle; 1 is UNITS; 0 is PLAIN and conforms to standard SQL",
+ "type": "integer",
+ "name": "DefaultIntervalStyle",
+ "restart_required": false
+ },
+ {
+ "description": "Defines the default session startup Locale for the database",
+ "type": "string",
+ "name": "DefaultSessionLocale",
+ "restart_required": false
+ },
+ {
+ "description": "Disable schema-level privileges on tables.",
+ "type": "integer",
+ "name": "DisableInheritedPrivileges",
+ "restart_required": false
+ },
+ {
+ "description": "Set to disable local resegmentation",
+ "type": "integer",
+ "name": "DisableLocalResegmentation",
+ "restart_required": false
+ },
+ {
+ "description": "If \u2018false\u2019, the optimizer randomly chooses nodes to do the work of any down nodes",
+ "type": "integer",
+ "name": "DisableNodeDownOptimization",
+ "restart_required": false
+ },
+ {
+ "description": "Do not allow creating prejoin projections",
+ "type": "integer",
+ "name": "DisablePrejoinProjections",
+ "restart_required": false
+ },
+ {
+ "description": "Disallow the MultipleActiveResultSets (MARS) feature to be enabled",
+ "type": "integer",
+ "name": "DisallowMars",
+ "restart_required": false
+ },
+ {
+ "description": "Interval between disk space polls (for disk resource management) (seconds)",
+ "type": "integer",
+ "name": "DiskSpacePollingInterval",
+ "restart_required": true
+ },
+ {
+ "description": "Enable DMLs to cancel conflicting TM tasks to acquire lock",
+ "type": "integer",
+ "name": "DMLCancelTM",
+ "restart_required": false
+ },
+ {
+ "description": "Use as recommended by Technical Support",
+ "type": "integer",
+ "name": "EEVerticaOptions",
+ "restart_required": false
+ },
+ {
+ "description": "Enables Access Policy feature",
+ "type": "integer",
+ "name": "EnableAccessPolicy",
+ "restart_required": false
+ },
+ {
+ "description": "Enable all granted roles on login",
+ "type": "integer",
+ "name": "EnableAllRolesOnLogin",
+ "restart_required": false
+ },
+ {
+ "description": "If true and apportionable source/parser are defined for the load, input may get split into multiple parts (portions) and loaded by multiple threads/servers in parallel",
+ "type": "integer",
+ "name": "EnableApportionLoad",
+ "restart_required": false
+ },
+ {
+ "description": "Turn on/off the automatic update row count, min and max when DML queries are run",
+ "type": "integer",
+ "name": "EnableAutoDMLStats",
+ "restart_required": false
+ },
+ {
+ "description": "A value of 1 enables block memory manager or 0 disables memory manager",
+ "type": "integer",
+ "name": "EnableBlockMemoryManager",
+ "restart_required": true
+ },
+ {
+ "description": "If true and a chunker is defined for the corresponding parser multiple parse threads can cooperate to parse the output of a single source",
+ "type": "integer",
+ "name": "EnableCooperativeParse",
+ "restart_required": false
+ },
+ {
+ "description": "Enable the usage data collector",
+ "type": "integer",
+ "name": "EnableDataCollector",
+ "restart_required": false
+ },
+ {
+ "description": "Enabled cipher suites for TLS",
+ "type": "string",
+ "name": "EnabledCipherSuites",
+ "restart_required": true
+ },
+ {
+ "description": "Enable EE Thread Pool to reduce threads used",
+ "type": "integer",
+ "name": "EnableEEThreadPool",
+ "restart_required": false
+ },
+ {
+ "description": "Enable SIPS for early materialized merge join, on multi-block inners",
+ "type": "integer",
+ "name": "EnableEMMJMultiblockSIPS",
+ "restart_required": false
+ },
+ {
+ "description": "Allow expression results to be materialized as projection columns",
+ "type": "integer",
+ "name": "EnableExprsInProjections",
+ "restart_required": false
+ },
+ {
+ "description": "allow user-specified force outer rule",
+ "type": "integer",
+ "name": "EnableForceOuter",
+ "restart_required": false
+ },
+ {
+ "description": "Allow aggregate projections using GROUP BY",
+ "type": "integer",
+ "name": "EnableGroupByProjections",
+ "restart_required": false
+ },
+ {
+ "description": "Enable JIT compilation optimizations",
+ "type": "integer",
+ "name": "EnableJIT",
+ "restart_required": false
+ },
+ {
+ "description": "Determines whether new primary key constraints will be enabled by default",
+ "type": "integer",
+ "name": "EnableNewPrimaryKeysByDefault",
+ "restart_required": false
+ },
+ {
+ "description": "Determines whether new unique key constraints will be enabled by default",
+ "type": "integer",
+ "name": "EnableNewUniqueKeysByDefault",
+ "restart_required": false
+ },
+ {
+ "description": "Enable Parallel Hash build to improve join performance",
+ "type": "integer",
+ "name": "EnableParallelHashBuild",
+ "restart_required": false
+ },
+ {
+ "description": "Enable Parallel Sort to improve sort performance",
+ "type": "integer",
+ "name": "EnableParallelSort",
+ "restart_required": false
+ },
+ {
+ "description": "0 if the special ANY_ROW event for pattern matching is not enabled. Otherwise it is enabled.",
+ "type": "integer",
+ "name": "EnablePatternMatchingAnyRow",
+ "restart_required": false
+ },
+ {
+ "description": "Enable Plan Stability Feature",
+ "type": "integer",
+ "name": "EnablePlanStability",
+ "restart_required": false
+ },
+ {
+ "description": "Execute active directed queries in Plan Stability Store",
+ "type": "integer",
+ "name": "EnablePlanStabilityLookup",
+ "restart_required": false
+ },
+ {
+ "description": "Query threads can be restricted to executing on specific CPUs via session resource pool attributes",
+ "type": "integer",
+ "name": "EnableResourcePoolCPUAffinity",
+ "restart_required": false
+ },
+ {
+ "description": "Enable runtime task priority scheduler to allow high priority queries to use more CPU time and IO bandwidth",
+ "type": "integer",
+ "name": "EnableRuntimePriorityScheduler",
+ "restart_required": false
+ },
+ {
+ "description": "Enable SSL for the server",
+ "type": "integer",
+ "name": "EnableSSL",
+ "restart_required": true
+ },
+ {
+ "description": "Enable bundling data files along with their index files. Also MaxBundleableROSSizeKB is effective when this is enabled.",
+ "type": "integer",
+ "name": "EnableStorageBundling",
+ "restart_required": false
+ },
+ {
+ "description": "Force casts from varchar to Time,TimeTz,Timestamp,TimestampTz,Interval to error instead of returning null",
+ "type": "integer",
+ "name": "EnableStrictTimeCasts",
+ "restart_required": false
+ },
+ {
+ "description": "Allow aggregate projections using Top K / LIMIT",
+ "type": "integer",
+ "name": "EnableTopKProjections",
+ "restart_required": false
+ },
+ {
+ "description": "Allow aggregate projections using UDTransforms",
+ "type": "integer",
+ "name": "EnableUDTProjections",
+ "restart_required": false
+ },
+ {
+ "description": "Enable optimizations based on guarantee of uniqueness",
+ "type": "integer",
+ "name": "EnableUniquenessOptimization",
+ "restart_required": false
+ },
+ {
+ "description": "If set to 1 total threads will be equal to number of virtual processors else thread will be set to total real core",
+ "type": "integer",
+ "name": "EnableVirtualCoreCount",
+ "restart_required": false
+ },
+ {
+ "description": "Granularity of time to epoch mapping (seconds)",
+ "type": "integer",
+ "name": "EpochMapInterval",
+ "restart_required": false
+ },
+ {
+ "description": "Warn of strings which use backslash quoting; using an E'...' escape string will avoid this warning",
+ "type": "integer",
+ "name": "EscapeStringWarning",
+ "restart_required": false
+ },
+ {
+ "description": "The number of bands or clusters to form when taking samples while executing evaluating_delete_performance().",
+ "type": "integer",
+ "name": "EvaluateDeletePerformanceSampleStorageBandCount",
+ "restart_required": false
+ },
+ {
+ "description": "The number of samples to take while executing evaluating_delete_performance().",
+ "type": "integer",
+ "name": "EvaluateDeletePerformanceSampleStorageCount",
+ "restart_required": false
+ },
+ {
+ "description": "Exclude ephemeral nodes in SELECT queries. Default is false",
+ "type": "integer",
+ "name": "ExcludeEphemeralNodesInQueries",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum number of rejected/exceptions records that will be written while querying an external table. Default: 100, Unlimited: -1",
+ "type": "integer",
+ "name": "ExternalTablesExceptionsLimit",
+ "restart_required": false
+ },
+ {
+ "description": "Time interval to wait before replacing a DOWN node with a STANDBY node",
+ "type": "integer",
+ "name": "FailoverToStandbyAfter",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum memory (in MB) for each UDx side process",
+ "type": "string",
+ "name": "FencedUDxMemoryLimitMB",
+ "restart_required": false
+ },
+ {
+ "description": "Number of files (per projection) that are allowed before new ROSs are prevented (ROS pushback)",
+ "type": "integer",
+ "name": "FilesPerProjectionLimit",
+ "restart_required": false
+ },
+ {
+ "description": "Multiplier to pad the observed length of fields in flex tables when casting them to regular vs long types",
+ "type": "integer",
+ "name": "FlexTableDataTypeGuessMultiplier",
+ "restart_required": false
+ },
+ {
+ "description": "Default size of __raw__ column in flex tables",
+ "type": "integer",
+ "name": "FlexTableRawSize",
+ "restart_required": false
+ },
+ {
+ "description": "Force all UDx's to run in fenced mode",
+ "type": "integer",
+ "name": "ForceUDxFencedMode",
+ "restart_required": false
+ },
+ {
+ "description": "Ensure catalog durable on disk after each commit",
+ "type": "integer",
+ "name": "FsyncCatalogForLuck",
+ "restart_required": false
+ },
+ {
+ "description": "Call fsync after each data file is written",
+ "type": "integer",
+ "name": "FsyncDataForLuck",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum amount of memory (in megabytes) that can be used by a single GROUP BY",
+ "type": "string",
+ "name": "GBHashMemCapMB",
+ "restart_required": false
+ },
+ {
+ "description": "Enables profiling for all statements at the EE operator level",
+ "type": "integer",
+ "name": "GlobalEEProfiling",
+ "restart_required": false
+ },
+ {
+ "description": "A user who'll inherit objects of dropped users. Should be unset (blank) by default (opt-in)",
+ "type": "string",
+ "name": "GlobalHeirUsername",
+ "restart_required": false
+ },
+ {
+ "description": "Enables profiling for all statements",
+ "type": "integer",
+ "name": "GlobalQueryProfiling",
+ "restart_required": false
+ },
+ {
+ "description": "Enables profiling for all sessions",
+ "type": "integer",
+ "name": "GlobalSessionProfiling",
+ "restart_required": false
+ },
+ {
+ "description": "When enabled, the hash prepass mode of the EE GroupGenerator operator will be used",
+ "type": "integer",
+ "name": "GroupGeneratorHashingEnabled",
+ "restart_required": false
+ },
+ {
+ "description": "Amount of time in seconds waiting for connection to WebHCat before abort",
+ "type": "integer",
+ "name": "HCatConnectionTimeout",
+ "restart_required": false
+ },
+ {
+ "description": "Name of the HCatalog User Defined Parser",
+ "type": "string",
+ "name": "HCatParserName",
+ "restart_required": false
+ },
+ {
+ "description": "Slow transfer in bytes/sec limit lower than which transfer will abort after 'HCatSlowTransferTime' amount of time",
+ "type": "integer",
+ "name": "HCatSlowTransferLimit",
+ "restart_required": false
+ },
+ {
+ "description": "Amount of time allowed for transfer below slow transfer limit before abort",
+ "type": "integer",
+ "name": "HCatSlowTransferTime",
+ "restart_required": false
+ },
+ {
+ "description": "Name of the HCatalog User Defined Source",
+ "type": "string",
+ "name": "HCatSourceName",
+ "restart_required": false
+ },
+ {
+ "description": "Name of the HCatalog webservice, used in constructing a url to query this service",
+ "type": "string",
+ "name": "HCatWebserviceName",
+ "restart_required": false
+ },
+ {
+ "description": "Version of the HCatalog webservice, used in constructing a url to query this service",
+ "type": "string",
+ "name": "HCatWebserviceVersion",
+ "restart_required": false
+ },
+ {
+ "description": "Upper bound on the number of epochs kept in the epoch map",
+ "type": "integer",
+ "name": "HistoryRetentionEpochs",
+ "restart_required": false
+ },
+ {
+ "description": "Number of seconds of epochs kept in the epoch map (seconds)",
+ "type": "integer",
+ "name": "HistoryRetentionTime",
+ "restart_required": false
+ },
+ {
+ "description": "Path to the java binary for executing UDx written in Java",
+ "type": "string",
+ "name": "JavaBinaryForUDx",
+ "restart_required": false
+ },
+ {
+ "description": "Minimum heap size (in MB) for Java UDx side process",
+ "type": "integer",
+ "name": "JavaSideProcessMinHeapSizeMB",
+ "restart_required": false
+ },
+ {
+ "description": "Keep ROS Min/Max values on all columns. Enables some optimizations, at a cost of catalog space.",
+ "type": "integer",
+ "name": "KeepMinMaxOnAllColumns",
+ "restart_required": false
+ },
+ {
+ "description": "SNMP event when the LGE for the node lags more than LGELagThreshold seconds behind the last epoch close time",
+ "type": "integer",
+ "name": "LGELagThreshold",
+ "restart_required": false
+ },
+ {
+ "description": "Controls the maximum ROS output in data load; Negative and zero will be considerred as 1.",
+ "type": "integer",
+ "name": "LoadMaxFinalROSCount",
+ "restart_required": false
+ },
+ {
+ "description": "Time to wait for a table lock before giving up (seconds)",
+ "type": "integer",
+ "name": "LockTimeout",
+ "restart_required": false
+ },
+ {
+ "description": "Interval (in seconds) at which heartbeat messsages are sent to vertica.log. (Set to 0 to disable.)",
+ "type": "integer",
+ "name": "LogHeartbeatInterval",
+ "restart_required": false
+ },
+ {
+ "description": "SNMP event LowDiskSpace is raised when disk utilization exceeds this percentage",
+ "type": "integer",
+ "name": "LowDiskSpaceWarningPct",
+ "restart_required": false
+ },
+ {
+ "description": "Max number of columns used in auto projection segmentation expression (0 is to use all columns)",
+ "type": "integer",
+ "name": "MaxAutoSegColumns",
+ "restart_required": false
+ },
+ {
+ "description": "ROS files which are smaller than this size (KB) are selected for bundling. '0' means bundling of separate ROS's is disabled, though pidx and fdb files of an individual ROS will be bundled if EnableStorageBundling is set. Maximum allowed size is 1024 (1048576 bytes)",
+ "type": "integer",
+ "name": "MaxBundleableROSSizeKB",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum number of client sessions; in addition five dbadmin sessions are allowed",
+ "type": "integer",
+ "name": "MaxClientSessions",
+ "restart_required": false
+ },
+ {
+ "description": "Defines the no. of constraint violation checks per internal query in analyze_constraints(). Default is -1",
+ "type": "integer",
+ "name": "MaxConstraintChecksPerQuery",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum file size for Data Collector logs in KB",
+ "type": "integer",
+ "name": "MaxDataCollectorFileSize",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum desired size of an EE block (used to move tuples between operators), actual block size be larger (must have capacity for at least 2 rows)",
+ "type": "integer",
+ "name": "MaxDesiredEEBlockSize",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum number of DVROSes attached to a single ROS container once reached dv merge out happens",
+ "type": "integer",
+ "name": "MaxDVROSPerContainer",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum length of individual lines (entries) in the vertica.log log file. Longer lines are truncated. '0' means no limit.",
+ "type": "integer",
+ "name": "MaxLogLineLength",
+ "restart_required": false
+ },
+ {
+ "description": "The max ROS size in MB a merge out job can produce",
+ "type": "integer",
+ "name": "MaxMrgOutROSSizeMB",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum amount of memory used by the Optimizer; Increasing this value may help with 'Optimizer memory use exceeds allowed limit' errors (MB)",
+ "type": "integer",
+ "name": "MaxOptMemMB",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum amount of memory used by the Optimizer in the context of DBD; Increasing this value may help with 'Run Database Designer with more memory or increase Database Designer memory usage limit' errors (MB)",
+ "type": "integer",
+ "name": "MaxOptMemMBInDBD",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum amount of memory allowed for parsing a single request; Increasing this value may help with 'Request size too big' errors (MB)",
+ "type": "integer",
+ "name": "MaxParsedQuerySizeMB",
+ "restart_required": false
+ },
+ {
+ "description": "Max no of partitions per projection",
+ "type": "integer",
+ "name": "MaxPartitionCount",
+ "restart_required": false
+ },
+ {
+ "description": "The number of times the system might try to re-run a query if the first run does not succeed.",
+ "type": "integer",
+ "name": "MaxQueryRetries",
+ "restart_required": false
+ },
+ {
+ "description": "# of failed attempts before recovery gives up",
+ "type": "integer",
+ "name": "MaxRecoverErrors",
+ "restart_required": true
+ },
+ {
+ "description": "Maximum number of historic passes made by Recovery before moving to the current pass where locks are taken",
+ "type": "integer",
+ "name": "MaxRecoverHistoricPasses",
+ "restart_required": true
+ },
+ {
+ "description": "# of failed attempts before refresh gives up",
+ "type": "integer",
+ "name": "MaxRefreshErrors",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum number of historic passes made by Refresh before moving to the current pass where locks are taken",
+ "type": "integer",
+ "name": "MaxRefreshHistoricPasses",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum of number of ROSes in a stratum once reached merge out happens",
+ "type": "integer",
+ "name": "MaxROSPerStratum",
+ "restart_required": false
+ },
+ {
+ "description": "Memory to allocate to per-node Merge Join",
+ "type": "integer",
+ "name": "MergeJoinInnerInitialMB",
+ "restart_required": false
+ },
+ {
+ "description": "If set to true cache will be used pick the projection for mergeout",
+ "type": "integer",
+ "name": "MergeOutCache",
+ "restart_required": false
+ },
+ {
+ "description": "Interval between Tuple Mover checks for mergeouts to perform (seconds)",
+ "type": "integer",
+ "name": "MergeOutInterval",
+ "restart_required": false
+ },
+ {
+ "description": "Minimum free before catalog writes are refused (MB) (Default(-1) is 1GB or 2% free)",
+ "type": "integer",
+ "name": "MinimumCatalogDiskMegabytes",
+ "restart_required": false
+ },
+ {
+ "description": "Minimum free before column data writes are refused (MB) (Default(-1) is 4GB or 5% free)",
+ "type": "integer",
+ "name": "MinimumDataDiskMegabytes",
+ "restart_required": false
+ },
+ {
+ "description": "Minimum free before temp data writes are refused (MB) (Default(-1) is 8GB or 10% free)",
+ "type": "integer",
+ "name": "MinimumDataDiskTempMegabytes",
+ "restart_required": false
+ },
+ {
+ "description": "Minimum size of the inner input to a join that will trigger the Optimizer to attempt a sort merge join (MB)",
+ "type": "integer",
+ "name": "MinSortMergeJoinMB",
+ "restart_required": false
+ },
+ {
+ "description": "Interval between Tuple Mover checks for moveouts to perform (seconds)",
+ "type": "integer",
+ "name": "MoveOutInterval",
+ "restart_required": false
+ },
+ {
+ "description": "The number of epochs data resides in WOS before the Tuple Mover triggers a moveout based on age",
+ "type": "integer",
+ "name": "MoveOutMaxAgeEpochs",
+ "restart_required": false
+ },
+ {
+ "description": "The amount of time data resides in WOS before the Tuple Mover triggers a moveout based on age (seconds)",
+ "type": "integer",
+ "name": "MoveOutMaxAgeTime",
+ "restart_required": false
+ },
+ {
+ "description": "The amount of WOS used before the Tuple Mover triggers a moveout based on utilization (percent)",
+ "type": "integer",
+ "name": "MoveOutSizePct",
+ "restart_required": false
+ },
+ {
+ "description": "Memory to allocate to per-node Prepass GroupBy Operator",
+ "type": "integer",
+ "name": "NewEEGroupBySmallMemMB",
+ "restart_required": false
+ },
+ {
+ "description": "Number of rows the EE will assign per thread when multiple threads are processing the same large ROS",
+ "type": "integer",
+ "name": "NewEEROSSubdivisionRows",
+ "restart_required": false
+ },
+ {
+ "description": "Number of threads the EE will attempt to use for processing (per plan)",
+ "type": "integer",
+ "name": "NewEEThreads",
+ "restart_required": false
+ },
+ {
+ "description": "Time to wait during shutdown, when auto recovery is not possible",
+ "type": "integer",
+ "name": "NoRecoverShutdownWait",
+ "restart_required": true
+ },
+ {
+ "description": "Use as recommended by Technical Support",
+ "type": "string",
+ "name": "OptVerticaOptions",
+ "restart_required": false
+ },
+ {
+ "description": "If true use a DT per local segment, even when sorting",
+ "type": "integer",
+ "name": "ParallelizeLocalSegmentLoad",
+ "restart_required": false
+ },
+ {
+ "description": "Override the heap memory allocator for PCRE pattern matching library",
+ "type": "integer",
+ "name": "PatternMatchAllocator",
+ "restart_required": true
+ },
+ {
+ "description": "Sets the recursion limit for PCRE used by pattern matching.",
+ "type": "integer",
+ "name": "PatternMatchingMatchLimitRecursion",
+ "restart_required": false
+ },
+ {
+ "description": "The max number of rows per partition for pattern matching",
+ "type": "integer",
+ "name": "PatternMatchingMaxPartition",
+ "restart_required": false
+ },
+ {
+ "description": "The max number of matches per partition for pattern matching",
+ "type": "integer",
+ "name": "PatternMatchingMaxPartitionMatches",
+ "restart_required": false
+ },
+ {
+ "description": "The size of ovector for pcre_exec. Increase if using ANY_ROW and there are many subpattern groupings",
+ "type": "integer",
+ "name": "PatternMatchingPerMatchWorkspaceSize",
+ "restart_required": false
+ },
+ {
+ "description": "Use JIT for PCRE regex matching in queries",
+ "type": "integer",
+ "name": "PatternMatchingUseJit",
+ "restart_required": false
+ },
+ {
+ "description": "Override the stack memory allocator for PCRE pattern matching library",
+ "type": "integer",
+ "name": "PatternMatchStackAllocator",
+ "restart_required": true
+ },
+ {
+ "description": "Pin Vertica to given number of CPUs (-1 = no pin)",
+ "type": "integer",
+ "name": "PinProcessors",
+ "restart_required": true
+ },
+ {
+ "description": "Processor index to start with when pinning processors",
+ "type": "integer",
+ "name": "PinProcessorsOffset",
+ "restart_required": true
+ },
+ {
+ "description": "If set to true, allows creating unsegmented projection using pre-excavator style",
+ "type": "integer",
+ "name": "PreExcavatorReplicatedProjection",
+ "restart_required": false
+ },
+ {
+ "description": "Only load DataCollector records which satisfy time based predicates",
+ "type": "integer",
+ "name": "PruneDataCollectorByTime",
+ "restart_required": false
+ },
+ {
+ "description": "Only load system table columns which participate in the query into SysWOS",
+ "type": "integer",
+ "name": "PruneSystemTableColumns",
+ "restart_required": false
+ },
+ {
+ "description": "Maximum % of rows that may be deleted before Tuple Mover purges the ROS through mergeout",
+ "type": "integer",
+ "name": "PurgeMergeoutPercent",
+ "restart_required": false
+ },
+ {
+ "description": "The max amount of memory MIN/MAX for RANGE moving window can use in MB",
+ "type": "integer",
+ "name": "RangeWindowMaxMem",
+ "restart_required": false
+ },
+ {
+ "description": "Before starting recovery, perform cleanup of deleted files",
+ "type": "integer",
+ "name": "ReapBeforeRecover",
+ "restart_required": true
+ },
+ {
+ "description": "When recovering a projection with an identical buddy from scratch recovery may be able to directly copy storage containers if this feature is enabled",
+ "type": "integer",
+ "name": "RecoverByContainer",
+ "restart_required": false
+ },
+ {
+ "description": "Seconds to wait for dirty transactions before cancelling the session",
+ "type": "integer",
+ "name": "RecoveryDirtyTxnWait",
+ "restart_required": false
+ },
+ {
+ "description": "Trigger moveout automatically on commit of data to WOS",
+ "type": "integer",
+ "name": "ReflexiveMoveout",
+ "restart_required": false
+ },
+ {
+ "description": "When refreshing a projection from an identical buddy refresh may be able to directly copy storage containers if this feature is enabled",
+ "type": "integer",
+ "name": "RefreshByContainer",
+ "restart_required": false
+ },
+ {
+ "description": "Configure the buffer size (in Byte) for remote initiator to cache query result. Value zero will turn off the feature of routing one-executor query plan to remote initator",
+ "type": "integer",
+ "name": "RemoteInitiatorBufSize",
+ "restart_required": false
+ },
+ {
+ "description": "Interval between checking and removing unused database snapshots (seconds)",
+ "type": "integer",
+ "name": "RemoveSnapshotInterval",
+ "restart_required": false
+ },
+ {
+ "description": "Switch Replay Delete to use the new algorithm once runtime scan statistics exceeds the threshold",
+ "type": "integer",
+ "name": "ReplayDeleteAlgorithmSwitchThreshold",
+ "restart_required": false
+ },
+ {
+ "description": "Fraction of total resources that can be assigned to locally initiated requests; the remainder is only used by remote requests",
+ "type": "integer",
+ "name": "ResLowLimPctOfHighLim",
+ "restart_required": true
+ },
+ {
+ "description": "Restrict non-dbadmin users from viewing system-tables",
+ "type": "integer",
+ "name": "RestrictSystemTables",
+ "restart_required": true
+ },
+ {
+ "description": "Number of 64K ROS blocks that may be kept in the decompression cache (default is 4096 blocks; 256MB)",
+ "type": "integer",
+ "name": "ROSCacheBlocks",
+ "restart_required": true
+ },
+ {
+ "description": "Number of large (>64K) ROS blocks that may be kept in the decompression cache (for Grouped ROSs)",
+ "type": "integer",
+ "name": "ROSCacheLargeBlocks",
+ "restart_required": true
+ },
+ {
+ "description": "Maximum of number of ROSes in a stratum once reached merge out happens",
+ "type": "integer",
+ "name": "ROSPerStratum",
+ "restart_required": false
+ },
+ {
+ "description": "Set the query duration threshold in microseconds to save profiling information to the dc_execution_engine_profiles table.",
+ "type": "integer",
+ "name": "SaveDCEEProfileThresholdUS",
+ "restart_required": false
+ },
+ {
+ "description": "NONE (Default) MD5 and SHA512",
+ "type": "string",
+ "name": "SecurityAlgorithm",
+ "restart_required": false
+ },
+ {
+ "description": "Auto projections will always be segmented. Default: true",
+ "type": "integer",
+ "name": "SegmentAutoProjection",
+ "restart_required": false
+ },
+ {
+ "description": "Create range segmentation on node_name for DataCollector tables",
+ "type": "integer",
+ "name": "SegmentDataCollector",
+ "restart_required": false
+ },
+ {
+ "description": "# Days. Delete closed session profiling data when data SessionProfilingAgeOut days old.",
+ "type": "integer",
+ "name": "SessionProfilingAgeOut",
+ "restart_required": false
+ },
+ {
+ "description": "If the average of the rows scanned squared during a delete is higher than this limit, a warning message about the projection is printed to the conole. Disable by setting to -1.",
+ "type": "integer",
+ "name": "SlowDeleteConsoleWarningLimit",
+ "restart_required": false
+ },
+ {
+ "description": "If the average of the rows scanned squared during a delete is higher than this limit, a warning message about the projection is printed to the vertica.log and saved in vs_comments. This limit is also used by evaluate_delete_performance to determine if a projection is likely to have slow delete performance. Disable by setting to -1. Console delete performance warnings will still be printed to log.",
+ "type": "integer",
+ "name": "SlowDeleteSystemWarningLimit",
+ "restart_required": false
+ },
+ {
+ "description": "Size per column below which a ROS is automatically stored grouped (bytes)",
+ "type": "integer",
+ "name": "SmallROSSize",
+ "restart_required": false
+ },
+ {
+ "description": "Least length of time (in seconds) a snapshot has existed for before systemTask tries to remove it",
+ "type": "integer",
+ "name": "SnapshotRetentionTime",
+ "restart_required": false
+ },
+ {
+ "description": "Where Vertica sends SNMP traps - 'host_name port CommunityString'. This is a comma-separated list.",
+ "type": "string",
+ "name": "SnmpTrapDestinationsList",
+ "restart_required": false
+ },
+ {
+ "description": "List of events that Vertica traps: Low Disk Space, Read Only File System, Loss of K Safety, Current Fault Tolerance at Critical Level, Too Many ROS Containers, WOS Over Flow, Node State Change, Recovery Failure, Recovery Error, Recovery Lock Error, Recovery Projection Retrieval Error, Refresh Error, Tuple Mover Error, Stale Checkpoint",
+ "type": "string",
+ "name": "SnmpTrapEvents",
+ "restart_required": false
+ },
+ {
+ "description": "Enable sending of SNMP traps",
+ "type": "integer",
+ "name": "SnmpTrapsEnabled",
+ "restart_required": false
+ },
+ {
+ "description": "SortCheck to generate SortCheck step in plan",
+ "type": "integer",
+ "name": "SortCheckOption",
+ "restart_required": false
+ },
+ {
+ "description": "Report Level for Sort Order violation. default for error. 0 for logging, 1 for error, 2 for panic",
+ "type": "integer",
+ "name": "SortOrderReportLevel",
+ "restart_required": false
+ },
+ {
+ "description": "Controls the number of Sort worker threads; 0 disables background threads",
+ "type": "integer",
+ "name": "SortWorkerThreads",
+ "restart_required": false
+ },
+ {
+ "description": "The server's SSL CA certificate",
+ "type": "string",
+ "name": "SSLCA",
+ "restart_required": true
+ },
+ {
+ "description": "The server's SSL certificate",
+ "type": "string",
+ "name": "SSLCertificate",
+ "restart_required": true
+ },
+ {
+ "description": "The server's SSL private key",
+ "type": "string",
+ "name": "SSLPrivateKey",
+ "restart_required": true
+ },
+ {
+ "description": "Disable backslash quoting in string constants; required to conform to standard SQL",
+ "type": "integer",
+ "name": "StandardConformingStrings",
+ "restart_required": false
+ },
+ {
+ "description": "Sets the behavior to deal with undeclared UDx function parameters",
+ "type": "integer",
+ "name": "StrictUDxParameterChecking",
+ "restart_required": false
+ },
+ {
+ "description": "Enable event trapping for Syslog",
+ "type": "integer",
+ "name": "SyslogEnabled",
+ "restart_required": false
+ },
+ {
+ "description": "Low Disk Space, Read Only File System, Loss of K Safety, Current Fault Tolerance at Critical Level, Too Many ROS Containers, WOS Over Flow, Node State Change, Recovery Failure, Recovery Error, Recovery Lock Error, Recovery Projection Retrieval Error, Refresh Error, Tuple Mover Error, Stale Checkpoint",
+ "type": "string",
+ "name": "SyslogEvents",
+ "restart_required": false
+ },
+ {
+ "description": "auth, uucp, authpriv (Linux only) local0, cron, local1, daemon, local2, ftp (Linux only) local3, lpr, local4, mail, local5, news, local6, user (default system) local7",
+ "type": "string",
+ "name": "SyslogFacility",
+ "restart_required": false
+ },
+ {
+ "description": "Interval between system resource utilization monitoring checks (seconds)",
+ "type": "integer",
+ "name": "SystemMonitorInterval",
+ "restart_required": false
+ },
+ {
+ "description": "A message is logged if a monitored system resource changes by at least SystemMonitorThreshold (percent)",
+ "type": "integer",
+ "name": "SystemMonitorThreshold",
+ "restart_required": false
+ },
+ {
+ "description": "Turn on terraced (multi-level) data network routing if it would reduce stream count by this factor",
+ "type": "integer",
+ "name": "TerraceRoutingFactor",
+ "restart_required": false
+ },
+ {
+ "description": "When updating the index to account for deleted records in the source table, pre-compute the tokens for the deleted records. This takes time, but speeds up the actual deletion.",
+ "type": "integer",
+ "name": "TextIndexComputeDeletedTokens",
+ "restart_required": false
+ },
+ {
+ "description": "Default maximum size of tokens stored for text-indexing. Only affects new indices. Larger values will decrease the performance of the index.",
+ "type": "integer",
+ "name": "TextIndexMaxTokenLength",
+ "restart_required": false
+ },
+ {
+ "description": "The max amount of memory TopK(Heap) can use in MB",
+ "type": "integer",
+ "name": "TopKHeapMaxMem",
+ "restart_required": false
+ },
+ {
+ "description": "READ COMMITTED (Default) - Last epoch for reads and current epoch for writes. SERIALIZABLE - Current epoch for reads and writes",
+ "type": "string",
+ "name": "TransactionIsolationLevel",
+ "restart_required": false
+ },
+ {
+ "description": "Determines whether the transaction is read/write or read-only. Read/write is the default",
+ "type": "string",
+ "name": "TransactionMode",
+ "restart_required": false
+ },
+ {
+ "description": "Trust pk and unique constraint as guarantee of uniqueness",
+ "type": "integer",
+ "name": "TrustConstraintsAsUnique",
+ "restart_required": false
+ },
+ {
+ "description": "Number of seconds to wait for UDx to finish a block of data before give up",
+ "type": "integer",
+ "name": "UDxFencedBlockTimeout",
+ "restart_required": false
+ },
+ {
+ "description": "Number of seconds to wait for UDx to finish cancel related clean up work",
+ "type": "integer",
+ "name": "UDxFencedCancelTimeout",
+ "restart_required": false
+ },
+ {
+ "description": "Number of seconds to wait for external procedures in UDx fenced mode",
+ "type": "integer",
+ "name": "UDxFencedExternalProcedureTimeout",
+ "restart_required": false
+ },
+ {
+ "description": "Optimizer uses modular hash for resegmenting intermediate results.",
+ "type": "integer",
+ "name": "UseModularHashForReseg",
+ "restart_required": false
+ },
+ {
+ "description": "Optimizer only considers redistribution choices which are cost model resilient.",
+ "type": "integer",
+ "name": "UseOnlyResilientRedistribution",
+ "restart_required": false
+ },
+ {
+ "description": "Include virtual table data from recovering nodes in monitoring query results",
+ "type": "integer",
+ "name": "UseRecoveringNodesInVirtualTableQueries",
+ "restart_required": false
+ },
+ {
+ "description": "Use safer decompression scheme to reduce the chance of crashes if disk data has been corrupted",
+ "type": "integer",
+ "name": "UseSafeDecompression",
+ "restart_required": false
+ },
+ {
+ "description": "Use 5.0-style truncating integer division for the '/' operator",
+ "type": "integer",
+ "name": "UseV50IntegerDivision",
+ "restart_required": false
+ },
+ {
+ "description": "Execute the external procedures in the zygote process",
+ "type": "integer",
+ "name": "UseZygoteForExternalProcedures",
+ "restart_required": false
+ },
+ {
+ "description": "Create a log entry each time a client opens a connection and closes it immediately; load balancers often do this for a health check",
+ "type": "integer",
+ "name": "WarnOnIncompleteStartupPacket",
+ "restart_required": false
+ },
+ {
+ "description": "Use materialization strategy to support the WITH clause",
+ "type": "integer",
+ "name": "WithClauseMaterialization",
+ "restart_required": false
+ }
+ ]
+}
diff --git a/trove/tests/int_tests.py b/trove/tests/int_tests.py
index cd07f84c..238b9ebe 100644
--- a/trove/tests/int_tests.py
+++ b/trove/tests/int_tests.py
@@ -222,4 +222,4 @@ register(["pxc_supported"], common_groups,
register(["redis_supported"], common_groups,
backup_groups, replication_groups, cluster_actions_groups)
register(["vertica_supported"], common_groups,
- cluster_actions_groups, root_actions_groups)
+ cluster_actions_groups, root_actions_groups, configuration_groups)
diff --git a/trove/tests/scenario/helpers/vertica_helper.py b/trove/tests/scenario/helpers/vertica_helper.py
new file mode 100644
index 00000000..7245ced1
--- /dev/null
+++ b/trove/tests/scenario/helpers/vertica_helper.py
@@ -0,0 +1,54 @@
+# Copyright 2016 Tesora Inc.
+# All Rights Reserved.
+#
+# 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.
+
+from proboscis import SkipTest
+
+from trove.tests.scenario.helpers.sql_helper import SqlHelper
+
+
+class VerticaHelper(SqlHelper):
+
+ def __init__(self, expected_override_name):
+ super(VerticaHelper, self).__init__(expected_override_name, 'vertica')
+
+ def get_helper_credentials(self):
+ return {'name': 'lite', 'password': 'litepass', 'database': 'lite'}
+
+ def get_valid_user_definitions(self):
+ return [{'name': 'user1', 'password': 'password1', 'databases': []},
+ {'name': 'user2', 'password': 'password1',
+ 'databases': [{'name': 'db1'}]},
+ {'name': 'user3', 'password': 'password1',
+ 'databases': [{'name': 'db1'}, {'name': 'db2'}]}]
+
+ def add_actual_data(self, *args, **kwargs):
+ raise SkipTest("Adding data to Vertica is not implemented")
+
+ def verify_actual_data(self, *args, **kwargs):
+ raise SkipTest("Verifying data in Vertica is not implemented")
+
+ def remove_actual_data(self, *args, **kwargs):
+ raise SkipTest("Removing data from Vertica is not implemented")
+
+ def get_dynamic_group(self):
+ return {'ActivePartitionCount': 3}
+
+ def get_non_dynamic_group(self):
+ return {'BlockCacheSize': 1024}
+
+ def get_invalid_groups(self):
+ return [{'timezone': 997},
+ {"max_worker_processes": 'string_value'},
+ {"standard_conforming_strings": 'string_value'}]
diff --git a/trove/tests/unittests/guestagent/test_dbaas.py b/trove/tests/unittests/guestagent/test_dbaas.py
index e807800e..a24a0388 100644
--- a/trove/tests/unittests/guestagent/test_dbaas.py
+++ b/trove/tests/unittests/guestagent/test_dbaas.py
@@ -39,6 +39,7 @@ from trove.common.exception import ProcessExecutionError
from trove.common import instance as rd_instance
from trove.common import utils
from trove.conductor import api as conductor_api
+from trove.guestagent.common.configuration import ConfigurationManager
from trove.guestagent.common.configuration import ImportOverrideStrategy
from trove.guestagent.common import operating_system
from trove.guestagent.common import sql_query
@@ -2728,7 +2729,10 @@ class VerticaAppStatusTest(trove_testtools.TestCase):
class VerticaAppTest(trove_testtools.TestCase):
- def setUp(self):
+ @patch.object(ImportOverrideStrategy, '_initialize_import_directory')
+ @patch.multiple(operating_system, exists=DEFAULT, write_file=DEFAULT,
+ chown=DEFAULT, chmod=DEFAULT)
+ def setUp(self, *args, **kwargs):
super(VerticaAppTest, self).setUp()
self.FAKE_ID = 1000
self.appStatus = FakeAppStatus(self.FAKE_ID,
@@ -2758,14 +2762,14 @@ class VerticaAppTest(trove_testtools.TestCase):
super(VerticaAppTest, self).tearDown()
def test_enable_root_is_root_not_enabled(self):
- app = VerticaApp(MagicMock())
- with patch.object(app, 'read_config', return_value=self.test_config):
- with patch.object(app, 'is_root_enabled', return_value=False):
+ with patch.object(self.app, 'read_config',
+ return_value=self.test_config):
+ with patch.object(self.app, 'is_root_enabled', return_value=False):
with patch.object(vertica_system, 'exec_vsql_command',
MagicMock(side_effect=[['', ''],
['', ''],
['', '']])):
- app.enable_root('root_password')
+ self.app.enable_root('root_password')
create_user_arguments = (
vertica_system.exec_vsql_command.call_args_list[0])
expected_create_user_cmd = (
@@ -2793,22 +2797,25 @@ class VerticaAppTest(trove_testtools.TestCase):
@patch('trove.guestagent.datastore.experimental.vertica.service.LOG')
def test_enable_root_is_root_not_enabled_failed(self, *args):
- app = VerticaApp(MagicMock())
- with patch.object(app, 'read_config', return_value=self.test_config):
- with patch.object(app, 'is_root_enabled', return_value=False):
+ with patch.object(self.app, 'read_config',
+ return_value=self.test_config):
+ with patch.object(self.app, 'is_root_enabled', return_value=False):
with patch.object(vertica_system, 'exec_vsql_command',
- MagicMock(side_effect=[['', 'err']])):
- self.assertRaises(RuntimeError, app.enable_root,
+ MagicMock(side_effect=[
+ ['', vertica_system.VSqlError(
+ 'ERROR 123: Test'
+ )]])):
+ self.assertRaises(RuntimeError, self.app.enable_root,
'root_password')
@patch('trove.guestagent.datastore.experimental.vertica.service.LOG')
def test_enable_root_is_root_enabled(self, *args):
- app = VerticaApp(MagicMock())
- with patch.object(app, 'read_config', return_value=self.test_config):
- with patch.object(app, 'is_root_enabled', return_value=True):
+ with patch.object(self.app, 'read_config',
+ return_value=self.test_config):
+ with patch.object(self.app, 'is_root_enabled', return_value=True):
with patch.object(vertica_system, 'exec_vsql_command',
MagicMock(side_effect=[['', '']])):
- app.enable_root('root_password')
+ self.app.enable_root('root_password')
alter_user_password_arguments = (
vertica_system.exec_vsql_command.call_args_list[0])
expected_alter_user_cmd = (
@@ -2820,21 +2827,23 @@ class VerticaAppTest(trove_testtools.TestCase):
@patch('trove.guestagent.datastore.experimental.vertica.service.LOG')
def test_enable_root_is_root_enabled_failed(self, *arg):
- app = VerticaApp(MagicMock())
- with patch.object(app, 'read_config', return_value=self.test_config):
- with patch.object(app, 'is_root_enabled', return_value=True):
+ with patch.object(self.app, 'read_config',
+ return_value=self.test_config):
+ with patch.object(self.app, 'is_root_enabled', return_value=True):
with patch.object(vertica_system, 'exec_vsql_command',
MagicMock(side_effect=[
- ['', ProcessExecutionError]])):
- self.assertRaises(RuntimeError, app.enable_root,
+ ['', vertica_system.VSqlError(
+ 'ERROR 123: Test'
+ )]])):
+ self.assertRaises(RuntimeError, self.app.enable_root,
'root_password')
def test_is_root_enable(self):
- app = VerticaApp(MagicMock())
- with patch.object(app, 'read_config', return_value=self.test_config):
+ with patch.object(self.app, 'read_config',
+ return_value=self.test_config):
with patch.object(vertica_system, 'shell_execute',
MagicMock(side_effect=[['', '']])):
- app.is_root_enabled()
+ self.app.is_root_enabled()
user_exists_args = (
vertica_system.shell_execute.call_args_list[0])
expected_user_exists_cmd = vertica_system.USER_EXISTS % (
@@ -2844,12 +2853,12 @@ class VerticaAppTest(trove_testtools.TestCase):
@patch('trove.guestagent.datastore.experimental.vertica.service.LOG')
def test_is_root_enable_failed(self, *args):
- app = VerticaApp(MagicMock())
- with patch.object(app, 'read_config', return_value=self.test_config):
+ with patch.object(self.app, 'read_config',
+ return_value=self.test_config):
with patch.object(vertica_system, 'shell_execute',
MagicMock(side_effect=[
['', ProcessExecutionError]])):
- self.assertRaises(RuntimeError, app.is_root_enabled)
+ self.assertRaises(RuntimeError, self.app.is_root_enabled)
def test_install_if_needed_installed(self):
with patch.object(pkg.Package, 'pkg_is_installed', return_value=True):
@@ -2963,7 +2972,10 @@ class VerticaAppTest(trove_testtools.TestCase):
# delete the temporary_config_file
os.unlink(temp_file_handle.name)
- def test_restart(self):
+ @patch.object(ImportOverrideStrategy, '_initialize_import_directory')
+ @patch.multiple(operating_system, exists=DEFAULT, write_file=DEFAULT,
+ chown=DEFAULT, chmod=DEFAULT)
+ def test_restart(self, *args, **kwargs):
mock_status = MagicMock()
app = VerticaApp(mock_status)
mock_status.begin_restart = MagicMock(return_value=None)
@@ -2978,7 +2990,10 @@ class VerticaAppTest(trove_testtools.TestCase):
VerticaApp.stop_db.assert_any_call()
VerticaApp.start_db.assert_any_call()
- def test_start_db(self):
+ @patch.object(ImportOverrideStrategy, '_initialize_import_directory')
+ @patch.multiple(operating_system, exists=DEFAULT, write_file=DEFAULT,
+ chown=DEFAULT, chmod=DEFAULT)
+ def test_start_db(self, *args, **kwargs):
mock_status = MagicMock()
type(mock_status)._is_restarting = PropertyMock(return_value=False)
app = VerticaApp(mock_status)
@@ -3000,30 +3015,26 @@ class VerticaAppTest(trove_testtools.TestCase):
db_start.assert_called_with(db_expected_cmd)
def test_start_db_failure(self):
- mock_status = MagicMock()
- app = VerticaApp(mock_status)
- with patch.object(app, '_enable_db_on_boot',
+ with patch.object(self.app, '_enable_db_on_boot',
side_effect=RuntimeError()):
- with patch.object(app, 'read_config',
+ with patch.object(self.app, 'read_config',
return_value=self.test_config):
- self.assertRaises(RuntimeError, app.start_db)
+ self.assertRaises(RuntimeError, self.app.start_db)
def test_stop_db(self):
- mock_status = MagicMock()
- type(mock_status)._is_restarting = PropertyMock(return_value=False)
- app = VerticaApp(mock_status)
- with patch.object(app, '_disable_db_on_boot', return_value=None):
- with patch.object(app, 'read_config',
+ type(self.appStatus)._is_restarting = PropertyMock(return_value=False)
+ with patch.object(self.app, '_disable_db_on_boot', return_value=None):
+ with patch.object(self.app, 'read_config',
return_value=self.test_config):
with patch.object(vertica_system, 'shell_execute',
MagicMock(side_effect=[['', ''],
['db_srvr', None],
['', '']])):
- mock_status.wait_for_real_status_to_change_to = MagicMock(
- return_value=True)
- mock_status.end_restart = MagicMock(
+ self.appStatus.wait_for_real_status_to_change_to = \
+ MagicMock(return_value=True)
+ self.appStatus.end_restart = MagicMock(
return_value=None)
- app.stop_db()
+ self.app.stop_db()
self.assertEqual(
3, vertica_system.shell_execute.call_count)
@@ -3035,34 +3046,30 @@ class VerticaAppTest(trove_testtools.TestCase):
arguments = vertica_system.shell_execute.call_args_list[2]
expected_cmd = (vertica_system.STOP_DB % ('db_srvr',
'some_password'))
- self.assertTrue(
- mock_status.wait_for_real_status_to_change_to.called)
+ self.assertTrue(self.appStatus.
+ wait_for_real_status_to_change_to.called)
arguments.assert_called_with(expected_cmd, 'dbadmin')
def test_stop_db_do_not_start_on_reboot(self):
- mock_status = MagicMock()
- type(mock_status)._is_restarting = PropertyMock(return_value=True)
- app = VerticaApp(mock_status)
- with patch.object(app, '_disable_db_on_boot', return_value=None):
- with patch.object(app, 'read_config',
+ type(self.appStatus)._is_restarting = PropertyMock(return_value=True)
+ with patch.object(self.app, '_disable_db_on_boot', return_value=None):
+ with patch.object(self.app, 'read_config',
return_value=self.test_config):
with patch.object(vertica_system, 'shell_execute',
MagicMock(side_effect=[['', ''],
['db_srvr', None],
['', '']])):
- app.stop_db(do_not_start_on_reboot=True)
+ self.app.stop_db(do_not_start_on_reboot=True)
self.assertEqual(
3, vertica_system.shell_execute.call_count)
- app._disable_db_on_boot.assert_any_call()
+ self.app._disable_db_on_boot.assert_any_call()
def test_stop_db_database_not_running(self):
- mock_status = MagicMock()
- app = VerticaApp(mock_status)
- with patch.object(app, '_disable_db_on_boot', return_value=None):
- with patch.object(app, 'read_config',
+ with patch.object(self.app, '_disable_db_on_boot', return_value=None):
+ with patch.object(self.app, 'read_config',
return_value=self.test_config):
- app.stop_db()
+ self.app.stop_db()
# Since database stop command does not gets executed,
# so only 2 shell calls were there.
self.assertEqual(
@@ -3070,21 +3077,19 @@ class VerticaAppTest(trove_testtools.TestCase):
@patch('trove.guestagent.datastore.experimental.vertica.service.LOG')
def test_stop_db_failure(self, *args):
- mock_status = MagicMock()
- type(mock_status)._is_restarting = PropertyMock(return_value=False)
- app = VerticaApp(mock_status)
- with patch.object(app, '_disable_db_on_boot', return_value=None):
- with patch.object(app, 'read_config',
+ type(self.appStatus)._is_restarting = PropertyMock(return_value=False)
+ with patch.object(self.app, '_disable_db_on_boot', return_value=None):
+ with patch.object(self.app, 'read_config',
return_value=self.test_config):
with patch.object(vertica_system, 'shell_execute',
MagicMock(side_effect=[['', ''],
['db_srvr', None],
['', '']])):
- mock_status.wait_for_real_status_to_change_to = MagicMock(
- return_value=None)
- mock_status.end_restart = MagicMock(
+ self.appStatus.wait_for_real_status_to_change_to = \
+ MagicMock(return_value=None)
+ self.appStatus.end_restart = MagicMock(
return_value=None)
- self.assertRaises(RuntimeError, app.stop_db)
+ self.assertRaises(RuntimeError, self.app.stop_db)
def test_export_conf_to_members(self):
self.app._export_conf_to_members(members=['member1', 'member2'])
@@ -3092,11 +3097,11 @@ class VerticaAppTest(trove_testtools.TestCase):
@patch('trove.guestagent.datastore.experimental.vertica.service.LOG')
def test_fail__export_conf_to_members(self, *args):
- app = VerticaApp(MagicMock())
+ # app = VerticaApp(MagicMock())
with patch.object(vertica_system, 'shell_execute',
side_effect=ProcessExecutionError('Error')):
self.assertRaises(ProcessExecutionError,
- app._export_conf_to_members,
+ self.app._export_conf_to_members,
['member1', 'member2'])
def test_authorize_public_keys(self):
@@ -3182,8 +3187,7 @@ class VerticaAppTest(trove_testtools.TestCase):
self.assertEqual(5, vertica_system.shell_execute.call_count)
def test__enable_db_on_boot(self):
- app = VerticaApp(MagicMock())
- app._enable_db_on_boot()
+ self.app._enable_db_on_boot()
restart_policy, agent_enable = subprocess.Popen.call_args_list
expected_restart_policy = [
@@ -3205,8 +3209,7 @@ class VerticaAppTest(trove_testtools.TestCase):
self.app._enable_db_on_boot)
def test__disable_db_on_boot(self):
- app = VerticaApp(MagicMock())
- app._disable_db_on_boot()
+ self.app._disable_db_on_boot()
restart_policy, agent_disable = (
vertica_system.shell_execute.call_args_list)
@@ -3228,10 +3231,9 @@ class VerticaAppTest(trove_testtools.TestCase):
self.app._disable_db_on_boot)
def test_read_config(self):
- app = VerticaApp(MagicMock())
with patch.object(ConfigParser, 'ConfigParser',
return_value=self.test_config):
- test_config = app.read_config()
+ test_config = self.app.read_config()
self.assertEqual('some_password',
test_config.get('credentials', 'dbadmin_password')
)
@@ -3242,14 +3244,17 @@ class VerticaAppTest(trove_testtools.TestCase):
side_effect=ConfigParser.Error()):
self.assertRaises(RuntimeError, self.app.read_config)
- def test_start_db_with_conf_changes(self):
- mock_status = MagicMock()
- type(mock_status)._is_restarting = PropertyMock(return_value=False)
- app = VerticaApp(mock_status)
- with patch.object(app, 'read_config',
+ @patch.object(ConfigurationManager, 'save_configuration')
+ def test_start_db_with_conf_changes(self, save_cfg):
+ type(self.appStatus)._is_restarting = PropertyMock(return_value=False)
+ type(self.appStatus).is_running = PropertyMock(return_value=False)
+ with patch.object(self.app, 'read_config',
return_value=self.test_config):
- app.start_db_with_conf_changes('test_config_contents')
- app.status.end_restart.assert_any_call()
+ with patch.object(self.appStatus, 'end_restart') as end_restart:
+ config = 'tst_cfg_contents'
+ self.app.start_db_with_conf_changes(config)
+ save_cfg.assert_called_once_with(config)
+ end_restart.assert_any_call()
class DB2AppTest(trove_testtools.TestCase):
diff --git a/trove/tests/unittests/guestagent/test_vertica_manager.py b/trove/tests/unittests/guestagent/test_vertica_manager.py
index ab8d185f..74c7b0b4 100644
--- a/trove/tests/unittests/guestagent/test_vertica_manager.py
+++ b/trove/tests/unittests/guestagent/test_vertica_manager.py
@@ -11,6 +11,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from mock import DEFAULT
from mock import MagicMock
from mock import patch
from os import path
@@ -18,6 +19,8 @@ from testtools.matchers import Is
from trove.common.exception import DatastoreOperationNotSupported
from trove.common import instance as rd_instance
+from trove.guestagent.common import configuration
+from trove.guestagent.common.configuration import ImportOverrideStrategy
from trove.guestagent.common import operating_system
from trove.guestagent.datastore.experimental.vertica.manager import Manager
from trove.guestagent.datastore.experimental.vertica.service import (
@@ -31,7 +34,11 @@ from trove.tests.unittests import trove_testtools
class GuestAgentManagerTest(trove_testtools.TestCase):
- def setUp(self):
+
+ @patch.object(ImportOverrideStrategy, '_initialize_import_directory')
+ @patch.multiple(operating_system, exists=DEFAULT, write_file=DEFAULT,
+ chown=DEFAULT, chmod=DEFAULT)
+ def setUp(self, *args, **kwargs):
super(GuestAgentManagerTest, self).setUp()
self.context = trove_testtools.TroveTestContext(self)
self.manager = Manager()
@@ -80,6 +87,7 @@ class GuestAgentManagerTest(trove_testtools.TestCase):
mock_status.update.assert_any_call()
@patch.object(path, 'exists', MagicMock())
+ @patch.object(configuration.ConfigurationManager, 'save_configuration')
def _prepare_dynamic(self, packages,
config_content='MockContent', device_path='/dev/vdb',
backup_id=None,
@@ -233,13 +241,6 @@ class GuestAgentManagerTest(trove_testtools.TestCase):
mock_set_status.assert_called_with(
rd_instance.ServiceStatuses.INSTANCE_READY, force=True)
- def test_reset_configuration(self):
- try:
- configuration = {'config_contents': 'some junk'}
- self.manager.reset_configuration(self.context, configuration)
- except Exception:
- self.fail("reset_configuration raised exception unexpectedly.")
-
def test_rpc_ping(self):
output = self.manager.rpc_ping(self.context)
self.assertTrue(output)