IMP logo
IMP Reference Guide  2.12.0
The Integrative Modeling Platform
test/__init__.py
1 # This file was automatically generated by SWIG (http://www.swig.org).
2 # Version 3.0.10
3 #
4 # Do not make changes to this file unless you know what you are doing--modify
5 # the SWIG interface file instead.
6 
7 # This wrapper is part of IMP,
8 # Copyright 2007-2019 IMP Inventors. All rights reserved.
9 
10 from __future__ import print_function, division, absolute_import
11 
12 
13 
14 
15 from sys import version_info as _swig_python_version_info
16 if _swig_python_version_info >= (2, 7, 0):
17  def swig_import_helper():
18  import importlib
19  pkg = __name__.rpartition('.')[0]
20  mname = '.'.join((pkg, '_IMP_test')).lstrip('.')
21  try:
22  return importlib.import_module(mname)
23  except ImportError:
24  return importlib.import_module('_IMP_test')
25  _IMP_test = swig_import_helper()
26  del swig_import_helper
27 elif _swig_python_version_info >= (2, 6, 0):
28  def swig_import_helper():
29  from os.path import dirname
30  import imp
31  fp = None
32  try:
33  fp, pathname, description = imp.find_module('_IMP_test', [dirname(__file__)])
34  except ImportError:
35  import _IMP_test
36  return _IMP_test
37  if fp is not None:
38  try:
39  _mod = imp.load_module('_IMP_test', fp, pathname, description)
40  finally:
41  fp.close()
42  return _mod
43  _IMP_test = swig_import_helper()
44  del swig_import_helper
45 else:
46  import _IMP_test
47 del _swig_python_version_info
48 try:
49  _swig_property = property
50 except NameError:
51  pass # Python < 2.2 doesn't have 'property'.
52 
53 try:
54  import builtins as __builtin__
55 except ImportError:
56  import __builtin__
57 
58 def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
59  if (name == "thisown"):
60  return self.this.own(value)
61  if (name == "this"):
62  if type(value).__name__ == 'SwigPyObject':
63  self.__dict__[name] = value
64  return
65  method = class_type.__swig_setmethods__.get(name, None)
66  if method:
67  return method(self, value)
68  if (not static):
69  object.__setattr__(self, name, value)
70  else:
71  raise AttributeError("You cannot add attributes to %s" % self)
72 
73 
74 def _swig_setattr(self, class_type, name, value):
75  return _swig_setattr_nondynamic(self, class_type, name, value, 0)
76 
77 
78 def _swig_getattr(self, class_type, name):
79  if (name == "thisown"):
80  return self.this.own()
81  method = class_type.__swig_getmethods__.get(name, None)
82  if method:
83  return method(self)
84  raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))
85 
86 
87 def _swig_repr(self):
88  try:
89  strthis = "proxy of " + self.this.__repr__()
90  except __builtin__.Exception:
91  strthis = ""
92  return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
93 
94 
95 def _swig_setattr_nondynamic_method(set):
96  def set_attr(self, name, value):
97  if (name == "thisown"):
98  return self.this.own(value)
99  if hasattr(self, name) or (name == "this"):
100  set(self, name, value)
101  else:
102  raise AttributeError("You cannot add attributes to %s" % self)
103  return set_attr
104 
105 
106 try:
107  import weakref
108  weakref_proxy = weakref.proxy
109 except __builtin__.Exception:
110  weakref_proxy = lambda x: x
111 
112 
113 class IMP_TEST_SwigPyIterator(object):
114  """Proxy of C++ swig::IMP_TEST_SwigPyIterator class."""
115 
116  thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
117 
118  def __init__(self, *args, **kwargs):
119  raise AttributeError("No constructor defined - class is abstract")
120  __repr__ = _swig_repr
121  __swig_destroy__ = _IMP_test.delete_IMP_TEST_SwigPyIterator
122  __del__ = lambda self: None
123 
124  def value(self):
125  """value(IMP_TEST_SwigPyIterator self) -> PyObject *"""
126  return _IMP_test.IMP_TEST_SwigPyIterator_value(self)
127 
128 
129  def incr(self, n=1):
130  """
131  incr(IMP_TEST_SwigPyIterator self, size_t n=1) -> IMP_TEST_SwigPyIterator
132  incr(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator
133  """
134  return _IMP_test.IMP_TEST_SwigPyIterator_incr(self, n)
135 
136 
137  def decr(self, n=1):
138  """
139  decr(IMP_TEST_SwigPyIterator self, size_t n=1) -> IMP_TEST_SwigPyIterator
140  decr(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator
141  """
142  return _IMP_test.IMP_TEST_SwigPyIterator_decr(self, n)
143 
144 
145  def distance(self, x):
146  """distance(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> ptrdiff_t"""
147  return _IMP_test.IMP_TEST_SwigPyIterator_distance(self, x)
148 
149 
150  def equal(self, x):
151  """equal(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
152  return _IMP_test.IMP_TEST_SwigPyIterator_equal(self, x)
153 
154 
155  def copy(self):
156  """copy(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator"""
157  return _IMP_test.IMP_TEST_SwigPyIterator_copy(self)
158 
159 
160  def next(self):
161  """next(IMP_TEST_SwigPyIterator self) -> PyObject *"""
162  return _IMP_test.IMP_TEST_SwigPyIterator_next(self)
163 
164 
165  def __next__(self):
166  """__next__(IMP_TEST_SwigPyIterator self) -> PyObject *"""
167  return _IMP_test.IMP_TEST_SwigPyIterator___next__(self)
168 
169 
170  def previous(self):
171  """previous(IMP_TEST_SwigPyIterator self) -> PyObject *"""
172  return _IMP_test.IMP_TEST_SwigPyIterator_previous(self)
173 
174 
175  def advance(self, n):
176  """advance(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
177  return _IMP_test.IMP_TEST_SwigPyIterator_advance(self, n)
178 
179 
180  def __eq__(self, x):
181  """__eq__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
182  return _IMP_test.IMP_TEST_SwigPyIterator___eq__(self, x)
183 
184 
185  def __ne__(self, x):
186  """__ne__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
187  return _IMP_test.IMP_TEST_SwigPyIterator___ne__(self, x)
188 
189 
190  def __iadd__(self, n):
191  """__iadd__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
192  return _IMP_test.IMP_TEST_SwigPyIterator___iadd__(self, n)
193 
194 
195  def __isub__(self, n):
196  """__isub__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
197  return _IMP_test.IMP_TEST_SwigPyIterator___isub__(self, n)
198 
199 
200  def __add__(self, n):
201  """__add__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
202  return _IMP_test.IMP_TEST_SwigPyIterator___add__(self, n)
203 
204 
205  def __sub__(self, *args):
206  """
207  __sub__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator
208  __sub__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> ptrdiff_t
209  """
210  return _IMP_test.IMP_TEST_SwigPyIterator___sub__(self, *args)
211 
212  def __iter__(self):
213  return self
214 IMP_TEST_SwigPyIterator_swigregister = _IMP_test.IMP_TEST_SwigPyIterator_swigregister
215 IMP_TEST_SwigPyIterator_swigregister(IMP_TEST_SwigPyIterator)
216 
217 
218 _value_types=[]
219 _object_types=[]
220 _raii_types=[]
221 _plural_types=[]
222 
223 IMP_DEBUG = _IMP_test.IMP_DEBUG
224 IMP_RELEASE = _IMP_test.IMP_RELEASE
225 IMP_SILENT = _IMP_test.IMP_SILENT
226 IMP_PROGRESS = _IMP_test.IMP_PROGRESS
227 IMP_TERSE = _IMP_test.IMP_TERSE
228 IMP_VERBOSE = _IMP_test.IMP_VERBOSE
229 IMP_MEMORY = _IMP_test.IMP_MEMORY
230 IMP_NONE = _IMP_test.IMP_NONE
231 IMP_USAGE = _IMP_test.IMP_USAGE
232 IMP_INTERNAL = _IMP_test.IMP_INTERNAL
233 IMP_KERNEL_HAS_LOG4CXX = _IMP_test.IMP_KERNEL_HAS_LOG4CXX
234 IMP_COMPILER_HAS_AUTO = _IMP_test.IMP_COMPILER_HAS_AUTO
235 IMP_COMPILER_HAS_DEBUG_VECTOR = _IMP_test.IMP_COMPILER_HAS_DEBUG_VECTOR
236 IMP_COMPILER_HAS_UNIQUE_PTR = _IMP_test.IMP_COMPILER_HAS_UNIQUE_PTR
237 IMP_KERNEL_HAS_BOOST_RANDOM = _IMP_test.IMP_KERNEL_HAS_BOOST_RANDOM
238 IMP_KERNEL_HAS_NUMPY = _IMP_test.IMP_KERNEL_HAS_NUMPY
239 IMP_KERNEL_HAS_GPERFTOOLS = _IMP_test.IMP_KERNEL_HAS_GPERFTOOLS
240 IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER = _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER
241 IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER = _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER
242 IMPKERNEL_SHOW_WARNINGS = _IMP_test.IMPKERNEL_SHOW_WARNINGS
243 
244 import sys
245 class _DirectorObjects(object):
246  """@internal Simple class to keep references to director objects
247  to prevent premature deletion."""
248  def __init__(self):
249  self._objects = []
250  def register(self, obj):
251  """Take a reference to a director object; will only work for
252  refcounted C++ classes"""
253  if hasattr(obj, 'get_ref_count'):
254  self._objects.append(obj)
255  def cleanup(self):
256  """Only drop our reference and allow cleanup by Python if no other
257  Python references exist (we hold 3 references: one in self._objects,
258  one in x, and one in the argument list for getrefcount) *and* no
259  other C++ references exist (the Python object always holds one)"""
260  objs = [x for x in self._objects if sys.getrefcount(x) > 3 \
261  or x.get_ref_count() > 1]
262 # Do in two steps so the references are kept until the end of the
263 # function (deleting references may trigger a fresh call to this method)
264  self._objects = objs
265  def get_object_count(self):
266  """Get number of director objects (useful for testing only)"""
267  return len(self._objects)
268 _director_objects = _DirectorObjects()
269 
270 class _ostream(object):
271  """Proxy of C++ std::ostream class."""
272 
273  thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
274 
275  def __init__(self, *args, **kwargs):
276  raise AttributeError("No constructor defined")
277  __repr__ = _swig_repr
278 
279  def write(self, osa_buf):
280  """write(_ostream self, char const * osa_buf)"""
281  return _IMP_test._ostream_write(self, osa_buf)
282 
283 _ostream_swigregister = _IMP_test._ostream_swigregister
284 _ostream_swigregister(_ostream)
285 
286 IMP_COMPILER_HAS_OVERRIDE = _IMP_test.IMP_COMPILER_HAS_OVERRIDE
287 IMP_COMPILER_HAS_FINAL = _IMP_test.IMP_COMPILER_HAS_FINAL
288 IMP_HAS_NOEXCEPT = _IMP_test.IMP_HAS_NOEXCEPT
289 IMP_C_OPEN_BINARY = _IMP_test.IMP_C_OPEN_BINARY
290 import IMP
291 IMP_TEST_HAS_BOOST_FILESYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_FILESYSTEM
292 IMP_TEST_HAS_BOOST_PROGRAMOPTIONS = _IMP_test.IMP_TEST_HAS_BOOST_PROGRAMOPTIONS
293 IMP_TEST_HAS_BOOST_RANDOM = _IMP_test.IMP_TEST_HAS_BOOST_RANDOM
294 IMP_TEST_HAS_BOOST_SYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_SYSTEM
295 IMP_TEST_HAS_NUMPY = _IMP_test.IMP_TEST_HAS_NUMPY
296 IMPTEST_SHOW_WARNINGS = _IMP_test.IMPTEST_SHOW_WARNINGS
297 
298 
299 """@namespace IMP::test
300  @brief Methods and classes for testing the IMP kernel and modules.
301  @ingroup python
302 """
303 
304 import re, math
305 import sys
306 import os
307 import re
308 import tempfile
309 import random
310 import IMP
311 import time
312 import types
313 import shutil
314 import difflib
315 import pprint
316 from . import _compat_python
317 from ._compat_python import unittest2
318 from ._compat_python.unittest2.util import safe_repr
319 import datetime
320 import pickle
321 import contextlib
322 
323 # Fall back to the sets.Set class on older Pythons that don't have
324 # the 'set' builtin type.
325 try:
326  set = set
327 except NameError:
328  import sets
329  set = sets.Set
330 
331 # Load a new enough unittest package (should have the 'skip' decorator)
332 # - On Python 2.7 or 3.2, the standard 'unittest' package will work.
333 # - On older Pythons, use the 'unittest2' package if available, otherwise use
334 # our bundled version of this package.
335 def __load_unittest_package():
336  errors = []
337  for modname, fromlist in (('unittest', []),
338  ('unittest2', []),
339  ):
340  try:
341  u = __import__(modname, {}, {}, fromlist)
342  if hasattr(u, 'skip'):
343  return u
344  else:
345  errors.append("'%s' does not have the 'skip' decorator" \
346  % modname)
347  except ImportError as e:
348  errors.append(str(e))
349 #u = __import__("_compat_python.unittest2
350  return _compat_python.unittest2
351  raise ImportError("IMP.test requires a newer version of Python's unittest "
352  "package than is available. Either upgrade to a new "
353  "enough Python (at least 2.7 or 3.2) or install the "
354  "unittest2 package. Encountered errors: %s" \
355  % "; ".join(errors))
356 unittest = __load_unittest_package()
357 
358 # Expose some unittest decorators for convenience
359 expectedFailure = unittest.expectedFailure
360 skip = unittest.skip
361 skipIf = unittest.skipIf
362 skipUnless = unittest.skipUnless
363 
364 class _TempDir(object):
365  def __init__(self, dir=None):
366  self.tmpdir = tempfile.mkdtemp(dir=dir)
367  def __del__(self):
368  shutil.rmtree(self.tmpdir, ignore_errors=True)
369 
370 @contextlib.contextmanager
372  """Simple context manager to run in a temporary directory.
373  While the context manager is active (within the 'with' block)
374  the current working directory is set to a temporary directory.
375  When the context manager exists, the working directory is reset
376  and the temporary directory deleted."""
377  origdir = os.getcwd()
378  tmpdir = tempfile.mkdtemp()
379  os.chdir(tmpdir)
380  yield tmpdir
381  os.chdir(origdir)
382  shutil.rmtree(tmpdir, ignore_errors=True)
383 
384 @contextlib.contextmanager
385 def temporary_directory(dir=None):
386  """Simple context manager to make a temporary directory.
387  The temporary directory has the same lifetime as the context manager
388  (i.e. it is created at the start of the 'with' block, and deleted
389  at the end of the block).
390  @param dir If given, the temporary directory is made as a subdirectory
391  of that directory, rather than in the default temporary
392  directory location (e.g. /tmp)
393  @return the full path to the temporary directory.
394  """
395  tmpdir = tempfile.mkdtemp(dir=dir)
396  yield tmpdir
397  shutil.rmtree(tmpdir, ignore_errors=True)
398 
399 def numerical_derivative(func, val, step):
400  """Calculate the derivative of the single-value function `func` at
401  point `val`. The derivative is calculated using simple finite
402  differences starting with the given `step`; Richardson extrapolation
403  is then used to extrapolate the derivative at step=0."""
404  maxsteps = 50
405  con = 1.4
406  safe = 2.0
407  err = 1.0e30
408  f1 = func(val + step)
409  f2 = func(val - step)
410 # create first element in triangular matrix d of derivatives
411  d = [[(f1 - f2) / (2.0 * step)]]
412  retval = None
413  for i in range(1, maxsteps):
414  d.append([0.] * (i + 1))
415  step /= con
416  f1 = func(val + step)
417  f2 = func(val - step)
418  d[i][0] = (f1 - f2) / (2.0 * step)
419  fac = con * con
420  for j in range(1, i + 1):
421  d[i][j] = (d[i][j-1] * fac - d[i-1][j-1]) / (fac - 1.)
422  fac *= con * con
423  errt = max(abs(d[i][j] - d[i][j-1]),
424  abs(d[i][j] - d[i-1][j-1]))
425  if errt <= err:
426  err = errt
427  retval = d[i][j]
428  if abs(d[i][i] - d[i-1][i-1]) >= safe * err:
429  break
430  if retval is None:
431  raise ValueError("Cannot calculate numerical derivative")
432  return retval
433 
434 
435 def xyz_numerical_derivatives(sf, xyz, step):
436  """Calculate the x,y and z derivatives of the scoring function `sf`
437  on the `xyz` particle. The derivatives are approximated numerically
438  using the numerical_derivatives() function."""
439  class _XYZDerivativeFunc(object):
440  def __init__(self, sf, xyz, basis_vector):
441  self._xyz = xyz
442  self._sf = sf
443  self._basis_vector = basis_vector
444  self._starting_coordinates = xyz.get_coordinates()
445 
446  def __call__(self, val):
447  self._xyz.set_coordinates(self._starting_coordinates + \
448  self._basis_vector * val)
449  return self._sf.evaluate(False)
450 
451  return tuple([IMP.test.numerical_derivative(_XYZDerivativeFunc(sf, xyz,
452  IMP.algebra.Vector3D(*x)), 0, 0.01) \
453  for x in ((1,0,0), (0,1,0), (0,0,1))])
454 
455 
456 class TestCase(unittest.TestCase):
457  """Super class for IMP test cases.
458  This provides a number of useful IMP-specific methods on top of
459  the standard Python `unittest.TestCase` class.
460  Test scripts should generally contain a subclass of this class,
461  conventionally called `Tests` (this makes it easier to run an
462  individual test from the command line) and use IMP::test::main()
463  as their main function."""
464 
465 # Provide assert(Not)Regex for Python 2 users (assertRegexMatches is
466 # deprecated in Python 3)
467  if not hasattr(unittest.TestCase, 'assertRegex'):
468  assertRegex = unittest.TestCase.assertRegexpMatches
469  assertNotRegex = unittest.TestCase.assertNotRegexpMatches
470 
471  def __init__(self, *args, **keys):
472  unittest.TestCase.__init__(self, *args, **keys)
473  self._progname = os.path.abspath(sys.argv[0])
474 
475  def setUp(self):
476  self.__check_level = IMP.get_check_level()
477 # Turn on expensive runtime checks while running the test suite:
478  IMP.set_check_level(IMP.USAGE_AND_INTERNAL)
479 # python ints are bigger than C++ ones, so we need to make sure it fits
480 # otherwise python throws fits
481  IMP.random_number_generator.seed(hash(time.time())%2**30)
482 
483  def tearDown(self):
484 # Restore original check level
485  IMP.set_check_level(self.__check_level)
486 # Clean up any temporary files
487  if hasattr(self, '_tmpdir'):
488  del self._tmpdir
489 
490  def get_input_file_name(self, filename):
491  """Get the full name of an input file in the top-level
492  test directory."""
493  testdir = os.path.dirname(self._progname)
494  if self.__module__ != '__main__':
495  testdir = os.path.dirname(sys.modules[self.__module__].__file__)
496  dirs = testdir.split(os.path.sep)
497  for i in range(len(dirs), 0, -1):
498  input = os.path.sep.join(dirs[:i] + ['input'])
499  if os.path.isdir(input):
500  ret = os.path.join(input, filename)
501  if not os.path.exists(ret):
502  raise IOError("Test input file "+ret+" does not exist")
503  return ret
504  raise IOError("No test input directory found")
505 
506  def open_input_file(self, filename, mode='rb'):
507  """Open and return an input file in the top-level test directory."""
508  return open(self.get_input_file_name(filename), mode)
509 
510  def get_tmp_file_name(self, filename):
511  """Get the full name of an output file in the tmp directory.
512  The directory containing this file will be automatically
513  cleaned up when the test completes."""
514  if not hasattr(self, '_tmpdir'):
515  self._tmpdir = _TempDir(os.environ.get('IMP_TMP_DIR'))
516  tmpdir = self._tmpdir.tmpdir
517  return os.path.join(tmpdir, filename)
518 
519  def get_magnitude(self, vector):
520  """Get the magnitude of a list of floats"""
521  return sum([x*x for x in vector], 0)**.5
522 
523  def assertRaisesUsageException(self, c, *args, **keys):
524  """Assert that the given callable object raises UsageException.
525  This differs from unittest's assertRaises in that the test
526  is skipped in fast mode (where usage checks are turned off)."""
527  if IMP.get_check_level() >= IMP.USAGE:
528  return self.assertRaises(IMP.UsageException, c, *args, **keys)
529 
530  def assertRaisesInternalException(self, c, *args, **keys):
531  """Assert that the given callable object raises InternalException.
532  This differs from unittest's assertRaises in that the test
533  is skipped in fast mode (where internal checks are turned off)."""
534  if IMP.get_check_level() >= IMP.USAGE_AND_INTERNAL:
535  return self.assertRaises(IMP.InternalException, c, *args, **keys)
536 
537  def assertNotImplemented(self, c, *args, **keys):
538  """Assert that the given callable object is not implemented."""
539  return self.assertRaises(IMP.InternalException, c, *args, **keys)
540 
541  def assertXYZDerivativesInTolerance(self, sf, xyz, tolerance=0,
542  percentage=0):
543  """Assert that x,y,z analytical derivatives match numerical within
544  a tolerance, or a percentage (of the analytical value), whichever
545  is larger. `sf` should be a ScoringFunction or Restraint,
546  although for backwards compatibility a Model is also accepted."""
547  sf.evaluate(True)
548  derivs = xyz.get_derivatives()
549  num_derivs = xyz_numerical_derivatives(sf, xyz, 0.01)
550  pct = percentage / 100.0
551  self.assertAlmostEqual(self.get_magnitude(derivs-num_derivs),0,
552  delta=tolerance+percentage*self.get_magnitude(num_derivs),
553  msg="Don't match "+str(derivs) + str(num_derivs))
554  self.assertAlmostEqual(derivs[0], num_derivs[0],
555  delta=max(tolerance, abs(derivs[0]) * pct))
556  self.assertAlmostEqual(derivs[1], num_derivs[1],
557  delta=max(tolerance, abs(derivs[1]) * pct))
558  self.assertAlmostEqual(derivs[2], num_derivs[2],
559  delta=max(tolerance, abs(derivs[2]) * pct))
560 
561  def assertSequenceAlmostEqual(self, first, second, places=None, msg=None,
562  delta=None):
563  """Fail if the difference between any two items in the two sequences
564  are exceed the specified number of places or delta. See
565  `assertAlmostEqual`.
566  """
567  if delta is not None and places is not None:
568  raise TypeError("specify delta or places not both")
569 
570  ftype = type(first)
571  ftypename = ftype.__name__
572  stype = type(second)
573  stypename = stype.__name__
574  if ftype != stype:
575  raise self.failureException(
576  'Sequences are of different types: %s != %s' % (
577  ftypename, stypename))
578 
579  try:
580  flen = len(first)
581  except (NotImplementedError, TypeError):
582  raise self.failureException(
583  'First %s has no length' % (ftypename))
584  try:
585  slen = len(second)
586  except (NotImplementedError, TypeError):
587  raise self.failureException(
588  'Second %s has no length' % (stypename))
589 
590  if flen != slen:
591  raise self.failureException(
592  'Sequences have non equal lengths: %d != %d' % (flen, slen))
593 
594  differing = None
595  for i in range(min(flen, slen)):
596  differing = '%ss differ: %s != %s\n' % (
597  ftypename.capitalize(), safe_repr(first),
598  safe_repr(second))
599 
600  try:
601  f = first[i]
602  except (TypeError, IndexError, NotImplementedError):
603  differing += ('\nUnable to index element %d of first %s\n' %
604  (i, ftypename))
605  break
606 
607  try:
608  s = second[i]
609  except (TypeError, IndexError, NotImplementedError):
610  differing += ('\nUnable to index element %d of second %s\n' %
611  (i, stypename))
612  break
613 
614  try:
615  self.assertAlmostEqual(
616  f, s, places=places, msg=msg, delta=delta)
617  except (TypeError, ValueError, NotImplementedError, AssertionError):
618  differing += (
619  "\nFirst differing element "
620  "%d:\n%s\n%s\n") % (i, safe_repr(f), safe_repr(s))
621  break
622  else:
623  return
624 
625  standardMsg = differing
626  diffMsg = '\n' + '\n'.join(
627  difflib.ndiff(pprint.pformat(first).splitlines(),
628  pprint.pformat(second).splitlines()))
629  standardMsg = self._truncateMessage(standardMsg, diffMsg)
630  msg = self._formatMessage(msg, standardMsg)
631  raise self.failureException(msg)
632 
633  def create_point_particle(self, model, x, y, z):
634  """Make a particle with optimizable x, y and z attributes, and
635  add it to the model."""
636  p = IMP.Particle(model)
637  p.add_attribute(IMP.FloatKey("x"), x, True)
638  p.add_attribute(IMP.FloatKey("y"), y, True)
639  p.add_attribute(IMP.FloatKey("z"), z, True)
640  return p
641 
642  def probabilistic_check(self, testcall, chance_of_failure):
643  """Help handle a test which is expected to fail some fraction of
644  the time. The test is run multiple times and an exception
645  is thrown only if it fails too many times.
646  @note Use of this function should be avoided. If there is a corner
647  case that results in a test 'occasionally' failing, write a
648  new test specifically for that corner case and assert that
649  it fails consistently (and remove the corner case from the
650  old test).
651  """
652  prob=chance_of_failure
653  tries=1
654  while prob > .001:
655  tries=tries+1
656  prob= prob*chance_of_failure
657  for i in range(0, tries):
658  try:
659  eval(testcall)
660  except:
661  pass
662  else:
663  return
664  eval(testcall)
665  raise AssertError("Too many failures")
666 
667  def failure_probability(self, testcall):
668  """Estimate how likely a given block of code is to raise an
669  AssertionError."""
670  failures=0
671  tries=0.0
672  while failures < 10 and tries <1000:
673  try:
674  eval(testcall)
675  except:
676  failures=failures+1
677  tries=tries+1
678  return failures/tries
679 
680  def randomize_particles(self, particles, deviation):
681  """Randomize the xyz coordinates of a list of particles"""
682 # Note: cannot use XYZ here since that pulls in IMP.core
683  xkey = IMP.FloatKey("x")
684  ykey = IMP.FloatKey("y")
685  zkey = IMP.FloatKey("z")
686  for p in particles:
687  p.set_value(xkey, random.uniform(-deviation, deviation))
688  p.set_value(ykey, random.uniform(-deviation, deviation))
689  p.set_value(zkey, random.uniform(-deviation, deviation))
690 
691  def particle_distance(self, p1, p2):
692  """Return distance between two given particles"""
693  xkey = IMP.FloatKey("x")
694  ykey = IMP.FloatKey("y")
695  zkey = IMP.FloatKey("z")
696  dx = p1.get_value(xkey) - p2.get_value(xkey)
697  dy = p1.get_value(ykey) - p2.get_value(ykey)
698  dz = p1.get_value(zkey) - p2.get_value(zkey)
699  return math.sqrt(dx*dx + dy*dy + dz*dz)
700 
701  def check_unary_function_deriv(self, func, lb, ub, step):
702  """Check the unary function func's derivatives against numerical
703  approximations between lb and ub"""
704  for f in [lb + i * step for i in range(1, int((ub-lb)/step))]:
705  (v,d)= func.evaluate_with_derivative(f)
706  da = numerical_derivative(func.evaluate, f, step / 10.)
707  self.assertAlmostEqual(d, da, delta=max(abs(.1 *d), 0.01))
708 
709  def check_unary_function_min(self, func, lb, ub, step, expected_fmin):
710  """Make sure that the minimum of the unary function func over the
711  range between lb and ub is at expected_fmin"""
712  fmin, vmin = lb, func.evaluate(lb)
713  for f in [lb + i * step for i in range(1, int((ub-lb)/step))]:
714  v = func.evaluate(f)
715  if v < vmin:
716  fmin, vmin = f, v
717  self.assertAlmostEqual(fmin, expected_fmin, delta=step)
718 
720  """Check methods that every IMP::Object class should have"""
721  obj.set_was_used(True)
722 # Test get_from static method
723  cls = type(obj)
724  self.assertIsNotNone(cls.get_from(obj))
725  self.assertRaises(ValueError, cls.get_from, IMP.Model())
726 # Test __str__ and __repr__
727  self.assertIsInstance(str(obj), str)
728  self.assertIsInstance(repr(obj), str)
729 # Test get_version_info()
730  verinf = obj.get_version_info()
731  self.assertIsInstance(verinf, IMP.VersionInfo)
732 # Test SWIG thisown flag
733  o = obj.thisown
734  obj.thisown = o
735 
736  def create_particles_in_box(self, model, num=10,
737  lb= [0,0,0],
738  ub= [10,10,10]):
739  """Create a bunch of particles in a box"""
740  import IMP.algebra
741  lbv=IMP.algebra.Vector3D(lb[0],lb[1],lb[2])
742  ubv=IMP.algebra.Vector3D(ub[0],ub[1],ub[2])
743  ps= []
744  for i in range(0,num):
746  p = self.create_point_particle(model, v[0], v[1], v[2])
747  ps.append(p)
748  return ps
749  def _get_type(self, module, name):
750  return eval('type('+module+"."+name+')')
751  def assertValueObjects(self, module, exceptions_list):
752  "Check that all the C++ classes in the module are values or objects."
753  all= dir(module)
754  ok = set(exceptions_list + module._value_types + module._object_types + module._raii_types + module._plural_types)
755 
756  bad=[]
757  for name in all:
758  if self._get_type(module.__name__, name)==type and not name.startswith("_"):
759  if name.find("SwigPyIterator") != -1:
760  continue
761 # Exclude Python-only classes
762  if not eval('hasattr(%s.%s, "__swig_destroy__")' \
763  % (module.__name__, name)):
764  continue
765  if name in ok:
766  continue
767  bad.append(name)
768  message="All IMP classes should be labeled as values or objects to get memory management correct in Python. The following are not:\n%s\nPlease add an IMP_SWIG_OBJECT or IMP_SWIG_VALUE call to the Python wrapper, or if the class has a good reason to be neither, add the name to the value_object_exceptions list in the IMPModuleTest call." \
769  % (str(bad))
770  self.assertEqual(len(bad), 0, message)
771  for e in exceptions_list:
772  self.assertTrue(e not in module._value_types
773  + module._object_types
774  + module._raii_types
775  + module._plural_types,
776  "Value/Object exception "+e+" is not an exception")
777 
778  def _check_spelling(self, word, words):
779  """Check that the word is spelled correctly"""
780  if "words" not in dir(self):
781  with open(IMP.test.get_data_path("linux.words"), "r") as fh:
782  wordlist= fh.read().split("\n")
783 # why is "all" missing on my mac?
784  custom_words=["info", "prechange", "int", "ints", "optimizeds", "graphviz",
785  "voxel", "voxels", "endian", 'rna', 'dna',
786  "xyzr", "pdbs", "fft", "ccc", "gaussian"]
787 # Exclude some common alternative spellings - we want to
788 # be consistent
789  exclude_words = set(["adapter", "grey"])
790  self.words=set(wordlist+custom_words) - exclude_words
791  if self.words:
792  for i in "0123456789":
793  if i in word:
794  return True
795  if word in words:
796  return True
797  if word in self.words:
798  return True
799  else:
800  return False
801  else:
802  return True
803  def assertClassNames(self, module, exceptions, words):
804  """Check that all the classes in the module follow the IMP
805  naming conventions."""
806  all= dir(module)
807  misspelled = []
808  bad=[]
809  cc=re.compile("([A-Z][a-z]*)")
810  for name in all:
811  if self._get_type(module.__name__, name)==type and not name.startswith("_"):
812  if name.find("SwigPyIterator") != -1:
813  continue
814  for t in re.findall(cc, name):
815  if not self._check_spelling(t.lower(), words):
816  misspelled.append(t.lower())
817  bad.append(name)
818 
819  self.assertEqual(len(bad), 0,
820  "All IMP classes should be properly spelled. The following are not: %s.\nMisspelled words: %s. Add words to the spelling_exceptions variable of the IMPModuleTest if needed." \
821  % (str(bad), ", ".join(set(misspelled))))
822 
823  for name in all:
824  if self._get_type(module.__name__, name)==type and not name.startswith("_"):
825  if name.find("SwigPyIterator") != -1:
826  continue
827  if name.find('_') != -1:
828  bad.append(name)
829  if name.lower== name:
830  bad.append(name)
831  for t in re.findall(cc, name):
832  if not self._check_spelling(t.lower(), words):
833  print("misspelled %s in %s" % (t, name))
834  bad.append(name)
835  message="All IMP classes should have CamelCase names. The following do not: %s." \
836  % ("\n".join(bad))
837  self.assertEqual(len(bad), 0, message)
838 
839  def _check_function_name(self, prefix, name, verbs, all, exceptions, words,
840  misspelled):
841  if prefix:
842  fullname=prefix+"."+name
843  else:
844  fullname=name
845  old_exceptions=['unprotected_evaluate', "unprotected_evaluate_if_good",
846  "unprotected_evaluate_if_below",
847  "after_evaluate", "before_evaluate", "has_attribute",
848  "decorate_particle","particle_is_instance"]
849  if name in old_exceptions:
850  return []
851 #print "name", fullname
852  if fullname in exceptions:
853  return []
854  if name.endswith("swigregister"):
855  return []
856  if name.lower() != name:
857  if name[0].lower() != name[0] and name.split('_')[0] in all:
858 # static methods
859  return []
860  else:
861  return [fullname]
862  tokens= name.split("_")
863  if tokens[0] not in verbs:
864  return [fullname]
865  for t in tokens:
866  if not self._check_spelling(t, words):
867  misspelled.append(t)
868  print("misspelled %s in %s" % (t, name))
869  return [fullname]
870  return []
871 
872  def _static_method(self, module, prefix, name):
873  """For static methods of the form Foo.bar SWIG creates free functions
874  named Foo_bar. Exclude these from spelling checks since the method
875  Foo.bar has already been checked."""
876  if prefix is None and '_' in name:
877  modobj = eval(module)
878  cls, meth = name.split('_', 1)
879  if hasattr(modobj, cls):
880  clsobj = eval(module + '.' + cls)
881  if hasattr(clsobj, meth):
882  return True
883 
884  def _check_function_names(self, module, prefix, names, verbs, all,
885  exceptions, words, misspelled):
886  bad=[]
887  for name in names:
888  typ = self._get_type(module, name)
889  if name.startswith("_") or name =="weakref_proxy":
890  continue
891  if typ in (types.BuiltinMethodType, types.MethodType) \
892  or (typ == types.FunctionType and \
893  not self._static_method(module, prefix, name)):
894  bad.extend(self._check_function_name(prefix, name, verbs, all,
895  exceptions, words,
896  misspelled))
897  if typ == type and "SwigPyIterator" not in name:
898  members=eval("dir("+module+"."+name+")")
899  bad.extend(self._check_function_names(module+"."+name,
900  name, members, verbs, [],
901  exceptions, words,
902  misspelled))
903  return bad
904 
905  def assertFunctionNames(self, module, exceptions, words):
906  """Check that all the functions in the module follow the IMP
907  naming conventions."""
908  all= dir(module)
909  verbs=set(["add", "remove", "get", "set", "evaluate", "compute", "show", "create", "destroy",
910  "push", "pop", "write", "read", "do", "show", "load", "save", "reset",
911  "accept", "reject",
912  "clear", "handle", "update", "apply", "optimize", "reserve", "dump",
913  "propose", "setup", "teardown", "visit", "find", "run", "swap", "link",
914  "validate"])
915  misspelled = []
916  bad=self._check_function_names(module.__name__, None, all, verbs, all, exceptions, words, misspelled)
917  message="All IMP methods and functions should have lower case names separated by underscores and beginning with a verb, preferably one of ['add', 'remove', 'get', 'set', 'create', 'destroy']. Each of the words should be a properly spelled English word. The following do not (given our limited list of verbs that we check for):\n%(bad)s\nIf there is a good reason for them not to (eg it does start with a verb, just one with a meaning that is not covered by the normal list), add them to the function_name_exceptions variable in the standards_exceptions file. Otherwise, please fix. The current verb list is %(verbs)s" \
918  % {"bad":"\n".join(bad), "verbs":verbs}
919  if len(misspelled) > 0:
920  message += "\nMisspelled words: " + ", ".join(set(misspelled)) \
921  + ". Add words to the spelling_exceptions variable " \
922  + "of the standards_exceptions file if needed."
923  self.assertEqual(len(bad), 0, message)
924 
925 
926  def assertShow(self, modulename, exceptions):
927  """Check that all the classes in modulename have a show method"""
928  all= dir(modulename)
929  not_found=[]
930  for f in all:
931 # Exclude SWIG C global variables object
932  if f == 'cvar':
933  continue
934 # Exclude Python-only classes; they are all showable
935  if not eval('hasattr(%s.%s, "__swig_destroy__")' \
936  % (modulename.__name__, f)):
937  continue
938  if self._get_type(modulename.__name__, f) == type \
939  and not f.startswith("_") \
940  and not f.endswith("_swigregister")\
941  and f not in exceptions\
942  and not f.endswith("Temp") and not f.endswith("Iterator")\
943  and not f.endswith("Exception") and\
944  f not in modulename._raii_types and \
945  f not in modulename._plural_types:
946  if not hasattr(getattr(modulename, f), 'show'):
947  not_found.append(f)
948  message="All IMP classes should support show and __str__. The following do not:\n%s\n If there is a good reason for them not to, add them to the show_exceptions variable in the IMPModuleTest call. Otherwise, please fix." \
949  % "\n".join(not_found)
950  self.assertEqual(len(not_found), 0, message)
951  for e in exceptions:
952  self.assertIn(e, all, "Show exception "+e+" is not a class in module")
953  self.assertTrue(not hasattr(getattr(modulename, e), 'show'),
954  "Exception "+e+" is not really a show exception")
955 
956  def run_example(self, filename):
957  """Run the named example script.
958  @return a dictionary of all the script's global variables.
959  This can be queried in a test case to make sure
960  the example performed correctly."""
961  class _FatalError(Exception): pass
962 
963 # Add directory containing the example to sys.path, so it can import
964 # other Python modules in the same directory
965  path, name = os.path.split(filename)
966  oldsyspath = sys.path[:]
967  olssysargv= sys.argv[:]
968  sys.path.insert(0, path)
969  sys.argv=[filename]
970  vars = {}
971  try:
972  try:
973  exec(open(filename).read(), vars)
974 # Catch sys.exit() called from within the example; a non-zero exit
975 # value should cause the test case to fail
976  except SystemExit as e:
977  if e.code != 0 and e.code is not None:
978  raise _FatalError("Example exit with code %s" % str(e.code))
979  finally:
980 # Restore sys.path (note that Python 2.3 does not allow
981 # try/except/finally, so we need to use nested trys)
982  sys.path = oldsyspath
983  sys.argv= olssysargv
984 
985  return _ExecDictProxy(vars)
986 
987  def run_python_module(self, module, args):
988  """Run a Python module as if with "python -m <modname>",
989  with the given list of arguments as sys.argv.
990 
991  If module is an already-imported Python module, run its 'main'
992  function and return the result.
993 
994  If module is a string, run the module in a subprocess and return
995  a subprocess.Popen-like object containing the child stdin,
996  stdout and stderr.
997  """
998  def mock_setup_from_argv(*args, **kwargs):
999 # do-nothing replacement for boost command line parser
1000  pass
1001  if type(module) == type(os):
1002  mod = module
1003  else:
1004  mod = __import__(module, {}, {}, [''])
1005  modpath = mod.__file__
1006  if modpath.endswith('.pyc'):
1007  modpath = modpath[:-1]
1008  if type(module) == type(os):
1009  old_sys_argv = sys.argv
1010 # boost parser doesn't like being called multiple times per process
1011  old_setup = IMP.setup_from_argv
1012  IMP.setup_from_argv = mock_setup_from_argv
1013  try:
1014  sys.argv = [modpath] + args
1015  return module.main()
1016  finally:
1017  IMP.setup_from_argv = old_setup
1018  sys.argv = old_sys_argv
1019  else:
1020  return _SubprocessWrapper(sys.executable, [modpath] + args)
1021 
1022  def check_runnable_python_module(self, module):
1023  """Check a Python module designed to be runnable with 'python -m'
1024  to make sure it supports standard command line options."""
1025 # --help should return with exit 0, no errors
1026  r = self.run_python_module(module, ['--help'])
1027  out, err = r.communicate()
1028  self.assertEqual(r.returncode, 0)
1029  self.assertNotEqual(err, "")
1030  self.assertEqual(out, "")
1031 
1032 
1033 class _ExecDictProxy(object):
1034  """exec returns a Python dictionary, which contains IMP objects, other
1035  Python objects, as well as base Python modules (such as sys and
1036  __builtins__). If we just delete this dictionary, it is entirely
1037  possible that base Python modules are removed from the dictionary
1038  *before* some IMP objects. This will prevent the IMP objects' Python
1039  destructors from running properly, so C++ objects will not be
1040  cleaned up. This class proxies the base dict class, and on deletion
1041  attempts to remove keys from the dictionary in an order that allows
1042  IMP destructors to fire."""
1043  def __init__(self, d):
1044  self._d = d
1045  def __del__(self):
1046 # Try to release example objects in a sensible order
1047  module_type = type(IMP)
1048  d = self._d
1049  for k in d.keys():
1050  if type(d[k]) != module_type:
1051  del d[k]
1052 
1053  for meth in ['__contains__', '__getitem__', '__iter__', '__len__',
1054  'get', 'has_key', 'items', 'keys', 'values']:
1055  exec("def %s(self, *args, **keys): "
1056  "return self._d.%s(*args, **keys)" % (meth, meth))
1057 
1058 
1059 class _TestResult(unittest.TextTestResult):
1060 
1061  def __init__(self, stream=None, descriptions=None, verbosity=None):
1062  super(_TestResult, self).__init__(stream, descriptions, verbosity)
1063  self.all_tests = []
1064 
1065  def stopTestRun(self):
1066  if 'IMP_TEST_DETAIL_DIR' in os.environ:
1067  fname = os.path.join(os.environ['IMP_TEST_DETAIL_DIR'],
1068  os.path.basename(sys.argv[0]))
1069  with open(fname, 'wb') as fh:
1070  pickle.dump(self.all_tests, fh, -1)
1071  super(_TestResult, self).stopTestRun()
1072 
1073  def startTest(self, test):
1074  super(_TestResult, self).startTest(test)
1075  test.start_time=datetime.datetime.now()
1076 
1077  def _test_finished(self, test, state, detail=None):
1078  delta = datetime.datetime.now() - test.start_time
1079  try:
1080  pv= delta.total_seconds()
1081  except AttributeError:
1082  pv = (float(delta.microseconds) \
1083  + (delta.seconds + delta.days * 24 * 3600) * 10**6) / 10**6
1084  if pv > 1:
1085  self.stream.write("in %.3fs ... " % pv)
1086  if detail is not None and not isinstance(detail, str):
1087  detail = self._exc_info_to_string(detail, test)
1088  test_doc = self.getDescription(test)
1089  test_name = test.id()
1090  if test_name.startswith('__main__.'):
1091  test_name = test_name[9:]
1092  self.all_tests.append({'name': test_name,
1093  'docstring': test_doc,
1094  'time': pv, 'state': state, 'detail': detail})
1095 
1096  def addSuccess(self, test):
1097  self._test_finished(test, 'OK')
1098  super(_TestResult, self).addSuccess(test)
1099 
1100  def addError(self, test, err):
1101  self._test_finished(test, 'ERROR', err)
1102  super(_TestResult, self).addError(test, err)
1103 
1104  def addFailure(self, test, err):
1105  self._test_finished(test, 'FAIL', err)
1106  super(_TestResult, self).addFailure(test, err)
1107 
1108  def addSkip(self, test, reason):
1109  self._test_finished(test, 'SKIP', reason)
1110  super(_TestResult, self).addSkip(test, reason)
1111 
1112  def addExpectedFailure(self, test, err):
1113  self._test_finished(test, 'EXPFAIL', err)
1114  super(_TestResult, self).addExpectedFailure(test, err)
1115 
1116  def addUnexpectedSuccess(self, test):
1117  self._test_finished(test, 'UNEXPSUC')
1118  super(_TestResult, self).addUnexpectedSuccess(test)
1119 
1120  def getDescription(self, test):
1121  doc_first_line = test.shortDescription()
1122  if self.descriptions and doc_first_line:
1123  return doc_first_line
1124  else:
1125  return str(test)
1126 
1127 
1128 class _TestRunner(unittest.TextTestRunner):
1129  def _makeResult(self):
1130  return _TestResult(self.stream, self.descriptions, self.verbosity)
1131 
1132 
1133 def main(*args, **keys):
1134  """Run a set of tests; similar to unittest.main().
1135  Obviates the need to separately import the 'unittest' module, and
1136  ensures that main() is from the same unittest module that the
1137  IMP.test testcases are. In addition, turns on some extra checks
1138  (e.g. trying to use deprecated code will cause an exception
1139  to be thrown)."""
1140  import IMP
1142  return unittest.main(testRunner=_TestRunner, *args, **keys)
1143 
1144 import subprocess
1145 class _SubprocessWrapper(subprocess.Popen):
1146  def __init__(self, app, args, cwd=None):
1147 # For (non-Python) applications to work on Windows, the
1148 # PATH must include the directory containing built DLLs
1149  if sys.platform == 'win32' and app != sys.executable:
1150 # Hack to find the location of build/lib/
1151  libdir = os.environ['PYTHONPATH'].split(';')[0]
1152  env = os.environ.copy()
1153  env['PATH'] += ';' + libdir
1154  else:
1155  env = None
1156  subprocess.Popen.__init__(self, [app]+list(args),
1157  stdin=subprocess.PIPE,
1158  stdout=subprocess.PIPE,
1159  stderr=subprocess.PIPE, env=env, cwd=cwd,
1160  universal_newlines=True)
1161 
1162 
1164  """Super class for simple IMP application test cases"""
1165  def _get_application_file_name(self, filename):
1166 # If we ran from run-all-tests.py, it set an env variable for us with
1167 # the top-level test directory
1168  if sys.platform == 'win32':
1169  filename += '.exe'
1170 #if 'IMP_BUILD_ROOT' in os.environ:
1171 # testdir = os.environ['IMP_BUILD_ROOT']
1172 # return os.path.join(testdir, "build", "bin", filename)
1173  return filename
1174 
1175  def run_application(self, app, args, cwd=None):
1176  """Run an application with the given list of arguments.
1177  @return a subprocess.Popen-like object containing the child stdin,
1178  stdout and stderr.
1179  """
1180  filename = self._get_application_file_name(app)
1181  if sys.platform == 'win32':
1182 # Cannot rely on PATH on wine builds, so use full pathname
1183  return _SubprocessWrapper(os.path.join(os.environ['IMP_BIN_DIR'],
1184  filename), args, cwd=cwd)
1185  else:
1186  return _SubprocessWrapper(filename, args, cwd=cwd)
1187 
1188  def run_python_application(self, app, args):
1189  """Run a Python application with the given list of arguments.
1190  The Python application should be self-runnable (i.e. it should
1191  be executable and with a #! on the first line).
1192  @return a subprocess.Popen-like object containing the child stdin,
1193  stdout and stderr.
1194  """
1195 # Handle platforms where /usr/bin/python doesn't work
1196  if sys.executable != '/usr/bin/python' and 'IMP_BIN_DIR' in os.environ:
1197  return _SubprocessWrapper(sys.executable,
1198  [os.path.join(os.environ['IMP_BIN_DIR'], app)] + args)
1199  else:
1200  return _SubprocessWrapper(app, args)
1201 
1203  """Import an installed Python application, rather than running it.
1204  This is useful to directly test components of the application.
1205  @return the Python module object."""
1206  try:
1207  import importlib.machinery
1208  imp = None
1209  except ImportError:
1210  import imp
1211  name = os.path.splitext(app)[0]
1212  pathname = os.path.join(os.environ['IMP_BIN_DIR'], app)
1213  if imp is None:
1214  return importlib.machinery.SourceFileLoader(name,
1215  pathname).load_module()
1216  else:
1217  return imp.load_source(name, pathname)
1218 
1219  def run_script(self, app, args):
1220  """Run an application with the given list of arguments.
1221  @return a subprocess.Popen-like object containing the child stdin,
1222  stdout and stderr.
1223  """
1224  return _SubprocessWrapper(sys.executable, [app]+args)
1225 
1226  def assertApplicationExitedCleanly(self, ret, error):
1227  """Assert that the application exited cleanly (return value = 0)."""
1228  if ret < 0:
1229  raise OSError("Application exited with signal %d\n" % -ret\
1230  +error)
1231  else:
1232  self.assertEqual(ret, 0,
1233  "Application exited uncleanly, with exit code %d\n" % ret\
1234  + error)
1235 
1236  def read_shell_commands(self, doxfile):
1237  """Read and return a set of shell commands from a doxygen file.
1238  Each command is assumed to be in a \code{.sh}...\endcode block.
1239  The doxygen file is specified relative to the test file itself.
1240  This is used to make sure the commands shown in an application
1241  example actually work (the testcase can also check the resulting
1242  files for correctness)."""
1243  def win32_normpath(p):
1244 # Sometimes Windows can read Unix-style paths, but sometimes it
1245 # gets confused... so normalize all paths to be sure
1246  return " ".join([os.path.normpath(x) for x in p.split()])
1247  def fix_win32_command(cmd):
1248 # Make substitutions so a Unix shell command works on Windows
1249  if cmd.startswith('cp -r '):
1250  return 'xcopy /E ' + win32_normpath(cmd[6:])
1251  elif cmd.startswith('cp '):
1252  return 'copy ' + win32_normpath(cmd[3:])
1253  else:
1254  return cmd
1255  d = os.path.dirname(sys.argv[0])
1256  doc = os.path.join(d, doxfile)
1257  inline = False
1258  cmds = []
1259  example_path = os.path.abspath(IMP.get_example_path('..'))
1260  with open(doc) as fh:
1261  for line in fh.readlines():
1262  if '\code{.sh}' in line:
1263  inline = True
1264  elif '\endcode' in line:
1265  inline = False
1266  elif inline:
1267  cmds.append(line.rstrip('\r\n').replace(
1268  '<imp_example_path>', example_path))
1269  if sys.platform == 'win32':
1270  cmds = [fix_win32_command(x) for x in cmds]
1271  return cmds
1272 
1273  def run_shell_command(self, cmd):
1274  "Print and run a shell command, as returned by read_shell_commands()"
1275  import subprocess
1276  print(cmd)
1277  p = subprocess.call(cmd, shell=True)
1278  if p != 0:
1279  raise OSError("%s failed with exit value %d" % (cmd, p))
1280 
1281 
1282 class RefCountChecker(object):
1283  """Check to make sure the number of C++ object references is as expected"""
1284 
1285  def __init__(self, testcase):
1286 # Make sure no director objects are hanging around; otherwise these
1287 # may be unexpectedly garbage collected later, decreasing the
1288 # live object count
1289  IMP._director_objects.cleanup()
1290  self.__testcase = testcase
1291  if IMP.get_check_level() >= IMP.USAGE_AND_INTERNAL:
1292  self.__basenum = IMP.Object.get_number_of_live_objects()
1293  self.__names= IMP.get_live_object_names()
1294 
1295  def assert_number(self, expected):
1296  "Make sure that the number of references matches the expected value."
1297  t = self.__testcase
1298  IMP._director_objects.cleanup()
1299  if IMP.get_check_level() >= IMP.USAGE_AND_INTERNAL:
1300  newnames=[x for x in IMP.get_live_object_names() if x not in self.__names]
1301  newnum=IMP.Object.get_number_of_live_objects()-self.__basenum
1302  t.assertEqual(newnum, expected,
1303  "Number of objects don't match: "\
1304  +str(newnum)\
1305  +" != "+ str(expected) +" found "+\
1306  str(newnames))
1307 
1308 
1309 
1311  """Check to make sure the number of director references is as expected"""
1312 
1313  def __init__(self, testcase):
1314  IMP._director_objects.cleanup()
1315  self.__testcase = testcase
1316  self.__basenum = IMP._director_objects.get_object_count()
1317 
1318  def assert_number(self, expected, force_cleanup=True):
1319  """Make sure that the number of references matches the expected value.
1320  If force_cleanup is set, clean up any unused references first before
1321  doing the assertion.
1322  """
1323  t = self.__testcase
1324  if force_cleanup:
1325  IMP._director_objects.cleanup()
1326  t.assertEqual(IMP._director_objects.get_object_count() \
1327  - self.__basenum, expected)
1328 
1329 # Make sure that the IMP binary directory (build/bin) is in the PATH, if
1330 # we're running under wine (the imppy.sh script normally ensures this, but
1331 # wine overrides the PATH). This is needed so that tests of imported Python
1332 # applications can successfully spawn C++ applications (e.g. idock.py tries
1333 # to run recompute_zscore.exe). build/lib also needs to be in the PATH, since
1334 # that's how Windows locates dependent DLLs such as libimp.dll.
1335 if sys.platform == 'win32' and 'PYTHONPATH' in os.environ \
1336  and 'IMP_BIN_DIR' in os.environ:
1337  libdir = os.environ['PYTHONPATH'].split(';')[0]
1338  bindir = os.environ['IMP_BIN_DIR']
1339  path = os.environ['PATH']
1340  if libdir not in path or bindir not in path:
1341  os.environ['PATH'] = bindir + ';' + libdir + ';' + path
1342 
1343 
1344 def get_module_version():
1345  """get_module_version() -> std::string const"""
1346  return _IMP_test.get_module_version()
1347 
1348 def get_example_path(fname):
1349  """get_example_path(std::string fname) -> std::string"""
1350  return _IMP_test.get_example_path(fname)
1351 
1352 def get_data_path(fname):
1353  """get_data_path(std::string fname) -> std::string"""
1354  return _IMP_test.get_data_path(fname)
1355 
1356 from . import _version_check
1357 _version_check.check_version(get_module_version())
1358 __version__ = get_module_version()
1359 
1360 
1361 
def run_python_module
Run a Python module as if with "python -m <modname>", with the given list of arguments as sys...
def temporary_working_directory
Simple context manager to run in a temporary directory.
def assertApplicationExitedCleanly
Assert that the application exited cleanly (return value = 0).
CheckLevel get_check_level()
Get the current audit mode.
Definition: exception.h:81
def import_python_application
Import an installed Python application, rather than running it.
def open_input_file
Open and return an input file in the top-level test directory.
def run_application
Run an application with the given list of arguments.
def randomize_particles
Randomize the xyz coordinates of a list of particles.
A general exception for an internal error in IMP.
Definition: exception.h:102
def main
Run a set of tests; similar to unittest.main().
An exception for an invalid usage of IMP.
Definition: exception.h:123
Super class for simple IMP application test cases.
def assertRaisesInternalException
Assert that the given callable object raises InternalException.
std::string get_example_path(std::string file_name)
Return the full path to one of this module's example files.
def assert_number
Make sure that the number of references matches the expected value.
Check to make sure the number of director references is as expected.
def assertShow
Check that all the classes in modulename have a show method.
def run_shell_command
Print and run a shell command, as returned by read_shell_commands()
def assertRaisesUsageException
Assert that the given callable object raises UsageException.
Vector3D get_random_vector_in(const Cylinder3D &c)
Generate a random vector in a cylinder with uniform density.
def assertSequenceAlmostEqual
Fail if the difference between any two items in the two sequences are exceed the specified number of ...
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:72
def run_python_application
Run a Python application with the given list of arguments.
def assert_number
Make sure that the number of references matches the expected value.
Strings get_live_object_names()
Return the names of all live objects.
def check_standard_object_methods
Check methods that every IMP::Object class should have.
def particle_distance
Return distance between two given particles.
def check_unary_function_deriv
Check the unary function func's derivatives against numerical approximations between lb and ub...
def get_tmp_file_name
Get the full name of an output file in the tmp directory.
Version and module information for Objects.
Definition: VersionInfo.h:28
def run_example
Run the named example script.
def get_magnitude
Get the magnitude of a list of floats.
void set_deprecation_exceptions(bool tf)
Toggle whether an exception is thrown when a deprecated method is used.
def check_unary_function_min
Make sure that the minimum of the unary function func over the range between lb and ub is at expected...
def probabilistic_check
Help handle a test which is expected to fail some fraction of the time.
def create_particles_in_box
Create a bunch of particles in a box.
General purpose algebraic and geometric methods that are expected to be used by a wide variety of IMP...
def assertNotImplemented
Assert that the given callable object is not implemented.
The general base class for IMP exceptions.
Definition: exception.h:49
def numerical_derivative
Calculate the derivative of the single-value function func at point val.
std::string get_example_path(std::string file_name)
Return the full path to one of this module's example files.
def xyz_numerical_derivatives
Calculate the x,y and z derivatives of the scoring function sf on the xyz particle.
def failure_probability
Estimate how likely a given block of code is to raise an AssertionError.
VectorD< 3 > Vector3D
Definition: VectorD.h:421
def assertClassNames
Check that all the classes in the module follow the IMP naming conventions.
def create_point_particle
Make a particle with optimizable x, y and z attributes, and add it to the model.
Class to handle individual particles of a Model object.
Definition: Particle.h:41
def read_shell_commands
Read and return a set of shell commands from a doxygen file.
std::string get_data_path(std::string file_name)
Return the full path to one of this module's data files.
Check to make sure the number of C++ object references is as expected.
def assertFunctionNames
Check that all the functions in the module follow the IMP naming conventions.
def assertValueObjects
Check that all the C++ classes in the module are values or objects.
Super class for IMP test cases.
def assertXYZDerivativesInTolerance
Assert that x,y,z analytical derivatives match numerical within a tolerance, or a percentage (of the ...
def temporary_directory
Simple context manager to make a temporary directory.
def run_script
Run an application with the given list of arguments.
def get_input_file_name
Get the full name of an input file in the top-level test directory.
def check_runnable_python_module
Check a Python module designed to be runnable with 'python -m' to make sure it supports standard comm...
void set_check_level(CheckLevel tf)
Control runtime checks in the code.
Definition: exception.h:73