Package test_suite :: Package verification_tests :: Module library
[hide private]
[frames] | no frames]

Source Code for Module test_suite.verification_tests.library

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2014 Edward d'Auvergne                                        # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """Verification tests for the relax library.""" 
 24   
 25  # Python module imports. 
 26  from os import sep 
 27  from shutil import copytree, rmtree 
 28  from subprocess import PIPE, Popen 
 29  import sys 
 30  from tempfile import mkdtemp 
 31  from unittest import TestCase 
 32   
 33  # relax module imports. 
 34  from status import Status; status = Status() 
 35  from test_suite.clean_up import deletion 
 36   
 37   
38 -class Library(TestCase):
39 """Test the relax library.""" 40
41 - def setUp(self):
42 """Set up for all of the library tests.""" 43 44 # Initialise a temporary directory. 45 self.tmpdir = mkdtemp()
46 47
48 - def tearDown(self):
49 """Clean up after the library tests.""" 50 51 # Remove the temporary directory and all its contents. 52 deletion(obj=self, name='tmpdir', dir=True)
53 54
56 """Throughly check the independence of the relax library by importing it from a non-relax directory. 57 58 It will do this by copying just that package into a temporary directory, modifying the Python system path to include the directory, and then to recursively import all packages and modules. All import failures will be reported at the end. 59 """ 60 61 # Copy the entire library to the temporary directory. 62 tmplib = self.tmpdir + sep + 'lib' 63 copytree(status.install_path+sep+'lib', tmplib) 64 65 # Create a Python script for testing the import independently of relax. 66 script_name = self.tmpdir + sep + 'test.py' 67 script = open(script_name, 'w') 68 69 # Script contents. 70 lines = [ 71 "", 72 "# Python module imports.", 73 "import pkgutil", 74 "import sys", 75 "", 76 "# Direct copy of the Python 2.7 importlib function.", 77 "def _resolve_name(name, package, level):", 78 " \"\"\"Return the absolute name of the module to be imported.\"\"\"", 79 " if not hasattr(package, 'rindex'):", 80 " raise ValueError(\"'package' not set to a string\")", 81 " dot = len(package)", 82 " for x in range(level, 1, -1):", 83 " try:", 84 " dot = package.rindex('.', 0, dot)", 85 " except ValueError:", 86 " raise ValueError(\"attempted relative import beyond top-level package\")", 87 " return \"%s.%s\" % (package[:dot], name)", 88 "", 89 "", 90 "# Direct copy of the Python 2.7 importlib function.", 91 "def import_module(name, package=None):", 92 " \"\"\"Import a module.", 93 "", 94 " The 'package' argument is required when performing a relative import. It", 95 " specifies the package to use as the anchor point from which to resolve the", 96 " relative import to an absolute import.", 97 "", 98 " \"\"\"", 99 " if name.startswith('.'):", 100 " if not package:", 101 " raise TypeError(\"relative imports require the 'package' argument\")", 102 " level = 0", 103 " for character in name:", 104 " if character != '.':", 105 " break", 106 " level += 1", 107 " name = _resolve_name(name[level:], package, level)", 108 " __import__(name)", 109 " return sys.modules[name]", 110 "", 111 "", 112 "# Initialise a structure for later reporting of failed imports.", 113 "failed = []", 114 "", 115 "# Import each part of the library.", 116 "import lib", 117 "for importer, name, is_pkg in pkgutil.iter_modules(lib.__path__):", 118 " # The full name.", 119 " full_name = 'lib.%s' % name", 120 "", 121 " # Printout.", 122 " if is_pkg:", 123 " print(\"Package '%s'.\" % full_name)", 124 " else:", 125 " print(\"Module '%s'.\" % full_name)", 126 "", 127 " # Import it.", 128 " module = None", 129 " try:", 130 " module = import_module(full_name)", 131 " except:", 132 " message = sys.exc_info()[1]", 133 " failed.append([full_name, message])", 134 "", 135 " # Nothing more to do.", 136 " if not is_pkg or module is None:", 137 " continue", 138 "", 139 " # First recursion.", 140 " for importer2, name2, is_pkg2 in pkgutil.iter_modules(module.__path__):", 141 " # The full name.", 142 " full_name2 = 'lib.%s.%s' % (name, name2)", 143 "", 144 " # Printout.", 145 " if is_pkg2:", 146 " print(\" Package '%s'.\" % full_name2)", 147 " else:", 148 " print(\" Module '%s'.\" % full_name2)", 149 "", 150 " # Import it.", 151 " module2 = None", 152 " try:", 153 " module2 = import_module(full_name2)", 154 " except:", 155 " message = sys.exc_info()[1]", 156 " failed.append([full_name2, message])", 157 "", 158 " # Nothing more to do.", 159 " if not is_pkg2 or module2 is None:", 160 " continue", 161 "", 162 " # 2nd recursion (the last for now).", 163 " for importer3, name3, is_pkg3 in pkgutil.iter_modules(module2.__path__):", 164 " # The full name.", 165 " full_name3 = 'lib.%s.%s.%s' % (name, name2, name3)", 166 "", 167 " # Printout.", 168 " if is_pkg3:", 169 " print(\" Package '%s'.\" % full_name3)", 170 " raise NameError(\"Recursion limit exceeded.\")", 171 " else:", 172 " print(\" Module '%s'.\" % full_name3)", 173 "", 174 " # Import it.", 175 " try:", 176 " module3 = import_module(full_name3)", 177 " except:", 178 " message = sys.exc_info()[1]", 179 " failed.append([full_name3, message])", 180 "", 181 "# Printout of all import failures.", 182 "if len(failed):", 183 " sys.stderr.write('\\n\\nImport failures:\\n')", 184 " for name, message in failed:", 185 " sys.stderr.write(\" %s: %s\\n\" % (name, message))", 186 " sys.stderr.write('\\n')", 187 ] 188 for line in lines: 189 script.write(line + '\n') 190 191 # Close the script. 192 script.close() 193 194 # Execute the script using the same Python executable as relax. 195 cmd = "%s %s" % (sys.executable, script_name) 196 pipe = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=False) 197 198 # Close the pipe. 199 pipe.stdin.close() 200 201 # Write to stdout. 202 for line in pipe.stdout.readlines(): 203 # Decode Python 3 byte arrays. 204 if hasattr(line, 'decode'): 205 line = line.decode() 206 207 # Write. 208 sys.stdout.write(line) 209 210 # Write to stderr. 211 err_lines = pipe.stderr.readlines() 212 for line in err_lines: 213 # Decode Python 3 byte arrays. 214 if hasattr(line, 'decode'): 215 line = line.decode() 216 217 # Write. 218 sys.stderr.write(line) 219 220 # An import failure occurred, so print the error message and fail. 221 if len(err_lines): 222 for line in err_lines: 223 print(line) 224 self.fail()
225