You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@gump.apache.org by an...@apache.org on 2004/03/04 22:38:47 UTC

cvs commit: gump/python/gump/test sync.py pyunit.py

antoine     2004/03/04 13:38:47

  Modified:    python/gump/test pyunit.py
  Added:       python/gump/utils sync.py
               python/gump/test sync.py
  Log:
  a sync utility with 4 unit tests
  
  Revision  Changes    Path
  1.1                  gump/python/gump/utils/sync.py
  
  Index: sync.py
  ===================================================================
  #!/usr/bin/env python
  
  # $Header: /home/cvs/gump/python/gump/utils/sync.py,v 1.1 2004/03/04 21:38:47 antoine Exp $
  # $Revision: 1.1 $
  # $Date: 2004/03/04 21:38:47 $
  #
  # ====================================================================
  #
  # The Apache Software License, Version 1.1
  #
  # Copyright (c) 2004 The Apache Software Foundation.  All rights
  # reserved.
  #
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions
  # are met:
  #
  # 1. Redistributions of source code must retain the above copyright
  #    notice, this list of conditions and the following disclaimer.
  #
  # 2. Redistributions in binary form must reproduce the above copyright
  #    notice, this list of conditions and the following disclaimer in
  #    the documentation and/or other materials provided with the
  #    distribution.
  #
  # 3. The end-user documentation included with the redistribution, if
  #    any, must include the following acknowlegement:
  #       "This product includes software developed by the
  #        Apache Software Foundation (http://www.apache.org/)."
  #    Alternately, this acknowlegement may appear in the software itself,
  #    if and wherever such third-party acknowlegements normally appear.
  #
  # 4. The names "The Jakarta Project", "Alexandria", and "Apache Software
  #    Foundation" must not be used to endorse or promote products derived
  #    from this software without prior written permission. For written
  #    permission, please contact apache@apache.org.
  #
  # 5. Products derived from this software may not be called "Apache"
  #    nor may "Apache" appear in their names without prior written
  #    permission of the Apache Group.
  #
  # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  # DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  # ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  # SUCH DAMAGE.
  # ====================================================================
  #
  # This software consists of voluntary contributions made by many
  # individuals on behalf of the Apache Software Foundation.  For more
  # information on the Apache Software Foundation, please see
  # <http://www.apache.org/>.
  
  """
      Helper Stuff
  """
  
  import logging
  import os.path
  from stat import *
  import shutil
  from gump import log
  from gump.utils.work import *
  from gump.utils.file import *
  from gump.utils.launcher import *
  class Sync:
      """
      this class can be used to sync two directories
      x = Sync(sourcedir, targetdir) # construct
      x.execute() #run
      if targetdir does not exist, it will be created
      if sourcedir does not exist, the class will raise an IOError
      """
      def __init__(self, sourcedir, targetdir):
          self.sourcedir = sourcedir
          self.targetdir = targetdir
      def execute(self):
          log.info('Starting sync from [' + self.sourcedir + ']')
          log.info('        target dir [' + self.targetdir + ']')
          if not os.path.exists(self.sourcedir):
              log.error('Exiting sync, source directory does not exist [' + self.sourcedir + ']')
              raise IOError, 'source directory does not exist [' + self.sourcedir + ']'
              return
          if not os.path.isdir(self.sourcedir):
              log.error('Exiting sync, source is not a directory [' + self.sourcedir + ']')
              raise IOError, 'source is not a directory [' + self.sourcedir + ']'
              return
          if not os.path.exists(self.targetdir):
              try:
                  os.makedirs(self.targetdir)
              except Exception, details:
                  log.exception('failed on ' + str(details))
                  return
          copytree(self.sourcedir, self.targetdir, 1)    
              
  def copytree(src, dst, symlinks=0):
      names = os.listdir(src)
      try:
          result = os.stat(dst)
      except Exception, details:
          result = None
      # handle case where result exists but is not a directory    
      if result and not S_ISDIR(result[ST_MODE]):
          remove(dst)
          result = None
      if not result:    
          os.makedirs(dst)
      if result:
          names2 = os.listdir(dst)
          epurate(src, dst, names, names2)    
      for name in names:
          srcname = os.path.join(src, name)
          dstname = os.path.join(dst, name)
          try:
              if symlinks and os.path.islink(srcname):
                  linkto = os.readlink(srcname)
                  os.symlink(linkto, dstname)
              elif os.path.isdir(srcname):
                  copytree(srcname, dstname, symlinks)
              else:
                  maybecopy(srcname, dstname)
          except (IOError, os.error), why:
              message = "Can't copy [%s] to [%s]: [%s]" % (`srcname`, `dstname`, str(why))
              log.exception(message)
              raise IOError, message
  def epurate(sourcedir, destdir, acceptablefiles, existingfiles):
      """
      this routine will delete from a set of existing files
      in a directory the one which are not part of an 
      array of acceptablefiles
      somedir = directory where the epuration is to take place                                      
      """
      for afile in existingfiles:
          fullsourcefile = os.path.join(sourcedir, afile)
          fulldestfile = os.path.join(destdir, afile)
          if not afile in acceptablefiles:
              tobedeleted = os.path.join(destdir, afile)
              result = os.stat(tobedeleted)
              if S_ISDIR(result[ST_MODE]):
                  log.debug('attempting to remove directory [%s]' % (`tobedeleted`))
                  shutil.rmtree(tobedeleted)
              else:    
                  log.debug('attempting to remove file [%s]' % (`tobedeleted`))
                  os.remove(tobedeleted)
          elif os.path.isdir(fullsourcefile) and not os.path.isdir(fulldestfile):
              log.debug('removing file [%s] to be replaced by directory' 
              %(`fulldestfile`))
              os.remove(fulldestfile)
          elif os.path.isfile(fullsourcefile) and os.path.isdir(fulldestfile):              
              log.debug('removing directory [%s] to be replaced by file' 
              %(`fulldestfile`))
              shutil.rmtree(fulldestfile)
              
  def maybecopy(srcname, dstname):
      """
      copy a file from srcname to dstname if 
      dstname does not exist
      or srcname and dstname have different dates
      or srcname and dstname have different sizes
      """
      result = os.stat(srcname)
      try:
          result2 = os.stat(dstname)
      except (Exception), details:
          result2 = None
      okcopy = 0
      if not result2:
          okcopy = 1
      elif S_ISDIR(result2[ST_MODE]):
          shutil.rmtree(dstname)
          okcopy = 1
      elif result[ST_SIZE] != result2[ST_SIZE]:
          okcopy = 1
      elif result[ST_MTIME] != result2[ST_MTIME]:
          okcopy = 1
      if okcopy:
          log.debug("Attempting copy from [%s] to [%s]" %(`srcname`, `dstname`))    
          shutil.copy2(srcname, dstname)
          
              
              
  
  
  
  1.22      +7 -4      gump/python/gump/test/pyunit.py
  
  Index: pyunit.py
  ===================================================================
  RCS file: /home/cvs/gump/python/gump/test/pyunit.py,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- pyunit.py	18 Feb 2004 00:13:54 -0000	1.21
  +++ pyunit.py	4 Mar 2004 21:38:47 -0000	1.22
  @@ -334,6 +334,9 @@
       
       #:TODO: Figure out Python search/introspection to find these...
       
  +    from gump.test.sync import SyncTestSuite
  +    runner.addSuite(SyncTestSuite())
  +
       from gump.test.utils import UtilsTestSuite  
       runner.addSuite(UtilsTestSuite())
       
  @@ -377,4 +380,4 @@
       # Perform the tests...
       runner.run(patterns)
       
  -    
  \ No newline at end of file
  +    
  
  
  
  1.1                  gump/python/gump/test/sync.py
  
  Index: sync.py
  ===================================================================
  #!/usr/bin/env python
  #
  # $Header: /home/cvs/gump/python/gump/test/sync.py,v 1.1 2004/03/04 21:38:47 antoine Exp $
  # $Revision: 1.1 $
  # $Date: 2004/03/04 21:38:47 $
  #
  # ====================================================================
  #
  # The Apache Software License, Version 1.1
  #
  # Copyright (c) 2003 The Apache Software Foundation.  All rights
  # reserved.
  #
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions
  # are met:
  #
  # 1. Redistributions of source code must retain the above copyright
  #    notice, this list of conditions and the following disclaimer.
  #
  # 2. Redistributions in binary form must reproduce the above copyright
  #    notice, this list of conditions and the following disclaimer in
  #    the documentation and/or other materials provided with the
  #    distribution.
  #
  # 3. The end-user documentation included with the redistribution, if
  #    any, must include the following acknowlegement:
  #       "This product includes software developed by the
  #        Apache Software Foundation (http://www.apache.org/)."
  #    Alternately, this acknowlegement may appear in the software itself,
  #    if and wherever such third-party acknowlegements normally appear.
  #
  # 4. The names "The Jakarta Project", "Alexandria", and "Apache Software
  #    Foundation" must not be used to endorse or promote products derived
  #    from this software without prior written permission. For written
  #    permission, please contact apache@apache.org.
  #
  # 5. Products derived from this software may not be called "Apache"
  #    nor may "Apache" appear in their names without prior written
  #    permission of the Apache Group.
  #
  # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  # DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  # ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  # SUCH DAMAGE.
  # ====================================================================
  #
  # This software consists of voluntary contributions made by many
  # individuals on behalf of the Apache Software Foundation.  For more
  # information on the Apache Software Foundation, please see
  # <http://www.apache.org/>.
  
  """
      Utils Testing
  """
  
  from gump.utils.sync import Sync
  from gump.test.pyunit import UnitTestSuite
  from gump import log
  import os.path
  import shutil
  import time
  import stat
  class SyncTestSuite(UnitTestSuite):
      def __init__(self):
          UnitTestSuite.__init__(self)
          self.source = "./test/source"
          self.destination = "./test/destination"
          self.source_subdir1 = os.path.join(self.source, 'subdir1')
          self.destination_subdir1 = os.path.join(self.destination, 'subdir1')
          self.alphatxt = 'alpha.txt'
          self.source_alphatxt = os.path.join(self.source_subdir1, self.alphatxt)
          self.destination_alphatxt = os.path.join(self.destination_subdir1, self.alphatxt)
      def setUp(self):
          """
          this setup creates a subdirectory at source
          then a file in the subdirectory, with an arbitrary date time
          """
          self.tearDown()
          os.makedirs(self.source_subdir1)
          myfile = file(self.source_alphatxt, 'w+')
          myfile.write('Hello World')
          myfile.close()
          # Sat, 20 May 2000 12:07:40 +0000
          sometime=[2000,5,20,12,7,40,5,141,-1]
          epoch_sometime = time.mktime(sometime)
          os.utime(self.source_alphatxt, (epoch_sometime, epoch_sometime))
      def tearDown(self):
          if os.path.exists(self.source):
              log.debug('attempting to remove directory [%s]' % (`self.source`))
              shutil.rmtree(self.source)
          if os.path.exists(self.destination):
              log.debug('attempting to remove directory [%s]' % (`self.destination`))
              shutil.rmtree(self.destination)    
      def testSimpleSync(self):
          """
          assuming the setUp gets done,
          a sync runs
          the test checks :
              - that the destination directory gets created
              - that the destination subdirectory gets created
              - that a file exists in the destination subdir
              with the same size and modification time as 
              the original file
          """
          mySync = Sync(self.source, self.destination)
          mySync.execute()
          try:
              result = os.stat(self.destination)
          except Exception, details:
              raiseIssue(['destination directory was not created', self.destination])
          try:
              result = os.stat(self.destination_subdir1)
          except Exception, details:
              raiseIssue(['destination_subdir1 directory was not created', self.destination_subdir1])
          result_source = None
          result_destination = None    
          try:
              result_source = os.stat(self.source_alphatxt)    
          except Exception, details:
              raiseIssue(['file was not created', self.source_alphatxt])
          try:
              result_destination = os.stat(self.destination_alphatxt)
          except Exception, details:
              raiseIssue(['file was not created', self.destination_alphatxt])
          log.debug("size of file [%s] is %i" % (`self.destination_alphatxt`,
          result_destination[stat.ST_SIZE]))    
          log.debug("modification date of file [%s] is %s" % 
          (`self.destination_alphatxt`,
          time.ctime(result_destination[stat.ST_MTIME])))    
          self.assertTrue("modtime is equal for [%s] compared to [%s]"
          %(`self.source_alphatxt`,`self.destination_alphatxt`),
          result_source[stat.ST_MTIME]==result_destination[stat.ST_MTIME])
          self.assertTrue("size is equal for [%s] compared to [%s]"
          %(`self.source_alphatxt`,`self.destination_alphatxt`),
          result_source[stat.ST_SIZE]==result_destination[stat.ST_SIZE])    
      def testRemoveJunkDestinationFile(self):
          """
          assuming the setUp gets done,
          a sync runs
          then a file is added at destination
          the timestamp of the destination file gets changed
          then another sync
          the test checks :
              - that the extra destination file is removed
              - that the destination file gets copied again
              with the same size and modification time as 
              the original file
          """
          mySync = Sync(self.source, self.destination)
          mySync.execute()
          # create the destination junk file
          destination_junktxt = os.path.join(self.destination_subdir1, 
          'junk.txt')
          shutil.copy2(self.destination_alphatxt, destination_junktxt)
          sometime=[2000,5,20,12,7,45,5,141,-1]
          epoch_sometime = time.mktime(sometime)
          os.utime(self.destination_alphatxt, (epoch_sometime, epoch_sometime))
          mySync.execute()
          if os.path.exists(destination_junktxt):
              raiseIssue(['junk file was not deleted', destination_junktxt])
          result_source = None
          result_destination = None    
          try:
              result_source = os.stat(self.source_alphatxt)    
          except Exception, details:
              raiseIssue(['file was not created', self.source_alphatxt])
          try:
              result_destination = os.stat(self.destination_alphatxt)
          except Exception, details:
              raiseIssue(['file was not created', self.destination_alphatxt])
          log.debug("size of file [%s] is %i" % (`self.destination_alphatxt`,
          result_destination[stat.ST_SIZE]))    
          log.debug("modification date of file [%s] is %s" % 
          (`self.destination_alphatxt`,
          time.ctime(result_destination[stat.ST_MTIME])))    
          self.assertTrue("modtime is equal for [%s] compared to [%s]"
          %(`self.source_alphatxt`,`self.destination_alphatxt`),
          result_source[stat.ST_MTIME]==result_destination[stat.ST_MTIME])
      def testDestinationFileBecomesDirectory(self):
          """
          assuming the setUp gets done,
          a sync runs
          then destination_alphatxt is deleted and replaced by a directory
          in this directory another subdir, a file, and another file in the subdir
          then another sync
          the test checks :
              - that the destination file gets copied again
              with the same size and modification time as 
              the original file
          """
          mySync = Sync(self.source, self.destination)
          mySync.execute()
          os.remove(self.destination_alphatxt)
          junk_subdir = os.path.join(self.destination_alphatxt, "junk.dir")
          os.makedirs(junk_subdir)
          junk_file1 = os.path.join(self.destination_alphatxt, "junk.txt")
          junk_file2 = os.path.join(junk_subdir, "junk.txt")
          shutil.copy2(self.source_alphatxt, junk_file1)
          shutil.copy2(self.source_alphatxt, junk_file2)
          mySync.execute()
          if os.path.isdir(self.destination_alphatxt):
              raiseIssue(['destination text file remained a directory',
               self.destination_alphatxt])
          result_source = None
          result_destination = None    
          try:
              result_source = os.stat(self.source_alphatxt)    
          except Exception, details:
              raiseIssue(['file was not created', self.source_alphatxt])
          try:
              result_destination = os.stat(self.destination_alphatxt)
          except Exception, details:
              raiseIssue(['file was not created', self.destination_alphatxt])
          log.debug("size of file [%s] is %i" % (`self.destination_alphatxt`,
          result_destination[stat.ST_SIZE]))    
          log.debug("modification date of file [%s] is %s" % 
          (`self.destination_alphatxt`,
          time.ctime(result_destination[stat.ST_MTIME])))    
          self.assertTrue("modtime is equal for [%s] compared to [%s]"
          %(`self.source_alphatxt`,`self.destination_alphatxt`),
          result_source[stat.ST_MTIME]==result_destination[stat.ST_MTIME])
      def testOriginFileBecomesDirectory(self):
          """
          assuming the setUp gets done,
          a sync runs
          then source_alphatxt is deleted and replaced by a directory
          in this directory another subdir, a file, and another file in the subdir
          then another sync
          the test checks :
              - that the alpha.txt file gets replaced by a directory at destination
              - that the directory tree below alpha.txt is the same at 
              destination like at source
          """
          mySync = Sync(self.source, self.destination)
          mySync.execute()
          os.remove(self.source_alphatxt)
          junk_subdir = os.path.join(self.source_alphatxt, "junk.dir")
          os.makedirs(junk_subdir)
          junk_source_file1 = os.path.join(self.source_alphatxt, "junk.txt")
          myfile = file(junk_source_file1, 'w+')
          myfile.write('Hello World')
          myfile.close()
          junk_source_file2 = os.path.join(junk_subdir, "junk.txt")
          shutil.copy2(junk_source_file1, junk_source_file2)
          mySync.execute()
          if os.path.isfile(self.destination_alphatxt):
              raiseIssue(['destination text file remained a file',
               self.destination_alphatxt])
          self.genericCompare(self.source_alphatxt, self.destination_alphatxt)
          log.debug('finished')     
      def genericCompare(self, mysource, mydestination):
          """
          compare 2 directories source and destination
          """ 
          if not os.path.isdir(mysource):
              raiseIssue([mysource, ' not a directory'])
          if not os.path.isdir(mydestination):
              raiseIssue([mydestination, ' not a directory'])
          names = os.listdir(mysource)
          for aname in names:
              inode_source = os.path.join(mysource, aname)
              inode_dest = os.path.join(mydestination, aname)
              if os.path.isfile(inode_source):
                  self.compareFiles(inode_source, inode_dest)
              elif os.path.islink(inode_source):
                  if not os.path.islink(inode_dest):
                      raiseIssue([inode_dest, ' not a symbolic link'])
                  linkto_source = os.readlink(inode_source)
                  linkto_dest = os.readlink(inode_dest)
                  self.assertTrue([inode_dest, ' points to ', linkto_source ],
                  linkto_source==linkto_dest)
              elif os.path.isdir(inode_source):
                  self.genericCompare(inode_source, inode_dest)    
                              
                      
      def compareFiles(self, inode_source, inode_dest):
          """
          compare 2 files
          """     
          result_source = None
          result_dest = None
          try:
              result_source = os.stat(inode_source)
          except Exception, details:
              raiseIssue(['could not stat ', inode_source])
          try:
              result_dest = os.stat(inode_dest)
          except Exception, details:
              raiseIssue(['could not stat ', inode_dest])
          self.assertTrue("modtime is equal for [%s] compared to [%s]"
          %(`inode_source`,`inode_dest`),
          result_source[stat.ST_MTIME]==result_dest[stat.ST_MTIME])
          self.assertTrue("size is equal for [%s] compared to [%s]"
          %(`inode_source`,`inode_dest`),
          result_source[stat.ST_SIZE]==result_dest[stat.ST_SIZE])
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
For additional commands, e-mail: general-help@gump.apache.org


