bh@120: # Copyright (C) 2007, 2008 by Intevation GmbH
bh@84: # Authors:
bh@84: # Bernhard Herzog <bh@intevation.de>
bh@84: #
bh@84: # This program is free software under the GPL (>=v2)
bh@84: # Read the file COPYING coming with the software for details.
bh@84: 
bh@84: """Support code for the test cases"""
bh@84: 
bh@84: import os
bh@84: import shutil
bh@84: from treepkg.util import writefile
bh@84: 
bh@84: 
bh@84: def create_temp_dir():
bh@84:     """Create a temporary directory for the test-suite and return its name.
bh@84: 
bh@84:     The temporary directory is always called temp and is created in the
bh@84:     directory where the support module is located.
bh@84: 
bh@84:     If the temp directory already exists, just return the name.
bh@84:     """
bh@84:     name = os.path.abspath(os.path.join(os.path.dirname(__file__), "temp"))
bh@84: 
bh@84:     # if the directory already exists, we're done
bh@84:     if os.path.isdir(name):
bh@84:         return name
bh@84: 
bh@84:     # create the directory
bh@84:     os.mkdir(name)
bh@84:     return name
bh@84: 
bh@84: 
bh@84: class FileTestMixin:
bh@84: 
bh@185:     """Mixin class for tests that use temporary files.
bh@185: 
bh@185:     Instances of this class create a test-specific sub-directory under
bh@185:     the main test temp directory.  The name of the sub-directory is the
bh@185:     return value of the test's id() method.
bh@84:     """
bh@84: 
bh@185:     _test_specific_directory_created = False
bh@185: 
bh@185:     def create_test_specific_temp_dir(self):
bh@185:         """Creates the test specific directory and returns its absolute name.
bh@185:         When this method is called for the first time and the directory
bh@185:         exists, if is removed, so that a specific test instance always
bh@185:         starts with an empty directory.
bh@84:         """
bh@185:         dirname = os.path.join(create_temp_dir(), self.id())
bh@185:         if not self._test_specific_directory_created:
bh@185:             if os.path.exists(dirname):
bh@185:                 shutil.rmtree(dirname)
bh@185:             os.mkdir(dirname)
bh@185:             self._test_specific_directory_created = True
bh@185:         return dirname
bh@84: 
bh@185:     def temp_file_name(self, basename):
bh@185:         """Returns the full name of the file named basename in the temp. dir.
bh@185:         """
bh@185:         return os.path.join(self.create_test_specific_temp_dir(), basename)
bh@185: 
bh@185:     def create_temp_file(self, basename, contents, permissions=None):
bh@84:         """Creates a file in the temp directory with the given contents.
bh@185:         The optional parameter permissions should either be None (the
bh@185:         default) or an int specifying the file permissions (same format
bh@185:         as the second parameter of os.chmod).  The method returns the
bh@185:         absolute name of the created file.
bh@84:         """
bh@84:         filename = self.temp_file_name(basename)
bh@84:         file = open(filename, "w")
bh@84:         file.write(contents)
bh@84:         file.close()
bh@185:         if permissions is not None:
bh@185:             os.chmod(filename, permissions)
bh@84:         return filename
bh@84: 
bh@185:     def create_temp_dir(self, basename):
bh@84:         """Creates the directory basename in the temporary directory.
bh@84:         The method returns the absolute name of the created directory.
bh@84:         """
bh@185:         dirname = self.temp_file_name(basename)
bh@84:         os.mkdir(dirname)
bh@84:         return dirname
bh@84: 
bh@84:     def create_files(self, directory, filedesc):
bh@120:         """Creates a hierarchy of directories and files in directory.
bh@84:         The filedesc parameter should be a sequence of (name, contents)
bh@120:         pairs or (name, permissions, contents) triples.  Each item of
bh@120:         the sequence describes one entry of the directory.  If contents
bh@120:         is an instance of list, the entry is a subdirectory and the
bh@120:         contents is a list in the same format as filedesc and passed
bh@84:         recursively to the create_files method.  If contents is a
bh@84:         string, the new directory entry is a normal file and contents is
bh@120:         the contents of the file.  The permissions if present, should be
bh@120:         an int specifying the files permissions (setting permissions
bh@120:         doesn't work yet for directories).
bh@185: 
bh@185:         The method returns the absolute name of the toplevel directory
bh@185:         created by the method.
bh@84:         """
bh@185:         directory = self.temp_file_name(directory)
bh@120:         os.makedirs(directory)
bh@120:         for item in filedesc:
bh@120:             if len(item) == 3:
bh@120:                 name, permissions, contents = item
bh@120:             else:
bh@120:                 name, contents = item
bh@120:                 permissions = None # use default permissions
bh@84:             if isinstance(contents, list):
bh@84:                 # a list as contents indicates a directory
bh@185:                 self.create_files(os.path.join(directory, name), contents)
bh@84:             else:
bh@120:                 writefile(os.path.join(directory, name), contents, permissions)
bh@185:         return directory
bh@111: 
bh@195:     def check_file_contents(self, filename, contents):
bh@111:         """check the contents of a file"""
bh@111:         self.assertEquals(open(filename).read(), contents)