diff --git a/cts/lab/CM_corosync.py b/cts/lab/CM_corosync.py deleted file mode 100644 index 9a79e46d0a..0000000000 --- a/cts/lab/CM_corosync.py +++ /dev/null @@ -1,60 +0,0 @@ -""" Corosync-specific class for Pacemaker's Cluster Test Suite (CTS) -""" - -__copyright__ = "Copyright 2007-2023 the Pacemaker project contributors" -__license__ = "GNU General Public License version 2 or later (GPLv2+) WITHOUT ANY WARRANTY" - -from pacemaker._cts.CTS import Process -from pacemaker._cts.clustermanager import ClusterManager -from pacemaker._cts.patterns import PatternSelector - -class crm_corosync(ClusterManager): - ''' - Corosync version 2 cluster manager class - ''' - def __init__(self, name=None): - if not name: name="crm-corosync" - ClusterManager.__init__(self) - - self.fullcomplist = {} - self.templates = PatternSelector(self.name) - - @property - def components(self): - complist = [] - if not len(list(self.fullcomplist.keys())): - for c in [ "pacemaker-based", "pacemaker-controld", "pacemaker-attrd", "pacemaker-execd", "pacemaker-fenced" ]: - self.fullcomplist[c] = Process( - self, c, - pats = self.templates.get_component(c), - badnews_ignore = self.templates.get_component("%s-ignore" % c) + - self.templates.get_component("common-ignore")) - - # the scheduler uses dc_pats instead of pats - self.fullcomplist["pacemaker-schedulerd"] = Process( - self, "pacemaker-schedulerd", - dc_pats = self.templates.get_component("pacemaker-schedulerd"), - badnews_ignore = self.templates.get_component("pacemaker-schedulerd-ignore") + - self.templates.get_component("common-ignore")) - - # add (or replace) extra components - self.fullcomplist["corosync"] = Process( - self, "corosync", - pats = self.templates.get_component("corosync"), - badnews_ignore = self.templates.get_component("corosync-ignore") + - self.templates.get_component("common-ignore") - ) - - # Processes running under valgrind can't be shot with "killall -9 processname", - # so don't include them in the returned list - vgrind = self.env["valgrind-procs"].split() - for key in list(self.fullcomplist.keys()): - if self.env["valgrind-tests"]: - if key in vgrind: - self.log("Filtering %s from the component list as it is being profiled by valgrind" % key) - continue - if key == "pacemaker-fenced" and not self.env["DoFencing"]: - continue - complist.append(self.fullcomplist[key]) - - return complist diff --git a/cts/lab/CTSlab.py.in b/cts/lab/CTSlab.py.in index 667c6fe167..31d3a63f6e 100644 --- a/cts/lab/CTSlab.py.in +++ b/cts/lab/CTSlab.py.in @@ -1,132 +1,131 @@ #!@PYTHON@ """ Command-line interface to Pacemaker's Cluster Test Suite (CTS) """ __copyright__ = "Copyright 2001-2023 the Pacemaker project contributors" __license__ = "GNU General Public License version 2 or later (GPLv2+) WITHOUT ANY WARRANTY" import sys, signal, os pdir = os.path.dirname(sys.path[0]) sys.path.insert(0, pdir) # So that things work from the source directory try: - from cts.CM_corosync import * - from pacemaker._cts.CTS import CtsLab + from pacemaker._cts.cmcorosync import Corosync2 from pacemaker._cts.audits import audit_list from pacemaker._cts.logging import LogFactory from pacemaker._cts.scenarios import AllOnce, Boot, BootCluster, LeaveBooted, RandomTests, Sequence from pacemaker._cts.tests import test_list except ImportError as e: sys.stderr.write("abort: %s\n" % e) sys.stderr.write("check your install and PYTHONPATH; couldn't find cts libraries in:\n%s\n" % ' '.join(sys.path)) sys.exit(1) # These are globals so they can be used by the signal handler. scenario = None LogFactory().add_stderr() def sig_handler(signum, frame) : LogFactory().log("Interrupted by signal %d"%signum) if scenario: scenario.summarize() if signum == 15 : if scenario: scenario.teardown() sys.exit(1) def plural_s(n, uppercase=False): if n == 1: return "" elif uppercase: return "S" else: return "s" if __name__ == '__main__': Environment = CtsLab(sys.argv[1:]) NumIter = Environment["iterations"] Tests = [] # Set the signal handler signal.signal(15, sig_handler) signal.signal(10, sig_handler) # Create the Cluster Manager object cm = None if Environment["Stack"] == "corosync 2+": - cm = crm_corosync() + cm = Corosync2() else: LogFactory().log("Unknown stack: "+Environment["stack"]) sys.exit(1) if Environment["TruncateLog"]: if Environment["OutputFile"] is None: LogFactory().log("Ignoring truncate request because no output file specified") else: LogFactory().log("Truncating %s" % Environment["OutputFile"]) with open(Environment["OutputFile"], "w") as outputfile: outputfile.truncate(0) Audits = audit_list(cm) if Environment["ListTests"]: Tests = test_list(cm, Audits) LogFactory().log("Total %d tests"%len(Tests)) for test in Tests : LogFactory().log(str(test.name)); sys.exit(0) elif len(Environment["tests"]) == 0: Tests = test_list(cm, Audits) else: Chosen = Environment["tests"] for TestCase in Chosen: match = None for test in test_list(cm, Audits): if test.name == TestCase: match = test if not match: LogFactory().log("--choose: No applicable/valid tests chosen") sys.exit(1) else: Tests.append(match) # Scenario selection if Environment["scenario"] == "all-once": NumIter = len(Tests) scenario = AllOnce( cm, [ BootCluster(cm, Environment) ], Audits, Tests) elif Environment["scenario"] == "sequence": scenario = Sequence( cm, [ BootCluster(cm, Environment) ], Audits, Tests) elif Environment["scenario"] == "boot": scenario = Boot(cm, [ LeaveBooted(cm, Environment)], Audits, []) else: scenario = RandomTests( cm, [ BootCluster(cm, Environment) ], Audits, Tests) LogFactory().log(">>>>>>>>>>>>>>>> BEGINNING " + repr(NumIter) + " TEST" + plural_s(NumIter, True) + " ") LogFactory().log("Stack: %s (%s)" % (Environment["Stack"], Environment["Name"])) LogFactory().log("Schema: %s" % Environment["Schema"]) LogFactory().log("Scenario: %s" % scenario.__doc__) LogFactory().log("CTS Exerciser: %s" % Environment["cts-exerciser"]) LogFactory().log("CTS Logfile: %s" % Environment["OutputFile"]) LogFactory().log("Random Seed: %s" % Environment["RandSeed"]) LogFactory().log("Syslog variant: %s" % Environment["syslogd"].strip()) LogFactory().log("System log files: %s" % Environment["LogFileName"]) if "IPBase" in Environment: LogFactory().log("Base IP for resources: %s" % Environment["IPBase"]) LogFactory().log("Cluster starts at boot: %d" % Environment["at-boot"]) Environment.dump() rc = Environment.run(scenario, NumIter) sys.exit(rc) diff --git a/cts/lab/Makefile.am b/cts/lab/Makefile.am index 88c771a45a..cb7ef99415 100644 --- a/cts/lab/Makefile.am +++ b/cts/lab/Makefile.am @@ -1,25 +1,21 @@ # # Copyright 2001-2023 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # MAINTAINERCLEANFILES = Makefile.in noinst_SCRIPTS = cluster_test \ OCFIPraTest.py # Commands intended to be run only via other commands halibdir = $(CRM_DAEMON_DIR) dist_halib_SCRIPTS = cts-log-watcher -ctslibdir = $(pythondir)/cts -ctslib_PYTHON = __init__.py \ - CM_corosync.py - ctsdir = $(datadir)/$(PACKAGE)/tests/cts cts_SCRIPTS = CTSlab.py \ cts diff --git a/cts/lab/__init__.py b/cts/lab/__init__.py deleted file mode 100644 index ba6a429ea2..0000000000 --- a/cts/lab/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Python modules for Pacemaker's Cluster Test Suite (CTS) - -This package provides the following modules: - -CIB -cib_xml -CM_common -CM_corosync -CTS -CTSscenarios -CTStests -patterns -watcher -""" diff --git a/python/pacemaker/_cts/Makefile.am b/python/pacemaker/_cts/Makefile.am index f20726874a..d1d12cebef 100644 --- a/python/pacemaker/_cts/Makefile.am +++ b/python/pacemaker/_cts/Makefile.am @@ -1,34 +1,35 @@ # # Copyright 2023 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # MAINTAINERCLEANFILES = Makefile.in pkgpythondir = $(pythondir)/$(PACKAGE)/_cts pkgpython_PYTHON = CTS.py \ __init__.py \ audits.py \ cib.py \ cibxml.py \ clustermanager.py \ + cmcorosync.py \ corosync.py \ environment.py \ errors.py \ input.py \ logging.py \ network.py \ patterns.py \ process.py \ remote.py \ scenarios.py \ test.py \ timer.py \ watcher.py SUBDIRS = tests diff --git a/python/pacemaker/_cts/cmcorosync.py b/python/pacemaker/_cts/cmcorosync.py new file mode 100644 index 0000000000..868ad2c67d --- /dev/null +++ b/python/pacemaker/_cts/cmcorosync.py @@ -0,0 +1,73 @@ +""" Corosync-specific class for Pacemaker's Cluster Test Suite (CTS) """ + +__all__ = ["Corosync2"] +__copyright__ = "Copyright 2007-2023 the Pacemaker project contributors" +__license__ = "GNU General Public License version 2 or later (GPLv2+) WITHOUT ANY WARRANTY" + +from pacemaker._cts.CTS import Process +from pacemaker._cts.clustermanager import ClusterManager +from pacemaker._cts.patterns import PatternSelector + +# Throughout this file, pylint has trouble understanding that EnvFactory +# is a singleton instance that can be treated as a subscriptable object. +# Various warnings are disabled because of this. See also a comment about +# self._rsh in environment.py. +# pylint: disable=unsubscriptable-object + +class Corosync2(ClusterManager): + """ A subclass of ClusterManager specialized to handle corosync2 and later + based clusters + """ + + def __init__(self): + """ Create a new Corosync2 instance """ + + ClusterManager.__init__(self) + + self._fullcomplist = {} + self.templates = PatternSelector(self.name) + + @property + def components(self): + """ A list of all patterns that should be ignored for the cluster's + components. + """ + + complist = [] + + if not self._fullcomplist: + common_ignore = self.templates.get_component("common-ignore") + + for c in [ "pacemaker-based", "pacemaker-controld", "pacemaker-attrd", "pacemaker-execd", "pacemaker-fenced" ]: + badnews = self.templates.get_component("%s-ignore" % c) + common_ignore + proc = Process(self, c, pats=self.templates.get_component(c), + badnews_ignore=badnews) + self._fullcomplist[c] = proc + + # the scheduler uses dc_pats instead of pats + badnews = self.templates.get_component("pacemaker-schedulerd-ignore") + common_ignore + proc = Process(self, "pacemaker-schedulerd", + dc_pats=self.templates.get_component("pacemaker-schedulerd"), + badnews_ignore=badnews) + self._fullcomplist["pacemaker-schedulerd"] = proc + + # add (or replace) extra components + badnews = self.templates.get_component("corosync-ignore") + common_ignore + proc = Process(self, "corosync", pats=self.templates.get_component("corosync"), + badnews_ignore=badnews) + self._fullcomplist["corosync"] = proc + + # Processes running under valgrind can't be shot with "killall -9 processname", + # so don't include them in the returned list + vgrind = self.env["valgrind-procs"].split() + for (key, val) in self._fullcomplist.items(): + if self.env["valgrind-tests"] and key in vgrind: + self.log("Filtering %s from the component list as it is being profiled by valgrind" % key) + continue + + if key == "pacemaker-fenced" and not self.env["DoFencing"]: + continue + + complist.append(val) + + return complist