Re: cvs commit: gump/python/gump/test sync.py pyunit.py

Posted by Antoine Lévy-Lambert <an...@antbuild.com>.
Thanks for all your comments.

I am going to do the changes that you are suggesting, and check them in 
early next week.

Cheers,

Antoine

Adam R. B. Jack wrote:

>>this is my first attempt at doing something in Python for gumpy.
>>    
>>
>
>Awesome, I can't wait for us to be free of the bonds of 'rsync'. (I don't
>know how we'll get a feel for this, when thrown into the deep end w/ the
>CVS/SVN data we have, but I guess we wait a little then just plunge.)
>
>  
>
>>Since this code is not called from any where yet, it should not break
>>gumpy, the worst thing which could
>>break are the tests.
>>    
>>
>
>Great, we'll see how those go for a while then migrate.
>
>First, it seems you really figure this stuff out -- including my home grown
>pyunit stuff, cool.
>
>Second, in checking these out I noticed a couple of minor things:
>
>- In Sync.execute if you change the except below to makedirs to a finally,
>we ought get an exception when (if ) makedir fails.
>
>- It see that epurate is called unconditionally, could there be an optional
>switch on Sync to do that, or not? If we are to replace cp as well as rsynch
>we need 'copy on top of w/o clean-up'.
>
>A ponderance:
>
>- If we made the functions at the bottom of the module into methods on the
>class, and if we made Sync inherit from Annotatable (& call
>Annotatable.__init__(self) in __init__, we could log information to the
>object, and then (if we wanted to know what was done, perhaps for debugging)
>we could copy those annotations off (perhaps transfer them to the Module
>object for listing in the forrest page.)
>
>  
>
>>By the way, I have run the tests under Windows and Boa Constructor with
>>Python 2.2.
>>    
>>
>
>They run for me using Activestate Python 2.3. :-) [I know I ought work on
>2.2, but I was hoping we could move. I'll test this on Linux on 2.2 sometime
>soon.]
>
>  
>
>>I have seen that the logging sometimes work and sometimes not.
>>    
>>
>
>Gosh, interesting. I've never see that. I also never (overtly) noticed the
>logging config making much difference, I assumed that writting to stderr was
>the default. Could it be that in some cases your output is buffered and that
>output not sync'ed? [No pun intended. ;-)] I'm clutching at straws, I've no
>idea...
>
>  
>
>>Under cygwin I can run my test OK under Python 2.3.3 cygwin version.
>>    
>>
>
>This is just to be thorough, I take it, to ensure you cope in case folks
>do -- but they oughtn't (right) for other reason (launching Java/Ant) that
>you've stated before. Right?
>
>regards
>
>Adam
>
>  
>



