Commits

Anonymous committed 8286a59

see ChangeLog

Comments (0)

Files changed (7)

+20-03-2006 Martin Woudstra
+	python/trfutil.py: A
+	    - debugged functions append_path_env*, prepend_path_env*
+	    - fixed bug in function find_datafile
+	    - fixed bugs in RDBAccessOverride.preRunAction()
+	    - added class ServiceOverride
+	    - class Filename: Added supports rfio: file access (e.g. castor).
+	                      Removed isRegularFile() member function.
+	python/basic_trfarg.py: 
+	    - default value for help() is now the __doc__ string of the class.
+	python/full_trfarg.py: 
+	    - changed all help to 'default'
+	    - JobOptionsArg: added function defaultHelp()
+	test/myunittest.py: 
+	    - TestCase.tearDown(): make removal conditional (in case setUp was not called)
+	test/trfutil_test.py: 
+	    - added tests for functions append_path_env*, prepend_path_env*
+	    - moved to using myunittest module
+	    - argtest_trf.py: added the new Arguments + SQLiteGeomSupport
 17-03-2006 Martin Woudstra
 	python/trfutil.py: 
 	    - added classes RDOFile,ESDFile,AODFile,PreJobOptionsFile,PostJobOptionsFile,

python/basic_trfarg.py

 defined in this file, and should override the member function isFullArgument(self),
 which should return True."""
     
-    def __init__(self,help,name='default'):
+    def __init__(self,help='default',name='default'):
         """help    : short help string to help user fill in the argument
        name    : name of the argument (string)."""
         if help == 'default': help = self.defaultHelp()
 
     def defaultHelp(self):
         """Return default help string. Must be implemented in derived class"""
-        raise TransfromDefinitionError, 'defaultHelp() not implemented in class %s' % self.__class__.__name__
+        return self.__class__.__doc__ # raise TransformDefinitionError, 'defaultHelp() not implemented in class %s' % self.__class__.__name__
     
 
     def hasDefault(self):
             mess = 'No output file expected. Nothing to be done.'
         elif not Filename.exists(val):
             raise OutputFileError( val, 'not found. Argument %s' % (self.name()) )
-        elif not Filename.isRegular(val):
-            raise OutputFileError( val, 'is not a regular file. Argument %s' % (self.name()) )
         else:
             mess = 'Outputfile %s found. -> OK' % (self.value())
 

python/full_trfarg.py

 
 class InputEvgenFileArg(trfarg.InputDataFileArg):
     """Input file that contains generated events"""
-    def __init__(self,help='output data file with generated events',name='default',
+    def __init__(self,help='default',name='default',
                  contents=EvgenFile.defaultContents,type=EvgenFile.defaultType):
         trfarg.InputDataFileArg.__init__(self,help,name,contents,type)
 
 
 class OutputEvgenFileArg(trfarg.OutputDataFileArg):
     """Output file that contains generated events"""
-    def __init__(self,help='output data file with generated events',name='default',
+    def __init__(self,help='default',name='default',
                  contents=EvgenFile.defaultContents,type=EvgenFile.defaultType):
         trfarg.OutputDataFileArg.__init__(self,help,name,contents,type)
 
 
 class InputHitsFileArg(trfarg.InputDataFileArg):
     """Input file that contains hits"""
-    def __init__(self,help='output data file with generated events',name='default',
+    def __init__(self,help='default',name='default',
                  contents=HitsFile.defaultContents,type=HitsFile.defaultType):
         trfarg.InputDataFileArg.__init__(self,help,name,contents,type)
 
 
 class OutputHitsFileArg(trfarg.OutputDataFileArg):
     """Output file that contains hits"""
-    def __init__(self,help='output data file with generated events',name='default',
+    def __init__(self,help='default',name='default',
                  contents=HitsFile.defaultContents,type=HitsFile.defaultType):
         trfarg.OutputDataFileArg.__init__(self,help,name,contents,type)
 
 
 class InputRDOFileArg(trfarg.InputDataFileArg):
     """Input file that contains RDO's"""
