From 85b6ae4ef2289ad7489cedb95740340c18043eef Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Fri, 13 May 2016 16:14:08 -0400
Subject: [PATCH] Ticket 48796 - add function to remove logs

Description:  There are CI tests that need to search DS logs.  To avoid harmless error
              codes triggered by server instance creation we need a function to remove
              the logs so we can start with a clean slate once the actual test begins.

              We also need to modify the ServerCmd function which expected to see an
              errors log.  So if the log is not present we just create an empty log and
              move on.

              Also added a helper function to print a date/time stamp, and added
              docstrings to various functions(to start to prep for sphinx documentation).

https://fedorahosted.org/389/ticket/48796

Reviewed by: ?
---
 lib389/__init__.py | 72 +++++++++++++++++++++++++++++++++++++++--------
 lib389/tools.py    | 82 ++++++++++++++++++++++++++++++++++++++++++------------
 lib389/utils.py    | 11 ++++++++
 3 files changed, 135 insertions(+), 30 deletions(-)

diff --git a/lib389/__init__.py b/lib389/__init__.py
index b72f118..69338db 100644
--- a/lib389/__init__.py
+++ b/lib389/__init__.py
@@ -1076,7 +1076,7 @@ class DirSrv(SimpleLDAPObject):
 
         self.state = DIRSRV_STATE_OFFLINE
 
-    def start(self, timeout):
+    def start(self, timeout=120):
         '''
             It starts an instance and rebind it. Its final state after rebind
             (open) is DIRSRV_STATE_ONLINE
@@ -1088,9 +1088,6 @@ class DirSrv(SimpleLDAPObject):
 
             @raise None
         '''
-        # Default starting timeout (to find 'slapd started' in error log)
-        if not timeout:
-            timeout = 120
 
         # called with the default timeout
         if DirSrvTools.start(self, verbose=self.verbose, timeout=timeout):
@@ -1098,7 +1095,7 @@ class DirSrv(SimpleLDAPObject):
 
         self.open()
 
-    def stop(self, timeout):
+    def stop(self, timeout=120):
         '''
             It stops an instance.
             It changes the state  -> DIRSRV_STATE_OFFLINE
@@ -1111,10 +1108,6 @@ class DirSrv(SimpleLDAPObject):
             @raise None
         '''
 
-        # Default starting timeout (to find 'slapd started' in error log)
-        if not timeout:
-            timeout = 120
-
         # called with the default timeout
         if DirSrvTools.stop(self, verbose=self.verbose, timeout=timeout):
             self.log.error("Probable failure to stop the instance")
@@ -2623,17 +2616,72 @@ class DirSrv(SimpleLDAPObject):
         return outs
 
     def searchAccessLog(self, pattern):
-        return DirSrvTools.searchFile(self.accesslog, pattern)
+        """
+        Search all the access logs
+        """
+        return DirSrvTools.searchFile(self.accesslog + "*", pattern)
 
     def searchAuditLog(self, pattern):
-        return DirSrvTools.searchFile(self.auditlog, pattern)
+        """
+        Search all the audit logs
+        """
+        time.sleep(1)
+        return DirSrvTools.searchFile(self.auditlog + "*", pattern)
 
     def searchErrorsLog(self, pattern):
-        return DirSrvTools.searchFile(self.errlog, pattern)
+        """
+        Search all the error logs
+        """
+        time.sleep(1)
+        return DirSrvTools.searchFile(self.errlog + "*", pattern)
 
     def detectDisorderlyShutdown(self):
+        """
+        Search the current errors log for a disorderly shutdown message
+        """
+        time.sleep(1)
         return DirSrvTools.searchFile(self.errlog, DISORDERLY_SHUTDOWN)
 