---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
For additional commands, e-mail: general-help@gump.apache.org


Re: cvs commit: gump/python/gump/test sync.py pyunit.py

Posted by "Adam R. B. Jack" <aj...@trysybase.com>.
> this is my first attempt at doing something in Python for gumpy.

Awesome, I can't wait for us to be free of the bonds of 'rsync'. (I don't
know how we'll get a feel for this, when thrown into the deep end w/ the
CVS/SVN data we have, but I guess we wait a little then just plunge.)

> Since this code is not called from any where yet, it should not break
> gumpy, the worst thing which could
> break are the tests.

Great, we'll see how those go for a while then migrate.

First, it seems you really figure this stuff out -- including my home grown
pyunit stuff, cool.

Second, in checking these out I noticed a couple of minor things:

- In Sync.execute if you change the except below to makedirs to a finally,
we ought get an exception when (if ) makedir fails.

- It see that epurate is called unconditionally, could there be an optional
switch on Sync to do that, or not? If we are to replace cp as well as rsynch
we need 'copy on top of w/o clean-up'.

A ponderance:

- If we made the functions at the bottom of the module into methods on the
class, and if we made Sync inherit from Annotatable (& call
Annotatable.__init__(self) in __init__, we could log information to the
object, and then (if we wanted to know what was done, perhaps for debugging)
we could copy those annotations off (perhaps transfer them to the Module
object for listing in the forrest page.)

> By the way, I have run the tests under Windows and Boa Constructor with
> Python 2.2.

They run for me using Activestate Python 2.3. :-) [I know I ought work on
2.2, but I was hoping we could move. I'll test this on Linux on 2.2 sometime
soon.]