-    def __init__(self,help='output data file with generated events',name='default',
+    def __init__(self,help='default',name='default',
                  contents=RDOFile.defaultContents,type=RDOFile.defaultType):
         trfarg.InputDataFileArg.__init__(self,help,name,contents,type)
 
 
 class OutputRDOFileArg(trfarg.OutputDataFileArg):
     """Output file that contains RDO's"""
-    def __init__(self,help='output data file with generated events',name='default',
+    def __init__(self,help='default',name='default',
                  contents=RDOFile.defaultContents,type=RDOFile.defaultType):
         trfarg.OutputDataFileArg.__init__(self,help,name,contents,type)
 
 
 class InputESDFileArg(trfarg.InputDataFileArg):
     """Input file that contains ESD's"""
-    def __init__(self,help='output data file with generated events',name='default',
+    def __init__(self,help='default',name='default',
                  contents=ESDFile.defaultContents,type=ESDFile.defaultType):
         trfarg.InputDataFileArg.__init__(self,help,name,contents,type)
 
 
 class OutputESDFileArg(trfarg.OutputDataFileArg):
     """Output file that contains ESD's"""
-    def __init__(self,help='output data file with generated events',name='default',
+    def __init__(self,help='default',name='default',
                  contents=ESDFile.defaultContents,type=ESDFile.defaultType):
         trfarg.OutputDataFileArg.__init__(self,help,name,contents,type)
 
 
 class InputAODFileArg(trfarg.InputDataFileArg):
     """Input file that contains AOD's"""
-    def __init__(self,help='output data file with generated events',name='default',
+    def __init__(self,help='default',name='default',
                  contents=AODFile.defaultContents,type=AODFile.defaultType):
         trfarg.InputDataFileArg.__init__(self,help,name,contents,type)
 
 
 class OutputAODFileArg(trfarg.OutputDataFileArg):
     """Output file that contains AOD's"""
-    def __init__(self,help='output data file with generated events',name='default',
+    def __init__(self,help='default',name='default',
                  contents=AODFile.defaultContents,type=AODFile.defaultType):
         trfarg.OutputDataFileArg.__init__(self,help,name,contents,type)
 
 
 class OutputHistogramFileArg(trfarg.OutputFileArg):
     """Output file that contains histograms."""
-    def __init__(self,help='output histogram file',name='histogramFile',
+    def __init__(self,help='default',name='histogramFile',
                  contents=HistogramFile.defaultContents,type=HistogramFile.defaultType):
         trfarg.OutputFileArg.__init__(self,help,name,type,contents)
 
 
 class OutputNtupleFileArg(trfarg.OutputFileArg):
     """Output file that contains ntuples."""
-    def __init__(self,help='output ntuple file',name='ntupleFile',
+    def __init__(self,help='default',name='ntupleFile',
                  contents=NtupleFile.defaultContents,type=NtupleFile.defaultType):
         trfarg.OutputFileArg.__init__(self,help,name,type,contents)
 
     
 
 class JobOptionsArg(trfarg.StringArg):
-    def __init__(self,help='jobOptions file to use',package=None,name='default'):
-        if package is not None:
-            self.package = package
-            help += '. Default package: %s' % (package)
+    def __init__(self,help='default',package=None,name='default'):
+        self._package = package
         trfarg.StringArg.__init__(self,help,name)
 
 
         return True
 
 
+    def defaultHelp(self):
+        help='jobOptions file to use'
+        if self._package: help += '. Default package: %s' % (self._package)
+        return help
+    
+
     def hasPackage(self):
-        return hasattr(self,'package')
+        return self._package is not None
 
 
-    def getPackage(self):
-        return getattr(self,'package',None)
+    def package(self):
+        return self._package
 
 
     def value(self):
         val = trfarg.Argument.value(self)
-        if val and hasattr(self,'package') and not os.sep in val:
-            val = os.path.join(self.package, val)
+        if val and self._package and not os.sep in val:
+            val = os.path.join(self._package, val)
 
         return val
         
 
-
     def preRunAction(self):
         """Check than jobOptions file can be found"""
         val = self.value()
-        JobOptionsFile(val).preRunAction()
+        if not val: return
         full = find_joboptions( val )
         if not full: raise JobOptionsNotFoundError( val, "Argument %s" % self.name() )
 
-        self._logger.debug( 'Found %s in %s' % (val, strip_suffix(full,val)) )
+        self._logger.info( 'Found %s in %s' % (val, strip_suffix(full,val)) )
 
 
 #

python/trfutil.py

-import os,sys,re,exceptions,shutil
-from AthenaCommon.Utils.unixtools import FindFile
+import os,sys,re,exceptions,shutil,commands
+from AthenaCommon.Utils.unixtools import FindFile,which
 from PyJobTransformsCore import trfconsts
 
 
     (A list of paths separated by <sep>).
     If environment variable does not yet exist, it will
     be created and its value will be set that <what>"""
-    try:
-        var = os.environ[env_name]
-    except KeyError:
+    var = os.environ.get(env_name,"")
+    if not var:
         os.environ[env_name] = what
-        return
     else:
         os.environ[env_name] = var + sep + what
 
 
 def prepend_path_env( env_name, what, sep=os.pathsep ):
-    try:
-        var = os.environ[env_name]
-    except KeyError:
+    var = os.environ.get(env_name,"")
+    if not var:
         os.environ[env_name] = what
-        return
     else:
         os.environ[env_name] = what + sep + var
 
 def append_path_env_if( env_name, what, sep=os.pathsep ):
     """As append_path_env, except that <what> is only appended if it
     is not already present in the path."""
-    try:
-        var = os.environ[env_name]
-    except KeyError:
+    var = os.environ.get(env_name,"")
+    if not var:
         os.environ[env_name] = what
-        return
-    else:
-        if what not in var.split(sep):
-            os.environ[env_name] = var + sep + what
+    elif what not in var.split(sep):
+        os.environ[env_name] = var + sep + what
     
 
 def prepend_path_env_if( env_name, what, sep=os.pathsep ):
-    try:
-        var = os.environ[env_name]
-    except KeyError:
+    var = os.environ.get(env_name,"")
+    if not var:
         os.environ[env_name] = what
-        return
-    else:
-        if what not in var.split(sep):
-            os.environ[env_name] = what + sep + var
+    elif what not in var.split(sep):
+        os.environ[env_name] = what + sep + var
     
 
 def append_path_env_force( env_name, what, sep=os.pathsep ):
     """As append_path_env, except that <what> will be removed
     first if it is already present (not at the end)"""
-    try:
-        var = os.environ[env_name]
-    except KeyError:
+    var = os.environ.get(env_name,"")
+    if not var:
         os.environ[env_name] = what
-        return
     else:
         varList = var.split(sep)
         try:
             idx = varList.index(what)
-        except IndexError:
+        except ValueError:
             os.environ[env_name] = var + sep + what
-            return
         else:
             if idx != len(varList) - 1:
                 varList.remove(what)
                 varList.append(what)
                 os.environ[env_name] = sep.join(varList)
-                return
 
 
 def prepend_path_env_force( env_name, what, sep=os.pathsep ):
     """As prepend_path_env, except that <what> will be removed
     first if it is already present (not at the beginning)"""
-    try:
-        var = os.environ[env_name]
-    except KeyError:
+    var = os.environ.get(env_name,"")
+    if not var:
         os.environ[env_name] = what
-        return
     else:
         varList = var.split(sep)
         try:
             idx = varList.index(what)
-        except IndexError:
-            os.environ[env_name] = var + sep + what
+        except ValueError:
+            os.environ[env_name] = what + sep + var
             return
         else:
             if idx != 0:
 
 
 def find_datafile( filename ):
-    return find_file_env( trfconst.DATAPATH )
+    return find_file_env( trfconsts.DATAPATH )
 
 
 def find_joboptions( jobOptionsFile ):
     """Utility class for file manipulation.
     It does not have the filename, but it can hold optionally the
     file type, contents and suffix."""
+
+    # access types. Tuples of size 2. Item 0 is string representation (for
+    # printouts/errors), item 1 is regular expression to check filename against 
+    IO_LOCAL  = ('local' , '.*' )
+    IO_RFIO   = ('rfio'  , '^rfio:.*' )
+    IO_CASTOR = ('castor', '^/castor[$|/.*]' )
+    # listing them in order of trying a match. Derived classes could add values.
+    accessTypes = [  IO_CASTOR, IO_RFIO, IO_LOCAL ]
+
     def __init__(self,type=None,contents=None,suffix=None):
         """type: file type (root,txt,pool.root,doc,html,...)
         contents: file contents (evgen,simu,digi,esd,aod,...)
         return re.sub( self._fileSuffixRE, r"\1", filename )
 
 
-    def exists(filename): return os.path.exists(filename)
+    def accessType(filename):
+        for at in accessTypes:
+            if re.search( at[1], filename ): return at
+
+        return Filename.IO_LOCAL
+    accessType = staticmethod(accessType)
+
+
+    def exists(filename):
+        at = Filename.accessType(filename)
+        if at == IO_RFIO or at == IO_CASTOR:
+            statcmd = 'rfstat'
+            if not which(statcmd):
+                raise OSError( '%s not supported on this machine' % at[0] )
+            cmd = statcmd
+            status,dummy = commands.getstatusoutput( cmd )
+            return status == 0
+
+        # if not handled by any of the above special cases, use standard one
+        return os.path.exists(filename)
     exists = staticmethod(exists)
 
 
+    def listdir(dirname):
+        """Return the list of files in <dirname>. Also supports rfio and castor."""
+        at = Filename.accessType(filename)
+        if at == IO_RFIO or at == IO_CASTOR:
+            dircmd = 'rfdir'
+            if not which(dircmd):
+                raise OSError( '%s not supported on this machine' % at[0] )
+            cmd = '%s %s' % (dircmd,dirname)
+            status,ls_la = commands.getstatusoutput( cmd )
+            if status != 0:
+                raise OSError( 'directory %s not found' % dirname )
+            dir = [ ]
+            for d in ls_la.split(os.linesep):
+                dir.append( d.split()[-1] )
+            return dir
+
+        # if not handles by any of the above special cases, use standard one
+        return os.listdir(dirname)
+    listdir = staticmethod(listdir)
+
+
     def existsAttempt(filename):
         """Try if filename exists with attempt number appended. If file exists,
         return the filename including the attempt number, else return None"""
         pat = re.compile( r'%s\.[0-9]+' % filename )
         dir = os.path.dirname(filename) or os.curdir
-        for f in os.listdir( dir ):
+        for f in Filename.listdir( dir ):
             if pat.search( f ): return f
 
         return None
     existsAttempt = staticmethod(existsAttempt)
 
 
-    def isRegular(filename): return os.path.isfile(filename)
-    isRegular = staticmethod(isRegular)
-    
-
     def isReadable(filename):
+        at = Filename.accessType(filename)
+        if at == IO_RFIO or at == IO_CASTOR:
+            statcmd = 'rfstat'
+            if not which(dircmd):
+                raise IOError( '%s not supported on this machine' % at[0] )
+            cmd = statcmd
+            status,output = commands.getstatusoutput( cmd )
+            for line in output.split(os.linesep):
+                if line.startswith( 'Protection' ):
+                    prot = line.split(':')[-1].split()[0]
+                    pat = r'^[-d][-rs][-ws][-xs][-rs][-ws][-xs]r[-ws][-xs]$'
+                    return re.search(pat, prot) is not None
+            # unexpected output, assume OK if rfstat did not give error
+            return status == 0
+        # if not handles by any of the above special cases, use standard one
         # best check is to try to open it. This covers all authorisation systems.
         try:
             f = open(filename)
 
 
 
+class ServiceOverride(PostJobOptionsFile):
+    def __init__(self,serviceName,membersDict,environmentDict=None):
+        PostJobOptionsFile.__init__(self,"")
+        self._service = serviceName
+        self._members = membersDict
+        self._environDict = environmentDict
+        
 
+    def preRunAction(self):
+        nMem = len(self._members)
+        if nMen == 0: return
+        environDict = { }
+        if self._environDict:
+            for env in self._environDict:
+                if env in os.environ:
+                    val = os.environ[env]
+                    if val:
+                        environDict[env] = val
+                    else:
+                        environDict[env] = self._environDict[env]
+            if not environDict: return
+        
+        members = { }
+        for mem in self._members:
+            try:
+                val = self._members[mem] % environDict
+            except KeyError:
+                pass #don't set it if environment is needed but not present
+            else:
+                members[mem] = val
+        
+        if not members: return
+
+        jo = [ "%s = Service( \"%s\" )" % (self._service,self._service) ]
+        filename = self._service
+        for mem in members:
+            val = members[mem]
+            jo.append( "%s.%s = %r" % (self._service, mem, val) )
+            filename += '_%s_%s' % (mem,val)
+
+        joFile = open(filename,'w')
+        joFile.write( os.linesep.join(jo) + os.linesep )
+        joFile.close()
+        self.setFilename(filename)
+         
+        # only now call baseclass preRunAction()
+        PostJobOptionsFile.preRunAction(self)
+
+
+    def setMember(self,name,value):
+        self._members[name] = value
+        
+
+    def getMember(self,name):
+        return self._members[name]
+
+
+            
 class RDBAccessOverride(PostJobOptionsFile):
     """Override settings of RDBAccessSvc. Properties that can be overridden:
     UseDBConnSvc,Technology,HostName.
 
 
     def preRunAction(self):
-        """Create joboptions file to support SQLite for geometry database.
-        file if T_SQLITEGEOM environment
-        variable is set. Else set filename to empty string"""
+        """If environment variable <environmentHostname> is set,
+        create joboptions file to support SQLite database and
+        set filename to point to this jobOptions file."""
         # set the hostname
         host = self.getHostName()
-        if environHost is not None and self._environHost not in os.environ.keys():
+        if self._environHost is not None and self._environHost not in os.environ.keys():
             return
 
         if os.path.isabs(host):
        
         if fulldb and os.path.exists(fulldb):
             # convert UseDBConnSvc
-            if self._useDBConnSvc:
+            if self._useDBConnSvc is None:
+                useConn = None
+            elif self._useDBConnSvc:
                 useConn = 'TRUE'
             else:
                 useConn = 'FALSE'
             # make jobOptions snippet
             jo = [ '# override DB Access' ,
-                   'RDBAccessSvc = Service( "RDBAccessSvc" )' ,
-                   'RDBAccessSvc.UseDBConnSvc = %s' % (useConn) ,
-                   'RDBAccessSvc.Technology   = %r' % (self._technology) ,
+                   'RDBAccessSvc = Service( "RDBAccessSvc" )', 
                    'RDBAccessSvc.HostName     = %r' % (host) ]
+            if useConn is not None:
+                jo.append( 'RDBAccessSvc.UseDBConnSvc = %s' % (useConn) )
+            if self._technology is not None:
+                jo.append( 'RDBAccessSvc.Technology   = %r' % (self._technology) )
             # make (hopefully) unique yet meaningful filename
             filename = 'RDBAccessSvc_%s_%s_%s.py' % (useConn, self._technology,
                                                      os.path.basename(host))
         
-            joFile = open(filename)
+            joFile = open(filename,'w')
             joFile.write( os.linesep.join(jo) + os.linesep )
             joFile.close()
             self.setFilename(filename)
-
+            
         # only now call baseclass preRunAction()
         PostJobOptionsFile.preRunAction(self)
 
     def __init__(self):
         SQLiteSupport.__init__(self,'geomDB_sqlite','T_SQLITEGEOM')
         
+
+

test/argstest_trf.py

         self.add( OutputEvgenFileArg() )
         self.add( InputHitsFileArg() )
         self.add( OutputHitsFileArg() )
+        self.add( InputRDOFileArg() )
+        self.add( OutputRDOFileArg() )
+        self.add( InputESDFileArg() )
+        self.add( OutputESDFileArg() )
+        self.add( InputAODFileArg() )
+        self.add( OutputAODFileArg() )
         self.add( OutputHistogramFileArg() )
         self.add( OutputNtupleFileArg() )
-                  
+        
+
+        # add utilities
+        self.add( SQLiteGeomSupport() )
 
 # make transformation object              
 trf = TestArgsJobTransform()

test/myunittest.py

 
     def tearDown(self):
         """Clean up temporary files and go back to startup directory"""
+        if not hasattr(self,'tmpdir'): return
         self.recursiveTmpRemove()
         if os.path.isdir(self.tmpdir):
             if self.debug: print "Removing directory %s" % self.tmpdir

test/trfutil_test.py

 #!/usr/bin/env python
-import unittest
+import myunittest
 import os
 
+
 from PyJobTransformsCore.trfutil import *
 
-class MyTest(unittest.TestCase):
-    def shortDescription(self):
-        return '%s: %s' % (self.__class__.__name__, unittest.TestCase.shortDescription(self))
 
+class PathEnvManips(myunittest.TestCase):
 
-class TestStringNumberList(MyTest):
+ 
+    def assertPath(self, pathIn, pathOut ):
+        envName = 'TESTPATH'
+        if pathIn is None:
+            if envName in os.environ.keys():
+                del os.environ[envName]
+        else:
+            os.environ[envName] = pathIn
+
+        self.func(envName,'mydir')
+        if pathIn is None:
+            pathInMess = "Undefined environment variable"
+        else:
+            pathInMess = pathIn
+        errMess = 'Starting with \"%s\" gives \"%s\" instead of \"%s\"' % \
+                  ( pathInMess, os.environ[envName], pathOut )
+        
+        self.assertEqual( os.environ[envName], pathOut, errMess )
+
+    
+    def testAppendPathEnv(self):
+        """append_path_env"""
+        self.func = append_path_env
+
+        self.assertPath( None, 'mydir' )
+
+        self.assertPath( 'mydir', 'mydir:mydir' )
+       
+        self.assertPath( "", 'mydir' )
+
+        self.assertPath( 'dir1', 'dir1:mydir' )
+                        
+        self.assertPath( 'dir1:dir2', 'dir1:dir2:mydir' )
+
+        self.assertPath( 'mydir:dir1:dir2', 'mydir:dir1:dir2:mydir' )
+
+        self.assertPath( 'dir1:mydir:dir2', 'dir1:mydir:dir2:mydir' )
+
+        self.assertPath( 'dir1:dir2:mydir', 'dir1:dir2:mydir:mydir' )
+                        
+
+    def testAppendPathEnvIf(self):
+        """append_path_env_if"""
+        self.func = append_path_env_if
+
+        self.assertPath( None, 'mydir' )
+
+        self.assertPath( 'mydir', 'mydir' )
+       
+        self.assertPath( "", 'mydir' )
+
+        self.assertPath( 'dir1', 'dir1:mydir' )
+                        
+        self.assertPath( 'dir1:dir2', 'dir1:dir2:mydir' )
+
+        self.assertPath( 'mydir:dir1:dir2', 'mydir:dir1:dir2' )
+
+        self.assertPath( 'dir1:mydir:dir2', 'dir1:mydir:dir2' )
+
+        self.assertPath( 'dir1:dir2:mydir', 'dir1:dir2:mydir' )
+                        
+
+    def testAppendPathEnvForce(self):
+        """append_path_env_force"""
+        self.func = append_path_env_force
+
+        self.assertPath( None, 'mydir' )
+
+        self.assertPath( 'mydir', 'mydir' )
+       
+        self.assertPath( "", 'mydir' )
+
+        self.assertPath( 'dir1', 'dir1:mydir' )
+                        
+        self.assertPath( 'dir1:dir2', 'dir1:dir2:mydir' )
+
+        self.assertPath( 'mydir:dir1:dir2', 'dir1:dir2:mydir' )
+
+        self.assertPath( 'dir1:mydir:dir2', 'dir1:dir2:mydir' )
+
+        self.assertPath( 'dir1:dir2:mydir', 'dir1:dir2:mydir' )
+                        
+
+    def testPrependPathEnv(self):
+        """prepend_path_env"""
+        self.func = prepend_path_env
+
+        self.assertPath( None, 'mydir' )
+
+        self.assertPath( 'mydir', 'mydir:mydir' )
+       
+        self.assertPath( "", 'mydir' )
+
+        self.assertPath( 'dir1', 'mydir:dir1' )
+                        
+        self.assertPath( 'dir1:dir2', 'mydir:dir1:dir2' )
+
+        self.assertPath( 'mydir:dir1:dir2', 'mydir:mydir:dir1:dir2' )
+
+        self.assertPath( 'dir1:mydir:dir2', 'mydir:dir1:mydir:dir2' )
+
+        self.assertPath( 'dir1:dir2:mydir', 'mydir:dir1:dir2:mydir' )
+                        
+
+    def testPrependPathEnvIf(self):
+        """prepend_path_env_if"""
+        self.func = prepend_path_env_if
+
+        self.assertPath( None, 'mydir' )
+
+        self.assertPath( 'mydir', 'mydir' )
+       
+        self.assertPath( "", 'mydir' )
+
+        self.assertPath( 'dir1', 'mydir:dir1' )
+                        
+        self.assertPath( 'dir1:dir2', 'mydir:dir1:dir2' )
+
+        self.assertPath( 'mydir:dir1:dir2', 'mydir:dir1:dir2' )
+
+        self.assertPath( 'dir1:mydir:dir2', 'dir1:mydir:dir2' )
+
+        self.assertPath( 'dir1:dir2:mydir', 'dir1:dir2:mydir' )
+                        
+
+    def testPrependPathEnvForce(self):
+        """prepend_path_env_force"""
+        self.func = prepend_path_env_force
+
+        self.assertPath( None, 'mydir' )
+
+        self.assertPath( 'mydir', 'mydir' )
+       
+        self.assertPath( "", 'mydir' )
+
+        self.assertPath( 'dir1', 'mydir:dir1' )
+                        
+        self.assertPath( 'dir1:dir2', 'mydir:dir1:dir2' )
+
+        self.assertPath( 'mydir:dir1:dir2', 'mydir:dir1:dir2' )
+
+        self.assertPath( 'dir1:mydir:dir2', 'mydir:dir1:dir2' )
+
+        self.assertPath( 'dir1:dir2:mydir', 'mydir:dir1:dir2' )
+                        
+
+
+
+class TestStringNumberList(myunittest.TestCase):
     def setUp(self):
         self.obj = StringNumberList()
 
         for valIn in valsIn:
             self.assertEqual( self.obj.convertStringList(valIn), None ) 
 
-            
 
 class StringNumberList_GoodInput(TestStringNumberList):
     def testSingleFilename(self):
         self.assertNone( badargs )
 
 
-class TestLoadTransforms(MyTest):
+class TestLoadTransforms(myunittest.TestCase):
     def setUp(self):
         self.trfName = "argstest_trf.py"
 
         
         
 if __name__ == "__main__":
-    unittest.main(testRunner=unittest.TextTestRunner(verbosity=2))
+    myunittest.main()