gump-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From leosim...@apache.org
Subject svn commit: r157798 - in gump/branches/Gump3/pygump: main.py python/gump/config.py python/gump/engine/__init__.py python/gump/engine/modeller.py python/gump/model/__init__.py python/gump/plugins/dynagumper.py python/gump/test/testModel.py python/gump/util/mysql.py
Date Wed, 16 Mar 2005 20:53:03 GMT
Author: leosimons
Date: Wed Mar 16 12:52:58 2005
New Revision: 157798

URL: http://svn.apache.org/viewcvs?view=rev&rev=157798
Log:

* Make model support unicode strings and add tests to check for that

* fix the dynagumper sql queries

* fix the start|end project property names dynagumper uses after they were made non-configurable

* fix the glue code to synchronize with the small changes I made recently everhwere

* some formatting and documentation in different places

* allow for kewl error handling in the verifier (seems like a place where we need that, in
particular, recovery strategies for circular dependencies is something we really do want)
to have

* made database settings CLI-time configurable

* made it possible to use a database without password in mysql.py

that's about it :-D

Modified:
    gump/branches/Gump3/pygump/main.py
    gump/branches/Gump3/pygump/python/gump/config.py
    gump/branches/Gump3/pygump/python/gump/engine/__init__.py
    gump/branches/Gump3/pygump/python/gump/engine/modeller.py
    gump/branches/Gump3/pygump/python/gump/model/__init__.py
    gump/branches/Gump3/pygump/python/gump/plugins/dynagumper.py
    gump/branches/Gump3/pygump/python/gump/test/testModel.py
    gump/branches/Gump3/pygump/python/gump/util/mysql.py

Modified: gump/branches/Gump3/pygump/main.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/main.py?view=diff&r1=157797&r2=157798
==============================================================================
--- gump/branches/Gump3/pygump/main.py (original)
+++ gump/branches/Gump3/pygump/main.py Wed Mar 16 12:52:58 2005
@@ -52,7 +52,10 @@
     parser = get_parser()
     parser.print_help(file)
 
