mirror of
				https://git.proxmox.com/git/mirror_corosync
				synced 2025-11-04 13:15:00 +00:00 
			
		
		
		
	This is counterpart of adcc21a30c70a40861736bc9d902c2ef2d4b42c4 in pacemaker. Signed-off-by: Jan Friesse <jfriesse@redhat.com>
		
			
				
	
	
		
			326 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			326 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/python
 | 
						|
 | 
						|
'''CTS: Cluster Testing System: Lab environment module
 | 
						|
 '''
 | 
						|
 | 
						|
__copyright__='''
 | 
						|
Copyright (c) 2010 Red Hat, Inc.
 | 
						|
 | 
						|
'''
 | 
						|
 | 
						|
# All rights reserved.
 | 
						|
# 
 | 
						|
# Author: Angus Salkeld <asalkeld@redhat.com>
 | 
						|
#
 | 
						|
# This software licensed under BSD license, the text of which follows:
 | 
						|
# 
 | 
						|
# Redistribution and use in source and binary forms, with or without
 | 
						|
# modification, are permitted provided that the following conditions are met:
 | 
						|
# 
 | 
						|
# - Redistributions of source code must retain the above copyright notice,
 | 
						|
#   this list of conditions and the following disclaimer.
 | 
						|
# - Redistributions in binary form must reproduce the above copyright notice,
 | 
						|
#   this list of conditions and the following disclaimer in the documentation
 | 
						|
#   and/or other materials provided with the distribution.
 | 
						|
# - Neither the name of the MontaVista Software, Inc. nor the names of its
 | 
						|
#   contributors may be used to endorse or promote products derived from this
 | 
						|
#   software without specific prior written permission.
 | 
						|
# 
 | 
						|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
						|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
						|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
						|
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 | 
						|
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
						|
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
						|
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
						|
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
						|
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
						|
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
						|
# THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
 | 
						|
import sys
 | 
						|
from cts.CTSscenarios import *
 | 
						|
from corotests import CoroTestList
 | 
						|
from corosync import *
 | 
						|
 | 
						|
 | 
						|
sys.path.append("/usr/share/pacemaker/tests/cts") # So that things work from the source directory
 | 
						|
 | 
						|
try:
 | 
						|
    from CTSlab import *
 | 
						|
 | 
						|
except ImportError:
 | 
						|
    sys.stderr.write("abort: couldn't find CTSLab in [%s]\n" %
 | 
						|
                     ' '.join(sys.path))
 | 
						|
    sys.stderr.write("(check your install and PYTHONPATH)\n")
 | 
						|
    sys.exit(-1)
 | 
						|
 | 
						|
tests = None
 | 
						|
cm = None
 | 
						|
old_handler = None
 | 
						|
DefaultFacility = "daemon"
 | 
						|
 | 
						|
 | 
						|
def usage(arg):
 | 
						|
    print "Illegal argument " + arg
 | 
						|
    print "usage: " + sys.argv[0] +" [options] number-of-iterations" 
 | 
						|
    print "\nCommon options: "  
 | 
						|
    print "\t [--at-boot (1|0)],         does the cluster software start at boot time" 
 | 
						|
    print "\t [--nodes 'node list'],     list of cluster nodes separated by whitespace" 
 | 
						|
    print "\t [--limit-nodes max],       only use the first 'max' cluster nodes supplied with --nodes" 
 | 
						|
    print "\t [--logfile path],          where should the test software look for logs from cluster nodes" 
 | 
						|
    print "\t [--rrp-bindaddr addr],       extra interface used for rrp, provide the bindaddr" 
 | 
						|
    print "\t [--outputfile path],       optional location for the test software to write logs to" 
 | 
						|
    print "\t [--syslog-facility name],  which syslog facility should the test software log to" 
 | 
						|
    print "\t [--choose testcase-name],  run only the named test" 
 | 
						|
    print "\t [--list-tests],            list the valid tests" 
 | 
						|
    print "\t [--benchmark],             add the timing information" 
 | 
						|
    print "\t "
 | 
						|
    print "Additional (less common) options: "  
 | 
						|
    print "\t [--trunc (truncate logfile before starting)]" 
 | 
						|
    print "\t [--xmit-loss lost-rate(0.0-1.0)]" 
 | 
						|
    print "\t [--recv-loss lost-rate(0.0-1.0)]" 
 | 
						|
    print "\t [--standby (1 | 0 | yes | no)]" 
 | 
						|
    print "\t [--fencing (1 | 0 | yes | no)]" 
 | 
						|
    print "\t [--once],                 run all valid tests once" 
 | 
						|
    print "\t [--no-loop-tests],        dont run looping/time-based tests" 
 | 
						|
    print "\t [--no-unsafe-tests],      dont run tests that are unsafe for use with ocfs2/drbd" 
 | 
						|
    print "\t [--valgrind-tests],       include tests using valgrind" 
 | 
						|
    print "\t [--experimental-tests],   include experimental tests" 
 | 
						|
    print "\t [--oprofile 'node list'], list of cluster nodes to run oprofile on]" 
 | 
						|
    print "\t [--qarsh]                 Use the QARSH backdoor to access nodes instead of SSH"
 | 
						|
    print "\t [--seed random_seed]"
 | 
						|
    print "\t [--set option=value]"
 | 
						|
    sys.exit(1)
 | 
						|
 | 
						|