+    def deleteLog(self, logtype, restart=True):
+        """
+        Delete all the logs for this log type.
+        """
+        if restart:
+            self.stop()
+        for log in glob.glob(logtype + "*"):
+            if os.path.isfile(log):
+                os.remove(log)
+        if restart:
+            self.start()
+
+    def deleteAccessLogs(self, restart=True):
+        """
+        Delete all the access logs.
+        """
+        self.deleteLog(self.accesslog, restart)
+
+    def deleteAuditLogs(self, restart=True):
+        """
+        Delete all the audit logs.
+        """
+        self.deleteLog(self.auditlog, restart)
+
+    def deleteErrorLogs(self, restart=True):
+        """
+        Delete all the error logs.
+        """
+        self.deleteLog(self.errlog, restart)
+
+    def deleteAllLogs(self, restart=True):
+        """
+        Delete all the logs.
+        """
+        self.stop()
+        self.deleteAccessLogs(restart=False)
+        self.deleteErrorLogs(restart=False)
+        self.deleteAuditLogs(restart=False)
+        self.start()
+
     def get_effective_rights(self, sourcedn, base=DEFAULT_SUFFIX,
                              scope=ldap.SCOPE_SUBTREE, *args, **kwargs):
         """
diff --git a/lib389/tools.py b/lib389/tools.py
index e892135..b525256 100644
--- a/lib389/tools.py
+++ b/lib389/tools.py
@@ -222,10 +222,21 @@ class DirSrvTools(object):
                 pass
 
         log.info("Setup error log")
-        logfp = open(errLog, 'r')
-        logfp.seek(0, os.SEEK_END)  # seek to end
-        pos = logfp.tell()  # get current position
-        logfp.seek(pos, os.SEEK_SET)  # reset the EOF flag
+        try:
+            logfp = open(errLog, 'r')
+            logfp.seek(0, os.SEEK_END)  # seek to end
+            pos = logfp.tell()  # get current position
+            logfp.seek(pos, os.SEEK_SET)  # reset the EOF flag
+        except IOError as e:
+            if e.errno == 2:
+                # No error log - just create one and move on
+                try:
+                    open(errLog, 'w').close()  # Create empty file
+                    logfp = open(errLog, 'r')  # now open it for reading
+                except:
+                    done = True
+            else:
+                done = True
 
         log.warn("Running command: %r" % (fullCmd))
         rc = os.system("%s" % (fullCmd))
@@ -296,6 +307,9 @@ class DirSrvTools(object):
 
     @staticmethod
     def start(self, verbose=False, timeout=120):
+        """
+        Start a server
+        """
         if not self.isLocal and hasattr(self, 'asport'):
             log.debug("starting remote server %s " % self)
             cgiargs = {}
@@ -888,10 +902,12 @@ class DirSrvTools(object):
 
     @staticmethod
     def createAndSetupReplica(createArgs, repArgs):
-        # pass this sub two dicts - the first one is a dict suitable to create
-        # a new instance - see createInstance for more details
-        # the second is a dict suitable for replicaSetupAll -
-        # see replicaSetupAll
+        """
+        Pass this sub two dicts - the first one is a dict suitable to create
+        a new instance - see createInstance for more details
+        the second is a dict suitable for replicaSetupAll -
+        see replicaSetupAll
+        """
         conn = DirSrvTools.createInstance(createArgs)
         if not conn:
             print("Error: could not create server", createArgs)
@@ -902,6 +918,9 @@ class DirSrvTools(object):
 
     @staticmethod
     def makeGroup(group=DEFAULT_USER):
+        """
+        Create a system group
+        """
         try:
             grp.getgrnam(group)
             print("OK group %s exists" % group)
@@ -912,6 +931,9 @@ class DirSrvTools(object):
 
     @staticmethod
     def makeUser(user=DEFAULT_USER, group=DEFAULT_USER, home=DEFAULT_USERHOME):
+        """
+        Create a system user
+        """
         try:
             pwd.getpwnam(user)
             print("OK user %s exists" % user)
@@ -923,12 +945,18 @@ class DirSrvTools(object):
 
     @staticmethod
     def lib389User(user=DEFAULT_USER):
+        """
+        Create the lib389 user/group
+        """
         DirSrvTools.makeGroup(group=user)
         time.sleep(1)  # Need a little time for the group to get fully created
         DirSrvTools.makeUser(user=user, group=user, home=DEFAULT_USERHOME)
 
     @staticmethod
     def searchHostsFile(expectedHost, ipPattern=None):
+        """
+        Search the hosts file
+        """
         hostFile = '/etc/hosts'
 
         with open(hostFile, 'r') as hostfp:
@@ -1040,27 +1068,42 @@ class DirSrvTools(object):
 
     @staticmethod
     def searchFile(filename, pattern):
-        # Open the file and read it line by line
+        """
+        Search file (or files using a wildcard) for the pattern
+        """
         found = False
-        try:
-            myfile = open(filename)
-            for line in myfile:
-                if re.search(pattern, line):
-                    found = True
-            myfile.close()
-        except IOError as e:
-            log.error('Problem opening/searching file (%s): I/O error(%d): %s'
-                      % (filename, e.errno, e.strerror))
 
+        file_list = glob.glob(filename)
+        for file_name in file_list:
+            try:
+                myfile = open(file_name)
+                for line in myfile:
+                    result = re.search(pattern, line)
+                    if result:
+                        found = True
+                        break
+                myfile.close()
+                if found:
+                    break
+            except IOError as e:
+                log.error('Problem opening/searching file ' +
+                          '(%s): I/O error(%d): %s' %
+                          (file_name, e.errno, e.strerror))
         return found
 
 
 class MockDirSrv(object):
+    """
+    Mock DirSrv Object
+    """
     host = 'localhost'
     port = 22389
     sslport = 0
 
     def __init__(self, dict_=None):
+        """
+        Init object
+        """
         if dict_:
             self.host = dict_['host']
             self.port = dict_['port']
@@ -1068,6 +1111,9 @@ class MockDirSrv(object):
                 self.sslport = dict_['sslport']
 
     def __str__(self):
+        """
+        Return ldap URL
+        """
         if self.sslport:
             return 'ldaps://%s:%s' % (self.host, self.sslport)
         else:
diff --git a/lib389/utils.py b/lib389/utils.py
index 458be61..8510121 100644
--- a/lib389/utils.py
+++ b/lib389/utils.py
@@ -30,6 +30,7 @@ import shutil
 import ldap
 import socket
 import subprocess
+import time
 from socket import getfqdn
 from ldapurl import LDAPUrl
 
@@ -726,3 +727,13 @@ def ds_is_older(ver):
     """Return True if current version of ns-slapd is older than provided
     version"""
     return get_ds_version() < ver
+
+
+def getDateTime():
+    """
+    Return the date and time:
+
+        2016-04-21 21:21:00
+
+    """
+    return time.strftime("%Y-%m-%d %H:%M:%S")
-- 
2.4.11