-def get_parser(_homedir=None, _hostname=None, _projects=None, _workdir=None, _logdir=None,
_workspace=None):
+def get_parser(_homedir=None, _hostname=None, _projects=None, _workdir=None,
+               _logdir=None, _workspace=None, _databaseserver="localhost",
+               _databaseport=3306, _databasename="gump", _databaseuser="gump",
+               _databasepassword=None):
     """Pygump uses the optparse package to provide the CLI.
     
     To add new options to pygump, change this method and document the changes
@@ -101,6 +104,27 @@
                       dest="no_updates",
                       default=False,
                       help="skip cvs and svn updates")
+    parser.add_option("--databaseserver",
+                      action="store",
+                      default=_databaseserver,
+                      help="hostname of the database server gump will connect to")
+    parser.add_option("--databaseport",
+                      action="store",
+                      default=_databaseport,
+                      help="port of the database server gump will connect to")
+    parser.add_option("--databasename",
+                      action="store",
+                      default=_databasename,
+                      help="name of the database gump will connect to")
+    parser.add_option("--databaseuser",
+                      action="store",
+                      default=_databaseuser,
+                      help="username gump will use to connect to the database")
+    parser.add_option("--databasepassword",
+                      action="store",
+                      default=_databasepassword,
+                      help="password gump will use to connect to the database")
+                      
     return parser
 
 
@@ -432,7 +456,7 @@
                 
             # finally: fire us up!
             _start_engine(log, options)
-            log.info("Run completed!")
+            log.debug("Run completed!")
         except Exception, details:
             # this is not good. Send e-mail to the admin, complaining rather loudly.
             log.exception("an uncaught exception occurred")

Modified: gump/branches/Gump3/pygump/python/gump/config.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/config.py?view=diff&r1=157797&r2=157798
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/config.py (original)
+++ gump/branches/Gump3/pygump/python/gump/config.py Wed Mar 16 12:52:58 2005
@@ -67,17 +67,13 @@
     config.mail_to         = settings.mailto
     config.mail_from       = settings.mailfrom
     
-    # TODO: set defaults in main.py instead
     config.database_server = "localhost"
-    if hasattr(settings,"databaseserver"): config.database_server = settings.databaseserver
+    config.database_server = settings.databaseserver
     config.database_port   = 3306
-    if hasattr(settings,"databaseport"): config.database_port = settings.databaseport
-    config.database_name   = "gump"
-    if hasattr(settings,"databasename"): config.database_name = settings.databasename
-    config.database_user   = "gump"
-    if hasattr(settings,"databaseuser"): config.database_user = settings.databaseuser
-    config.database_password   = "gump"
-    if hasattr(settings,"databasepassword"): config.database_password = settings.databasepassword
+    config.database_port = settings.databaseport
+    config.database_name = settings.databasename
+    config.database_user = settings.databaseuser
+    config.database_password = settings.databasepassword
     
     return config
 
@@ -108,7 +104,7 @@
     # TODO: append more plugins here...
 
     from gump.plugins import LoggingPlugin
-    log = get_logger(config.log_level, "plugin-log")
+    log = get_logger(config, "plugin-log")
     plugins.append(LoggingPlugin(log))
     
     post_process_plugins = []
@@ -116,10 +112,10 @@
     post_process_plugins.append(TimerPlugin("run_end"))
 
     from gump.plugins.dynagumper import Dynagumper
-    log = get_logger(config.log_level, "util-db")
+    log = get_logger(config, "util-db")
     db = get_db(log,config)
-    log = get_logger(config.log_level, "plugin-dynagumper")
-    post_process_plugins.append(Dynagumper(db, log, "run_start", "run_end"))
+    log = get_logger(config, "plugin-dynagumper")
+    post_process_plugins.append(Dynagumper(db, log))
     
     return (pre_process_plugins, plugins, post_process_plugins)
 
@@ -140,7 +136,7 @@
     # TODO: implement an error handler that does actual recovery...
     
     from gump.plugins import LoggingErrorHandler
-    log = get_logger(config.log_level, "plugin-error-handler")
+    log = get_logger(config, "plugin-error-handler")
     return LoggingErrorHandler(log)
 
 ###
@@ -208,10 +204,10 @@
     return VFS(config.paths_metadata, cache_dir)
 
 
-def get_modeller_loader(log, vfs=None, mergefile=None, dropfile=None):
+def get_modeller_loader(log, vfs=None):
     """Provide a Loader implementation."""
     from gump.engine.modeller import Loader
-    return Loader(log, vfs, mergefile, dropfile)
+    return Loader(log, vfs)
 
 
 def get_modeller_normalizer(log):
@@ -226,17 +222,17 @@
     return Objectifier(log)
 
 
-def get_modeller_verifier():
+def get_modeller_verifier(walker):
     """Provide a Verifier implementation."""
     from gump.engine.modeller import Verifier
-    return Verifier()
+    return Verifier(walker)
 
 
 def get_walker(config):
     """Provide a Walker implementation."""
     from gump.engine.walker import Walker
     
-    log = get_logger(config.log_level, "walker")
+    log = get_logger(config, "walker")
     return Walker(log)
 
 

Modified: gump/branches/Gump3/pygump/python/gump/engine/__init__.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/engine/__init__.py?view=diff&r1=157797&r2=157798
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/engine/__init__.py (original)
+++ gump/branches/Gump3/pygump/python/gump/engine/__init__.py Wed Mar 16 12:52:58 2005
@@ -86,17 +86,17 @@
     # get engine dependencies
     log = get_logger(config, _ENGINE_LOGGER_NAME)
     
-    vfsdir = os.path.join(config)
+    vfs = get_vfs(config)
+    walker = get_walker(config)
     modeller_log = get_logger(config, _MODELLER_LOGGER_NAME)
     modeller_loader = get_modeller_loader(modeller_log, vfs)
     modeller_normalizer = get_modeller_normalizer(modeller_log)
     modeller_objectifier = get_modeller_objectifier(modeller_log)
-    modeller_verifier = get_modeller_verifier()
+    modeller_verifier = get_modeller_verifier(walker)
     
     mergefile = os.path.join(config.paths_work, _MERGE_FILE_NAME)
     dropfile = os.path.join(config.paths_work, _DROPPED_FILE_NAME)
     
-    walker = get_walker(config)
     dom_implementation = get_dom_implementation()
     (pre_process_visitor, visitor, post_process_visitor) = get_plugin(config)
     

Modified: gump/branches/Gump3/pygump/python/gump/engine/modeller.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/engine/modeller.py?view=diff&r1=157797&r2=157798
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/engine/modeller.py (original)
+++ gump/branches/Gump3/pygump/python/gump/engine/modeller.py Wed Mar 16 12:52:58 2005
@@ -61,7 +61,8 @@
     parent = node
     while not parent.nodeType == dom.Node.DOCUMENT_NODE:
         parent = parent.parentNode
-        if not parent: # really ought not happen I think...
+        if not parent: # this indicates a bug in the DOM implementation as
+                       # its illegal
             raise ModellerError, "Cannot find document containing this node!"
     
     return parent
@@ -94,10 +95,8 @@
     
 def _import_attributes(target_node, new_node):
     """Copy all attributes from the new node to the target node."""
-    
     new_attributes = new_node.attributes
     if new_attributes:
-        #if new_attributes.length > 0:
         i = 0
         while i < new_attributes.length: # for loops gives a KeyError,
             att = new_attributes.item(i) #   seems like a minidom bug!
@@ -125,8 +124,14 @@
 ###
 
 class _TagNameFilter:
-    """Filter for use with _import_children."""
+    """Filter for use with _import_children().
+
+    This filter can be configured to filter out certain
+    elements based on the element name."""
     def __init__(self, excludedTags):
+        """Create a new instance. The excludeTags argument
+        should be an array of strings specifying element
+        names to exclude."""
         self.excludedTags = excludedTags
 
     def exclude(self, node):
@@ -182,7 +187,7 @@
     
     Of course, other parts of the modeller package are not so tolerant!
     """
