1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23  """Verification tests for the relax library.""" 
 24   
 25   
 26  from os import sep 
 27  from shutil import copytree 
 28  from subprocess import PIPE, Popen 
 29  import sys 
 30  from tempfile import mkdtemp 
 31  from unittest import TestCase 
 32   
 33   
 34  from status import Status; status = Status() 
 35  from test_suite.clean_up import deletion 
 36   
 37   
 39      """Test the relax library.""" 
 40   
 42          """Set up for all of the library tests.""" 
 43   
 44           
 45          self.tmpdir = mkdtemp() 
  46   
 47   
 49          """Clean up after the library tests.""" 
 50   
 51           
 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           
 62          tmplib = self.tmpdir + sep + 'lib' 
 63          copytree(status.install_path+sep+'lib', tmplib) 
 64   
 65           
 66          script_name = self.tmpdir + sep + 'test.py' 
 67          script = open(script_name, 'w') 
 68   
 69           
 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           
192          script.close() 
193   
194           
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           
199          pipe.stdin.close() 
200   
201           
202          for line in pipe.stdout.readlines(): 
203               
204              if hasattr(line, 'decode'): 
205                  line = line.decode() 
206   
207               
208              sys.stdout.write(line) 
209   
210           
211          err_lines = pipe.stderr.readlines() 
212          for line in err_lines: 
213               
214              if hasattr(line, 'decode'): 
215                  line = line.decode() 
216   
217               
218              sys.stderr.write(line) 
219   
220           
221          if len(err_lines): 
222              for line in err_lines: 
223                  print(line) 
224              self.fail() 
  225