class CoroLabEnvironment(CtsLab):
 | 
						|
 | 
						|
    def __init__(self):
 | 
						|
        CtsLab.__init__(self)
 | 
						|
 | 
						|
        #  Get a random seed for the random number generator.
 | 
						|
        self["DoStonith"] = 0
 | 
						|
        self["DoStandby"] = 0
 | 
						|
        self["DoFencing"] = 0
 | 
						|
        self["XmitLoss"] = "0.0"
 | 
						|
        self["RecvLoss"] = "0.0"
 | 
						|
        self["IPBase"] = "127.0.0.10"
 | 
						|
        self["ClobberCIB"] = 0
 | 
						|
        self["CIBfilename"] = None
 | 
						|
        self["CIBResource"] = 0
 | 
						|
        self["DoBSC"]    = 0
 | 
						|
        self["use_logd"] = 0
 | 
						|
        self["oprofile"] = []
 | 
						|
        self["RrpBindAddr"] = None
 | 
						|
        self["warn-inactive"] = 0
 | 
						|
        self["ListTests"] = 0
 | 
						|
        self["benchmark"] = 0
 | 
						|
        self["logrestartcmd"] = "systemctl restart rsyslog.service 2>&1 > /dev/null"
 | 
						|
        self["syslogd"] ="rsyslog"
 | 
						|
        self["Schema"] = "corosync 2.0"
 | 
						|
        self["Stack"] = "corosync (needle)"
 | 
						|
        self['CMclass'] = corosync_needle
 | 
						|
        self["stonith-type"] = "external/ssh"
 | 
						|
        self["stonith-params"] = "hostlist=all,livedangerously=yes"
 | 
						|
        self["at-boot"] = 0  # Does the cluster software start automatically when the node boot 
 | 
						|
        self["logger"] = ([StdErrLog(self)])
 | 
						|
        self["loop-minutes"] = 60
 | 
						|
        self["valgrind-prefix"] = None
 | 
						|
        self["valgrind-procs"] = "corosync"
 | 
						|
        self["valgrind-opts"] = """--leak-check=full --show-reachable=yes --trace-children=no --num-callers=25 --gen-suppressions=all --suppressions="""+CTSvars.CTS_home+"""/cts.supp"""
 | 
						|
 | 
						|
        self["experimental-tests"] = 0
 | 
						|
        self["valgrind-tests"] = 0
 | 
						|
        self["unsafe-tests"] = 0
 | 
						|
        self["loop-tests"] = 0
 | 
						|
        self["all-once"] = 0
 | 
						|
        self["LogWatcher"] = "remote"
 | 
						|
        self["SyslogFacility"] = DefaultFacility
 | 
						|
        self["stats"] = 0
 | 
						|
 | 
						|
#
 | 
						|
# Main entry into the test system.
 | 
						|
#
 | 
						|