-    def __init__(self, log, vfs=None, merge_file_or_stream=None, drop_file_or_stream=None):
+    def __init__(self, log, vfs=None):
         """
         Create a new Loader.
 
@@ -388,6 +393,7 @@
         self.log = log
     
     def normalize(self, olddoc):
+        """Turns a messy gump DOM workspace into a simplified and normalized form."""
         self.olddoc = olddoc
         self.oldroot = olddoc.documentElement
         self.impl = dom.getDOMImplementation()
@@ -463,6 +469,7 @@
             self._parse_maven_project(project)
     
     def _parse_maven_project(self, project):
+        #TODO: implement this!
         if True: return
 
         self._resolve_maven_imports(project)
@@ -497,7 +504,7 @@
         #new_project.appendChild(new_command)
     
     def _resolve_maven_imports(self, project):
-        pass #TODO
+        pass #TODO: implement this!
     
     def _normalize_repositories(self):
         repos = self._get_list_merged_by_name("repository")
@@ -977,18 +984,54 @@
         project.add_dependency(Dependency(dependency_project,project,optional,runtime,inherit,id))
 
 
-NOT_VISITED = 0
-VISITING = 1
-VISITED = 2
+class VerificationError(ModellerError):
+    """Error raised by the verifier if the model is not valid."""
+    pass
+
+class CyclicDependencyError(VerificationError):
+    """Error raised by the verifier if the model contains one or more cyclic
+    dependencies. The cycles property will contain an array of cycles, where
+    a cycle again is an array of projects that together make up a cycle."""
+    #TODO think about error hierarchies in gump and decide if this is the way
+    #     we want to implement them
+    def __init__(self, cycles):
+        self.cycles = cycles
+
+class AbstractErrorHandler:
+    """Base class for supporting configurable error recovery. Instead of
+    raising exceptions, supportive classes will pass the error to an instance
+    of this class. This allows clients to recover from errors more gracefully.
+    This default implementation tries to call a handleError() method on
+    itself, and raises the error if that is not possible.
+    
+    Subclasses should implement a handleError(error) method, where the
+    provided error argument is normally an instance of Exception.
+    
+    This setup is similar to that used by the SAX libraries."""
+    #TODO maybe move this elsewhere?
+    def _handleError(self,error):
+        if not hasattr(self,'handleError'): raise error
+        if not callable(self.handleError): raise error
+        self.handleError(error)
 
 class Verifier:
+    """Determines whether a finished gump model conforms to certain contracts.
+    
+    Those contracts are not currently completely specified, but it is somewhat
+    possible to digest them from the model documentation. However, the
+    verifier itself together with its unit tests is probably the only "hard"
+    specification of those contracts."""
     def __init__(self, walker):
         assert hasattr(walker, "walk")
         assert callable(walker.walk)
         
         self.walker = walker
         
-    def verify(self, workspace):
+    def verify(self, workspace, errorHandler=AbstractErrorHandler()):
+        """Sends VerificationError objects to the errorHandler argument if the
+        provided model contains errors. If no errorHandler is provided, the
+        exceptions are 'raise'd."""
+        # TODO: get rid of this return statement
         return
         # TODO: Test this code!!!
         from gump.plugins import AbstractPlugin
@@ -1003,10 +1046,11 @@
                 if not p in visited_projects:
                     unvisited.append(p)
             
-            cycles = self.find_cycles(unvisited[:])
-            # TODO now what?
+            cycles = self._find_cycles(unvisited[:])
+            
+            errorHandler._handleError(CyclicDependencyError(cycles))
     
-    def find_cycles(self,projects):
+    def _find_cycles(self,projects):
         """Brute-force find all cycles.
         
         1) depth-first traverse all paths extending from each project
