summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam R. Otte <wotte@dre.vanderbilt.edu>2006-07-19 23:40:54 +0000
committerWilliam R. Otte <wotte@dre.vanderbilt.edu>2006-07-19 23:40:54 +0000
commit93dced75e93b0594928078966030f7c82d21feae (patch)
treeaf98d7095493656260d26e044c93a3f88a5fcadf
parentb6b1457c9eec4969bba3603c0f5c89bd7d9de256 (diff)
downloadATCD-93dced75e93b0594928078966030f7c82d21feae.tar.gz
Wed Jul 19 23:39:05 UTC 2006 William R. Otte <wotte@dre.vanderbilt.edu>
-rw-r--r--ChangeLog13
-rw-r--r--bin/PythonACE/fuzz/__init__.py68
-rw-r--r--bin/PythonACE/fuzz/_generic_handler.py22
-rw-r--r--bin/PythonACE/fuzz/_mailer.py106
-rw-r--r--bin/PythonACE/fuzz/_singleton.py60
-rw-r--r--bin/PythonACE/fuzz/_warning_handler.py53
-rw-r--r--bin/PythonACE/fuzz/streams_include.py19
7 files changed, 311 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index d797c4c114e..1ec5a0bc3ca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Wed Jul 19 23:39:05 UTC 2006 William R. Otte <wotte@dre.vanderbilt.edu>
+
+ * bin/PythonACE/fuzz/__init__.py
+ * bin/PythonACE/fuzz/_generic_handler.py
+ * bin/PythonACE/fuzz/_mailer.py
+ * bin/PythonACE/fuzz/_singleton.py
+ * bin/PythonACE/fuzz/_warning_handler.py
+ * bin/PythonACE/fuzz/streams_include.py
+
+ Changes necessary to support mailing (non-fatal) Fuzz errors to
+ the user that attempts a commit. streams_include is an example
+ of a fuzz check that sends warnings instead of stopping commits.
+
Wed Jul 19 22:46:51 UTC 2006 Ossama Othman <ossama_othman at symantec dot com>
* ace/Basic_Types.h (ACE_INT64, ACE_UINT64):
diff --git a/bin/PythonACE/fuzz/__init__.py b/bin/PythonACE/fuzz/__init__.py
index 7abe5d913c4..26a7b9a3faf 100644
--- a/bin/PythonACE/fuzz/__init__.py
+++ b/bin/PythonACE/fuzz/__init__.py
@@ -1,7 +1,6 @@
""" This init script loads all python modules in the current directory that
do not start with an '_', loads them as a module"""
-
file_type_handlers = dict ()
def register_handler (module):
@@ -18,26 +17,6 @@ import re
extension_re = re.compile(".+\.([^.]+)$")
-def fuzz_check (file_name, file_content):
- # get the file extension
- ext_match = extension_re.search (file_name)
- if ext_match == None:
- # we don't have no stinking file extension!
- ext = ""
- else:
- ext = ext_match.group (1)
-
- retval = 0
-
- if file_type_handlers.has_key (ext):
- for handler in file_type_handlers[ext]:
- retval += handler (file_name, file_content)
-
- # Run the generic handlers
- for handler in file_type_handlers["*"]:
- retval += handler (file_name, file_content)
-
- return retval
# The following is the initialization logic that is executed
@@ -56,12 +35,21 @@ try:
chdir (script_path)
- path.append (".")
+ path.append (getcwd ())
files = listdir (".")
modules = list ()
+ # We need to import the warning handler here. If we use a traditional import elsewhere,
+ # we get all kinds of problems with the warning_handler being imported twice - once as
+ # fuzz._warning_handler and again as _warning_handler - making the singleton instances
+ # NOT the same.
+ _warning_handler = __import__ ("_warning_handler")
+ Warning_Handler = _warning_handler.Warning_Handler
+ STDERR = _warning_handler.STDERR
+ MAILER = _warning_handler.MAILER
+
for item in files:
if (item[0] != '_') and (item[-3:] == ".py"):
print "Registering " + item [:-3]
@@ -70,8 +58,40 @@ try:
register_handler (module)
except:
stderr.write ("FUZZ ERROR: Unable to load the " + item[:-3] + " module, please notify the build czar\n")
- raise
finally:
chdir (oldwd)
- path.pop ()
+
+
+def fuzz_check (file_name, file_content):
+ # If the user of the module has not instanciated the warning handler,
+ # lets do it here
+ if not Warning_Handler._isInstantiated ():
+ Warning_Handler.getInstance (STDERR)
+
+ # get the file extension
+ ext_match = extension_re.search (file_name)
+ if ext_match == None:
+ # we don't have no stinking file extension!
+ ext = ""
+ else:
+ ext = ext_match.group (1)
+
+ retval = 0
+
+ if file_type_handlers.has_key (ext):
+ for handler in file_type_handlers[ext]:
+ try: # We don't want one misbehaving handler to screw up the whole sustem
+ retval += handler (file_name, file_content)
+ except:
+ stderr.write ("An unknown exception was thrown while trying to run one of the handlers\n")
+
+ # Run the generic handlers
+ for handler in file_type_handlers["*"]:
+ try: # We don't want one misbehaving handler to screw up the whole sustem
+ retval += handler (file_name, file_content)
+ except:
+ stderr.write ("An unknown exception was thrown while trying to run one of the handlers\n")
+
+
+ return retval
diff --git a/bin/PythonACE/fuzz/_generic_handler.py b/bin/PythonACE/fuzz/_generic_handler.py
index 46f7e16b08b..ffc7bc10167 100644
--- a/bin/PythonACE/fuzz/_generic_handler.py
+++ b/bin/PythonACE/fuzz/_generic_handler.py
@@ -1,8 +1,9 @@
""" Defines a generic handler that tests against a given regex, and allows for exclusions. """
from sys import stderr
+import _warning_handler
-def generic_handler (regex, begin_exclude, end_exclude, error_message, file_name, file_content):
+def generic_handler (regex, begin_exclude, end_exclude, error_message, file_name, file_content, warn = False):
retval = 0
if regex.search (file_content) != None:
@@ -16,11 +17,16 @@ def generic_handler (regex, begin_exclude, end_exclude, error_message, file_name
exclusion = False
elif (exclusion == False) and (regex.search (lines[line]) != None):
# Violation!
- stderr.write (file_name + ':' + str (line + 1) + error_message)
- retval = 1
+ msg = file_name + ':' + str (line + 1) + error_message
+ if not warn:
+ stderr.write (msg)
+ retval = 1
+ else:
+ handler = _warning_handler.Warning_Handler.getInstance ()
+ handler.add_warning (msg)
return retval
-def generic_handler_no_exceptions (regex, error_message, file_name, file_content):
+def generic_handler_no_exceptions (regex, error_message, file_name, file_content, warn = False):
retval = 0
if regex.search (file_content) != None:
@@ -28,7 +34,11 @@ def generic_handler_no_exceptions (regex, error_message, file_name, file_content
lines = file_content.splitlines ()
for line in range (len (lines)):
if regex.search (lines[line]) != None:
+ msg = file_name + ':' + str (line + 1) + error_message
# Violation!
- stderr.write (file_name + ':' + str (line + 1) + error_message)
- retval = 1
+ if not warn:
+ stderr.write (msg)
+ retval = 1
+ else:
+ Warning_Handler.getInstance ().add_warning (msg)
return retval
diff --git a/bin/PythonACE/fuzz/_mailer.py b/bin/PythonACE/fuzz/_mailer.py
new file mode 100644
index 00000000000..6e33cc82c9e
--- /dev/null
+++ b/bin/PythonACE/fuzz/_mailer.py
@@ -0,0 +1,106 @@
+""" This module implements a mailer to mail a user about fuzz warnings """
+
+import _singleton
+
+def ldap_lookup (username):
+ """ Performs a ldap lookup to find the email address associated with
+ username. If none exists, it returns the empty string."""
+ import ldap
+
+ try:
+ conn = ldap.open ("ldap.dre.vanderbilt.edu")
+ conn.protocol_version = ldap.VERSION3
+
+ baseDN = "dc=dre,dc=vanderbilt,dc=edu"
+ scope = ldap.SCOPE_SUBTREE
+ attrFilter = None
+ searchFilter = "uid=" + username
+
+ result = conn.search (baseDN, scope, searchFilter, attrFilter)
+
+ result_type, result_data = conn.result (result, 0)
+ email = ""
+ if (result_data != []) and (result_type == ldap.RES_SEARCH_ENTRY):
+ # we have a valid result!
+ if (result_data[0][1].has_key ('mail')):
+ email = result_data[0][1]['mail'][0]
+ elif (result_data[0][1].has_key ('svnmail')):
+ email = result_data[0][1]['svnmail'][0]
+ else:
+ email = ""
+
+ conn.unbind ()
+
+ return email
+ except:
+ # Some error occurred when looking this guy up.
+ return ""
+
+
+
+class Mailer:
+ def __init__ (self):
+ self.recipient = ""
+ self.body = """\
+This is an automatically generated message from the fuzz check system
+in the subversion repository.
+
+Your recent commit to the ACE/TAO/CIAO repository had a number of warnings
+which should be addressed.
+
+"""
+ self.warnings = ""
+ self.subject = "Your recent commit to the DOC group repository."
+ self.sent = False
+
+ def get_messages (self):
+ return self.warnings
+ def open (self, ldap_user_name):
+ from sys import stderr
+ stderr.write ("LDAP Name: " + ldap_user_name.rstrip () + "\n")
+ self.recipient = ldap_lookup (ldap_user_name.rstrip ())
+
+ def add_warning (self, warning_text):
+ self.warnings += warning_text
+
+ def close (self):
+ try:
+ message = """\
+From: %s
+To: %s
+Subject: %s
+\r\n
+%s
+""" % ("bczar@dre.vanderbilt.edu",
+ self.recipient,
+ self.subject,
+ self.body + self.warnings)
+
+ print message
+
+ import smtplib
+ server = smtplib.SMTP('discovery.isis.vanderbilt.edu')
+ server.sendmail ("bczar@dre.vanderbilt.edu",
+ [self.recipient],
+ message)
+ except smtplib.SMTPRecipientsRefused:
+ print "Recipients refused exception"
+ server.close ()
+ except smtplib.SMTPHeloError:
+ print "Helo error"
+ server.close ()
+ except smtplib.SMTPSenderRefused:
+ print "Sender refused"
+ server.close ()
+ except smtplib.SMTPDataError:
+ print "Data error"
+ server.close ()
+ except:
+ from sys import stderr
+ stderr.write ("Caught exception while sending email\n")
+ server.close ()
+
+
+
+
+
diff --git a/bin/PythonACE/fuzz/_singleton.py b/bin/PythonACE/fuzz/_singleton.py
new file mode 100644
index 00000000000..f7a686d4988
--- /dev/null
+++ b/bin/PythonACE/fuzz/_singleton.py
@@ -0,0 +1,60 @@
+""" Implements a singleton mixin class """
+
+# The following code was written by Gary Robinson
+# (grobinson@transpose.com) and placed in the public domain. His
+# copyright notice is as follows:
+
+# By Gary Robinson, grobinson@transpose.com. No rights reserved --
+# placed in the public domain -- which is only reasonable considering
+# how much it owes to other people's version which are in the
+# public domain. The idea of using a metaclass came from
+# a comment on Gary's blog (see
+# http://www.garyrobinson.net/2004/03/python_singleto.html#comments).
+# Other improvements came from comments and email from other
+# people who saw it online. (See the blog post and comments
+# for further credits.)
+
+# Not guaranteed to be fit for any particular purpose. Use at your
+# own risk.
+
+
+class SingletonException(Exception):
+ pass
+
+class MetaSingleton(type):
+ def __new__(metaclass, strName, tupBases, dict):
+ if dict.has_key('__new__'):
+ raise SingletonException, 'Can not override __new__ in a Singleton'
+ return super(MetaSingleton,metaclass).__new__(metaclass, strName, tupBases, dict)
+
+ def __call__(cls, *lstArgs, **dictArgs):
+ raise SingletonException, 'Singletons may only be instantiated through getInstance()'
+
+class Singleton(object):
+ __metaclass__ = MetaSingleton
+
+ def getInstance(cls, *lstArgs):
+ """
+ Call this to instantiate an instance or retrieve the existing instance.
+ If the singleton requires args to be instantiated, include them the first
+ time you call getInstance.
+ """
+ if cls._isInstantiated():
+ if len(lstArgs) != 0:
+ raise SingletonException, 'If no supplied args, singleton must already be instantiated, or __init__ must require no args'
+ else:
+ if cls._getConstructionArgCountNotCountingSelf() > 0 and len(lstArgs) <= 0:
+ raise SingletonException, 'If the singleton requires __init__ args, supply them on first instantiation'
+ instance = cls.__new__(cls)
+ instance.__init__(*lstArgs)
+ cls.cInstance = instance
+ return cls.cInstance
+ getInstance = classmethod(getInstance)
+
+ def _isInstantiated(cls):
+ return hasattr(cls, 'cInstance')
+ _isInstantiated = classmethod(_isInstantiated)
+
+ def _getConstructionArgCountNotCountingSelf(cls):
+ return cls.__init__.im_func.func_code.co_argcount - 1
+ _getConstructionArgCountNotCountingSelf = classmethod(_getConstructionArgCountNotCountingSelf)
diff --git a/bin/PythonACE/fuzz/_warning_handler.py b/bin/PythonACE/fuzz/_warning_handler.py
new file mode 100644
index 00000000000..f88b43a0782
--- /dev/null
+++ b/bin/PythonACE/fuzz/_warning_handler.py
@@ -0,0 +1,53 @@
+""" Implements a warning handler base class and a simple handler that simply
+ outputs warnings to stderr. """
+
+import _singleton
+
+# Constants
+STDERR = 1
+MAILER = 2
+
+from sys import stderr
+
+class Warning_Handler (_singleton.Singleton):
+ def __init__(self, handlertype=STDERR):
+ """ Constructor. Type should be either STDERR or MAILER.
+ There are probably better ways to do this, but it is implemented
+ this way because I only wanted to have a dependancy on ldap if someone
+ actually wanted to use the mailer. """
+ super (Warning_Handler, self).__init__ ()
+ self.messages = ""
+ self.add_warning = self.default_add_warning
+ self.close = self.default_close
+ self.open = self.default_open
+
+ if handlertype is STDERR:
+ self.add_warning = self.stderr_add_warning
+ elif handlertype is MAILER:
+ from _mailer import Mailer
+ self.handler = Mailer ()
+ self.add_warning = self.handler.add_warning
+ self.open = self.handler.open
+ self.close = self.handler.close
+ self.get_messages = self.handler.get_messages
+ else:
+ self.add_warning = self.stderr_add_warning
+
+ def default_add_warning (self, warning_text):
+ pass
+
+ def default_open (self, arg = ""):
+ pass
+
+ def default_close (self, arg = ""):
+ pass
+
+ def get_messages (self):
+ return self.messages
+
+ def stderr_add_warning (self, warning_text):
+ stderr.write (warning_text)
+ return
+
+
+
diff --git a/bin/PythonACE/fuzz/streams_include.py b/bin/PythonACE/fuzz/streams_include.py
new file mode 100644
index 00000000000..24def75fd66
--- /dev/null
+++ b/bin/PythonACE/fuzz/streams_include.py
@@ -0,0 +1,19 @@
+""" Checks for inclusion of a non efficient streams include """
+
+import _types
+type_list = _types.source_files +_types. header_files + _types.inline_files
+
+import re
+
+regex = re.compile ("^\s*#\s*include\s*(\/\*\*\/){0,1}\s*\"ace\/streams\.h\"")
+begin_exclude = re.compile ("FUZZ\: disable check_for_streams_include")
+end_exclude = re.compile ("FUZZ\: enable check_for_streams_include")
+
+error_message = ": warning: expensive ace/streams.h included; consider ace/iosfwd.h\n"
+
+from _generic_handler import generic_handler
+def handler (file_name, file_content):
+ return generic_handler (regex, begin_exclude,
+ end_exclude, error_message,
+ file_name, file_content, True)
+