> I have seen that the logging sometimes work and sometimes not.

Gosh, interesting. I've never see that. I also never (overtly) noticed the
logging config making much difference, I assumed that writting to stderr was
the default. Could it be that in some cases your output is buffered and that
output not sync'ed? [No pun intended. ;-)] I'm clutching at straws, I've no
idea...

> Under cygwin I can run my test OK under Python 2.3.3 cygwin version.

This is just to be thorough, I take it, to ensure you cope in case folks
do -- but they oughtn't (right) for other reason (launching Java/Ant) that
you've stated before. Right?

regards

Adam


---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
For additional commands, e-mail: general-help@gump.apache.org


Re: cvs commit: gump/python/gump/test sync.py pyunit.py

Posted by Antoine Lévy-Lambert <an...@antbuild.com>.
Hi,

this is my first attempt at doing something in Python for gumpy.

Since this code is not called from any where yet, it should not break 
gumpy, the worst thing which could
break are the tests.

By the way, I have run the tests under Windows and Boa Constructor with 
Python 2.2.
I have seen that the logging sometimes work and sometimes not. I mean that
if I set the log level to debug, under Windows I sometimes see the log 
messages in the output window of Boa
and sometimes not, both for my test and for other tests. What is the 
issue there ?
Does it have to do with some tests changing the current directory, which 
then prevents the logging module from
finding the logging configuration, or is this something more subtle or a 
Python bug or ...

Under cygwin I can run my test OK under Python 2.3.3 cygwin version.

Cheers,

Antoine


antoine@apache.org wrote:

>antoine     2004/03/04 13:38:47
>
>  Modified:    python/gump/test pyunit.py
>  Added:       python/gump/utils sync.py
>               python/gump/test sync.py
>  Log:
>  a sync utility with 4 unit tests
>  
>  
>



---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
For additional commands, e-mail: general-help@gump.apache.org