@@ -1024,11 +1068,12 @@
             needle = project
             visited = []
             stack = [project]
-            visit(project,visited,stack,needle,cycles)
+            self._visit(project,visited,stack,needle,cycles)
         
         return cycles
     
-    def visit(project,visited,stack,needle,cycles):
+    def _visit(self,project,visited,stack,needle,cycles):
+        #TODO: test this
         visited.append(project)
         for relationship in project.dependencies:
             dependency = relationship.dependency
@@ -1041,7 +1086,7 @@
                       # for loop iteration
             else:
                 if not dependency in visited:
-                    visit(dependency,visited,stack,needle,cycles)
+                    self._visit(dependency,visited,stack,needle,cycles)
                 # else we have a cycle not involving the needle,
                 # we'll find it later (or we've found it already)
         

Modified: gump/branches/Gump3/pygump/python/gump/model/__init__.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/model/__init__.py?view=diff&r1=157797&r2=157798
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/model/__init__.py (original)
+++ gump/branches/Gump3/pygump/python/gump/model/__init__.py Wed Mar 16 12:52:58 2005
@@ -41,7 +41,7 @@
         - dependencies -- list of all dependencies between projects
     """
     def __init__(self, name):
-        assert isinstance(name, str)
+        assert isinstance(name, basestring)
     
         self.name = name
         self.repositories = {}
@@ -78,7 +78,7 @@
                  cvsweb = None,
                  redistributable = False):
         assert isinstance(workspace, Workspace)
-        assert isinstance(name, str)
+        assert isinstance(name, basestring)
         
         self.workspace       = workspace
         self.name            = name
@@ -125,8 +125,8 @@
                  method = CVS_METHOD_PSERVER,
                  user = None,
                  password = None):
-        assert isinstance(hostname,str)
-        assert isinstance(path,str)
+        assert isinstance(hostname,basestring), "Hostname should be a valid string, not '%s'"
% hostname
+        assert isinstance(path,basestring)
         Repository.__init__(self, workspace, name, title, home_page, cvsweb, redistributable)
         
         self.hostname = hostname
@@ -164,7 +164,7 @@
                  redistributable = False,
                  user = None,
                  password = None):
-        assert isinstance(url, str)
+        assert isinstance(url, basestring)
         Repository.__init__(self, workspace, name, title, home_page, cvsweb, redistributable)
         self.url      = url
         self.user     = user
@@ -190,7 +190,7 @@
                  url = None,
                  description = None):
         assert isinstance(repository, Repository)
-        assert isinstance(name, str)
+        assert isinstance(name, basestring)
         self.repository  = repository
         self.name        = name
         self.url         = url
@@ -269,7 +269,7 @@
 
     def __init__(self, module, name):
         assert isinstance(module, Module)
-        assert isinstance(name, str)
+        assert isinstance(name, basestring)
         
         self.module = module
         self.name   = name
@@ -395,7 +395,7 @@
         - directory -- the directory to create
     """
     def __init__(self, project, directory):
-        assert isinstance(directory, str)
+        assert isinstance(directory, basestring)
         Command.__init__(self, project)
         self.directory = directory
 
@@ -411,7 +411,7 @@
         - directory -- the directory to delete
     """
     def __init__(self, project, directory):
-        assert isinstance(directory,str)
+        assert isinstance(directory,basestring)
         Command.__init__(self, project)
         self.directory = directory
 
@@ -427,10 +427,10 @@
                   tuple
     """
     def __init__(self, project, name, args=[]):
-        assert isinstance(name, str)
+        assert isinstance(name, basestring)
         assert isinstance(args, list)
         for arg in args:
-            assert isinstance(arg, str)
+            assert isinstance(arg, basestring)
         Command.__init__(self, project)
         self.name = name
         self.args = args
@@ -465,7 +465,7 @@
                        its homedirectory
     """
     def __init__(self, project, directory):
-        assert isinstance(directory, str)
+        assert isinstance(directory, basestring)
         Output.__init__(self, project, OUTPUT_ID_HOME)
         self.directory = directory
 
@@ -481,7 +481,7 @@
                 added 
     """
     def __init__(self, project, name, id = None, add_to_bootclass_path = False ):
-        assert isinstance(name, str)
+        assert isinstance(name, basestring)
         Output.__init__(self, project, id)
         self.name = name
         self.add_to_bootclass_path = add_to_bootclass_path

