qa: test mgr live configuration updates

Signed-off-by: John Spray <john.spray@redhat.com>
This commit is contained in:
John Spray 2018-04-10 09:28:36 -04:00
parent 98a3d0e04a
commit d4ed33c2e0
3 changed files with 132 additions and 11 deletions

View File

@ -48,13 +48,13 @@ class MgrCluster(CephCluster):
return [s['name'] for s in self.get_mgr_map()["standbys"]]
def set_module_conf(self, module, key, val):
self.mon_manager.raw_cluster_cmd("config-key", "set",
self.mon_manager.raw_cluster_cmd("config", "set", "mgr",
"mgr/{0}/{1}".format(
module, key
), val)
def set_module_localized_conf(self, module, mgr_id, key, val):
self.mon_manager.raw_cluster_cmd("config-key", "set",
self.mon_manager.raw_cluster_cmd("config", "set", "mgr",
"mgr/{0}/{1}/{2}".format(
module, mgr_id, key
), val)

View File

@ -2,10 +2,13 @@
import time
import requests
import errno
import logging
from teuthology.exceptions import CommandFailedError
from tasks.mgr.mgr_test_case import MgrTestCase
log = logging.getLogger(__name__)
class TestModuleSelftest(MgrTestCase):
"""
@ -49,6 +52,111 @@ class TestModuleSelftest(MgrTestCase):
self._load_module("selftest")
self.mgr_cluster.mon_manager.raw_cluster_cmd("mgr", "self-test", "run")
def test_selftest_config_update(self):
"""
That configuration updates are seen by running mgr modules
"""
self._load_module("selftest")
def get_value():
return self.mgr_cluster.mon_manager.raw_cluster_cmd(
"mgr", "self-test", "config", "get", "testkey").strip()
self.assertEqual(get_value(), "None")
self.mgr_cluster.mon_manager.raw_cluster_cmd("config", "set",
"mgr", "mgr/selftest/testkey", "testvalue")
self.wait_until_equal(get_value, "testvalue",timeout=10)
active_id = self.mgr_cluster.get_active_id()
def get_localized_value():
return self.mgr_cluster.mon_manager.raw_cluster_cmd(
"mgr", "self-test", "config", "get_localized", "testlkey").strip()
self.mgr_cluster.mon_manager.raw_cluster_cmd("config", "set",
"mgr", "mgr/selftest/{0}/testlkey".format(active_id),
"test localized value")
self.wait_until_equal(get_localized_value, "test localized value",
timeout=10)
def test_selftest_config_upgrade(self):
"""
That pre-mimic config-key config settings are migrated into
mimic-style config settings and visible from mgr modules.
"""
self._load_module("selftest")
def get_value():
return self.mgr_cluster.mon_manager.raw_cluster_cmd(
"mgr", "self-test", "config", "get", "testkey").strip()
def get_config():
lines = self.mgr_cluster.mon_manager.raw_cluster_cmd(
"config", "dump")\
.strip().split("\n")
result = []
for line in lines[1:]:
tokens = line.strip().split()
log.info("tokens: {0}".format(tokens))
subsys, key, value = tokens[0], tokens[2], tokens[3]
result.append((subsys, key, value))
return result
# Stop ceph-mgr while we synthetically create a pre-mimic
# configuration scenario
for mgr_id in self.mgr_cluster.mgr_daemons.keys():
self.mgr_cluster.mgr_stop(mgr_id)
self.mgr_cluster.mgr_fail(mgr_id)
# Blow away any modern-style mgr module config options
# (the ceph-mgr implementation may only do the upgrade if
# it doesn't see new style options)
stash = []
for subsys, key, value in get_config():
if subsys == "mgr" and key.startswith("mgr/"):
log.info("Removing config key {0} ahead of upgrade".format(
key))
self.mgr_cluster.mon_manager.raw_cluster_cmd(
"config", "rm", subsys, key)
stash.append((subsys, key, value))
# Inject an old-style configuration setting in config-key
self.mgr_cluster.mon_manager.raw_cluster_cmd(
"config-key", "set", "mgr/selftest/testkey", "testvalue")
# Inject configuration settings that looks data-ish and should
# not be migrated to a config key
self.mgr_cluster.mon_manager.raw_cluster_cmd(
"config-key", "set", "mgr/selftest/testnewline", "foo\nbar")
# Bring mgr daemons back online, the one that goes active
# should be doing the upgrade.
for mgr_id in self.mgr_cluster.mgr_daemons.keys():
self.mgr_cluster.mgr_restart(mgr_id)
# Wait for a new active
self.wait_until_true(
lambda: self.mgr_cluster.get_active_id() != "", timeout=30)
# Check that the selftest module sees the upgraded value
self.assertEqual(get_value(), "testvalue")
# Check that the upgraded value is visible in the configuration
seen_keys = [k for s,k,v in get_config()]
self.assertIn("mgr/selftest/testkey", seen_keys)
# And that the non-config-looking one isn't
self.assertNotIn("mgr/selftest/testnewline", seen_keys)
# Restore previous configuration
for subsys, key, value in stash:
self.mgr_cluster.mon_manager.raw_cluster_cmd(
"config", "set", subsys, key, value)
def test_selftest_command_spam(self):
# Use the selftest module to stress the mgr daemon
self._load_module("selftest")

View File

@ -29,23 +29,31 @@ class Module(MgrModule):
{
"cmd": "mgr self-test run",
"desc": "Run mgr python interface tests",
"perm": "r"
"perm": "rw"
},
{
"cmd": "mgr self-test background start name=workload,type=CephString",
"desc": "Activate a background workload (one of {0})".format(
", ".join(WORKLOADS)),
"perm": "r"
"perm": "rw"
},
{
"cmd": "mgr self-test background stop",
"desc": "Stop background workload if any is running",
"perm": "r"
"perm": "rw"
},
{
"cmd": "mgr self-test config get name=key,type=CephString",
"desc": "Peek at a configuration value",
"perm": "rw"
},
{
"cmd": "mgr self-test config get_localized name=key,type=CephString",
"desc": "Peek at a configuration value (localized variant)",
"perm": "rw"
},
]
def __init__(self, *args, **kwargs):
super(Module, self).__init__(*args, **kwargs)
self._event = threading.Event()
@ -73,7 +81,10 @@ class Module(MgrModule):
was_running)
else:
return 0, '', 'No background workload was running'
elif command['prefix'] == 'mgr self-test config get':
return 0, str(self.get_config(command['key'])), ''
elif command['prefix'] == 'mgr self-test config get_localized':
return 0, str(self.get_localized_config(command['key'])), ''
else:
return (-errno.EINVAL, '',
"Command not found '{0}'".format(command['prefix']))
@ -139,16 +150,18 @@ class Module(MgrModule):
self.set_localized_config("testkey", "testvalue")
assert self.get_localized_config("testkey") == "testvalue"
assert sorted(self.get_config_prefix("test").keys()) == sorted(
["testkey"])
def _self_test_store(self):
existing_keys = set(self.get_store_prefix("test").keys())
self.set_store("testkey", "testvalue")
assert self.get_store("testkey") == "testvalue"
self.set_store_json("testjsonkey", {"testblob": 2})
assert self.get_store_json("testjsonkey") == {"testblob": 2}
assert sorted(self.get_store_prefix("test").keys()) == sorted(
list({"testkey", "testjsonkey"} | existing_keys))
def _self_test_perf_counters(self):
self.get_perf_schema("osd", "0")
self.get_counter("osd", "0", "osd.op")