diff options
author | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-19 23:40:54 +0000 |
---|---|---|
committer | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-19 23:40:54 +0000 |
commit | 5d4ad0a1822f2e7cc13619c9feb4257a2af5ef35 (patch) | |
tree | af98d7095493656260d26e044c93a3f88a5fcadf /bin | |
parent | a337ed8faf1081e72ee71fa8c8410f974fc1e0d1 (diff) | |
download | ATCD-5d4ad0a1822f2e7cc13619c9feb4257a2af5ef35.tar.gz |
Wed Jul 19 23:39:05 UTC 2006 William R. Otte <wotte@dre.vanderbilt.edu>
Diffstat (limited to 'bin')
-rw-r--r-- | bin/PythonACE/fuzz/__init__.py | 68 | ||||
-rw-r--r-- | bin/PythonACE/fuzz/_generic_handler.py | 22 | ||||
-rw-r--r-- | bin/PythonACE/fuzz/_mailer.py | 106 | ||||
-rw-r--r-- | bin/PythonACE/fuzz/_singleton.py | 60 | ||||
-rw-r--r-- | bin/PythonACE/fuzz/_warning_handler.py | 53 | ||||
-rw-r--r-- | bin/PythonACE/fuzz/streams_include.py | 19 |
6 files changed, 298 insertions, 30 deletions
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) + |