Modified: gump/branches/Gump3/pygump/python/gump/plugins/dynagumper.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/plugins/dynagumper.py?view=diff&r1=157797&r2=157798
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/plugins/dynagumper.py (original)
+++ gump/branches/Gump3/pygump/python/gump/plugins/dynagumper.py Wed Mar 16 12:52:58 2005
@@ -48,7 +48,7 @@
         (system, host, release, version, machine, processor) = platform.uname()
         tablename = "hosts"
         
-        cmd = "SELECT * FROM %s WHERE address = '%s' AND name = '%s';"
+        cmd = "SELECT * FROM %s WHERE address = '%s' AND name = '%s';" % (tablename, host,
host)
         (rows, result) = self.db.execute(cmd)
         if rows == 0:
             memory = amount_of_memory()
@@ -56,7 +56,7 @@
             cpus = number_of_cpus()
             
             description = "%s (%s,%s,%s,%s,%s)" % (host, system, release, version, machine,
processor)
-            cmd = """INSERT INTO %s (address, name, cpu_arch, cpu_number, cpu_speed_Mhz,
memory, description)
+            cmd = """INSERT INTO %s (address, name, cpu_arch, cpu_number, cpu_speed_Mhz,
memory_Mb, description)
                      VALUES ('%s', '%s', '%s', %s, %s, %s, '%s')""" \
                 % (tablename, host, host, processor, cpus, mhz, memory, description)
             self.db.execute(cmd)
@@ -74,8 +74,8 @@
     def visit_project(self, project):    
         """Add information about a project to the database."""
         tablename = "projects"
-        startdate = project.startdate
-        enddate = project.enddate
+        startdate = project.run_start
+        enddate = project.run_end
         name = project.name
         
         cmd = "INSERT INTO %s (project_name, start_date, end_date) VALUES ('%s', '%s', '%s')"
\

Modified: gump/branches/Gump3/pygump/python/gump/test/testModel.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/test/testModel.py?view=diff&r1=157797&r2=157798
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/test/testModel.py (original)
+++ gump/branches/Gump3/pygump/python/gump/test/testModel.py Wed Mar 16 12:52:58 2005
@@ -63,6 +63,7 @@
         self.assertEqual([], w.dependencies)
         
         self.assertRaises(AssertionError, Workspace, None)
+        Workspace(unicode("blah")) # unicode is okay too...
         
         r = Repository(w, "booh")
         w.add_repository(r)
@@ -107,7 +108,8 @@
         
         self.assertRaises(AssertionError, Repository, "test", name)
         self.assertRaises(AssertionError, Repository, "test", w)
-        
+        Repository(w,unicode("blah")) # unicode is okay too...
+
         r = Repository(w,name)
         mname="bweh"
         m = Module(r,mname)
@@ -218,6 +220,7 @@
         self.assertRaises(AssertionError, Module, name, None)
         self.assertRaises(AssertionError, Module, "wrong", name)
         self.assertRaises(AssertionError, Module, r, r)
+        Module(r,unicode("blah")) # unicode is okay too...
         
         m = Module(r,name,url=url)
         self.assertEqual(url,m.url)
@@ -322,6 +325,7 @@
         self.assertRaises(AssertionError, Project, name, None)
         self.assertRaises(AssertionError, Project, "wrong", name)
         self.assertRaises(AssertionError, Project, m, m)
+        Project(m,unicode("blah")) # unicode is okay too...
         
         # note that dependencies are tested in test_dependencies...
         

Modified: gump/branches/Gump3/pygump/python/gump/util/mysql.py
URL: http://svn.apache.org/viewcvs/gump/branches/Gump3/pygump/python/gump/util/mysql.py?view=diff&r1=157797&r2=157798
==============================================================================
--- gump/branches/Gump3/pygump/python/gump/util/mysql.py (original)
+++ gump/branches/Gump3/pygump/python/gump/util/mysql.py Wed Mar 16 12:52:58 2005
@@ -100,10 +100,18 @@
         if not self._conn:
             import MySQLdb
             import MySQLdb.cursors
-            self._conn = MySQLdb.Connect(
+            if self.password:
+                self._conn = MySQLdb.Connect(
                     host=self.host, 
                     user=self.user,
                     passwd=self.password, 
+                    db=self.db,
+                    compress=1,
+                    cursorclass=MySQLdb.cursors.DictCursor)
+            else:
+                self._conn = MySQLdb.Connect(
+                    host=self.host, 
+                    user=self.user,
                     db=self.db,
                     compress=1,
                     cursorclass=MySQLdb.cursors.DictCursor)



Mime
View raw message