diff options
Diffstat (limited to 'Libraries')
-rwxr-xr-x | Libraries/ClientUtils/ATFClientUtils.py | 213 | ||||
-rwxr-xr-x | Libraries/GlusterCommands/ATFGlusterPeer.py | 38 | ||||
-rwxr-xr-x | Libraries/GlusterCommands/ATFGlusterVolume.py | 230 | ||||
-rwxr-xr-x | Libraries/GlusterCommands/ATFGlusterd.py | 103 | ||||
-rwxr-xr-x | Libraries/Log/ATFLog.py | 221 | ||||
-rwxr-xr-x | Libraries/Ssh/ATFSsh.py | 177 | ||||
-rwxr-xr-x | Libraries/TestEnv/ATFTestEnv.py | 460 | ||||
-rwxr-xr-x | Libraries/Tests/ATFTests.py | 105 | ||||
-rwxr-xr-x | Libraries/Utils/ATFUtils.py | 402 | ||||
-rw-r--r-- | Libraries/Validate/ATFValidate.py | 79 |
10 files changed, 2028 insertions, 0 deletions
diff --git a/Libraries/ClientUtils/ATFClientUtils.py b/Libraries/ClientUtils/ATFClientUtils.py new file mode 100755 index 0000000..e3a1bfe --- /dev/null +++ b/Libraries/ClientUtils/ATFClientUtils.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python + +import re +import ATFUtils + +def create_mountpoint(mountname, **arguments): + """ + Description: + Create a Mount Point On the Client + + Parameter: + mountname: Name of the MountPoint + **arguments: key=value pair for specifying server, host, user + + Example: + mountname=mount1 + server=server1 + host=host1 + user=user1 + + Returns: + Success: 0 + Failure: 1 + """ + + command = "mkdir -p" + mountpoint = ATFUtils.TestEnvObj.get_mountpoint(mountname) + + if mountpoint == '': + ATFUtils.Logger.error("MountPoint: %s Not defined in GlobalParam File" + % mountname) + return 1 + else: + command = command + " " + mountpoint + + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if status == 1: + return 1 + else: + output = ATFUtils.parse_output(stdout, stderr) + return ATFUtils.set_environ(ATF_MOUNTPOINT = mountname) + +def umount(mountname, **arguments): + """ + Description: + Unmount a mount point + + Parameters: + mountname: Name of the mountpoint to unmount + **arguments: key=value pair for specifying server, host, user + + Example: + mountname=mount1 + server=server1 + host=host1 + user=user1 + + Returns: + Success: 0 + Failure: 1 + """ + + command = "umount" + + mountpoint = ATFUtils.TestEnvObj.get_mountpoint(mountname) + + if mountpoint == '': + ATFUtils.Logger.error("MountPoint: %s Not defined in GlobalParam File" + % mountname) + return 1 + else: + command = command + " " + mountpoint + + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if status == 1: + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + + +def mount(mountname, fstype, hostvolume, **arguments): + """ + Description: + Mount a filesystem + + Parameter: + mountname: Absolute Path of the mount point + fstype: FileSystem type + hostvolume: HostVolumeName to mount on mountpoint + **arguments: key=value pair for specifying host, user + + Returns: + Success: 0 + Failure: 1 + """ + + command = "mount" + mounttype = " -t " + fstype + command = command + mounttype + hostkey, volumekey = re.split(":", hostvolume) + + host = ATFUtils.TestEnvObj.get_host(hostkey) + if host == '': + ATFUtils.Logger.error("Host %s Not defined in GlobalParam File" % + hostkey) + return 1 + + volumename = ATFUtils.TestEnvObj.get_volume(volumekey) + if volumename == '': + ATFUtils.Logger.error("Volume %s Not defined in GlobalParam File" % + volumekey) + return 1 + + mountpoint = ATFUtils.TestEnvObj.get_mountpoint(mountname) + if mountpoint == '': + ATFUtils.Logger.error("MountPoint: %s Not defined in GlobalParam File" + % mountname) + return 1 + + hostvolume = host + ":" + volumename + command = command + " " + hostvolume + " " + mountpoint + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if status == 1: + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + + +def touch(filename, mountname='', **arguments): + """ + Description: + Creates a File. + + Parameters: + filename: Name of a file + mountname : Name of the MountPoint + **arguments: key=value pair for specifying host, user + + Returns: + Success: 0 + Failure: 1 + """ + + command = "touch" + + if mountname == '': + mountname = ATFUtils.get_environ('ATF_MOUNTPOINT') + if mountname == 1: + return 1 + + mountpoint = ATFUtils.TestEnvObj.get_mountpoint(mountname) + if mountpoint == '': + ATFUtils.Logger.error("MountPoint: %s Not defined in GlobalParam File" + % mountname) + return 1 + + abspath = mountpoint + "/" + filename + command = command + " " + abspath + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if status == 1: + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + +def mkdir(dirname, mountname='', **arguments): + """ + Description: + Create a Directory under the mountpoint + + Parameters: + dirname: directory path (Relative path from the mount point) + mountname: Name of the Mount Point + **arguments: key=value pair for specifying host, user + + Returns: + Success: 0 + Failure: 1 + """ + + command = "mkdir" + + if mountname == '': + mountname = ATFUtils.get_environ('ATF_MOUNTPOINT') + if mountname == 1: + return 1 + + mountpoint = ATFUtils.TestEnvObj.get_mountpoint(mountname) + if mountpoint == '': + ATFUtils.Logger.error("MountPoint: %s Not defined in GlobalParam File" + % mountname) + return 1 + + abspath = mountpoint + "/" + dirname + command = command + " " + abspath + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if status == 1: + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + diff --git a/Libraries/GlusterCommands/ATFGlusterPeer.py b/Libraries/GlusterCommands/ATFGlusterPeer.py new file mode 100755 index 0000000..9e40f50 --- /dev/null +++ b/Libraries/GlusterCommands/ATFGlusterPeer.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +import ATFUtils +import ATFTestEnv + +def probe(): + """ + Description: + probe peer specified by <HOSTNAME> + + Parameters: + None + + Returns: + Success: 0 + Failure: 1 + """ + + command = "gluster peer probe " + servers = ATFUtils.TestEnvObj.get_servershostlist() + + length = len(servers) + if (length == 1): + ATFUtils.Logger.warning("Self Probing of Server Not Required") + return 0 + else: + fromhost = servers.pop(0) + for host in servers: + command = command + host + " " + + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + host=fromhost, + user='root') + + if (status == 1): + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + diff --git a/Libraries/GlusterCommands/ATFGlusterVolume.py b/Libraries/GlusterCommands/ATFGlusterVolume.py new file mode 100755 index 0000000..20bfd4f --- /dev/null +++ b/Libraries/GlusterCommands/ATFGlusterVolume.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python +import ATFUtils +import ATFTestEnv +import re + +def create_volume(volumekey, *exportdirs, **arguments): + """ + Description: + Create a new Volume of specified type with mentioned bricks + + Parameters: + volumekey: Name of the Volume + + exportdirs: List of exportdirs to be used to create Volume + + arguments: Key=Value pair for "Volume Type" and "Transport Type". + 'voltype' = stripe|replica|distribute + 'transport' = tcp|rdma|tcp,rdma + 'host' = Server_IP + 'user' = User + + Return: + Success: 0 + Failure: 1 + + Example: + create('Replicate', + 'host1:export1', + 'host2:export1, + voltype='replica 2', + transport='transport tcp' + host = 'host(1..n)' + server = 'server(1..n)' + ) + """ + + command = "gluster volume create" + + volumename = ATFUtils.TestEnvObj.get_volume(volumekey) + if ( volumename == ''): + ATFUtils.Logger.error("Volume %s Not defined in GlobalParam File" % + volumekey) + return 1 + else: + command = command + " " + volumename + + if (arguments.has_key('voltype')): + command = command + " " + arguments.pop('voltype') + + if (arguments.has_key('transport')): + command = command + " " + arguments.pop('transport') + + exportdirlist = [] + for exportdir in exportdirs: + hostkey, exportkey = re.split(':', exportdir) + + host = ATFUtils.TestEnvObj.get_host(hostkey) + if ( host == '' ): + ATFUtils.Logger.error("Host %s Not defined in GlobalParam File" % + hostkey) + return 1 + + export = ATFUtils.TestEnvObj.get_exportdir(exportkey) + if (export == '' ): + ATFUtils.Logger.error( + "ExportDir %s Not defined in GlobalParam File" % exportkey) + return 1 + + exportdirlist.append(host + ":" +export) + + for exportdir in exportdirlist: + command = command + " " + exportdir + + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if (status == 1): + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + +def start_volume(volumekey, force='', **arguments): + """ + Description: + Start volume specified by volumename + + Parameters: + volumekey: Name of the Volume + + Returns: + Success: 0 + Failure: 1 + """ + + command = "gluster volume start" + + volumename = ATFUtils.TestEnvObj.get_volume(volumekey) + if ( volumename == ''): + ATFUtils.Logger.error("Volume %s Not defined in GlobalParam File" % + volumekey) + return 1 + else: + command = command + " " + volumename + " " + force + + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if (status == 1): + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + +def stop_volume(volumekey, force='', **arguments): + """ + Description: + Stop volume specified by volumename + + Parameters: + volumekey: Name of the Volume + force: force stop Gluster Volume + + Returns: + Success: 0 + Failure: 1 + """ + + command = "gluster volume stop" + + volumename = ATFUtils.TestEnvObj.get_volume(volumekey) + if ( volumename == ''): + ATFUtils.Logger.error("Volume %s Not defined in GlobalParam File" % + volumekey) + return 1 + else: + command = command + " " + volumename + " " + force + + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if (status == 1): + return 1 + else: + stdin.write("y\n") + return ATFUtils.parse_output(stdout, stderr) + + +def delete_volume(volumekey, **arguments): + """ + Description: + Delete volume specified by volumename + + Parameters: + volumekey: Name of the Volume + + Returns: + Success: 0 + Failure: 1 + """ + + command = "gluster volume delete" + + volumename = ATFUtils.TestEnvObj.get_volume(volumekey) + if ( volumename == ''): + ATFUtils.Logger.error("Volume %s Not defined in GlobalParam File" % + volumekey) + return 1 + else: + command = command + " " + volumename + + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if (status == 1): + return 1 + else: + stdin.write("y\n") + return ATFUtils.parse_output(stdout, stderr) + +def create_exportdirs(*exportdirs, **arguments): + """ + Description: + Create Bricks on the Server 'server' + + Parameters: + server: IP Address of Server where bricks has to be created + username: User on Server 'server' + bricks: List of Bricks to be created + + Return: + Success: 0 + Failure: 1 + """ + + command = "mkdir -p" + cleanup_command = "rm -rf" + exportdirlist = [] + + for exportkey in exportdirs: + exportdir = ATFUtils.TestEnvObj.get_exportdir(exportkey) + if (exportdir == '' ): + ATFUtils.Logger.error( + "ExportDir %s Not defined in GlobalParam File" % exportkey) + return 1 + else: + exportdirlist.append(exportdir) + + for exportdir in exportdirlist: + command = command + " " + exportdir + cleanup_command = cleanup_command + " " + exportdir + + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(cleanup_command, + **arguments) + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if (status == 1): + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + + + + + + diff --git a/Libraries/GlusterCommands/ATFGlusterd.py b/Libraries/GlusterCommands/ATFGlusterd.py new file mode 100755 index 0000000..fe2a838 --- /dev/null +++ b/Libraries/GlusterCommands/ATFGlusterd.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +import ATFUtils + +def start_glusterd(**arguments): + """ + Objective : + Start Glusterd process on the server + + Parameter : + arguments: key = value pair. + server = 'server(1..n)' + host = 'host(1..n)' + Return: + Success : 0 + Failure : 1 + """ + + command = "/etc/init.d/glusterd start" + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if (status == 1): + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + +def stop_glusterd(**arguments): + """ + Description: + Stop Glusterd process on the server + + Parameter: + arguments: key = value pair. + server = 'server(1..n)' + host = 'host(1..n)' + + Return: + Success : 0 + Failure : 1 + """ + + command = "/etc/init.d/glusterd stop" + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if (status == 1): + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + +def restart_glusterd(**arguments): + """ + Description: + Restart Glusterd process on the server + + Parameter: + arguments: key = value pair. + server = 'server(1..n)' + host = 'host(1..n)' + + Return: + Success : 0 + Failure : 1 + """ + + command = "/etc/init.d/glusterd restart" + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if (status == 1): + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + +def cleanup_glusterd(**arguments): + """ + Description: + Cleans up the glusterd directory on Servers + + Parameter: + arguments: key = value pair. + server = 'server(1..n)' + host = 'host(1..n)' + + Return: + Success : 0 + Failure : 1 + """ + + command = "rm -rf /etc/glusterd/*" + arguments['user'] = 'root' + status, stdin, stdout, stderr = ATFUtils.execute_command(command, + **arguments) + + if (status == 1): + return 1 + else: + return ATFUtils.parse_output(stdout, stderr) + + diff --git a/Libraries/Log/ATFLog.py b/Libraries/Log/ATFLog.py new file mode 100755 index 0000000..9165a7c --- /dev/null +++ b/Libraries/Log/ATFLog.py @@ -0,0 +1,221 @@ +#!/usr/bin/env python + +import logging +import ATFUtils + +####################################################################### +## ATFLog class contains variables and methods for Logging +## the events during the test run. +## +## Variables: +## SummaryLog: [filename, loglevel, format] +## +## DetailLog: [filename, loglevel, format] +## +## StdoutLog: [loglevel, format] +## +###################################################################### +class Log(): + + + def __init__(self): + self.SummaryLog = {'format': + '%(asctime)s %(levelname)s : %(filename)s %(lineno)d - \ + \'%(message)s\''} + self.DetailLog = {'format': + '%(asctime)s %(levelname)s : %(pathname)s %(funcName)s \ + %(lineno)d - \'%(message)s\''} + self.StdoutLog = {'logstatus':'false', 'format':'%(asctime)s \ + %(levelname)s : %(filename)s %(lineno)d - \'%(message)s\''} + self.loggers = [] + + def get_loglevel(self, loglevel): + """ + Description: + Returns logging.(LogLevel) for loglevel + + Parameters: + loglevel: String specifying the loglevel + + Returns: + logging.(Loglevel) + """ + + LEVELS = {'DEBUG': logging.DEBUG, + 'INFO': logging.INFO, + 'WARNING': logging.WARNING, + 'ERROR': logging.ERROR, + 'CRITICAL': logging.CRITICAL, + 'debug': logging.DEBUG, + 'info': logging.INFO, + 'warning': logging.WARNING, + 'error': logging.ERROR, + 'critical': logging.CRITICAL} + return LEVELS.get(loglevel, logging.NOTSET) + + def set_summarylog(self, filename='SummaryLog.out', loglevel='INFO'): + """ + Description: + Set Summary Log Name and Log Level + + Parameters: + filename: SummaryLog File Name + loglevel : Log level to be set for summary log + """ + + self.SummaryLog['filename'] = filename + self.SummaryLog['loglevel'] = self.get_loglevel(loglevel) + + def set_detaillog(self, filename='DetailLog.out', loglevel = 'DEBUG'): + """ + Description: + Set Detail Log Name and Log Level + + Parameters: + filename: DetailLog FIle name + loglevel: Log level to be set for detail log + """ + + self.DetailLog['filename'] = filename + self.DetailLog['loglevel'] = self.get_loglevel(loglevel) + + def set_stdoutlog(self, loglevel='INFO'): + """ + Description: + Set Log Level for logging to STDOUT + + Parameters: + loglevel: Log level for logging to STDOUT + """ + + self.StdoutLog['loglevel'] = self.get_loglevel(loglevel) + self.StdoutLog['logstatus'] = 'true' + + def create(self, logname='ATF_LOG'): + """ + Description: + Create a Logger with LogName 'logname' + + Parameters: + logname: Name of the Logger + + Return: + Success: 0 (Successful creation of logger with name : 'logname') + Failure: 1 (Unable to create logger with name: logname) + """ + + # Create a Logger Object with name "logname". + # Set the log level to 'DEBUG' + logger = logging.getLogger(logname) + logger.setLevel(logging.DEBUG) + self.loggers.append({'logname': logname}) + + # Create Summary Log File Handler + # Set the Log Level + # Set the Log Record format for Summary Log + atfrootdir = ATFUtils.get_environ('ATF_ROOT') + abspath = atfrootdir + "/" + self.SummaryLog['filename'] + + try: + summary_handler = logging.FileHandler(abspath, mode='a') + + except IOError as (errno, errstr): + print "I/0 error({0}): {1}".format(errno, errstr) + return 1 + + else: + summary_handler.setLevel(self.SummaryLog['loglevel']) + summary_formatter = logging.Formatter(self.SummaryLog['format']) + summary_handler.setFormatter(summary_formatter) + logger.addHandler(summary_handler) + for log in self.loggers: + if log['logname'] == logname: + log['summary_handler'] = summary_handler + break + + # Create Stdout Log StreamHandler if log to stdout is defined + # Set the Log Level + # Set the Log Record format for STDOUT + if self.StdoutLog['logstatus'] == 'true': + stdout_handler = logging.StreamHandler() + stdout_handler.setLevel(self.StdoutLog['loglevel']) + stdout_formatter = logging.Formatter(self.StdoutLog['format']) + stdout_handler.setFormatter(stdout_formatter) + logger.addHandler(stdout_handler) + for log in self.loggers: + if log['logname'] == logname: + log['stdout_handler'] = stdout_handler + break + + ATFUtils.Logger = logger + return 0 + + def add_detaillog_handler(self, logname): + """ + Description: + Add a Detail Log FileHandler to Logger with logname 'logname' + + Parameters: + logname: Name of the Logger + + Returns: + Success: 0 + Failure: 1 + """ + + logger = logging.getLogger(logname) + + # Create Detail Log File Handler + # Set the Log Level + # Set the Log Record format for Detail Log + atfworkdir = ATFUtils.get_environ('ATF_WORKUNIT') + abspath = atfworkdir + "/Log/" + self.DetailLog['filename'] + + try: + detail_handler = logging.FileHandler(abspath, mode='w') + + except IOError as (errno, errstr): + logger.error("IOError ({0}): {1}".format(errno, errstr)) + return 1 + + else: + detail_handler.setLevel(self.DetailLog['loglevel']) + detail_formatter = logging.Formatter(self.DetailLog['format']) + detail_handler.setFormatter(detail_formatter) + logger.addHandler(detail_handler) + + for log in self.loggers: + if log['logname'] == logname: + log['detail_handler'] = detail_handler + break + + logger.debug("Detail Log File Handler Successfully Added") + + ATFUtils.Logger = logger + return 0 + + def remove_detaillog_handler(self, logname): + """ + Description: + Remove Detail Log File Handler from Logger with + logname 'logname' + + Parameters: + logname: Name of the Logger + """ + + logger = logging.getLogger(logname) + Map = {} + for log in self.loggers: + Map = log + + if Map.has_key('detail_handler'): + detail_handler = log.pop('detail_handler') + logger.removeHandler(detail_handler) + logger.info("DetailLog Handler Removed for the Logger: " + + logname) + else: + logger.warning("DetailLog Handler Not Found for the Logger: " + + logname) + return + diff --git a/Libraries/Ssh/ATFSsh.py b/Libraries/Ssh/ATFSsh.py new file mode 100755 index 0000000..63e690b --- /dev/null +++ b/Libraries/Ssh/ATFSsh.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +import paramiko +import logging + +################################################################### +## ATFSsh.Ssh Class contains variables and methods for +## Connecting to remote machine using SSH +## +## Variables: +## connections: List of Dictionaries. +## Each Dictionary contains {host, user, conn} information. +## host : Server IP address +## user : User on host +## conn : SSH Conn Object to user@host +################################################################### +class Ssh(): + + + def __init__(self): + self.connections = [] + + def connect(self, host, user): + """ + Objective: + SSH to Server "host" as User "user" + + Parameter: + host: Server IP Address + user: Login Username + + Return: + Success: 0 + Failure: 1 + """ + + logger = logging.getLogger('ATF_LOG') + connection = paramiko.SSHClient() + connection.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + + try: + connection.connect(host, username=user) + + except paramiko.BadHostKeyException as result: + logger.exception( + "BadHostKeyException: Unable to Connect to Server: '" + host + + "' as User: '" + user + "'") + return 1 + + except paramiko.AuthenticationException: + logger.exception("AuthenticationException: Unable to Authenticate " + + user + "@" + host) + return 1 + + except paramiko.SSHException: + logger.exception("SSHException: Unknown server " + host) + return 1 + + else: + self.connections.append({'host':host, 'user': user, 'conn': + connection}) + logger.info("Successfully Able to SSH to: " + user + "@" + host) + + return 0 + + def close(self, host, user): + """ + Objective: + Close SSH Connections for User "username" + on the Server "server" + + Parameters: + server: Server IP Address + username: User on the Server + + Return: + Success: 0 + Failure: 1 + """ + + logger = logging.getLogger('ATF_LOG') + index = 0 + + for conn in self.connections: + if conn['host'] == host and conn['user'] == user: + conn['conn'].close() + logger.info("Closing SSH Connection: " + conn['user'] + "@" + + conn['host']) + self.connection[index:(index + 1)] = [] + index = index - 1 + + index = index + 1 + + return 0 + + def closeall(self): + """ + Objective: + Close All Existing SSH Connections + + Parameters: + None. + + Return: + Success: 0 + Failure: 1 + """ + + logger = logging.getLogger('ATF_LOG') + + for conn in self.connections: + conn['conn'].close() + logger.info("Closing SSH Connection: " + conn['user'] + "@" + + conn['host']) + + self.connections[:] = [] + + return 0 + + def getconnection(self, host, user): + """ + Objective: + Return SSH connection object for username@server + + Parameters: + host: Server IP Address + user: User on the Server + + Return: + Success:SSH connection Object If SSH Connection Object exists + for username@server + Failure: 1 (If SSH Connection doesn't exist) + """ + + for conn in self.connections: + if conn['host'] == host and conn['user'] == user: + return conn['conn'] + + else: + return 1 + + def executecommand(self, command, host, user): + """ + Objective: + Execute Command "comamnd" on user@host + + Parameters: + host: IP address of Server/Client + user: username of user on Host 'host' + command: command to execute + + Return: + Success: 0 + Failure: 1 + """ + + logger = logging.getLogger('ATF_LOG') + output = [] + conn = self.getconnection(host, user) + + if conn == 1: + logger.error("SSH Connection Not Established to:" + user + "@" + + host) + output = [1, 0, 0, 0] + return output + + try: + stdin, stdout, stderr = conn.exec_command(command) + + except paramiko.SSHException: + logger.exception("Unable to Execute Command: " + command) + output = [1, 0, 0, 0] + return output + + else: + output = [0, stdin, stdout, stderr] + return output + diff --git a/Libraries/TestEnv/ATFTestEnv.py b/Libraries/TestEnv/ATFTestEnv.py new file mode 100755 index 0000000..09c5b79 --- /dev/null +++ b/Libraries/TestEnv/ATFTestEnv.py @@ -0,0 +1,460 @@ +#!/usr/bin/env python + +######################################################################## +## TestEnv Class contains variables and methods for storing and retrieving +## information about the Test Environment. +## +## Variables: +## Hosts: List of Dictionaries. +## Each Dictionary contains {'name':name, 'host':host} +## information +## +## Users: List of Dictionaries +## Each Dictionary contains {'name':name, 'user':user} +## information +## +## Servers: List of Dictionaries. +## Each Dictionary contains {'name': name, 'host': host, +## 'user': user} information +## +## Clients: List of Dictionaries. +## Each Dictionary contains {'name': name, 'host': host, +## 'user': user} information +## +## ExportDirs: List of Dictionaries. +## Each Dictionary contains {'exportname': exportname, +## 'exportdir': exportdir} information +## +## ServersHostList: Unique List of Hosts derieved from Servers List +## +## ClientsHostList: Unique List of Hosts derieved from Clients List +## +## +######################################################################## + +class TestEnv(): + + + def __init__(self): + self.Hosts = [] + self.Users = [] + self.Servers = [] + self.Clients = [] + self.ExportDirs = [] + self.ServersHostList = [] + self.ClientsHostList = [] + self.MountPoints = [] + self.Volumes = [] + self.GlobalParamFile = '' + + def set_globalparamfile(self, filename): + """ + Description: + Sets GlobalParameter file name + + Parameter: + filename: Name of the GlobalParam File + + Returns: + """ + + self.GlobalParamFile = filename + return + + def get_globalparamfile(self): + """ + Description: + Return GlobalParamFileName + + Parameter: + None + + Returns: + GlobalParamFIleName + """ + + return self.GlobalParamFile + + def add_host(self, name, host): + """ + Description: + Add a host to Hosts List + + Parameters: + name: Name of the host Ex: host1, host2 + host: Address of the host Ex: 192.168.1.5 + + Return: + """ + + self.Hosts.append({'name': name, 'host': host}) + return + + def get_host(self, name): + """ + Description: + Return host with name 'name' + + Parameters: + name: Name of the host to return + + Returns: + Success: host + Failure: '' + """ + + output = '' + + for host in self.Hosts: + if host['name'] == name: + output = host['host'] + break + + return output + + def get_hostslist(self): + """ + Description: + Returns self.Servers List + Returns: + self.Servers + """ + + return self.Hosts + + def add_user(self, name, user): + """ + Description: + Add a user to Users List + + Parameters: + name: key to recognize a user Ex: user1/user2 + user: Username + + Return: + """ + + self.Users.append({'name': name, 'user': user}) + return + + def get_user(self, name): + """ + Description: + Return user with key 'name' + + Parameters: + name: key used to recognize the user + + Returns: + Success: user + Failure: '' + """ + + output = '' + + for user in self.Users: + if user['name'] == name: + output = user['user'] + break + + return output + + def add_server(self, name, hostkey, userkey): + """ + Description: + Add a server to Servers List + + Parameters: + name: Name of the server (Example: Server1/Server2) + host: IP Address of the server + user: Username of User on 'host' + + Returns: + Success: 0 + Failure: 1 + """ + + host = self.get_host(hostkey) + user = self.get_user(userkey) + + if host == '' or user == '': + ATFUtils.Logger.error("%s or %s Not Defined " % (hostkey, userkey)) + return 1 + + self.Servers.append({'name': name, 'host': host, 'user': user}) + return 0 + + def get_server(self, name): + """ + Description: + Returns [host, user] tuple for Server Name 'name' + + Parameters: + name: Name of the Server + + Returns: + Success: Returns [host, user] tuple + Failure: ['', ''] tuple + """ + + output = ['', ''] + + for server in self.Servers: + if server['name'] == name: + output = [server['host'], server['user']] + break + + return output + + def get_serverslist(self): + """ + Description: + Returns self.Servers List + + Parameters: + None + + Returns: + self.Servers + """ + + return self.Servers + + def add_client(self, name, hostkey, userkey): + """ + Description: + Add a client to Clients List + + Parameters: + name: Name of the client (Example: Client1/Client2) + host: IP Address of the client + user: Username of User on 'host' + + Returns: + Success: 0 + Failure: 1 + """ + + host = self.get_host(hostkey) + user = self.get_user(userkey) + + if host == '' or user == '': + ATFUtils.Logger.error("%s or %s Not Defined " % (hostkey, userkey)) + return 1 + + self.Clients.append({'name': name, 'host': host, 'user': user}) + return 0 + + def get_client(self, name): + """ + Description: + Returns [host, user] tuple for Client Name 'name' + + Parameters: + name: Name of the Client + + Returns: + Success: Returns [host, user] tuple + Failure: ['', ''] tuple + """ + + output = ['', ''] + + for client in self.Clients: + if client['name'] == name: + output = [client['host'], client['user']] + break + + return output + + def get_clientslist(self): + """ + Description: + Returns self.Clients List + + Parameters: + None + + Returns: + self.Clients + """ + + return self.Clients + + def add_exportdir(self, exportname, dirname): + """ + Description: + Add a Export Directory to the Export Directory List + + Parameters: + exportname: Name of a Export Directory(Example: export1/export2) + dirname: Absolute Path of the Export DIrecotry + + Returns: + """ + + self.ExportDirs.append({'exportname': exportname, 'dirname': dirname}) + return + + def get_exportdir(self, exportname): + """ + Description: + Return Dir Name of the Export Directory Name 'exportname' + + Parameters: + exportname: Name of a Export Directory + + Returns: + Success: Absolute Path of Export DIrectory + Failure: '' + """ + + output = '' + + for exportdir in self.ExportDirs: + if exportdir['exportname'] == exportname: + output = exportdir['dirname'] + break + + return output + + def add_mountpoint(self, mountname, dirname): + """ + Description: + Add a Mount Point to the MountPoint List + + Parameters: + mountname: Name of a MountPoint(Example: mount1/mount2) + dirname: Absolute Path of the Mount Point + + Returns: + """ + + self.MountPoints.append({'mountname': mountname, 'dirname': dirname}) + return + + def get_mountpoint(self, mountname): + """ + Description: + Return MountPoint with Name 'mountname' + + Parameters: + mountname: Name of a MountPoint + + Returns: + Success: Absolute Path of MountPoint + Failure: '' + """ + + output = '' + + for mountpoint in self.MountPoints: + if mountpoint['mountname'] == mountname: + output = mountpoint['dirname'] + break + + return output + + def add_volume(self, volumekey, volumename): + """ + Description: + Add a Volume to Volumes List + + Parameters: + volumekey: key used to recognize the volumename Ex: volume1 + volumename: Volume Name Ex: Replicate_Volume + + Returns: + """ + + self.Volumes.append({'volumekey': volumekey, 'volumename': volumename}) + return + + def get_volume(self, volumekey): + """ + Description: + Returns Volumename with Volumekey 'volumekey' + + Parameters: + volumekey: VolumeKey + + Returns: + Success: Volumename + Failure: '' + """ + + output = '' + + for volume in self.Volumes: + if volume['volumekey'] == volumekey: + output = volume['volumename'] + break + + return output + + def create_servershostlist(self): + """ + Description: + Creats a Unique List of Hosts from the Servers List + + Parameters: + None + + Returns: + """ + + for server in self.Servers: + host = server['host'] + + if host not in self.ServersHostList: + self.ServersHostList.append(host) + + return + + def create_clientshostlist(self): + """ + Description: + Creats a Unique List of Hosts from the Clients List + + Parameters: + None + + Returns: + """ + + for client in self.Clients: + host = client['host'] + + if host not in self.ClientsHostList: + self.ClientsHostList.append(host) + + return + + def get_servershostlist(self): + """ + Description: + Returns ServersHostList + + Parameters: + None + + Returns: + Return ServersHostList + """ + + return self.ServersHostList + + def get_clientshostlist(self): + """ + Description: + Returns ClientsHostList + + Parameters: + None + + Returns: + Return ClientsHostList + """ + + return self.ClientsHostList + diff --git a/Libraries/Tests/ATFTests.py b/Libraries/Tests/ATFTests.py new file mode 100755 index 0000000..245e96a --- /dev/null +++ b/Libraries/Tests/ATFTests.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +############################################################################## +## ATFTests Class contains variables and methods for storing and retrieving +## information about "TESTS" that has to be executed. +## +## Variables: +## TestUnits: List of TestUnits to be run. +## +## KeyWords: List of keywords to be used to select tests under each +## TestUnit. +## +## Version: Glusterfs version. This is used to select tests based on version +## of Glusterfs. +############################################################################## + +class Tests(): + def __init__(self): + self.TestUnits = [] + self.KeyWords = [] + self.Version = '' + + def add_testunits(self, testunit): + """ + Description: + Add a testunit to TestUnits List + + Parameter: + testunit: Name of the Testing Unit + + Returns: + """ + + self.TestUnits.append(testunit) + return + + def sort_testunits(self): + """ + Description: + Sort the TestUnit List in Descending Order + + Parameter: + + Returns: + """ + + self.TestUnits.sort() + self.TestUnits.reverse() + return + + def get_testunits(self): + """ + Description: + Return TestUnits List + + Parameters: + + Returns: + Success: Testunit Name + Failure: '' + """ + + return self.TestUnits + + def add_keywords(self, keyname): + """ + Description: + Add Keywords to KeyWords List + + Parameters: + keyname: Keyword + + Returns: + """ + + self.KeyWords.append(keyname) + return + + def set_version(self, version): + """ + Description: + Set Glusterfs Version under test. + + Parameters: + version: Glusterfs version + + Returns: + """ + + self.Version = version + return + + def get_version(self): + """ + Description: + Returns Glusterfs Vesrion under test + + Parameters: + + Returns: + Glusterfs Version + """ + + return self.Version + diff --git a/Libraries/Utils/ATFUtils.py b/Libraries/Utils/ATFUtils.py new file mode 100755 index 0000000..0afcf22 --- /dev/null +++ b/Libraries/Utils/ATFUtils.py @@ -0,0 +1,402 @@ +#!/usr/bin/env python + +import os +import re +import logging +import ATFLog +import ATFTests +import ATFTestEnv +import ATFSsh +import ATFGlusterd +import ATFGlusterPeer + +######################################################################### +## ATFLog.Log Object +######################################################################### +LogObj = ATFLog.Log() + +######################################################################### +## ATFTests.Tests Object +######################################################################### +TestsObj = ATFTests.Tests() + +######################################################################### +## ATFTestEnv.TestEnv Object +######################################################################### +TestEnvObj = ATFTestEnv.TestEnv() + +######################################################################### +## ATFSsh.Ssh Object +######################################################################### +SshObj = ATFSsh.Ssh() + +######################################################################### +## Logger for 'ATF_LOG' +######################################################################### +Logger = logging.getLogger('ATF_LOG') + +def set_environ(**arguments): + """ + Description: + Set the Env Variable 'envvar' to Value 'value' + + Parameters: + **arguments: key=value pairs. + key: Environment Variable name + value: Value of the Environment Valiable + + Return: + Success: 1 (Successfully Set the envar to value) + Failure: 0 (Unable to set the envvar to value) + + Example: + ATFUtils.set_environ(ATF_USER = user1 ,ATF_SERVER = server1) + """ + + envvars = sorted(arguments.keys()) + + for var in envvars: + try: + os.environ[var] = arguments[var] + + except KeyError as (key): + Logger.error("Unable to Export Environment Variable '" + key + "'") + return 1 + + else: + Logger.debug("Exported Environment Variable '" + var + "' = " + + arguments[var]) + + return 0 + +def get_environ(envvar, log = 1): + """ + Description: + Return the Value of Environment Variable 'envvar' + + Parameters: + name: Name of the Environment Variable + log: To keep track of whether to log the error message or not + + Return: + Success : Value of Environment Variable 'envvar' + Failure: 1 + """ + + try: + value = os.environ[envvar] + + except KeyError: + if log == 1: + Logger.error("Key Error: Environment Variable %s Not Defined" % + envvar) + value = 1 + + except OSError as key: + if log == 1: + Logger.error("Environment Variable '" + key + "' Not Defined") + value = 1 + + else: + Logger.debug("Returning " + envvar + " = " + value) + + return value + +def parse_output(stdout, stderr): + """ + Description: + Parse the STDOUT and STDERR ChannelFiles + + Parameter: + stdout: ChannelFile for stdout + stderr: ChannelFile for stderr + + Return: + Success: 0 (STDOUT has DATA) + Failure: 1 (STDERR has DATA) + """ + + output = stderr.readlines() + + if len(output) == 0: + for line in stdout.readlines(): + Logger.debug(line) + return 0 + else: + for line in output: + Logger.error(line) + return 1 + +def execute_command(command, **arguments): + """ + Description: + + Parameter: + command: Command to be executed + **arguments: key=value pair for specifying server, host, user + + Returns: + Success: 0 + Failure: 1 + """ + + output = [1, 0, 0, 0] + ip_string = '(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})' + serverkey = hostkey = userkey = '' + serverkeyfound = hostkeyfound = 0 + + if arguments.has_key('server'): + serverkey = arguments['server'] + serverkeyfound = 1 + elif arguments.has_key('host'): + hostkey = arguments['host'] + hostkeyfound = 1 + else: + serverkey = get_environ('ATF_SERVER', log = 0) + + if serverkey == 1: + serverkeyfound = 0 + hostkey = get_environ('ATF_HOST') + + if hostkey == 1: + Logger.error("Server/Host not defined for command execution") + return output + else: + hostkeyfound = 1 + else: + serverkeyfound = 1 + + if serverkeyfound == 1: + host, user = TestEnvObj.get_server(serverkey) + + if host == '' or user == '': + Logger.error("Server: " + serverkey + + "Not Defined in GlobalParam File") + return output + elif hostkey != '': + if re.match(ip_string, hostkey): + host = hostkey + else : + host = TestEnvObj.get_host(hostkey) + if host == '': + Logger.error("Host: " + hostkey + + "Not Defined in GlobalParam File") + return output + + if arguments.has_key('user'): + userkey = arguments['user'] + else: + userkey = get_environ('ATF_USER') + if userkey == 1: + Logger.error( + "Ignoring KeyError: Environment Variable ATF_USER Not " + + "Defined for command execution") + return output + + if userkey != 'root': + user = TestEnvObj.get_user(userkey, log = 0) + if user == '': + Logger.error("User: " + userkey + + "Not Defined in GlobalParam File") + return output + else: + user = 'root' + + Logger.info("Executing Command: " + command + " - " + user + "@" + host) + status, stdin, stdout, stderr = SshObj.executecommand(command, host, user) + output = [status, stdin, stdout, stderr] + return output + +def sshservers(): + """ + Description: + SSH to all Servers in the ServersList + + Parameters: + None + + Returns: + Success: 0 + Failure: 1 + """ + + for server in TestEnvObj.get_serverslist(): + host = server['host'] + user = server['user'] + + if SshObj.connect(host, user): + return 1 + else: + continue + + return 0 + +def sshclients(): + """ + Description: + SSH to all Clients in the ClientsList + + Parameters: + None + + Returns: + Success: 0 + Failure: 1 + """ + + for client in TestEnvObj.get_clientslist(): + host = client['host'] + user = client['user'] + + if SshObj.connect(host, user): + return 1 + else: + continue + + return 0 + +def cleanupserversglusterd(): + """ + Descriptions: + Cleanup glusterd directory on all Servers in ServersList + + Parameters: + None + + Returns: + Success: 0 + Failure: 1 + """ + + for host in TestEnvObj.get_servershostlist(): + if ATFGlusterd.cleanup_glusterd(host = host): + return 1 + else: + continue + + return 0 + +def cleanupclientsglusterd(): + """ + Description: + Cleanup Glusted directory on all the Clients in ClientsList + + Parameters: + None + + Returns: + Success: 0 + Failure: 1 + """ + + for host in TestEnvObj.get_clientshostlist(): + if ATFGlusterd.cleanup_glusterd(host = host): + return 1 + else: + continue + + return 0 + +def stopserversglusterd(): + """ + Description: + Stop Glusterd on all the Servers in ServersList + + Parameters: + None + + Returns: + Success: 0 + Failure: 1 + """ + + for host in TestEnvObj.get_servershostlist(): + if ATFGlusterd.stop_glusterd(host = host): + return 1 + else: + continue + + return 0 + +def stopclientsglusterd(): + """ + Description: + Stop Glusted on all the Clients in ClientsList + + Parameters: + None + + Returns: + Success: 0 + Failure: 1 + """ + + for host in TestEnvObj.get_clientshostlist(): + if ATFGlusterd.stop_glusterd(host = host): + return 1 + else: + continue + + return 0 + +def startserversglusterd(): + """ + Description: + Start Glusterd on all the Servers in ServersList + + Parameters: + None + + Returns: + Success: 0 + Failure: 1 + """ + + for host in TestEnvObj.get_servershostlist(): + if ATFGlusterd.start_glusterd(host = host): + return 1 + else: + continue + + return 0 + +def startclientsglusterd(): + """ + Description: + Start GLusterd on all Clients in ClientsList + + Parameters: + None + + Returns: + Success: 0 + Failure: 1 + """ + + for host in TestEnvObj.get_clientshostlist(): + if ATFGlusterd.start_glusterd(host = host): + return 1 + else: + continue + + return 0 + +def peerprobe(): + """ + Description: + PeerProbe to all Servers in ServerList from one of the server + in the ServerList + + Parameters: + None + + Returns: + Success: 0 + Failure: 1 + """ + + if ATFGlusterPeer.probe(): + return 1 + else: + return 0 + diff --git a/Libraries/Validate/ATFValidate.py b/Libraries/Validate/ATFValidate.py new file mode 100644 index 0000000..9cebbf8 --- /dev/null +++ b/Libraries/Validate/ATFValidate.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +import re +import ATFUtils + +def validate_replication(**arguments): + """ + Description: + Validate whether the files are replicated or not + + Parameters: + arguments: key=value pair. + key: file1..filen + value: host:exportdir:filename comabination + + Example:f1 = 'host1:export1:file1.txt', f2 = 'host1:export2:file1.txt + + Returns: + Success: 0 + Failure: 1 + """ + + Map = [] + command = "ls" + + for key in arguments.keys(): + value = arguments[key] + hostkey, exportkey, filename = re.split(":", value) + + host = ATFUtils.TestEnvObj.get_host(hostkey) + if (host == ''): + ATFUtils.Logger.error("Host %s Not defined in GlobalParam File" % + hostkey) + return 1 + + exportdir = ATFUtils.TestEnvObj.get_exportdir(exportkey) + if (exportdir == ''): + ATFUtils.Logger.error( + "ExportDir %s Not defined in GlobalParam File" % exportkey) + return 1 + else: + abspath = exportdir + "/" + filename + Map.append({'host':host, 'path':abspath}) + + + for item in Map: + arguments['host'] = item['host'] + arguments['user'] = 'root' + abspath = item['path'] + val_command = command + " " + abspath + + status, stdin, stdout, stderr = ATFUtils.execute_command(val_command, + **arguments) + + if ( status == 1): + ATFUtils.Logger.error("Error in Validation") + else: + status = False + readout = stdout.readlines() + readerr = stderr.readlines() + + if( len(readerr) == 0): + for line in readout: + if ( re.match(abspath, line)): + status = True + else: + status = False + + if (status == False): + ATFUtils.Logger.error("Validation Failed: Path Not found - %s" % abspath) + return + else: + continue + + if(status == True): + ATFUtils.Logger.info("Validate_replication Successfully Complete") + + return 0 + |