if __name__ == '__main__': 
 | 
						|
    Environment = CoroLabEnvironment()
 | 
						|
 | 
						|
    NumIter = 0
 | 
						|
    Version = 1
 | 
						|
    LimitNodes = 0
 | 
						|
    TestCase = None
 | 
						|
    TruncateLog = 0
 | 
						|
    ListTests = 0
 | 
						|
    HaveSeed = 0
 | 
						|
    node_list = ''
 | 
						|
 | 
						|
    #
 | 
						|
    # The values of the rest of the parameters are now properly derived from
 | 
						|
    # the configuration files.
 | 
						|
    #
 | 
						|
    # Set the signal handler
 | 
						|
    signal.signal(15, sig_handler)
 | 
						|
    signal.signal(10, sig_handler)
 | 
						|
    
 | 
						|
    # Process arguments...
 | 
						|
 | 
						|
    skipthis=None
 | 
						|
    args=sys.argv[1:]
 | 
						|
    for i in range(0, len(args)):
 | 
						|
       if skipthis:
 | 
						|
           skipthis=None
 | 
						|
           continue
 | 
						|
 | 
						|
       elif args[i] == "-l" or args[i] == "--limit-nodes":
 | 
						|
           skipthis=1
 | 
						|
           LimitNodes = int(args[i+1])
 | 
						|
 | 
						|
       elif args[i] == "-L" or args[i] == "--logfile":
 | 
						|
           skipthis=1
 | 
						|
           Environment["LogFileName"] = args[i+1]
 | 
						|
 | 
						|
       elif args[i] == "--outputfile":
 | 
						|
           skipthis=1
 | 
						|
           Environment["OutputFile"] = args[i+1]
 | 
						|
 | 
						|
       elif args[i] == "--rrp-bindaddr":
 | 
						|
           skipthis=1
 | 
						|
           Environment["RrpBindAddr"] = args[i+1]
 | 
						|
 | 
						|
       elif args[i] == "--oprofile":
 | 
						|
           skipthis=1
 | 
						|
           Environment["oprofile"] = args[i+1].split(' ')
 | 
						|
 | 
						|
       elif args[i] == "--trunc":
 | 
						|
           Environment["TruncateLog"]=1
 | 
						|
 | 
						|
       elif args[i] == "--list-tests":
 | 
						|
           Environment["ListTests"]=1
 | 
						|
 | 
						|
       elif args[i] == "--benchmark":
 | 
						|
           Environment["benchmark"]=1
 | 
						|
 | 
						|
       elif args[i] == "--qarsh":
 | 
						|
           Environment.rsh.enable_qarsh()
 | 
						|
 | 
						|
       elif args[i] == "--fencing":
 | 
						|
           skipthis=1
 | 
						|
           if args[i+1] == "1" or args[i+1] == "yes":
 | 
						|
               Environment["DoFencing"] = 1
 | 
						|
           elif args[i+1] == "0" or args[i+1] == "no":
 | 
						|
               Environment["DoFencing"] = 0
 | 
						|
           else:
 | 
						|
               usage(args[i+1])
 | 
						|
 | 
						|
       elif args[i] == "--xmit-loss":
 | 
						|
           try:
 | 
						|
               float(args[i+1])
 | 
						|
           except ValueError:
 | 
						|
               print ("--xmit-loss parameter should be float")
 | 
						|
               usage(args[i+1])
 | 
						|
           skipthis=1
 | 
						|
           Environment["XmitLoss"] = args[i+1]
 | 
						|
 | 
						|
       elif args[i] == "--recv-loss":
 | 
						|
           try:
 | 
						|
               float(args[i+1])
 | 
						|
           except ValueError:
 | 
						|
               print ("--recv-loss parameter should be float")
 | 
						|
               usage(args[i+1])
 | 
						|
           skipthis=1
 | 
						|
           Environment["RecvLoss"] = args[i+1]
 | 
						|
 | 
						|
       elif args[i] == "--choose":
 | 
						|
           skipthis=1
 | 
						|
           TestCase = args[i+1]
 | 
						|
 | 
						|
       elif args[i] == "--nodes":
 | 
						|
           skipthis=1
 | 
						|
           node_list = args[i+1].split(' ')
 | 
						|
 | 
						|
       elif args[i] == "--at-boot" or args[i] == "--cluster-starts-at-boot":
 | 
						|
           skipthis=1
 | 
						|
           if args[i+1] == "1" or args[i+1] == "yes":
 | 
						|
               Environment["at-boot"] = 1
 | 
						|
           elif args[i+1] == "0" or args[i+1] == "no":
 | 
						|
               Environment["at-boot"] = 0
 | 
						|
           else:
 | 
						|
               usage(args[i+1])
 | 
						|
 | 
						|
       elif args[i] == "--set":
 | 
						|
           skipthis=1
 | 
						|
           (name, value) = args[i+1].split('=')
 | 
						|
           Environment[name] = value
 | 
						|
 | 
						|
       else:
 | 
						|
           try:
 | 
						|
               NumIter=int(args[i])
 | 
						|
           except ValueError:
 | 
						|
               usage(args[i])
 | 
						|
 | 
						|
    if Environment["OutputFile"]:
 | 
						|
        Environment["logger"].append(FileLog(Environment, Environment["OutputFile"]))
 | 
						|
 | 
						|
    if len(node_list) < 1:
 | 
						|
        print "No nodes specified!"
 | 
						|
        sys.exit(1)
 | 
						|
 | 
						|
    if LimitNodes > 0:
 | 
						|
        if len(node_list) > LimitNodes:
 | 
						|
            print("Limiting the number of nodes configured=%d (max=%d)"
 | 
						|
                  %(len(node_list), LimitNodes))
 | 
						|
            while len(node_list) > LimitNodes:
 | 
						|
                node_list.pop(len(node_list)-1)
 | 
						|
 | 
						|
    Environment["nodes"] = node_list
 | 
						|
 | 
						|
    # Create the Cluster Manager object
 | 
						|
    cm = Environment['CMclass'](Environment)
 | 
						|
    Audits = CoroAuditList(cm)
 | 
						|
        
 | 
						|
    if Environment["ListTests"] == 1 :
 | 
						|
        Tests = CoroTestList(cm, Audits)
 | 
						|
        Environment.log("Total %d tests"%len(Tests))
 | 
						|
        for test in Tests :
 | 
						|
            Environment.log(str(test.name));
 | 
						|
        sys.exit(0)
 | 
						|
 | 
						|
    if TruncateLog:
 | 
						|
        Environment.log("Truncating %s" % LogFile)
 | 
						|
        lf = open(LogFile, "w");
 | 
						|
        if lf != None:
 | 
						|
            lf.truncate(0)
 | 
						|
            lf.close()
 | 
						|
 | 
						|
    if TestCase != None:
 | 
						|
        for test in CoroTestList(cm, Audits):
 | 
						|
            if test.name == TestCase:
 | 
						|
                Tests.append(test)
 | 
						|
        if Tests == []:
 | 
						|
            usage("--choose: No applicable/valid tests chosen")        
 | 
						|
 | 
						|
    else:
 | 
						|
        Tests = CoroTestList(cm, Audits)
 | 
						|
    
 | 
						|
    # Scenario selection
 | 
						|
    if Environment["DoBSC"]:
 | 
						|
        scenario = RandomTests(cm, [ BasicSanityCheck(Environment) ], Audits, Tests)
 | 
						|
 | 
						|
    elif Environment["all-once"] or NumIter == 0: 
 | 
						|
        NumIter = len(Tests)
 | 
						|
        scenario = AllOnce(
 | 
						|
            cm, [ InitClusterManager(Environment), TestAgentComponent(Environment), PacketLoss(Environment) ], Audits, Tests)
 | 
						|
    else:
 | 
						|
        scenario = RandomTests(
 | 
						|
            cm, [ InitClusterManager(Environment), TestAgentComponent(Environment), PacketLoss(Environment) ], Audits, Tests)
 | 
						|
 | 
						|
    Environment.log(">>>>>>>>>>>>>>>> BEGINNING " + repr(NumIter) + " TESTS ")
 | 
						|
    Environment.log("Stack:            %s" % Environment["Stack"])
 | 
						|
    Environment.log("Schema:           %s" % Environment["Schema"])
 | 
						|
    Environment.log("Scenario:         %s" % scenario.__doc__)
 | 
						|
    Environment.log("Random Seed:      %s" % Environment["RandSeed"])
 | 
						|
    Environment.log("System log files: %s" % Environment["LogFileName"])
 | 
						|
 | 
						|
    Environment.dump()
 | 
						|
    rc = Environment.run(scenario, NumIter)
 | 
						|
    sys.exit(rc)
 |