summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xSharedModules/Connect/ssh.py114
-rw-r--r--SharedModules/Globals/atfglobals.py85
-rw-r--r--SharedModules/Globals/logger.py211
-rwxr-xr-xSharedModules/Globals/manager.py64
-rwxr-xr-xSharedModules/Globals/testenv.py462
-rw-r--r--SharedModules/Globals/testruninfo.py144
-rw-r--r--SharedModules/Parser/parser.py315
-rw-r--r--SharedModules/Utils/atfutils.py58
-rw-r--r--SharedModules/Utils/clientutils.py282
-rw-r--r--SharedModules/Utils/glusterutils.py644
-rw-r--r--SharedModules/Utils/hostutils.py193
-rw-r--r--SharedModules/Utils/managerutils.py55
-rw-r--r--SharedModules/Utils/serverutils.py33
-rw-r--r--TestUnits/replicate/self_heal/Main.py69
-rw-r--r--TestUnits/replicate/self_heal/testcases.py96
-rw-r--r--TestUnits/replicate/self_heal/testcaseslist9
-rw-r--r--TestUnits/replicate/self_heal/testenv.cfg98
-rwxr-xr-xatf.py296
-rw-r--r--atfexecute.py63
-rw-r--r--atfinit.py27
-rw-r--r--atfsetup.py37
-rwxr-xr-xexport.py13
-rwxr-xr-xtestruninfo.cfg99
23 files changed, 3185 insertions, 282 deletions
diff --git a/SharedModules/Connect/ssh.py b/SharedModules/Connect/ssh.py
new file mode 100755
index 0000000..a9952bb
--- /dev/null
+++ b/SharedModules/Connect/ssh.py
@@ -0,0 +1,114 @@
+"""
+ sshConnection Class for connecting and performing operation on
+ remote server using SSH Protocol.
+"""
+import paramiko
+import pdb
+import time
+
+class SshConnection():
+
+ def __init__(self):
+ self._connection = None
+ self._connection = paramiko.SSHClient()
+
+ def connect(self, host, user=None, password=None):
+ """
+ Objective:
+ SSH to Server "host" as User "user"
+
+ Parameter:
+ host: Server IP Address
+ user: Login Username
+ password: Login password
+
+ Return:
+ Success: 0
+ Failure: 1
+ """
+ self._connection.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+
+ if user == None:
+ user = "root"
+
+ if password == None:
+ password = "syst3m"
+
+ try:
+ self._connection.connect(host, username=user, password=password)
+
+ except paramiko.BadHostKeyException as result:
+ print(
+ "BadHostKeyException: Unable to Connect to Server: '" + host +
+ "' as User: '" + user + "'")
+ return 1
+
+ except paramiko.AuthenticationException:
+ print("AuthenticationException: Unable to Authenticate "
+ + user + "@" + host)
+ return 1
+
+ except paramiko.SSHException:
+ print("SSHException: Unknown server " + host)
+ return 1
+
+ return 0
+
+ def close(self):
+ """
+ Objective:
+ Close SSH Connections
+ """
+ self._connection.close()
+ return
+
+ def executecommand(self, command, commandInput=None):
+ """
+ Objective:
+ Execute Command "comamnd"
+
+ Parameters:
+ command: command to execute
+
+ Return:
+ Success: 0
+ Failure: 1
+ """
+ output = {}
+ output["exitstatus"] = None
+ output["stdoutdata"] = None
+ output["stderrdata"] = None
+ exit_status_ready_flag = True
+
+ try:
+ transport = self._connection.get_transport()
+ channel = transport.open_session()
+ channel.exec_command(command)
+ # Adding sleep to get the correct exit_status.
+ time.sleep(5)
+ exit_status_ready_flag = channel.exit_status_ready()
+ if not exit_status_ready_flag:
+ stdin = channel.makefile("wb")
+
+ if commandInput:
+ stdin.write(commandInput)
+ else:
+ print "This command requirs Command Input \
+ after executing comamnd for command completion"
+ stdin.write("\n")
+ return output
+
+ stdout = channel.makefile("rb")
+ stderr = channel.makefile_stderr("rb")
+ exit_status = channel.recv_exit_status()
+
+ output["exitstatus"] = exit_status
+ output["stdoutdata"] = stdout.readlines()
+ output["stderrdata"] = stderr.readlines()
+
+ except paramiko.SSHException:
+ print("Unable to Execute Command: " + command)
+
+ return output
+
+
diff --git a/SharedModules/Globals/atfglobals.py b/SharedModules/Globals/atfglobals.py
new file mode 100644
index 0000000..ff1faad
--- /dev/null
+++ b/SharedModules/Globals/atfglobals.py
@@ -0,0 +1,85 @@
+"""atfglobals module contain AtfGlobal class and GlobalObj
+
+AtfGlobals class wrapps all global objects used in the framework
+*) TestrunInfo
+*) Logger
+*) Testenv
+*) ConnectionsManager
+
+GlobalObj is 'The Instance' of AtfGlobals which will be referred throughout
+the framework utilities.
+"""
+
+import testruninfo
+import logger
+import testenv
+import manager
+
+class AtfGlobals:
+
+
+ def __init__(self):
+ self._testruninfo = None
+ self._logger = logger.Log()
+ self._env = None
+ self._connectionsmanager = manager.ConnectionsManager()
+
+ def getTestrunInfoObj(self):
+ """Returns TestrunInfo Object
+ """
+ return self._testruninfo
+
+ def getLoggerObj(self):
+ """Returns Logger Object
+ """
+ return self._logger
+
+ def getTestenvObj(self):
+ """Returns Current TestEnvironment Object.
+ """
+ return self._env
+
+ def getConnectionsManagerObj(self):
+ """Returns ConnectionsManager Object
+ """
+ return self._connectionsmanager
+
+ def initTestrunInfoObj(self):
+ """Instantiation of TestrunInfo Object
+ """
+ self._testruninfo = testruninfo.TestRunInfo()
+
+ def initLoggerObj(self):
+ """Instantiation of Logger Object
+ """
+ self._logger = logger.Log()
+
+ def initTestenvObj(self):
+ """Instantiation of Testenv Object
+ """
+ self._env = testenv.TestEnv()
+
+ def initConnectionsManagerObj(self):
+ """Instantiation of ConnectionsManager Object
+ """
+ self._connectionsmanager = manager.ConnectionsManager()
+
+GlobalObj = AtfGlobals()
+__all__ = ['GlobalObj']
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SharedModules/Globals/logger.py b/SharedModules/Globals/logger.py
new file mode 100644
index 0000000..9d11bd7
--- /dev/null
+++ b/SharedModules/Globals/logger.py
@@ -0,0 +1,211 @@
+"""
+ logger 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]
+
+"""
+import logging
+
+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 getLogLevel(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 setSummaryLog(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.getLogLevel(loglevel)
+
+ def setDetailLog(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.getLogLevel(loglevel)
+
+ def setStdoutLog(self, do_log=True, loglevel='INFO'):
+ """
+ Description:
+ Set Log Level for logging to STDOUT
+
+ Parameters:
+ loglevel: Log level for logging to STDOUT
+ """
+ self._stdoutlog['do_log'] = do_log
+ self._stdoutlog['loglevel'] = self.getLogLevel(loglevel)
+
+ def createLogger(self, atfdir, logname='ATFLOG'):
+ """
+ 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
+ summarylog_abspath = atfdir + "/" + self._summarylog['filename']
+ try:
+ summary_handler = logging.FileHandler(summarylog_abspath, mode='w')
+
+ except IOError as (errno, errstr):
+ print "I/0 error({0}): {1}".format(errno, errstr)
+ return 1
+
+ else:
+ summary_formatter = logging.Formatter(self._summarylog['format'])
+ summary_handler.setFormatter(summary_formatter)
+ summary_handler.setLevel(self._summarylog['loglevel'])
+ 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['do_log'] == '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
+ return 0
+
+ def addDetaillogHandler(self, abspath, 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
+ abspath = abspath + 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")
+
+ return 0
+
+ def removeDetaillogHandler(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/SharedModules/Globals/manager.py b/SharedModules/Globals/manager.py
new file mode 100755
index 0000000..d73cf15
--- /dev/null
+++ b/SharedModules/Globals/manager.py
@@ -0,0 +1,64 @@
+""" manager module contains:
+
+*) ConnectionsManager Class
+"""
+class ConnectionsManager():
+ """
+ *) Manages Client SSH Connections in the current TestEnvironment
+ *) Manages Server SSH Connections in the current TestEnvironment
+ *) Manages allhosts SSH Connection in the current TestEnvironment
+ """
+ def __init__(self):
+
+ self._serverpool = {}
+ self._clientpool = {}
+ self._all = {}
+
+ def addServer(self, key, server):
+ """
+ Add a server to _serverpool
+ """
+
+ self._serverpool[key] = server
+ self._all[key] = server
+ return
+
+ def addClient(self, key, client):
+ """
+ Add a client to clientpool
+ """
+
+ self._clientpool[key] = client
+ self._all[key] = client
+ return
+
+ def getServers(self):
+ """
+ Return the server object
+ """
+
+ return self._serverpool
+
+ def getClients(self):
+ """
+ Return the client object
+ """
+
+ return self._clientpool
+
+ def getConnection(self, key):
+ """
+ """
+ value = None
+ if self._all.has_key(key):
+ value = self._all[key]
+ return value
+
+ def getConnections(self):
+ """
+ """
+ return self._all
+
+
+
+
diff --git a/SharedModules/Globals/testenv.py b/SharedModules/Globals/testenv.py
new file mode 100755
index 0000000..9aa8ec8
--- /dev/null
+++ b/SharedModules/Globals/testenv.py
@@ -0,0 +1,462 @@
+"""testenv module.
+
+TestEnv Class has attributes which holds information of the current
+testenvironment. It includes information about Servers, Clients, Volume,
+Bricks, MountPoints etc.
+TestEnv Class provides methods to access the testenvironment info
+"""
+
+from collections import namedtuple
+import re
+
+class TestEnv():
+
+ def __init__(self):
+ self._exportdirs = {}
+ self._servers = {}
+ self._bricks = {}
+ self._volumes = {}
+ self._clients = {}
+ self._mountdevices = {}
+ self._mounts = {}
+ self._gluster_download_paths = []
+ self._active_volume = None
+
+ self._exportdir_tuple = namedtuple('ExportDir',
+ ['dir', 'fstype', 'device'])
+
+ self._server_tuple = namedtuple('Server',
+ ['hostname', 'user', 'password',
+ 'glusterversion', 'installpath'])
+
+ self._brick_tuple = namedtuple('Brick',
+ ['hostname', 'path'])
+
+ self._volume_tuple = namedtuple('Volume',
+ ['volumename', 'volumetype', 'count',
+ 'transporttype', 'bricks'])
+
+ self._client_tuple = namedtuple('Client',
+ ['hostname', 'user', 'password',
+ 'glusterversion', 'installpath'])
+
+ self._mountdevice_tuple = namedtuple('MountDevice',
+ ['hostname', 'volumename'])
+
+ self._mount_tuple = namedtuple('Mount',
+ ['client', 'dir', 'device',
+ 'type', 'logfile', 'options'])
+
+ def addExportdir(self, key, dir_, **arguments):
+ """
+ """
+ fstype = device = None
+ if (arguments.has_key('fstype') and arguments['fstype']):
+ fstype = arguments['fstype']
+
+ if (arguments.has_key('device') and arguments['device']):
+ device = arguments['device']
+
+ exportdir_obj = self._exportdir_tuple(dir_, fstype, device)
+ self._exportdirs[key] = exportdir_obj
+
+ def getExportdir(self, exportdirkey):
+ """
+ """
+ exportdir_obj = None
+ if self._exportdirs.has_key(exportdirkey):
+ exportdir_obj = self._exportdirs[exportdirkey]
+
+ return exportdir_obj
+
+ def getExportdirs(self):
+ """Returns self._exportdirs dictionary.
+ 'key' in dict is exportdirkey
+ 'value' is exportdir namedtuple object
+ """
+
+ return self._exportdirs
+
+ def addServer(self, key, hostname, user, password,
+ glusterversion, **arguments):
+ """
+ """
+ installpath = None
+ if (arguments.has_key('installpath') and arguments['installpath']):
+ installpath = arguments['installpath']
+
+ server_obj = self._server_tuple(hostname, user, password,
+ glusterversion, installpath)
+
+ self._servers[key] = server_obj
+
+ def getServer(self, serverkey):
+ """
+ """
+ server_obj = None
+ if self._servers.has_key(serverkey):
+ server_obj = self._servers[serverkey]
+
+ return server_obj
+
+ def getServers(self):
+ """
+ """
+ servers = {}
+
+ for serverkey in self._servers.keys():
+ servers[serverkey] = self.getServer(serverkey)
+
+ return servers
+
+ def addClient(self, key, hostname, user, password,
+ glusterversion, **arguments):
+ """
+ """
+ installpath = None
+ if arguments.has_key('installpath') and arguments['installpath']:
+ installpath = arguments['installpath']
+
+ client_obj = self._client_tuple(hostname, user, password,
+ glusterversion, installpath)
+ self._clients[key] = client_obj
+
+ def getClient(self, clientkey):
+ """
+ """
+ client_obj = None
+ if self._clients.has_key(clientkey):
+ client_obj = self._clients[clientkey]
+
+ return client_obj
+
+ def getClients(self):
+ """
+ """
+ clients = {}
+
+ for clientkey in self._clients.keys():
+ clients[clientkey] = self.getClient(clientkey)
+
+ return clients
+
+ def addBrick(self, key, hostname, path, **arguments):
+ """
+ """
+ brick_obj = self._brick_tuple(hostname, path)
+ self._bricks[key] = brick_obj
+
+ def getBrick(self, brickkey):
+ """
+ """
+ return_brick_obj = None
+ newhostname = newpath = ''
+
+ if self._bricks.has_key(brickkey):
+ brick_obj = self._bricks[brickkey]
+ else:
+ return return_brick_obj
+
+ hostname_value = brick_obj.hostname
+ serverkey = re.split("\.", hostname_value, maxsplit=1)[0]
+ server_obj = self.getServer(serverkey)
+ if server_obj:
+ newhostname = server_obj.hostname
+ else:
+ return return_brick_obj
+
+ path_value = brick_obj.path
+ if re.match("^\/", path_value):
+ path = path_value
+ else:
+ exportdir_obj = self.getExportdir(path_value)
+ if exportdir_obj:
+ newpath = exportdir_obj.dir
+ else:
+ brick_obj = None
+ return return_brick_obj
+
+ return_brick_obj = brick_obj._replace(hostname=newhostname,
+ path=newpath)
+
+ return return_brick_obj
+
+ def getBricks(self):
+ """
+ """
+ return_bricks = {}
+
+ for brickkey in self._bricks.keys():
+ return_bricks[brickkey] = self.getBrick(brickkey)
+
+ return return_bricks
+
+ def getRawBrick(self, brickkey):
+ brick_obj = None
+ if self._bricks.has_key(brickkey):
+ brick_obj = self._bricks[brickkey]
+ return brick_obj
+
+ def getBrickKeys(self):
+ """
+ """
+ brick_keys = []
+ brick_keys.extend(self._bricks.keys())
+ return brick_keys
+
+ def addBricksToVolume(self, volumekey="ActiveVolume", *bricks):
+ """
+ """
+ volume_obj = None
+ if volumekey == "ActiveVolume":
+ volumekey = self._active_volume
+
+ if not (volumekey and self._volumes.has_key(volumekey)):
+ return 1
+
+ volume_obj = self._volumes[volumekey]
+
+ for brick in bricks:
+ volume_obj.bricks.append(brick)
+
+ return 0
+
+ def replaceBrickInVolume(self, replace_brick, to_brick,
+ volumekey="ActiveVolume"):
+ """
+ """
+ volume_obj = None
+ replaced_status = False
+ if volumekey == "ActiveVolume":
+ volumekey = self._active_volume
+
+ if not (volumekey and self._volumes.has_key(volumekey)):
+ return 1
+
+ volume_obj = self._volumes[volumekey]
+ for index, brick in enumerate(volume_obj.bricks):
+ if brick == replace_brick:
+ volume_obj.bricks[index] = to_brick
+ replaced_status = True
+ break
+ else:
+ continue
+
+ if replaced_status:
+ return 0
+ else:
+ return 1
+
+ def addVolume(self, key, volumename, volumetype, count,
+ transporttype, bricks):
+ """
+ """
+ brickskeylist = [x.strip() for x in bricks.split(",")]
+ volume_obj = self._volume_tuple(volumename, volumetype,
+ count, transporttype, brickskeylist)
+ self._volumes[key] = volume_obj
+
+ def getVolume(self, volumekey):
+ """
+ """
+ return_volume_obj = None
+
+ if not self._volumes.has_key(volumekey):
+ return return_volume_obj
+
+ volume_obj = self._volumes[volumekey]
+ brickslist = []
+ for brickkey in volume_obj.bricks:
+ brick_obj = self.getBrick(brickkey)
+ if not brick_obj:
+ return return_volume_obj
+ else:
+ brickslist.append(brick_obj)
+
+ return_volume_obj = volume_obj._replace(bricks=brickslist)
+
+ return return_volume_obj
+
+ def getVolumes(self):
+ """
+ """
+ return_volumes = {}
+ for volumekey in self._volumes.keys():
+ return_volumes[volumekey] = self.getVolume(volumekey)
+
+ return return_volumes
+
+ def addMountDevice(self, key, hostname, volumename):
+ """
+ """
+ mountdevice_obj = self._mountdevice_tuple(hostname, volumename)
+ self._mountdevices[key] = mountdevice_obj
+
+ def getMountDevice(self, mountdevicekey):
+ """
+ *) Check the hostname = IPAddress
+ *) Check hostname refers to any server
+ *) Check the volume is defined.
+ *) Substitute all values
+ """
+ returndevice_obj = None
+ ip_pattern = re.compile('(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})')
+
+ if not self._mountdevices.has_key(mountdevicekey):
+ return returndevice_obj
+
+ else:
+ mountdevice_obj = self._mountdevices[mountdevicekey]
+
+ hostname_value = mountdevice_obj.hostname
+ if ip_pattern.match(hostname_value):
+ newhostname = hostname_value
+ elif re.match('(([a-z]|[A-Z])+[0-9]+)\.hostname', hostname_value):
+ serverkey = re.split("\.", hostname_value, maxsplit=1)[0]
+ server_obj = self.getServer(serverkey)
+ if server_obj:
+ newhostname = server_obj.hostname
+ else:
+ return returndevice_obj
+ else:
+ newhostname = hostname_value
+ volumekey = re.split("\.", mountdevice_obj.volumename, maxsplit=1)[0]
+ volume_obj = self.getVolume(volumekey)
+ if volume_obj:
+ newvolumename = volume_obj.volumename
+ else:
+ return returndevice_obj
+
+
+ returndevice_obj = mountdevice_obj._replace(hostname=newhostname,
+ volumename=newvolumename)
+ return returndevice_obj
+
+ def getMountDevices(self):
+ """
+ """
+ return_mount_devices = {}
+
+ for mountdevicekey in self._mountdevices.keys():
+ return_mount_devices[mountdevicekey] = self.getMountDevice(mountdevicekey)
+
+ return return_mount_devices
+
+ def addMount(self, key, client, dir_, device, **arguments):
+ """
+ """
+ logfile = options = None
+ type_ = "glusterfs"
+
+ if (arguments.has_key("type") and arguments['type']):
+ type_ = arguments['type']
+
+ if (arguments.has_key("logfile") and arguments['logfile']):
+ logfile = arguments['logfile']
+
+ if (arguments.has_key("options") and arguments['options']):
+ options = arguments['options']
+
+ mount_obj = self._mount_tuple(client, dir_, device,
+ type_, logfile, options)
+ self._mounts[key] = mount_obj
+
+ def getMount(self, mountkey):
+ """
+ """
+ return_mount_obj = None
+ if not self._mounts.has_key(mountkey):
+ return return_mount_obj
+
+ mount_obj = self._mounts[mountkey]
+ devicekey = mount_obj.device
+ device_obj = self.getMountDevice(devicekey)
+ if not device_obj:
+ return return_mount_obj
+ else:
+ return_mount_obj = mount_obj._replace(device=device_obj)
+
+ return return_mount_obj
+
+ def getMounts(self):
+ """
+ """
+ return_mounts = {}
+
+ for mountkey in self._mounts.keys():
+ return_mounts[mountkey] = self.getMount(mountkey)
+
+ return return_mounts
+
+ def getMountsKeys(self):
+ """
+ """
+ mounts_keys = []
+ mounts_keys.extend(self._mounts.keys())
+ return mounts_keys
+
+ def addDefaults(self, **arguments):
+ """
+ """
+ downloadpaths = []
+
+ if (arguments.has_key('downloadpath') and arguments['downloadpath']):
+ paths = arguments['downloadpath']
+ downloadpaths = [x.strip() for x in paths.split(",")]
+
+ self._gluster_download_paths = downloadpaths
+
+ def setActiveVolume(self, volumekey):
+ """
+ """
+ if self._volumes.has_key(volumekey):
+ self._active_volume = volumekey
+ return 0
+ else:
+ return 1
+
+ def getActiveVolume(self):
+ """
+ """
+ active_volume_key = self._active_volume
+ active_volume = self.getVolume(active_volume_key)
+ return active_volume
+
+ def getGlusterDownloadPaths(self):
+ """
+ """
+ return self._gluster_download_paths
+
+ def getHosts(self):
+ """
+ """
+ all_hosts = {}
+ all_hosts.update(self.getServers)
+ all_hosts.update(self.getClients)
+ return all_hosts
+
+ def getHostsKeys(self):
+ """
+ """
+ hosts_keys = []
+ hosts_keys.extend(self._servers.keys())
+ hosts_keys.extend(self._clients.keys())
+ return hosts_keys
+
+ def getHost(self, hostkey):
+ """
+ """
+ host_obj = None
+ host_obj = self.getServer(hostkey)
+ if host_obj:
+ return host_obj
+ else:
+ host_obj = self.getClient(hostkey)
+ return host_obj
+
+
+
+
+
+
+
diff --git a/SharedModules/Globals/testruninfo.py b/SharedModules/Globals/testruninfo.py
new file mode 100644
index 0000000..9b012e8
--- /dev/null
+++ b/SharedModules/Globals/testruninfo.py
@@ -0,0 +1,144 @@
+"""testruninfo module
+
+TestRunInfo Class contains variables and methods for storing and retrieving
+information about current "TestRun".
+"""
+import re
+
+class TestRunInfo():
+ def __init__(self):
+ self._testunits = []
+ self._keywords = ''
+ self._glusterversion = ''
+ self._atfdir = ''
+ self._summaryloginfo = {}
+ self._detailloginfo = {}
+ self._stdoutloginfo = {}
+
+ def addGlusterVersion(self, version):
+ """
+ """
+ self._glusterversion = version
+
+ def getGlusterVersion(self):
+ """
+ """
+ return self._glusterversion
+
+ def addSummaryLogInfo(self, filename, loglevel):
+ """
+ """
+ if not filename:
+ filename = "SummaryLog.out"
+
+ if not loglevel:
+ loglevel = "info"
+
+ self._summaryloginfo['filename'] = filename
+ self._summaryloginfo['loglevel'] = loglevel
+
+ def getSummaryLogInfo(self):
+ """
+ """
+ return self._summaryloginfo
+
+ def addDetailLogInfo(self, filename, loglevel):
+ """
+ """
+ if not filename:
+ filename = "DetailLog.out"
+
+ if not loglevel:
+ loglevel = "info"
+
+ self._detailloginfo['filename'] = filename
+ self._detailloginfo['loglevel'] = loglevel
+
+ def getDetailLogInfo(self):
+ """
+ """
+ return self._detailloginfo
+
+ def addStdoutLogInfo(self, do_log, loglevel):
+ """
+ """
+ true_pattern = re.compile('True|Yes', re.IGNORECASE)
+ false_pattern = re.compile('False|No', re.IGNORECASE)
+
+ if not loglevel:
+ loglevel = "info"
+
+ if true_pattern.match(do_log):
+ do_log = True
+
+ elif false_pattern.match(do_log):
+ do_log = False
+
+ else:
+ do_log = True
+
+ self._stdoutloginfo['do_log'] = do_log
+ self._stdoutloginfo['loglevel'] = loglevel
+
+ def getStdoutLogInfo(self):
+ """
+ """
+ return self._stdoutloginfo
+
+ def addAtfDir(self, atfdir):
+ """
+ """
+ self._atfdir = atfdir
+
+ def getAtfDir(self):
+ """
+ """
+ return self._atfdir
+
+ def addTestUnits(self, testunit):
+ """
+ Description:
+ Add a testunit to TestUnits List
+
+ Parameter:
+ testunit: Name of the Testing Unit
+
+ Returns:
+ """
+
+ self._testunits.append(testunit)
+ return
+
+ def getTestUnits(self):
+ """
+ Description:
+ Return TestUnits List
+
+ Parameters:
+
+ Returns:
+ Success: Testunit Name
+ Failure: ''
+ """
+
+ return self._testunits
+
+ def addKeywords(self, keywords):
+ """
+ Description:
+ Add Keywords to KeyWords List
+
+ Parameters:
+ keyname: Keyword
+
+ Returns:
+ """
+ self._keywords = keywords
+
+ def getKeywords(self):
+ """
+ """
+ return self._keywords
+
+
+
diff --git a/SharedModules/Parser/parser.py b/SharedModules/Parser/parser.py
new file mode 100644
index 0000000..ee3a2d1
--- /dev/null
+++ b/SharedModules/Parser/parser.py
@@ -0,0 +1,315 @@
+""" Parser module contains parsers for parsing:
+*) TestrunInfo file
+*) TestEnvironment file
+*) Testcaselist file.
+"""
+
+import ConfigParser
+import re
+from collections import OrderedDict
+import os
+from atfglobals import GlobalObj
+
+
+def verify_necessary_options(cp, section, necessary_options):
+ """Helper function for all parsers to verify necessary options
+ in a section of the config file.
+
+ Parameters:
+ cp : Config Parser Object
+ section: name of the section in ConfigFile
+ necessary_options: Options necessary under Section 'section'
+
+ Returns:
+ Success: True (if all necessary_options are found in 'section')
+ Failure: False ( if any of the necessaty_options not found in 'section')
+ """
+ all_options_found = True
+ items = dict(cp.items(section))
+ for option in necessary_options:
+ if not (items.has_key(option) and items[option]):
+ print "' %s ' Should be defined in Section: %s" % (option, section)
+ all_options_found = False
+ return all_options_found
+
+
+def parse_testrun_info_file(filename):
+ """
+ Parse TestrunInfo File
+ """
+ GlobalObj.initTestrunInfoObj()
+ testruninfo_obj = GlobalObj.getTestrunInfoObj()
+ cp = ConfigParser.SafeConfigParser()
+ necessary_sections = ["keywords", "testunits", "atfdir",
+ "summarylog","detaillog", "stdoutlog",
+ "glusterversion"]
+ matched_sections = []
+ unmatched_sections = []
+
+ if not cp.read(filename):
+ print "Error reading file ' %s '.File Not found " % filename
+ return 1
+ else:
+ available_sections = cp.sections()
+ found_all_sections = True
+ for section in necessary_sections:
+ matched_obj = re.search(section, str(available_sections),
+ re.IGNORECASE)
+ if not matched_obj:
+ found_all_sections = False
+ unmatched_sections.append(section)
+ else:
+ matched_sections.append(matched_obj.group(0))
+
+ if not found_all_sections:
+ for section in unmatched_sections:
+ print "Section %s Not Found" % section
+ print "Please define the above sections in TestRunInfo File"
+ return 1
+
+ else:
+ for section in matched_sections:
+ Map = {}
+ if re.match("keywords", section, re.IGNORECASE):
+ Map = dict(cp.items(section))
+ testruninfo_obj.addKeywords(Map['keywords'])
+
+ elif re.match("testunits", section, re.IGNORECASE):
+ Map = dict(cp.items(section))
+ testunits = Map.values()
+ for testunit in testunits:
+ if testunit:
+ testruninfo_obj.addTestUnits(testunit)
+
+ elif re.match("atfdir", section, re.IGNORECASE):
+ Map = dict(cp.items(section))
+ atfdir = Map['dir']
+ if not atfdir:
+ print "dir option not defined in ATFDir. " + \
+ "The 'dir'option should be defined"
+ return 1
+ else:
+ testruninfo_obj.addAtfDir(atfdir)
+
+ elif re.match("summarylog", section, re.IGNORECASE):
+ Map = dict(cp.items(section))
+ testruninfo_obj.addSummaryLogInfo(Map['filename'],
+ Map['loglevel'])
+
+ elif re.match("detaillog", section, re.IGNORECASE):
+ Map = dict(cp.items(section))
+ testruninfo_obj.addDetailLogInfo(Map['filename'],
+ Map['loglevel'])
+
+ elif re.match("stdoutlog", section, re.IGNORECASE):
+ Map = dict(cp.items(section))
+ testruninfo_obj.addStdoutLogInfo(Map['do_log'],
+ Map['loglevel'])
+
+ elif re.match("glusterversion", section, re.IGNORECASE):
+ Map = dict(cp.items(section))
+ glusterversion = Map['version']
+ if not glusterversion:
+ print "version option not defined in GlusterVersion. " + \
+ "The 'version' option should be defined"
+ return 1
+ else:
+ testruninfo_obj.addGlusterVersion(glusterversion)
+
+ return 0
+
+def parse_testcaseslist_file(filename):
+ """
+ Parse TestCasesList file
+ """
+ return_status = 1
+ testcaseslist = []
+ if not os.path.exists(filename):
+ print "%s file not found." % filename
+ return return_status
+
+ testruninfo_obj = GlobalObj.getTestrunInfoObj()
+ glusterversion = testruninfo_obj.getGlusterVersion()
+
+ testcaseslistfile = open(filename, "r")
+ filedata = testcaseslistfile.readlines()
+
+ testcaseslist = []
+ for data in filedata:
+ if (not data.strip() or re.match("^#", data)):
+ continue
+
+ else:
+ testcaseid, version, keyword = (value.strip() for value in
+ data.split(':'))
+ testcaseslist.append({'testcaseid':testcaseid, 'version':version,
+ 'keyword':keyword})
+
+ selected_testcases = []
+ if glusterversion == "master":
+ for testcase in testcaseslist:
+ selected_testcases.append(testcase['testcaseid'])
+ return selected_testcases
+ else:
+ for testcase in testcaseslist:
+ if re.match("^(<|>|=|<=|>=)", testcase['version']):
+ condition, version = (x.strip() for x in
+ testcase['version'].split())
+
+ if ((condition == "<=" and glusterversion <= version) or
+ (condition == ">=" and glusterversion >= version) or
+ (condition == "<" and glusterversion < version) or
+ (condition == ">" and glusterversion > version) or
+ (condition == "=" and glusterversion == version)):
+ selected_testcases.append(testcase['testcaseid'])
+
+ elif re.search("-", testcaseid['version']):
+ fromversion, toversion = (x.strip() for x in
+ testcaseid['version'].split("-"))
+ if (glusterversion >= fromversion and
+ glusterversion <= toversion):
+ selected_testcases.append(testcase['testcaseid'])
+
+ return selected_testcases
+
+
+def parse_testenv_configfile(filename):
+ """
+ parse testenv.cfg file
+ """
+ GlobalObj.initTestenvObj()
+ env = GlobalObj.getTestenvObj()
+ cp = ConfigParser.SafeConfigParser(dict_type=OrderedDict)
+ sections_to_functions_mapping = {
+ "export" : "addExportdir",
+ "server" : "addServer",
+ "brick" : "addBrick",
+ "volume" : "addVolume",
+ "client" : "addClient",
+ "mountdevice" : "addMountDevice",
+ "mount" : "addMount",
+ "defaults" : "addDefaults"}
+ section_pattern = re.compile('(export|server|brick|volume|client|mountdevice|mount)*')
+ if not cp.read(filename):
+ print "Error reading file ' %s '.File Not found " % filename
+ return 1
+ else:
+ defaults = dict(cp.defaults())
+ function = getattr(env, "addDefaults")
+ function(**defaults)
+ sections = cp.sections()
+ for section in sections:
+ items = dict(cp.items(section))
+ matched_obj = section_pattern.match((section.lower()))
+ result = matched_obj.group(0)
+ if result is '':
+ continue
+ else:
+ funcname = sections_to_functions_mapping[result]
+ function = getattr(env, funcname)
+ necessary_options = []
+
+ if re.match('export', result):
+ necessary_options = ["dir"]
+ if verify_necessary_options(cp, section, necessary_options):
+ dir_ = items.pop('dir')
+ function(section, dir_, **items)
+ else:
+ return 1
+
+ elif re.match('server', result):
+ necessary_options = ["hostname", "user", "password",
+ "glusterversion"]
+ if verify_necessary_options(cp, section, necessary_options):
+ hostname = items.pop('hostname')
+ user = items.pop('user')
+ password = items.pop('password')
+ glusterversion = items.pop('glusterversion')
+ function(section, hostname, user, password,
+ glusterversion, **items)
+ else:
+ return 1
+
+ elif re.match('client', result):
+ necessary_options = ["hostname", "user", "password",
+ "glusterversion"]
+ if verify_necessary_options(cp, section, necessary_options):
+ hostname = items.pop('hostname')
+ user = items.pop('user')
+ password = items.pop('password')
+ glusterversion = items.pop('glusterversion')
+ function(section, hostname, user, password,
+ glusterversion, **items)
+ else:
+ return 1
+
+ elif re.match('brick', result):
+ necessary_options = ["hostname", "path"]
+ if verify_necessary_options(cp, section, necessary_options):
+ hostname = items.pop('hostname')
+ path = items.pop('path')
+ function(section, hostname, path, **items)
+ else:
+ return 1
+
+ elif re.match('volume', result):
+ necessary_options = ["volumename", "volumetype",
+ "count", "transporttype",
+ "bricks"]
+ if verify_necessary_options(cp, section, necessary_options):
+ volumename = items.pop('volumename')
+ volumetype = items.pop('volumetype')
+ count = items.pop('count')
+ transporttype = items.pop('transporttype')
+ bricks = items.pop('bricks')
+ function(section, volumename, volumetype,
+ count, transporttype, bricks)
+ else:
+ return 1
+
+ elif re.match('mountdevice', result):
+ necessary_options = ["hostname", "volumename"]
+ if verify_necessary_options(cp, section, necessary_options):
+ hostname = items.pop('hostname')
+ volumename = items.pop('volumename')
+ function(section, hostname, volumename)
+
+ elif re.match('mount', result):
+ necessary_options = ["client", "dir", "device"]
+ if verify_necessary_options(cp, section, necessary_options):
+ client = items.pop('client')
+ dir_ = items.pop('dir')
+ device = items.pop('device')
+ function(section, client, dir_, device, **items)
+
+ else:
+ return 1
+ return 0
+
+
+__all__ = ['parse_testrun_info_file',
+ 'parse_testcaseslist_file',
+ 'parse_testenv_configfile']
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SharedModules/Utils/atfutils.py b/SharedModules/Utils/atfutils.py
new file mode 100644
index 0000000..980c286
--- /dev/null
+++ b/SharedModules/Utils/atfutils.py
@@ -0,0 +1,58 @@
+"""atfutils module contains general purpose wrappers
+
+*) assert_success
+*) assert_failure
+*) print-stdout
+*) print_stderr
+*) set_active_volume
+"""
+
+import re
+import ssh
+from atfglobals import GlobalObj
+
+def assert_success(**arguments):
+ """
+ """
+ if not arguments["exitstatus"]:
+ return 0
+ else:
+ return 1
+
+def assert_failure(**arguments):
+ """
+ """
+ if arguments["exitstatus"]:
+ return 0
+ else:
+ return 1
+
+def print_stdout(stdoutdata):
+ """
+ """
+ if not stdoutdata == None:
+ for data in stdoutdata:
+ print data
+
+def print_stderr(stderrdata):
+ if not stderrdata == None:
+ for data in stderrdata:
+ print data
+
+def set_active_volume(volumekey):
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+ return_status = env.setActiveVolume(volumekey)
+ if return_status:
+ print "Unable to set Active Volume. '%s' Not defined in TestEnvironment"\
+ % volumekey
+ return return_status
+
+
+
+__all__ = ['assert_success',
+ 'assert_failure',
+ 'print-stdout',
+ 'print_stderr',
+ 'set_active_volume']
diff --git a/SharedModules/Utils/clientutils.py b/SharedModules/Utils/clientutils.py
new file mode 100644
index 0000000..ad5d593
--- /dev/null
+++ b/SharedModules/Utils/clientutils.py
@@ -0,0 +1,282 @@
+"""clientutils module contains functions required for performing
+certain operations on client
+
+Supported Wrappers :-
+-----------
+*) umount
+*) umountall
+*) mount
+*) mountall
+"""
+
+import atfutils
+import hostutils
+from atfglobals import GlobalObj
+
+def umount(mountkey):
+ """unmounts a mountpoint
+
+ Parameters:
+ mountkey : name given to a mount as specified in testenv.cfg file.
+ Ex:-"mount1"
+
+ Returns:
+ Success : 0
+ Failure : 1`
+ """
+ base_command = "umount "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+
+ mount_obj = env.getMount(mountkey)
+ if not mount_obj:
+ print "InValid Mount. %s not defined in TestEnvironment" % mountkey
+ return 1
+
+ clientkey = mount_obj.client
+ client_connection = cm.getConnection(clientkey)
+ if not client_connection:
+ print "SSH connection to host '%s' has not been established" % clientkey
+ return 1
+
+ command = base_command + mount_obj.dir
+ print "%s : %s" % (clientkey, command)
+ output = client_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ if return_status:
+ stdoutdata = str(output["stdoutdata"])
+ if ((stdoutdata.rfind("not found")) or (stdoutdata.rfind("not mount"))):
+ return_status = 0
+
+ else:
+ print "Unable to umount %s" % mountkey
+
+ return return_status
+
+def umountall():
+ """unmounts all mount specified in testenv.cfg file.
+ Ex:- mount1, mount2 etc
+
+ Parameters:
+ None
+
+ Returns:
+ Success : 0
+ Failure : 1`
+ """
+ env = GlobalObj.getTestenvObj()
+ failure_flag = False
+
+ mounts_keys = env.getMountsKeys()
+ for mountkey in mounts_keys:
+ return_status = umount(mountkey)
+ if return_status:
+ failure_flag = True
+
+ if failure_flag:
+ return 1
+ else:
+ return 0
+
+def mount(mountkey):
+ """mounts a filesystem
+
+ Parameters:
+ mountkey : name given to a mount as specified in testenv.cfg file.
+ Ex:-"mount1"
+
+ Returns:
+ Success : 0
+ Failure : 1`
+ """
+
+ base_command = command = "mount "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+
+ mount_obj = env.getMount(mountkey)
+ if not mount_obj:
+ print "InValid Mount. %s not defined in TestEnvironment" % mountkey
+ return 1
+
+ clientkey = mount_obj.client
+ client_connection = cm.getConnection(clientkey)
+ if not client_connection:
+ print "SSH connection to host '%s' has not been established" % clientkey
+ return 1
+
+ mountdevice_obj = mount_obj.device
+ device = mountdevice_obj.hostname + ":/" + mountdevice_obj.volumename
+ options = ["-t", mount_obj.type]
+ if mount_obj.logfile:
+ options.extend(["-o", ("log-file="+mount_obj.logfile),
+ "log-level=INFO"])
+
+ if mount_obj.options:
+ options.extend([mount_obj.option])
+
+ options.extend([device, mount_obj.dir])
+ for index, option in enumerate(options):
+ command = command + option + " "
+
+ return_status = hostutils.mkdir(clientkey, mount_obj.dir)
+ if return_status:
+ return return_status
+
+ print "%s : %s" % (clientkey, command)
+ output = client_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def mountall():
+ """mounts a filesystem for all mounts specified in testenv.cfg file.
+
+ Parameters:
+ None
+
+ Returns:
+ Success : 0
+ Failure : 1`
+ """
+ env = GlobalObj.getTestenvObj()
+
+ mounts_keys = env.getMountsKeys()
+ for mountkey in mounts_keys:
+ return_status = mount(mountkey)
+ if return_status:
+ return return_status
+
+ return 0
+
+
+def execute_on_mount(mountkey, command, commandInput=None):
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+ mount_obj = env.getMount(mountkey)
+ if not mount_obj:
+ print "InValid Mount. %s not defined in TestEnvironment" % mountkey
+ return 1
+
+ clientkey = mount_obj.client
+ mountdir = mount_obj.dir
+ command = "cd " + mountdir + " ;" + command
+ return_status = hostutils.execute_command(clientkey, command, commandInput)
+ return return_status
+
+__all__ = ['execute_on_mount',
+ 'umount',
+ 'umountall',
+ 'mount',
+ 'mountall']
+
+##def umountall(clientkey):
+## """
+## """
+## base_command = "umount "
+## env = GlobalObj.get_testenv_obj()
+## cm = GlobalObj.get_connectionsmanager_obj()
+## client_obj = env.getclient(clientkey)
+## mountdir = client_obj.mountdir
+## volume = client_obj.device
+## client = cm.getconnection(clientkey)
+##
+## mountpoints = []
+## success_flag = False
+## failure_flag = False
+## command = "mount | grep " + mountdir
+## output = client.executecommand(command)
+## if not output["exitstatus"]:
+## for data in output["stdoutdata"]:
+## mountpoints.append(data.split(" ")[2])
+##
+## for mountpoint in mountpoints:
+## command = base_command + mountpoint
+## output = client.executecommand(command)
+## return_code = utils.assert_success(**output)
+## if return_code:
+## failure_flag = True
+## else:
+## success_flag = True
+## continue
+##
+## if failure_flag:
+## return 1
+##
+## mountpoints = []
+## success_flag = False
+## failure_flag = False
+## command = "mount | grep " + volume
+## output = client.executecommand(command)
+## if not output["exitstatus"]:
+## for data in output["stdoutdata"]:
+## mountpoints.append(data.split(" ")[2])
+##
+## for mountpoint in mountpoints:
+## command = base_command + mountpoint
+## output = client.executecommand(command)
+## return_code = utils.assert_success(**output)
+## if return_code:
+## failure_flag = True
+## else:
+## success_flag = True
+## continue
+##
+## if failure_flag:
+## return 1
+##
+## return 0
+
+##def cd_mount(mountkey):
+## """
+## """
+## env = GlobalObj.getTestenvObj()
+## mount_obj = env.getMount(mountkey)
+## if not mount_obj:
+## print "InValid Mount. %s not defined in TestEnvironment" % mountkey
+## return 1
+##
+## clientkey = mount_obj.client
+## dirpath = mount_obj.dir
+## return_status = hostutils.cd(clientkey, dirpath)
+## return return_status
+##
+##def cd_allmounts():
+## """
+## """
+## env = GlobalObj.getTestenvObj()
+## mounts_keys = env.getMountsKeys()
+## for mountkey in mounts_keys:
+## return_status = cd_mount(mountkey)
+## if return_status:
+## return return_status
+##
+## return 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SharedModules/Utils/glusterutils.py b/SharedModules/Utils/glusterutils.py
new file mode 100644
index 0000000..0c15af1
--- /dev/null
+++ b/SharedModules/Utils/glusterutils.py
@@ -0,0 +1,644 @@
+"""glusterutils module contains wrappers for gluster commands.
+
+*) glusterd_start
+*) glusterd_start_allservers
+*) glusterd_stop
+*) glusterd_stop_allservers
+*) glusterd_restart
+*) glusterd_remove_dir
+*) glusterd_remove_dir_allservers
+*) glusterd_remove_logs_allservers
+*) volume_delete
+*) volume_create
+*) volume_start
+*) volume_stop
+*) volume_addbrick
+*) volume_replacebrick
+*) volume_set
+*) volume_reset
+*) peer_probe
+*) create_brick
+*) mount_exportdir
+*) umount_exportdir
+"""
+
+import re
+import atfutils
+import hostutils
+from atfglobals import GlobalObj
+
+
+def glusterd_start(serverkey, force=False):
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ commands_to_execute = ["which glusterd", "ps -e | grep glusterd"]
+ gluster_version = env.getServer(serverkey).glusterversion
+ host_connection = cm.getConnection(serverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ """ Check if gluster is already running. If already Running and force=True,
+ restart glusterd process"""
+ command = commands_to_execute.pop()
+ output = host_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ if not return_status:
+ if force:
+ return_status = glusterd_restart(serverkey)
+ return return_status
+ else:
+ return return_status
+
+ command = commands_to_execute.pop()
+ output = host_connection.executecommand(command)
+ if output["exitstatus"]:
+ print "Unable to start glusterd"
+ return_status = atfutils.assert_success(**output)
+ return return_status
+ else:
+ if output["stdoutdata"]:
+ gluster_path = None
+ gluster_path = output["stdoutdata"][0].strip("\n")
+ else:
+ print "Unable to find gluster path"
+ return_status = atfutils.assert_success(**output)
+ return return_status
+
+ if gluster_path:
+ command = gluster_path + " --version"
+ output = host_connection.executecommand(command)
+ if not output["stdoutdata"] == None:
+ if re.search(gluster_version, str(output["stdoutdata"])):
+ print "%s : %s" % (serverkey, gluster_path)
+ output = host_connection.executecommand(gluster_path)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+ else:
+ print "Unable to start glusterd"
+ return 1
+ else:
+ print "Unable to start glusterd"
+ return 1
+
+def glusterd_start_allservers(force=False):
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+ all_servers = env.getServers()
+ for serverkey in all_servers.keys():
+ return_status = glusterd_start(serverkey)
+ if return_status:
+ return return_status
+
+ return 0
+
+def glusterd_stop(serverkey):
+ """
+ """
+ base_command = "kill -KILL "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ host_connection = cm.getConnection(serverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ gluster_pid_list = []
+ output = host_connection.executecommand("pidof glusterd")
+ return_status = atfutils.assert_failure(**output)
+ if not return_status:
+ return return_status
+
+ else:
+ if output["stdoutdata"]:
+ for output in output["stdoutdata"]:
+ gluster_pid_list.append(output)
+
+ for pid in gluster_pid_list:
+ command = base_command + pid
+ print "%s : %s" % (serverkey, command)
+ output = host_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ if return_status:
+ break
+
+ return return_status
+
+def glusterd_stop_allservers():
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+ all_servers = env.getServers()
+ for serverkey in all_servers.keys():
+ return_status = glusterd_stop(serverkey)
+ if return_status:
+ return return_status
+
+ return 0
+
+def glusterd_restart(serverkey):
+ """
+ """
+ return_status = glusterd_stop(serverkey)
+ if return_status:
+ return return_status
+ else:
+ return_status = glusterd_start(serverkey)
+ return return_status
+
+def glusterd_remove_dir(serverkey):
+ """
+ """
+ command = "rm -rf /etc/glusterd/*"
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+
+ server_obj = env.getServer(serverkey)
+ if not server_obj:
+ print "Invalid Host. %s not defined in TestEnvironment" % serverkey
+ return 1
+
+ server_connection = cm.getConnection(serverkey)
+ if not server_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ print "%s : %s" % (serverkey, command)
+ output = server_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return 0
+
+def glusterd_remove_dir_allservers():
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+ all_servers = env.getServers()
+ for serverkey in all_servers.keys():
+ return_status = glusterd_remove_dir(serverkey)
+
+ return 0
+
+
+def glusterd_remove_logs(serverkey):
+ """
+ """
+ base_command = "rm -rf "
+ log_paths = ["/var/log/glusterfs/*.log", "/var/log/glusterfs/bricks/*"]
+ absolute_path_list = []
+ prefix_path = ''
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+
+ server_obj = env.getServer(serverkey)
+ if not server_obj:
+ print "Invalid Host. %s not defined in TestEnvironment" % serverkey
+ return 1
+
+ server_connection = cm.getConnection(serverkey)
+ if not server_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ if server_obj.installpath:
+ prefix_path = server_obj.installpath
+
+ for path in log_paths:
+ absolute_path_list.append(prefix_path + path)
+
+ for path in absolute_path_list:
+ command = base_command + path
+ print "%s : %s" % (serverkey, command)
+ output = server_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+
+ return 0
+
+def glusterd_remove_logs_allservers():
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+ all_servers = env.getServers()
+ for serverkey in all_servers.keys():
+ return_status = glusterd_remove_logs(serverkey)
+
+ return 0
+
+def volume_delete(serverkey):
+ """
+ """
+ base_command = "gluster volume delete "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ active_volume = env.getActiveVolume()
+ if not active_volume:
+ print "Invalid Volume.ActiveVolume not defined for the TestEnvironment"
+ return 1
+ volumename = active_volume.volumename
+ command = base_command + volumename
+ host_connection = cm.getConnection(serverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ print "%s : %s" % (serverkey, command)
+ output = host_connection.executecommand(command, commandInput="y\n")
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def volume_create(serverkey):
+ """
+ """
+ base_command = "gluster volume create "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ active_volume = env.getActiveVolume()
+ if not active_volume:
+ print "ActiveVolume not defined for the TestEnvironment"
+ return 1
+
+ command = base_command + \
+ active_volume.volumename + " " + \
+ active_volume.volumetype + " " + \
+ active_volume.count + " " + \
+ "transport " + active_volume.transporttype + " "
+
+ for brick_obj in active_volume.bricks:
+ brick_value = brick_obj.hostname + ":" + brick_obj.path
+ command = command + brick_value + " "
+
+ host_connection = cm.getConnection(serverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ print "%s : %s" % (serverkey, command)
+ output = host_connection.executecommand(command, commandInput="y\n")
+ return_status = atfutils.assert_success(**output)
+ if return_status:
+ if str(output["stdoutdata"]).rfind("already exists"):
+ return_status = 0
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def volume_start(serverkey, force=False):
+ """
+ """
+ base_command = "gluster volume start "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ active_volume = env.getActiveVolume()
+ if not active_volume:
+ print "ActiveVolume not defined for the TestEnvironment"
+ return 1
+ volumename = active_volume.volumename
+ command = base_command + volumename
+ if force:
+ command = command + " force"
+
+ host_connection = cm.getConnection(serverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ print "%s : %s" % (serverkey, command)
+ output = host_connection.executecommand(command, commandInput="y\n")
+ return_status = atfutils.assert_success(**output)
+ if return_status:
+ if str(output["stdoutdata"]).rfind("already started"):
+ return_status = 0
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def volume_stop(serverkey, force=False):
+ """
+ """
+ base_command = "gluster volume stop "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ active_volume = env.getActiveVolume()
+ if not active_volume:
+ print "ActiveVolume not defined for the TestEnvironment"
+ return 1
+ volumename = active_volume.volumename
+ command = base_command + volumename
+ if force:
+ command = command + " force"
+
+ host_connection = cm.getConnection(serverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ print "%s : %s" % (serverkey, command)
+ output = host_connection.executecommand(command, commandInput="y\n")
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def volume_addbrick(serverkey, *bricks):
+ """
+ """
+ base_command = "gluster volume add-brick "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ active_volume = env.getActiveVolume()
+ if not active_volume:
+ print "ActiveVolume not defined for the TestEnvironment"
+ return 1
+ volumename = active_volume.volumenameGlobalObj.getConnectionsManagerObj()
+ command = base_command + volumename + " "
+ for brick in bricks:
+ brick_obj = env.getBrick(brick)
+ if not brick_obj:
+ print "Invalid Brick. Brick Not defined in TestEnvironment"
+ return 1
+ brick_value = brick_obj.hostname + ":" + brick_obj.path
+ command = command + brick_value
+
+ host_connection = cm.getConnection(serverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ print "%s : %s" % (serverkey, command)
+ output = host_connection.executecommand(command, commandInput="y\n")
+ return_status = atfutils.assert_success(**output)
+ if not return_status:
+ if env.addBricksToVolume(*bricks):
+ return 1
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def volume_replacebrick(serverkey, replacebrick_key, tobrick_key):
+ """
+ """
+ base_command = "gluster volume replace-brick "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ active_volume = env.getActiveVolume()
+ if not active_volume:
+ print "ActiveVolume not defined for the TestEnvironment"
+ return 1
+ volumename = active_volume.volumename
+ command = base_command + volumename + " "
+ replace_brick = env.getbrick(replacebrick_key)
+ to_brick = env.getbrick(tobrick_key)
+ command = command + replace_brick + " " + to_brick
+
+ host_connection = cm.getConnection(serverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ print "%s : %s" % (serverkey, command)
+ output = host_connection.executecommand(command, commandInput="y\n")
+ return_status = atfutils.assert_success(**output)
+ if not return_status:
+ if env.replaceBrickInVolume(replacebrick_key, tobrick_key):
+ return 1
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def volume_set(serverkey, key, value):
+ """
+ """
+ base_command = "gluster volume set "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ active_volume = env.getActiveVolume()
+ if not active_volume:
+ print "ActiveVolume not defined for the TestEnvironment"
+ return 1
+ volumename = active_volume.volumename
+ command = base_command + volumename + " " + key + " " + value
+ host_connection = cm.getConnection(serverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ print "%s : %s" % (serverkey, command)
+ output = host_connection.executecommand(command, commandInput="y\n")
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def volume_reset(serverkey):
+ """
+ """
+ base_command = "gluster volume reset "
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ active_volume = env.getActiveVolume()
+ if not active_volume:
+ print "ActiveVolume not defined for the TestEnvironment"
+ return 1
+ volumename = active_volume.volumename
+ command = base_command + volumename
+ host_connection = cm.getConnection(serverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ print "%s : %s" % (serverkey, command)
+ output = host_connection.executecommand(command, commandInput="y\n")
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def peer_probe(fromserverkey):
+ """
+ """
+ base_command = "gluster peer probe "
+ command = base_command
+ all_servers = {}
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ all_servers = env.getServers()
+ all_servers.pop(fromserverkey)
+
+ for key in all_servers.keys():
+ if key is fromserverkey:
+ continue
+ else:
+ server_obj = all_servers[key]
+ command = command + server_obj.hostname + " "
+
+ host_connection = cm.getConnection(fromserverkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ print "%s : %s" % (fromserverkey, command)
+ output = host_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def create_brick(brickkey):
+ """
+ """
+ return_status = 1
+ env = GlobalObj.getTestenvObj()
+ brick_obj = env.getRawBrick(brickkey)
+
+ hostname_value = brick_obj.hostname
+ serverkey = re.split("\.", hostname_value, maxsplit=1)[0]
+
+ exportdir = brick_obj.path
+ device = fstype = None
+ """If the exportdir is not a mount point of a device:
+ 1) Remove the existing exportdir
+ 2) Create new exportdir"""
+
+ if re.match("^\/", exportdir):
+ dirpath = exportdir
+ command = base_command + dirpath
+ else:
+ export_obj = env.getExportdir(exportdir)
+ dirpath = export_obj.dir
+ device = export_obj.device
+ fstype = export_obj.fstype
+
+ print "%s : %s" % (serverkey, 'create_brick')
+ if device:
+ if umount_device(serverkey, device):
+ return return_status
+ if hostutils.mkfs(serverkey, device, fstype):
+ return return_status
+ if mount_exportdir(serverkey, device, fstype, dirpath):
+ return return_status
+ return 0
+
+ else:
+ if hostutils.rmdir(serverkey, dirpath):
+ return return_status
+ if hostutils.mkdir(serverkey, dirpath):
+ return return_status
+
+ return 0
+
+def umount_device(serverkey, device):
+ """
+ """
+ base_command = "umount "
+ cm = GlobalObj.getConnectionsManagerObj()
+
+ server_connection = cm.getConnection(serverkey)
+ if not server_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ mountpoints = hostutils.find_mountpoints(serverkey, device)
+
+ for mountpoint in mountpoints:
+ command = base_command + mountpoint
+ print "%s : %s" % (serverkey, command)
+ output = server_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ if return_status:
+ stdoutdata = str(output["stdoutdata"])
+ if ((stdoutdata.rfind("not found")) or (stdoutdata.rfind("not mount"))):
+ return_status = 0
+
+ else:
+ return return_status
+
+ return 0
+
+def mount_exportdir(serverkey, device, fstype, dirpath):
+ """
+ """
+ base_command = "mount "
+ cm = GlobalObj.getConnectionsManagerObj()
+
+ server_connection = cm.getConnection(serverkey)
+ if not server_connection:
+ print "SSH connection to host '%s' has not been established" % serverkey
+ return 1
+
+ if fstype is None:
+ fstype = "xfs"
+
+ command = base_command + "-t " + fstype + " " + device + " " + dirpath
+
+ print "%s : %s" % (serverkey, command)
+ output = server_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def create_brick_allservers():
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+ brick_keys = env.getBrickKeys()
+ for brickkey in brick_keys:
+ return_status = create_brick(brickkey)
+ if return_status:
+ return return_status
+
+ return 0
+
+
+__all__ = ['glusterd_start',
+ 'glusterd_start_allservers',
+ 'glusterd_stop',
+ 'glusterd_stop_allservers',
+ 'glusterd_restart',
+ 'glusterd_remove_dir',
+ 'glusterd_remove_dir_allservers',
+ 'glusterd_remove_logs_allservers',
+ 'volume_delete',
+ 'volume_create',
+ 'volume_start',
+ 'volume_stop',
+ 'volume_addbrick',
+ 'volume_replacebrick',
+ 'volume_set',
+ 'volume_reset',
+ 'peer_probe',
+ 'create_brick',
+ 'create_brick_allservers',
+ 'mount_exportdir',
+ 'umount_device']
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SharedModules/Utils/hostutils.py b/SharedModules/Utils/hostutils.py
new file mode 100644
index 0000000..68bb1bf
--- /dev/null
+++ b/SharedModules/Utils/hostutils.py
@@ -0,0 +1,193 @@
+"""hostutils module contains wrappers for commands that can be executed on any
+host in the test environment
+
+Supported Wrappers:
+-------------------
+*) rmdir
+*) mkdir
+*) mkfs
+*) execute_command
+"""
+
+import re
+import atfutils
+from atfglobals import GlobalObj
+
+def cd(hostkey, dirpath):
+ """
+ """
+ base_command = "cd "
+ cm = GlobalObj.getConnectionsManagerObj()
+ host_connection = cm.getConnection(hostkey)
+ if not host_connection:
+ print "SSH Connection Not established to host '%s' " % hostkey
+ return 1
+ command = base_command + dirpath
+ print "%s : %s" % (hostkey, command)
+ output = host_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def rmdir(hostkey, dirpath):
+ """
+ """
+ base_command = "rm -rf "
+ cm = GlobalObj.getConnectionsManagerObj()
+ system_dirs = re.compile('(/bin|/boot|/dev|/etc|/lib|/mnt|/net|/opt|/root|/sbin|/usr|/var|/sys)\/?$')
+ if system_dirs.match(dirpath):
+ print "System Directiories cannot be deleted"
+ return 1
+
+ else:
+ host_connection = cm.getConnection(hostkey)
+ if not host_connection:
+ print "SSH Connection Not established to host '%s' " % hostkey
+ return 1
+ command = base_command + dirpath
+ print "%s : %s" % (hostkey, command)
+ output = host_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def mkdir(hostkey, dirpath):
+ """
+ """
+ base_command = "mkdir -p "
+ cm = GlobalObj.getConnectionsManagerObj()
+ system_dirs = re.compile('(/bin|/boot|/dev|/etc|/lib|/mnt|/net|/opt|/root|/sbin|/usr|/var|/sys)\/?$')
+ if system_dirs.match(dirpath):
+ print "System Directiories cannot be created"
+ return 1
+
+ else:
+ host_connection = cm.getConnection(hostkey)
+ if not host_connection:
+ print "SSH Connection Not established to host '%s' " % hostkey
+ return 1
+ command = base_command + dirpath
+ print "%s : %s" % (hostkey, command)
+ output = host_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def mkfs(hostkey, device, fstype=None):
+ """
+ """
+ base_command = "mkfs "
+ cm = GlobalObj.getConnectionsManagerObj()
+ host_connection = cm.getConnection(hostkey)
+ if not host_connection:
+ print "SSH Connection Not established to host '%s' " % hostkey
+ return 1
+
+ if fstype is None:
+ fstype = "xfs"
+
+ command = base_command + " -t " + fstype + " -f " + device
+ print "%s : %s" % (hostkey, command)
+ output = host_connection.executecommand(command)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+def find_mountpoints(hostkey, device):
+ """
+ """
+ base_command = "mount | grep "
+ cm = GlobalObj.getConnectionsManagerObj()
+
+ host_connection = cm.getConnection(hostkey)
+ if not host_connection:
+ print "SSH connection to host '%s' has not been established" % hostkey
+ return 1
+
+ mountpoints = []
+ command = base_command + device
+ print "%s : %s" % (hostkey, command)
+ output = host_connection.executecommand(command)
+ if not output["exitstatus"]:
+ for data in output["stdoutdata"]:
+ mountpoints.append(data.split(" ")[2])
+
+ return mountpoints
+
+def execute_command(hostkey, command, commandInput=None):
+ """
+ """
+ cm = GlobalObj.getConnectionsManagerObj()
+ host_connection = cm.getConnection(hostkey)
+ if not host_connection:
+ print "SSH Connection Not established to host '%s' " % hostkey
+ return 1
+ new_command = _substitute_value_for_variables(hostkey, command)
+
+ print "%s : %s" % (hostkey, command)
+ output = host_connection.executecommand(new_command, commandInput)
+ return_status = atfutils.assert_success(**output)
+ atfutils.print_stdout(output['stdoutdata'])
+ atfutils.print_stderr(output['stderrdata'])
+ return return_status
+
+
+def _substitute_value_for_variables(hostkey, command):
+ """
+ """
+ pattern_for_variables = re.compile("<[a-z]+\d*>")
+ pattern_for_hosts = re.compile('(server|client|master)*')
+ variables_to_replace = []
+ replace_values = {}
+ new_command = command
+ Functions_Map = {
+ "server" : "getserver",
+ "client" : "getclient",
+ "master" : "getmaster"
+ }
+ variables = pattern_for_variables.findall(command)
+ host = None
+
+ if not variables:
+ return new_command
+
+ else:
+ result = pattern_for_hosts.match(hostkey.lower()).group(0)
+ if result:
+ funcname = Functions_Map[result]
+ function = getattr(env, funcname)
+ if re.match("master", result):
+ host = function()
+ else:
+ host = function(hostkey)
+
+ if not host:
+ print "No Host to execute the command\n"
+ return 1
+
+ for variable in variables:
+ if variable not in variables_to_replace:
+ variables_to_replace.append(variable.strip("<>"))
+
+ for variable in variables_to_replace:
+ value = host.__getattribute__(variable)
+ replace_values[variable] = value
+
+ for key in replace_values.keys():
+ value = replace_values[key]
+ key = "<" + key + ">"
+ pattern = re.compile(key)
+ new_command = pattern.sub(value, new_command)
+
+ return new_command
+
+__all__ = ['cd',
+ 'rmdir',
+ 'mkdir',
+ 'mkfs',
+ 'find_mountpoints',
+ 'execute_command']
diff --git a/SharedModules/Utils/managerutils.py b/SharedModules/Utils/managerutils.py
new file mode 100644
index 0000000..ca38b3f
--- /dev/null
+++ b/SharedModules/Utils/managerutils.py
@@ -0,0 +1,55 @@
+"""managerutils module.
+
+Supported Wrappers:-
+---------------
+*) ssh_connect
+*) ssh_connect_allhosts
+"""
+
+import re
+import ssh
+from atfglobals import GlobalObj
+
+def ssh_connect(hostkey):
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ host_connection = cm.getConnection(hostkey)
+ if not host_connection:
+ host_obj = env.getHost(hostkey)
+ if not host_obj:
+ print "Invalid Host. %s is not defined in TestEnvironment" % hostkey
+ return 1
+ else:
+ host_connection = ssh.SshConnection()
+ if host_connection.connect(host_obj.hostname, host_obj.user,
+ host_obj.password):
+ return 1
+ else:
+ if re.match("server", hostkey, re.IGNORECASE):
+ cm.addServer(hostkey, host_connection)
+ else:
+ cm.addClient(hostkey, host_connection)
+ return 0
+ else:
+ print "Connection to %s already exist" % hostkey
+
+ return 0
+
+def ssh_connect_allhosts():
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+ cm = GlobalObj.getConnectionsManagerObj()
+ hosts_keys = env.getHostsKeys()
+ for hostkey in hosts_keys:
+ return_status = ssh_connect(hostkey)
+ if return_status:
+ return return_status
+
+ return 0
+
+__all__ = ['ssh_connect',
+ 'ssh_connect_allhosts']
+
diff --git a/SharedModules/Utils/serverutils.py b/SharedModules/Utils/serverutils.py
new file mode 100644
index 0000000..618ee23
--- /dev/null
+++ b/SharedModules/Utils/serverutils.py
@@ -0,0 +1,33 @@
+"""serverutils module
+"""
+import re
+import hostutils
+from atfglobals import GlobalObj
+
+def execute_on_brick(brickkey, command, commandInput=None):
+ """
+ """
+ env = GlobalObj.getTestenvObj()
+
+ raw_brick_obj = env.getRawBrick(brickkey)
+ if not raw_brick_obj:
+ print "InValid Brick. %s not defined in TestEnvironment" % brickkey
+ return 1
+ serverkey = re.split("\.", raw_brick_obj.hostname, maxsplit=1)[0]
+
+ brick_obj = env.getBrick(brickkey)
+ if not brick_obj:
+ print "InValid Brick. %s not defined in TestEnvironment" % brickkey
+ return 1
+ exportdirpath = brick_obj.path
+
+ command = "cd " + exportdirpath + ";" + command
+ return_status = hostutils.execute_command(serverkey, command, commandInput)
+ return return_status
+
+__all__ = ['execute_on_brick']
+
+
+
+
+
diff --git a/TestUnits/replicate/self_heal/Main.py b/TestUnits/replicate/self_heal/Main.py
new file mode 100644
index 0000000..4e37265
--- /dev/null
+++ b/TestUnits/replicate/self_heal/Main.py
@@ -0,0 +1,69 @@
+"""Main module for the testunit.
+
+This module "main" function is called from atfexecute to execute the testunit.
+"""
+import parser
+import atfutils
+import glusterutils
+import managerutils
+import testcases
+
+def initialize(filename):
+ """
+ """
+ return_status = 1
+ if parser.parse_testenv_configfile(filename):
+ return return_status
+ if managerutils.ssh_connect_allhosts():
+ return return_status
+
+ return 0
+
+def setup():
+ """
+ """
+ return_status = 1
+ if atfutils.set_active_volume("volume1"):
+ return return_status
+ return 0
+
+def execute(*testcaselist):
+ """
+ """
+ passedtestcases = 0
+ failedtestcases = 0
+ selectedtestcases = len(testcaselist)
+
+ for testcase in testcaselist:
+ function_obj = getattr(testcases, testcase)
+ if function_obj:
+ print "Starting Test: ' %s '" % testcase
+ return_status = function_obj()
+ if return_status:
+ print "TestCase ' %s ' Failed" % testcase
+ failedtestcases += 1
+ else:
+ print "TestCase ' %s ' Passed" % testcase
+ passedtestcases += 1
+ print "Ending Test: ' %s '" % testcase
+ else:
+ print "TestCase %s not defined in 'testcases' module" % testcase
+ continue
+
+ print "Selected %d : Passed %d, Failed %d" % (selectedtestcases,
+ passedtestcases,
+ failedtestcases)
+
+def cleanup():
+ """
+ """
+ pass
+
+def main(testenvfile, *testcaselist):
+ """
+ """
+ initialize(testenvfile)
+ setup()
+ execute(*testcaselist)
+ cleanup()
+ return
diff --git a/TestUnits/replicate/self_heal/testcases.py b/TestUnits/replicate/self_heal/testcases.py
new file mode 100644
index 0000000..0015e5f
--- /dev/null
+++ b/TestUnits/replicate/self_heal/testcases.py
@@ -0,0 +1,96 @@
+"""testcases for replicate/self-heal
+"""
+
+import sys
+import time
+import hostutils
+import managerutils
+import glusterutils
+import atfutils
+import clientutils
+import serverutils
+import parser
+
+def reset_testenv():
+ return_status = 1
+ if clientutils.umountall():
+ return return_status
+ glusterutils.volume_stop("server1", force=True)
+ glusterutils.volume_delete("server1")
+ glusterutils.glusterd_stop_allservers()
+ glusterutils.glusterd_remove_dir_allservers()
+ glusterutils.glusterd_remove_logs_allservers()
+ return 0
+
+def setup_testenv():
+ """
+ """
+ return_status = 1
+ if glusterutils.glusterd_start_allservers(force=True):
+ return return_status
+ if glusterutils.peer_probe("server1"):
+ return return_status
+ if glusterutils.create_brick_allservers():
+ return return_status
+ if glusterutils.volume_create("server1"):
+ return 1
+ glusterutils.volume_set("server1", key="diagnostics.client-log-level", value="DEBUG")
+ if glusterutils.volume_start("server1"):
+ return 1
+ if clientutils.mountall():
+ return 1
+ return 0
+
+def test001():
+ """
+ Description: Test for failure when the entry does not exist
+ """
+ return_status = 1
+ if reset_testenv():
+ return return_status
+ if setup_testenv():
+ return return_status
+ return_status = clientutils.execute_on_mount("mount1", "ls abcd")
+
+ if return_status:
+ test_status = 0
+ else:
+ test_status = 1
+
+ return test_status
+
+def test002():
+ """
+ Description: Test for estale when the fs is stale
+ """
+ return_status = 1
+ if reset_testenv():
+ return return_status
+ if setup_testenv():
+ return return_status
+
+ clientutils.execute_on_mount("mount1", "touch file")
+ serverutils.execute_on_brick("brick1",
+ "setfattr -n trusted.gfid -v 0sBfz5vAdHTEK1GZ99qjqTIg== file")
+ return_status = clientutils.execute_on_mount("mount1", "find file | xargs stat")
+
+ if return_status:
+ test_status = 0
+ else:
+ test_status = 1
+
+ return test_status
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TestUnits/replicate/self_heal/testcaseslist b/TestUnits/replicate/self_heal/testcaseslist
new file mode 100644
index 0000000..ba90492
--- /dev/null
+++ b/TestUnits/replicate/self_heal/testcaseslist
@@ -0,0 +1,9 @@
+#################################################################
+# List of testcases for the self-heal feature of afr.
+# TestCaseId : Version : Keyword
+##################################################################
+test001 : >= 3.2 : art
+test002 : >= 3.2 : art
+
+
+
diff --git a/TestUnits/replicate/self_heal/testenv.cfg b/TestUnits/replicate/self_heal/testenv.cfg
new file mode 100644
index 0000000..a8b15c8
--- /dev/null
+++ b/TestUnits/replicate/self_heal/testenv.cfg
@@ -0,0 +1,98 @@
+[DEFAULT]
+user = root
+password = syst3m
+glusterversion = 3.2.5
+installpath =
+downloadpath =
+
+# ExportDir Section.
+# Necessary Options: dir
+# Optional: fstype, device
+[export1]
+dir = /export
+fstype = xfs
+device = /dev/sdb1
+
+[export2]
+dir = /export
+fstype = xfs
+device = /dev/sda1
+
+# Server Section
+# Necessary Options: hostname, username, password, glusterversion.
+# The username, password, glusterversion defaults from DEFAULTS Section and
+# can be overridden
+# Optional: installpath
+[server1]
+hostname = 10.1.11.110
+
+[server2]
+hostname = 10.1.11.111
+
+# Brick Section
+# Necessary Options: hostname, path
+[brick1]
+hostname = server1.hostname
+path = export1
+
+[brick2]
+hostname = server2.hostname
+path = export2
+
+
+# Volume Section
+# Necessary Options: volumename, volumetype, count, transporttype, bricks
+[volume1]
+volumename = replicate
+volumetype = replica
+count = 2
+transporttype = tcp
+bricks = brick1, brick2
+
+# Client Section
+# Necessary Options: hostname, username, password, glusterversion.
+# The username, password, glusterversion defaults from DEFAULTS Section and
+# can be overridden
+# Optional: installpath
+[client1]
+hostname = 10.1.11.109
+
+# MountDevice Section
+# Necessary Options: hostname, volume
+# The Server1.hostname could be a VIP also. Need not be a server hostname
+# IN a general case,(without NFS) we keep the 1st server from serverpool
+# The volume specified in this section is the "active_volume" onto which all
+# clients will be mounting to. This active volume and hostname can be changed
+# during testrun.
+[mountdevice1]
+hostname = server1.hostname
+volumename = volume1.volumename
+
+# Mount Section
+# addMount(dir, type, client, device=master.volume, logfile=None)
+[mount1]
+dir = /mnt/replicate1
+client = client1
+device = mountdevice1
+type = glusterfs
+logfile =
+options =
+
+[mount2]
+dir = /mnt/replicate2
+client = client1
+device = mountdevice1
+type = glusterfs
+
+[mount3]
+dir = /mnt/replicate3
+client = client1
+device = mountdevice1
+type = glusterfs
+
+
+
+
+
+
+
diff --git a/atf.py b/atf.py
index e60bbb9..63b0f9d 100755
--- a/atf.py
+++ b/atf.py
@@ -1,222 +1,16 @@
-#!/usr/bin/env python
+"""atf module is the entry point of the regression suite.
-import sys
+CommandLine Usage: python atf.py -f testruninfo.cfg
+"""
import argparse
-import ConfigParser
-import ATFInit
-import ATFSetup
-import ATFExecute
-import ATFCleanup
-import ATFUtils
-
-##########################################################################
-## commandline : command executed to start the TestRun.
-##########################################################################
-commandline = ''
-
-##########################################################################
-## Configuration File Parser Object
-##########################################################################
-Config = ConfigParser.SafeConfigParser()
-
-def ConfigSectionMap(section):
- """
- Description:
- Get the key=value pair for the Section 'section' in the Config File
-
- Parameters:
- section: Section Name in the Config File
-
- Returns:
- Success: Dictionary: List of key=value pairs from section 'section'
- Failure: 1
- """
-
- dict1 = {}
-
- try:
- options = Config.options(section)
-
- except ConfigParser.NoSectionError:
- return 1
-
- else:
- for option in options:
- dict1[option] = Config.get(section, option)
-
- return dict1
-
-def parse_configfile(filename):
- """
- Description:
- Function to Parse the Configuration file
-
- Parameters:
- filename: Name of the configuration file
-
- Returns:
- Success: 0
- Failure: 1
- """
-
- keyword = ''
- workunit = ''
-
- status = Config.read(filename)
-
- if status == []:
- print "Configuration File: " + filename + "Not Found"
- return 1
- else:
- ### Parse Section: [Keywords] ###
- Map = ConfigSectionMap('Keywords')
-
- if Map == 1:
- print "Section: [Keywords] Not Found"
- return 1
- else:
- keyword = Map['keystring']
- ATFUtils.TestsObj.add_keywords(keyword)
-
- ### Parse Section: [WorkUnits] ###
- Map = ConfigSectionMap('WorkUnits')
-
- if Map == 1:
- print "Section: [WorkUnits] Not Found"
- return 1
- else:
- for key in Map.keys():
- workunit = Map[key]
- ATFUtils.TestsObj.add_testunits(workunit)
- ATFUtils.TestsObj.sort_testunits()
-
- ### Parse Section: [ATFRoot] ###
- Map = ConfigSectionMap('ATFRoot')
-
- if Map == 1:
- print "Section: [ATFRoot] Not Found"
- return 1
- else:
- atfroot = Map['rootdir']
-
- if atfroot == None:
- print "ATF_ROOT Not defined. "
- return 1
- else:
- if ATFUtils.set_environ(ATF_ROOT = atfroot):
- return 1
-
- ### Parse Section: [SummaryLog] ###
- Map = ConfigSectionMap('SummaryLog')
-
- if Map == 1:
- print "Section: [SummaryLog] Not Found"
- return 1
- else:
- summarylog_filename = Map['filename']
- summarylog_level = Map['loglevel']
-
- if summarylog_filename == None:
- summarylog_filename = 'SummaryLog.out'
-
- if summarylog_level == None:
- summarylog_level = 'INFO'
-
- ATFUtils.LogObj.set_summarylog(filename=summarylog_filename,
- loglevel=summarylog_level)
- abspath = atfroot + "/" + summarylog_filename
-
- if ATFUtils.set_environ(ATF_SUMMARYLOG = abspath):
- return 1
-
- ### Parse Detail Log Section ###
- Map = ConfigSectionMap('DetailLog')
-
- if Map == 1:
- print "Section: [DetailLog] Not Found"
- return 1
- else:
- detaillog_filename = Map['filename']
- detaillog_level = Map['loglevel']
-
- if detaillog_filename == None:
- detaillog_filename = 'DetailLog.out'
-
- if detaillog_level == None:
- detaillog_level = 'DEBUG'
-
- ATFUtils.LogObj.set_detaillog(filename=detaillog_filename,
- loglevel=detaillog_level)
-
- ### Parse Stdout Log Section ###
- Map = ConfigSectionMap('StdoutLog')
-
- if Map == 1:
- print "Section: [StdoutLog] Not Found"
- else:
- stdoutlog_log = Map['do_log']
- stdoutlog_level = Map['loglevel']
-
- if stdoutlog_log == 'true':
- if stdoutlog_level == None:
- stdoutlog_level = 'INFO'
- ATFUtils.LogObj.set_stdoutlog(loglevel=stdoutlog_level)
-
- ### Parse GlobalParam Section ###
- Map = ConfigSectionMap('GlobalParam')
-
- if Map == 1:
- print "Section: [GlobalParam] Not Found"
- return 1
- else:
- globalparamfile = Map['filename']
-
- if globalparamfile == None:
- print "Global Param File Not defined."
- return 1
- else :
- ATFUtils.TestEnvObj.set_globalparamfile(globalparamfile)
-
- #### Log the contents of Config File to SummaryLog and Stdout ####
- abspath = atfroot + "/" + summarylog_filename
-
- try:
- fhr = open(filename, "r")
-
- except IOError:
- print "IOError: Cannot Open Config FIle for Reading" + abspath
- return 1
-
- else:
- try:
- fhw = open(abspath, "w")
-
- except IOError:
- print "IOError: Cannot Open Summary Log FIle " + abspath
- fhr.close()
- return 1
-
- else:
- lines = fhr.readlines()
- fhw.write("Starting the Glusterfs Regression Tests")
- fhw.write("\n\nCommandLine: " + commandline + "\n\n")
- fhw.write(("-" * 50) + "\nConfiguration File Contents: \n" +
- ("-" * 50) + "\n")
- fhw.writelines(lines)
-
- fhw.close()
- fhr.close()
-
- return 0
+import atfinit
+import atfexecute
def main(args):
"""
Description:
- 1) Parse the Configuration File
- 2) Initialize the Loggers, TestEnvironment
- 3) Set-up TestBed for TestRun Execution
- 4) Execute the Tests for the WorkUnits Specified
- 5) Cleanup the TestEnvironment after the Test Execution is complete
+ *) Initialize TestRun
+ *) Execute TestUnits
Parameters:
args: Command Line Arguments passed to 'atf'
@@ -225,95 +19,33 @@ def main(args):
Success: 0
Failure: 1
"""
-
- configfilename = args.file[0]
- if parse_configfile(configfilename):
- exit(1)
-
- if ATFInit.initialize():
- exit(1)
-
- if ATFSetup.setup():
+ if atfinit.initialize(args):
exit(1)
- if ATFExecute.execute():
- exit(1)
-
- if ATFCleanup.cleanup():
+ if atfexecute.execute():
exit(1)
else:
exit(0)
if __name__ == "__main__":
-
- for arg in sys.argv:
- commandline = commandline + arg + " "
- parser = argparse.ArgumentParser(
- description="Runs GlusterFS Regression Test Suite",
+ argparser = argparse.ArgumentParser(
+ description="Runs GlusterFS Functional/Regression Test Suite",
epilog="Report Bugs to dl-qa@gluster.com")
- parser.add_argument('-f', '--file', nargs=1, required=True, type=str,
- help="Configuration FIleName")
+ argparser.add_argument('-f', '--file', required=True, type=str,
+ help="TestRunInfo FileName")
- args = parser.parse_args()
+ args = argparser.parse_args()
main(args)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/atfexecute.py b/atfexecute.py
new file mode 100644
index 0000000..a60402b
--- /dev/null
+++ b/atfexecute.py
@@ -0,0 +1,63 @@
+"""atfexecute
+"""
+
+import os.path
+import sys
+import parser
+from atfglobals import GlobalObj
+
+def _execute_testunit(testunit):
+ """
+ *) Parse the testcaseslist file in the 'testunit' and select test cases
+ specified for testing 'glusterversion'
+ *) Call Main.py of 'testunit' to execute the testcases.
+ """
+ return_status = 1
+ testruninfo_obj = GlobalObj.getTestrunInfoObj()
+ atfdir = testruninfo_obj.getAtfDir()
+ testunit_abspath = atfdir + "/TestUnits/" + testunit
+
+ testenvfile = testunit_abspath + "/testenv.cfg"
+ testcaseslistfile = testunit_abspath + "/testcaseslist"
+
+ if not os.path.exists(testenvfile):
+ default_testenvfile = atfdir + "testenv.cfg"
+ if not os.path.exists(testenvfile):
+ print "Skipping TestUnit %s . TestEnv File Not Found" % testenvfile
+ return return_status
+ else:
+ testenvfile = default_testenvfile
+
+ if not os.path.exists(testcaseslistfile):
+ print "Skipping TestUnit %s" % testunit
+ return return_status
+ else:
+ testcaseslist = []
+ testcasespassed = None
+ testcasesfailed = None
+ totaltestcases = None
+
+ testcaseslist = parser.parse_testcaseslist_file(testcaseslistfile)
+ if not testcaseslist:
+ print "Skipping TestUnit %s. No testcases to execute" % testunit
+ return return_status
+ else:
+ sys.path.append(testunit_abspath)
+ import Main
+ print "Executing TestUnit: %s" % testunit
+ print "-" * 50
+ return_status = Main.main(testenvfile, *testcaseslist)
+ return return_status
+
+def execute():
+ """
+ *) Execute the TestsCases form TestUnits specified in TestRunInfo File
+ """
+ testruninfo_obj = GlobalObj.getTestrunInfoObj()
+ testunits = testruninfo_obj.getTestUnits()
+ for testunit in testunits:
+ _execute_testunit(testunit)
+
+ return 0
+
+__all__ = ['execute']
diff --git a/atfinit.py b/atfinit.py
new file mode 100644
index 0000000..f50eefb
--- /dev/null
+++ b/atfinit.py
@@ -0,0 +1,27 @@
+"""atfinit module
+
+"""
+import os.path
+import parser
+from atfglobals import GlobalObj
+
+def _initialize_testrun_info(testrun_info_filename):
+ """
+ """
+ return_status = 1
+ if not os.path.exists(testrun_info_filename):
+ print "Testrun Info File ' %s ' not found" % testrun_info_filename
+ return return_status
+ else:
+ return_status = parser.parse_testrun_info_file(testrun_info_filename)
+ return return_status
+
+def initialize(args):
+ """
+ *) Initialize TestrunInfo File
+ """
+ testrun_info_filename = args.file
+ return_status = _initialize_testrun_info(testrun_info_filename)
+ return return_status
+
+__all__ = ['initialize']
diff --git a/atfsetup.py b/atfsetup.py
new file mode 100644
index 0000000..8631ab4
--- /dev/null
+++ b/atfsetup.py
@@ -0,0 +1,37 @@
+"""atf setup
+"""
+
+from atfglobals import GlobalObj
+
+def _setup_loggers():
+ """
+ """
+ testruninfo_obj = GlobalObj.getTestrunInfoObj()
+ logger_obj = GlobalObj.getLoggerObj()
+
+ summaryloginfo = testruninfo_obj.getSummaryLogInfo()
+ detailloginfo = testruninfo_obj.getDetailLogInfo()
+ stdoutloginfo = testruninfo_obj.getStdoutLogInfo()
+
+ logger_obj.setSummaryLog(summaryloginfo['filename'],
+ summaryloginfo['loglevel'])
+ loggerobj.setDetailLog(detailloginfo['filename'],
+ detailloginfo['loglevel'])
+ loggerobj.setStdoutLog(stdoutloginfo['do_log'],
+ stdoutloginfo['loglevel'])
+
+ atfdir = testruninfo_obj.getAtfDir()
+ return_status = logger_obj.createLogger(atfdir)
+ if return_status:
+ print "Unable to create Loggers"
+ return return_status
+
+def setup():
+ """
+ *) Setup SummaryLogs , DetailLogs Handlers
+ """
+ return_status = _setup_loggers()
+ return return_status
+
+__all__ = ['setup']
+
diff --git a/export.py b/export.py
new file mode 100755
index 0000000..e33812a
--- /dev/null
+++ b/export.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+import os
+import os
+
+exportstr = ''
+libdir = os.getcwd() + "/SharedModules/"
+for dirname, dirnames, filenames in os.walk(libdir):
+ for subdirname in dirnames:
+ exportstr = exportstr + os.path.join(dirname, subdirname) + ':'
+
+exportstr = os.getcwd() + ":" + libdir + ":" + exportstr
+print exportstr
diff --git a/testruninfo.cfg b/testruninfo.cfg
new file mode 100755
index 0000000..ed65461
--- /dev/null
+++ b/testruninfo.cfg
@@ -0,0 +1,99 @@
+#############################################################################
+## ATF Configuration File. This is input for the atf.py python script.
+## This File contains various sections.
+## The information under each section will be used for Selecting/Running Tests
+#############################################################################
+
+#############################################################################
+## Section: [Keywords]
+## Used to select the testcases tagged with keystring for test execution.
+## keywords: sanity
+## Selects all testcases tagged with sanity keyword under given TestUnit
+## (This is used for Sanity Runs)
+## keywords: art
+## Selects all testcases tagged with art keyword under given TestUnit
+## (This is used for Regression Runs)
+## Example:
+## keywords = art
+## keywords = sanity
+#############################################################################
+[Keywords]
+keywords =
+
+#############################################################################
+## Section: [WorkUnits]
+## unit specifies glusterfs features (testuntis) under test.
+## Each TestUnit is directory under Glusterfs/TestUnits directory
+## Example:
+## unit1 = Replication
+## unit2 = Replication/Self-heal
+## unit3 = Distribution
+## unit4 = Stripe
+#############################################################################
+[TestUnits]
+unit1 = replicate/self_heal
+
+#############################################################################
+## Section: [ATFDir]
+## atfdir = absolute path of the directory where Automation Framework
+## is Installed
+## Example:
+## dir = /ATF
+## dir = /home/qa/ATF
+#############################################################################
+[ATFDir]
+dir = /home/shwetha/PythonCustomLibs/ATF
+
+#############################################################################
+## Section: [SummaryLog]
+## filename = FileName to Log SummaryLogs
+## loglevel = LogLevel could be debug| info | warning | error
+## Example:
+## filename = SummaryLog.out
+## loglevel = info
+#############################################################################
+[SummaryLog]
+filename =
+loglevel =
+
+#############################################################################
+## Section: [DetailLog]
+## filename = FileName to Log DetailLogs of test case execution
+## loglevel = LogLevel could be debug| info | warning | error
+## Example:
+## filename = DetailLog.out
+## loglevel = info
+#############################################################################
+[DetailLog]
+filename =
+loglevel =
+
+#############################################################################
+## Section: [StdoutLog]
+## do_log = true | false.
+## If do_log = true, Log to STDOUT. Else, do not log to STDOUT.
+## loglevel = LogLevel could be debug| info | warning | error
+## Example:
+## do_log = true
+## loglevel = info
+#############################################################################
+[StdoutLog]
+do_log =
+loglevel =
+
+#############################################################################
+## Section: [GlusterVersion]
+## filename = Version of the 'Gluster' for testing
+##
+## Example:
+## version = '3.3.2'
+##
+#############################################################################
+[GlusterVersion]
+version = 3.2.5
+
+
+
+
+
+