10 from __future__
import print_function, division, absolute_import
15 from sys
import version_info
16 if version_info >= (2, 6, 0):
17 def swig_import_helper():
18 from os.path
import dirname
22 fp, pathname, description = imp.find_module(
'_IMP_test', [dirname(__file__)])
28 _mod = imp.load_module(
'_IMP_test', fp, pathname, description)
32 _IMP_test = swig_import_helper()
33 del swig_import_helper
38 _swig_property = property
43 def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
44 if (name ==
"thisown"):
45 return self.this.own(value)
47 if type(value).__name__ ==
'SwigPyObject':
48 self.__dict__[name] = value
50 method = class_type.__swig_setmethods__.get(name,
None)
52 return method(self, value)
54 object.__setattr__(self, name, value)
56 raise AttributeError(
"You cannot add attributes to %s" % self)
59 def _swig_setattr(self, class_type, name, value):
60 return _swig_setattr_nondynamic(self, class_type, name, value, 0)
63 def _swig_getattr_nondynamic(self, class_type, name, static=1):
64 if (name ==
"thisown"):
65 return self.this.own()
66 method = class_type.__swig_getmethods__.get(name,
None)
70 return object.__getattr__(self, name)
72 raise AttributeError(name)
74 def _swig_getattr(self, class_type, name):
75 return _swig_getattr_nondynamic(self, class_type, name, 0)
80 strthis =
"proxy of " + self.this.__repr__()
83 return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
88 except AttributeError:
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)
102 raise AttributeError(
"You cannot add attributes to %s" % self)
108 weakref_proxy = weakref.proxy
110 weakref_proxy =
lambda x: x
113 class IMP_TEST_SwigPyIterator(object):
114 """Proxy of C++ swig::IMP_TEST_SwigPyIterator class"""
115 thisown = _swig_property(
lambda x: x.this.own(),
lambda x, v: x.this.own(v), doc=
'The membership flag')
117 def __init__(self, *args, **kwargs):
118 raise AttributeError(
"No constructor defined - class is abstract")
119 __repr__ = _swig_repr
120 __swig_destroy__ = _IMP_test.delete_IMP_TEST_SwigPyIterator
121 __del__ =
lambda self:
None
124 """value(IMP_TEST_SwigPyIterator self) -> PyObject *"""
125 return _IMP_test.IMP_TEST_SwigPyIterator_value(self)
130 incr(IMP_TEST_SwigPyIterator self, size_t n=1) -> IMP_TEST_SwigPyIterator
131 incr(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator
133 return _IMP_test.IMP_TEST_SwigPyIterator_incr(self, n)
138 decr(IMP_TEST_SwigPyIterator self, size_t n=1) -> IMP_TEST_SwigPyIterator
139 decr(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator
141 return _IMP_test.IMP_TEST_SwigPyIterator_decr(self, n)
144 def distance(self, x):
145 """distance(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> ptrdiff_t"""
146 return _IMP_test.IMP_TEST_SwigPyIterator_distance(self, x)
150 """equal(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
151 return _IMP_test.IMP_TEST_SwigPyIterator_equal(self, x)
155 """copy(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator"""
156 return _IMP_test.IMP_TEST_SwigPyIterator_copy(self)
160 """next(IMP_TEST_SwigPyIterator self) -> PyObject *"""
161 return _IMP_test.IMP_TEST_SwigPyIterator_next(self)
165 """__next__(IMP_TEST_SwigPyIterator self) -> PyObject *"""
166 return _IMP_test.IMP_TEST_SwigPyIterator___next__(self)
170 """previous(IMP_TEST_SwigPyIterator self) -> PyObject *"""
171 return _IMP_test.IMP_TEST_SwigPyIterator_previous(self)
174 def advance(self, n):
175 """advance(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
176 return _IMP_test.IMP_TEST_SwigPyIterator_advance(self, n)
180 """__eq__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
181 return _IMP_test.IMP_TEST_SwigPyIterator___eq__(self, x)
185 """__ne__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
186 return _IMP_test.IMP_TEST_SwigPyIterator___ne__(self, x)
189 def __iadd__(self, n):
190 """__iadd__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
191 return _IMP_test.IMP_TEST_SwigPyIterator___iadd__(self, n)
194 def __isub__(self, n):
195 """__isub__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
196 return _IMP_test.IMP_TEST_SwigPyIterator___isub__(self, n)
199 def __add__(self, n):
200 """__add__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
201 return _IMP_test.IMP_TEST_SwigPyIterator___add__(self, n)
204 def __sub__(self, *args):
206 __sub__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator
207 __sub__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> ptrdiff_t
209 return _IMP_test.IMP_TEST_SwigPyIterator___sub__(self, *args)
213 IMP_TEST_SwigPyIterator_swigregister = _IMP_test.IMP_TEST_SwigPyIterator_swigregister
214 IMP_TEST_SwigPyIterator_swigregister(IMP_TEST_SwigPyIterator)
223 _IMP_test.IMP_DEBUG_swigconstant(_IMP_test)
224 IMP_DEBUG = _IMP_test.IMP_DEBUG
226 _IMP_test.IMP_RELEASE_swigconstant(_IMP_test)
227 IMP_RELEASE = _IMP_test.IMP_RELEASE
229 _IMP_test.IMP_SILENT_swigconstant(_IMP_test)
230 IMP_SILENT = _IMP_test.IMP_SILENT
232 _IMP_test.IMP_PROGRESS_swigconstant(_IMP_test)
233 IMP_PROGRESS = _IMP_test.IMP_PROGRESS
235 _IMP_test.IMP_TERSE_swigconstant(_IMP_test)
236 IMP_TERSE = _IMP_test.IMP_TERSE
238 _IMP_test.IMP_VERBOSE_swigconstant(_IMP_test)
239 IMP_VERBOSE = _IMP_test.IMP_VERBOSE
241 _IMP_test.IMP_MEMORY_swigconstant(_IMP_test)
242 IMP_MEMORY = _IMP_test.IMP_MEMORY
244 _IMP_test.IMP_NONE_swigconstant(_IMP_test)
245 IMP_NONE = _IMP_test.IMP_NONE
247 _IMP_test.IMP_USAGE_swigconstant(_IMP_test)
248 IMP_USAGE = _IMP_test.IMP_USAGE
250 _IMP_test.IMP_INTERNAL_swigconstant(_IMP_test)
251 IMP_INTERNAL = _IMP_test.IMP_INTERNAL
253 _IMP_test.IMP_KERNEL_HAS_LOG4CXX_swigconstant(_IMP_test)
254 IMP_KERNEL_HAS_LOG4CXX = _IMP_test.IMP_KERNEL_HAS_LOG4CXX
256 _IMP_test.IMP_COMPILER_HAS_AUTO_swigconstant(_IMP_test)
257 IMP_COMPILER_HAS_AUTO = _IMP_test.IMP_COMPILER_HAS_AUTO
259 _IMP_test.IMP_COMPILER_HAS_DEBUG_VECTOR_swigconstant(_IMP_test)
260 IMP_COMPILER_HAS_DEBUG_VECTOR = _IMP_test.IMP_COMPILER_HAS_DEBUG_VECTOR
262 _IMP_test.IMP_COMPILER_HAS_UNIQUE_PTR_swigconstant(_IMP_test)
263 IMP_COMPILER_HAS_UNIQUE_PTR = _IMP_test.IMP_COMPILER_HAS_UNIQUE_PTR
265 _IMP_test.IMP_KERNEL_HAS_BOOST_RANDOM_swigconstant(_IMP_test)
266 IMP_KERNEL_HAS_BOOST_RANDOM = _IMP_test.IMP_KERNEL_HAS_BOOST_RANDOM
268 _IMP_test.IMP_KERNEL_HAS_GPERFTOOLS_swigconstant(_IMP_test)
269 IMP_KERNEL_HAS_GPERFTOOLS = _IMP_test.IMP_KERNEL_HAS_GPERFTOOLS
271 _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER_swigconstant(_IMP_test)
272 IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER = _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER
274 _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER_swigconstant(_IMP_test)
275 IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER = _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER
277 _IMP_test.IMPKERNEL_SHOW_WARNINGS_swigconstant(_IMP_test)
278 IMPKERNEL_SHOW_WARNINGS = _IMP_test.IMPKERNEL_SHOW_WARNINGS
281 class _DirectorObjects(object):
282 """@internal Simple class to keep references to director objects
283 to prevent premature deletion."""
286 def register(self, obj):
287 """Take a reference to a director object; will only work for
288 refcounted C++ classes"""
289 if hasattr(obj,
'get_ref_count'):
290 self._objects.append(obj)
292 """Only drop our reference and allow cleanup by Python if no other
293 Python references exist (we hold 3 references: one in self._objects,
294 one in x, and one in the argument list for getrefcount) *and* no
295 other C++ references exist (the Python object always holds one)"""
296 objs = [x
for x
in self._objects
if sys.getrefcount(x) > 3 \
297 or x.get_ref_count() > 1]
301 def get_object_count(self):
302 """Get number of director objects (useful for testing only)"""
303 return len(self._objects)
304 _director_objects = _DirectorObjects()
306 class _ostream(object):
307 """Proxy of C++ std::ostream class"""
308 thisown = _swig_property(
lambda x: x.this.own(),
lambda x, v: x.this.own(v), doc=
'The membership flag')
310 def __init__(self, *args, **kwargs):
311 raise AttributeError(
"No constructor defined")
312 __repr__ = _swig_repr
314 def write(self, osa_buf):
315 """write(_ostream self, char const * osa_buf)"""
316 return _IMP_test._ostream_write(self, osa_buf)
318 _ostream_swigregister = _IMP_test._ostream_swigregister
319 _ostream_swigregister(_ostream)
322 _IMP_test.IMP_COMPILER_HAS_OVERRIDE_swigconstant(_IMP_test)
323 IMP_COMPILER_HAS_OVERRIDE = _IMP_test.IMP_COMPILER_HAS_OVERRIDE
325 _IMP_test.IMP_COMPILER_HAS_FINAL_swigconstant(_IMP_test)
326 IMP_COMPILER_HAS_FINAL = _IMP_test.IMP_COMPILER_HAS_FINAL
328 _IMP_test.IMP_HAS_NOEXCEPT_swigconstant(_IMP_test)
329 IMP_HAS_NOEXCEPT = _IMP_test.IMP_HAS_NOEXCEPT
332 _IMP_test.IMP_TEST_HAS_BOOST_FILESYSTEM_swigconstant(_IMP_test)
333 IMP_TEST_HAS_BOOST_FILESYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_FILESYSTEM
335 _IMP_test.IMP_TEST_HAS_BOOST_PROGRAMOPTIONS_swigconstant(_IMP_test)
336 IMP_TEST_HAS_BOOST_PROGRAMOPTIONS = _IMP_test.IMP_TEST_HAS_BOOST_PROGRAMOPTIONS
338 _IMP_test.IMP_TEST_HAS_BOOST_RANDOM_swigconstant(_IMP_test)
339 IMP_TEST_HAS_BOOST_RANDOM = _IMP_test.IMP_TEST_HAS_BOOST_RANDOM
341 _IMP_test.IMP_TEST_HAS_BOOST_SYSTEM_swigconstant(_IMP_test)
342 IMP_TEST_HAS_BOOST_SYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_SYSTEM
344 _IMP_test.IMPTEST_SHOW_WARNINGS_swigconstant(_IMP_test)
345 IMPTEST_SHOW_WARNINGS = _IMP_test.IMPTEST_SHOW_WARNINGS
348 """@namespace IMP::test
349 @brief Methods and classes for testing the IMP kernel and modules.
363 from .
import _compat_python
364 from ._compat_python
import unittest2
380 def __load_unittest_package():
382 for modname, fromlist
in ((
'unittest', []),
386 u = __import__(modname, {}, {}, fromlist)
387 if hasattr(u,
'skip'):
390 errors.append(
"'%s' does not have the 'skip' decorator" \
392 except ImportError
as e:
393 errors.append(str(e))
395 return _compat_python.unittest2
396 raise ImportError(
"IMP.test requires a newer version of Python's unittest "
397 "package than is available. Either upgrade to a new "
398 "enough Python (at least 2.7 or 3.2) or install the "
399 "unittest2 package. Encountered errors: %s" \
401 unittest = __load_unittest_package()
404 expectedFailure = unittest.expectedFailure
406 skipIf = unittest.skipIf
407 skipUnless = unittest.skipUnless
410 """Simple RAII-style class to run in a temporary directory.
411 When the object is created, the temporary directory is created
412 and becomes the current working directory. When the object goes out
413 of scope, the working directory is reset and the temporary directory
416 self.origdir = os.getcwd()
417 self.tmpdir = tempfile.mkdtemp()
418 os.chdir(self.tmpdir)
420 os.chdir(self.origdir)
421 shutil.rmtree(self.tmpdir, ignore_errors=
True)
425 """Simple RAII-style class to make a temporary directory. When the object
426 is created, the temporary directory is created. When the object goes
427 out of scope, the temporary directory is deleted."""
428 def __init__(self, dir=None):
429 self.tmpdir = tempfile.mkdtemp(dir=dir)
431 shutil.rmtree(self.tmpdir, ignore_errors=
True)
435 """Calculate the derivative of the single-value function `func` at
436 point `val`. The derivative is calculated using simple finite
437 differences starting with the given `step`; Richardson extrapolation
438 is then used to extrapolate the derivative at step=0."""
443 f1 = func(val + step)
444 f2 = func(val - step)
446 d = [[(f1 - f2) / (2.0 * step)]]
448 for i
in range(1, maxsteps):
449 d.append([0.] * (i + 1))
451 f1 = func(val + step)
452 f2 = func(val - step)
453 d[i][0] = (f1 - f2) / (2.0 * step)
455 for j
in range(1, i + 1):
456 d[i][j] = (d[i][j-1] * fac - d[i-1][j-1]) / (fac - 1.)
458 errt = max(abs(d[i][j] - d[i][j-1]),
459 abs(d[i][j] - d[i-1][j-1]))
463 if abs(d[i][i] - d[i-1][i-1]) >= safe * err:
466 raise ValueError(
"Cannot calculate numerical derivative")
471 """Calculate the x,y and z derivatives of the scoring function `sf`
472 on the `xyz` particle. The derivatives are approximated numerically
473 using the numerical_derivatives() function."""
474 class _XYZDerivativeFunc(object):
475 def __init__(self, sf, xyz, basis_vector):
478 self._basis_vector = basis_vector
479 self._starting_coordinates = xyz.get_coordinates()
481 def __call__(self, val):
482 self._xyz.set_coordinates(self._starting_coordinates + \
483 self._basis_vector * val)
484 return self._sf.evaluate(
False)
488 for x
in ((1,0,0), (0,1,0), (0,0,1))])
492 """Super class for IMP test cases"""
494 def __init__(self, *args, **keys):
495 unittest.TestCase.__init__(self, *args, **keys)
496 self._progname = os.path.abspath(sys.argv[0])
504 IMP.random_number_generator.seed(hash(time.time())%2**30)
511 """Get the full name of an input file in the top-level
513 testdir = os.path.dirname(self._progname)
514 dirs = testdir.split(os.path.sep)
515 for i
in range(len(dirs), 0, -1):
516 input = os.path.sep.join(dirs[:i] + [
'input'])
517 if os.path.isdir(input):
518 ret = os.path.join(input, filename)
519 if not os.path.exists(ret):
520 raise IOError(
"Test input file "+ret+
" does not exist")
522 raise IOError(
"No test input directory found")
525 """Open and return an input file in the top-level test directory."""
529 """Get the full name of an output file in the tmp directory."""
530 if not hasattr(self,
'_tmpdir'):
531 self._tmpdir =
TempDir(os.environ[
'IMP_TMP_DIR'])
532 tmpdir = self._tmpdir.tmpdir
533 return os.path.join(tmpdir, filename)
535 def get_magnitude(self, vector):
536 return sum([x*x
for x
in vector], 0)**.5
539 """Assert that the given callable object raises UsageException.
540 This differs from unittest's assertRaises in that the test
541 is skipped in fast mode (where usage checks are turned off)."""
546 """Assert that the given callable object raises InternalException.
547 This differs from unittest's assertRaises in that the test
548 is skipped in fast mode (where internal checks are turned off)."""
553 """Assert that the given callable object is not implemented."""
558 """Assert that x,y,z analytical derivatives match numerical within
559 a tolerance, or a percentage (of the analytical value), whichever
560 is larger. `sf` should be a ScoringFunction or Restraint,
561 although for backwards compatibility a Model is also accepted."""
563 derivs = xyz.get_derivatives()
565 pct = percentage / 100.0
566 self.assertAlmostEqual(self.get_magnitude(derivs-num_derivs),0,
567 delta=tolerance+percentage*self.get_magnitude(num_derivs),
568 msg=
"Don't match "+str(derivs) + str(num_derivs))
569 self.assertAlmostEqual(derivs[0], num_derivs[0],
570 delta=max(tolerance, abs(derivs[0]) * pct))
571 self.assertAlmostEqual(derivs[1], num_derivs[1],
572 delta=max(tolerance, abs(derivs[1]) * pct))
573 self.assertAlmostEqual(derivs[2], num_derivs[2],
574 delta=max(tolerance, abs(derivs[2]) * pct))
577 """Make a particle with optimizable x, y and z attributes, and
578 add it to the model."""
586 """Help handle a test which is expected to fail some fraction of
587 the time. The test is run multiple times and an exception
588 is thrown only if it fails too many times."""
589 prob=chance_of_failure
593 prob= prob*chance_of_failure
594 for i
in range(0, tries):
602 raise AssertError(
"Too many failures")
605 """Estimate how likely a given block of code is to raise an
609 while failures < 10
and tries <1000:
615 return failures/tries
618 """Randomize the xyz coordinates of a list of particles"""
624 p.set_value(xkey, random.uniform(-deviation, deviation))
625 p.set_value(ykey, random.uniform(-deviation, deviation))
626 p.set_value(zkey, random.uniform(-deviation, deviation))
629 """Return distance between two given particles"""
633 dx = p1.get_value(xkey) - p2.get_value(xkey)
634 dy = p1.get_value(ykey) - p2.get_value(ykey)
635 dz = p1.get_value(zkey) - p2.get_value(zkey)
636 return math.sqrt(dx*dx + dy*dy + dz*dz)
639 """Check the unary function func's derivatives against numerical
640 approximations between lb and ub"""
641 for f
in [lb + i * step
for i
in range(1, int((ub-lb)/step))]:
642 (v,d)= func.evaluate_with_derivative(f)
644 self.assertAlmostEqual(d, da, delta=max(abs(.1 *d), 0.01))
647 """Make sure that the minimum of the unary function func over the
648 range between lb and ub is at expected_fmin"""
649 fmin, vmin = lb, func.evaluate(lb)
650 for f
in [lb + i * step
for i
in range(1, int((ub-lb)/step))]:
654 self.assertAlmostEqual(fmin, expected_fmin, delta=step)
657 """Check that the get_from() static method works correctly"""
659 self.assertIsNotNone(cls.get_from(obj))
660 self.assertRaises(ValueError, cls.get_from,
IMP.Model())
665 """Create a bunch of particles in a box"""
670 for i
in range(0,num):
675 def _get_type(self, module, name):
676 return eval(
'type('+module+
"."+name+
')')
678 "Check that all the C++ classes in the module are values or objects."
680 ok = set(exceptions_list + module._value_types + module._object_types + module._raii_types + module._plural_types)
684 if self._get_type(module.__name__, name)==type
and not name.startswith(
"_"):
685 if name.find(
"SwigPyIterator") != -1:
688 if not eval(
'hasattr(%s.%s, "__swig_destroy__")' \
689 % (module.__name__, name)):
694 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." \
696 self.assertEqual(len(bad), 0, message)
697 for e
in exceptions_list:
698 self.assertTrue(e
not in module._value_types
699 + module._object_types
701 + module._plural_types,
702 "Value/Object exception "+e+
" is not an exception")
704 def _check_spelling(self, word, words):
705 """Check that the word is spelled correctly"""
706 if "words" not in dir(self):
708 wordlist= fh.read().split("\n")
710 custom_words=[
"info",
"prechange",
"int",
"ints",
"optimizeds",
"graphviz",
711 "voxel",
"voxels",
"endian",
'rna',
'dna',
712 "xyzr",
"pdbs",
"fft",
"ccc",
"gaussian"]
715 exclude_words = set([
"adapter",
"grey"])
716 self.words=set(wordlist+custom_words) - exclude_words
718 for i
in "0123456789":
723 if word
in self.words:
730 """Check that all the classes in the module follow the imp naming conventions."""
734 cc=re.compile(
"([A-Z][a-z]*)")
736 if self._get_type(module.__name__, name)==type
and not name.startswith(
"_"):
737 if name.find(
"SwigPyIterator") != -1:
739 for t
in re.findall(cc, name):
740 if not self._check_spelling(t.lower(), words):
741 misspelled.append(t.lower())
744 self.assertEqual(len(bad), 0,
745 "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." \
746 % (str(bad),
", ".join(set(misspelled))))
749 if self._get_type(module.__name__, name)==type
and not name.startswith(
"_"):
750 if name.find(
"SwigPyIterator") != -1:
752 if name.find(
'_') != -1:
754 if name.lower== name:
756 for t
in re.findall(cc, name):
757 if not self._check_spelling(t.lower(), words):
758 print(
"misspelled %s in %s" % (t, name))
760 message=
"All IMP classes should have CamelCase names. The following do not: %s." \
762 self.assertEqual(len(bad), 0, message)
764 def _check_function_name(self, prefix, name, verbs, all, exceptions, words,
767 fullname=prefix+
"."+name
770 old_exceptions=[
'unprotected_evaluate',
"unprotected_evaluate_if_good",
771 "unprotected_evaluate_if_below",
772 "after_evaluate",
"before_evaluate",
"has_attribute",
773 "decorate_particle",
"particle_is_instance"]
774 if name
in old_exceptions:
777 if fullname
in exceptions:
779 if name.endswith(
"swigregister"):
781 if name.lower() != name:
782 if name[0].lower() != name[0]
and name.split(
'_')[0]
in all:
787 tokens= name.split(
"_")
788 if tokens[0]
not in verbs:
791 if not self._check_spelling(t, words):
793 print(
"misspelled %s in %s" % (t, name))
797 def _static_method(self, module, prefix, name):
798 """For static methods of the form Foo.bar SWIG creates free functions
799 named Foo_bar. Exclude these from spelling checks since the method
800 Foo.bar has already been checked."""
801 if prefix
is None and '_' in name:
802 modobj = eval(module)
803 cls, meth = name.split(
'_', 1)
804 if hasattr(modobj, cls):
805 clsobj = eval(module +
'.' + cls)
806 if hasattr(clsobj, meth):
809 def _check_function_names(self, module, prefix, names, verbs, all,
810 exceptions, words, misspelled):
813 typ = self._get_type(module, name)
814 if name.startswith(
"_")
or name ==
"weakref_proxy":
816 if typ
in (types.BuiltinMethodType, types.MethodType) \
817 or (typ == types.FunctionType
and \
818 not self._static_method(module, prefix, name)):
819 bad.extend(self._check_function_name(prefix, name, verbs, all,
822 if typ == type
and "SwigPyIterator" not in name:
823 members=eval(
"dir("+module+
"."+name+
")")
824 bad.extend(self._check_function_names(module+
"."+name,
825 name, members, verbs, [],
831 """Check that all the functions in the module follow the IMP
832 naming conventions."""
834 verbs=set([
"add",
"remove",
"get",
"set",
"evaluate",
"compute",
"show",
"create",
"destroy",
835 "push",
"pop",
"write",
"read",
"do",
"show",
"load",
"save",
"reset",
837 "clear",
"handle",
"update",
"apply",
"optimize",
"reserve",
"dump",
838 "propose",
"setup",
"teardown",
"visit",
"find",
"run",
"swap",
"link",
841 bad=self._check_function_names(module.__name__,
None, all, verbs, all, exceptions, words, misspelled)
842 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" \
843 % {
"bad":
"\n".join(bad),
"verbs":verbs}
844 if len(misspelled) > 0:
845 message +=
"\nMisspelled words: " +
", ".join(set(misspelled)) \
846 +
". Add words to the spelling_exceptions variable " \
847 +
"of the standards_exceptions file if needed."
848 self.assertEqual(len(bad), 0, message)
852 """Check that all the classes in modulename have a show method"""
860 if not eval(
'hasattr(%s.%s, "__swig_destroy__")' \
861 % (modulename.__name__, f)):
863 if self._get_type(modulename.__name__, f) == type \
864 and not f.startswith(
"_") \
865 and not f.endswith(
"_swigregister")\
866 and f
not in exceptions\
867 and not f.endswith(
"Temp")
and not f.endswith(
"Iterator")\
868 and not f.endswith(
"Exception")
and\
869 f
not in modulename._raii_types
and \
870 f
not in modulename._plural_types:
871 if not hasattr(getattr(modulename, f),
'show'):
873 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." \
874 %
"\n".join(not_found)
875 self.assertEqual(len(not_found), 0, message)
877 self.assertIn(e, all,
"Show exception "+e+
" is not a class in module")
878 self.assertTrue(
not hasattr(getattr(modulename, e),
'show'),
879 "Exception "+e+
" is not really a show exception")
882 """Run the named example script.
883 A dictionary of all the script's global variables is returned.
884 This can be queried in a test case to make sure the example
885 performed correctly."""
890 path, name = os.path.split(filename)
891 oldsyspath = sys.path[:]
892 olssysargv= sys.argv[:]
893 sys.path.insert(0, path)
898 exec(open(filename).read(), vars)
901 except SystemExit
as e:
902 if e.code != 0
and e.code
is not None:
903 raise _FatalError(
"Example exit with code %s" % str(e.code))
907 sys.path = oldsyspath
910 return _ExecDictProxy(vars)
913 """Run a Python module as if with "python -m <modname>",
914 with the given list of arguments as sys.argv.
916 If module is an already-imported Python module, run its 'main'
917 function and return the result.
919 If module is a string, run the module in a subprocess and return
920 a subprocess.Popen-like object containing the child stdin,
923 if type(module) == type(os):
926 mod = __import__(module, {}, {}, [
''])
927 modpath = mod.__file__
928 if modpath.endswith(
'.pyc'):
929 modpath = modpath[:-1]
930 if type(module) == type(os):
931 old_sys_argv = sys.argv
933 IMP.OptionParser._use_boost_parser =
False
935 sys.argv = [modpath] + args
938 IMP.OptionParser._use_boost_parser =
True
939 sys.argv = old_sys_argv
941 return _SubprocessWrapper(sys.executable, [modpath] + args)
944 """Check a Python module designed to be runnable with 'python -m'
945 to make sure it supports standard command line options."""
948 out, err = r.communicate()
949 self.assertEqual(r.returncode, 0)
950 self.assertNotEqual(err,
"")
951 self.assertEqual(out,
"")
954 class _ExecDictProxy(object):
955 """exec returns a Python dictionary, which contains IMP objects, other
956 Python objects, as well as base Python modules (such as sys and
957 __builtins__). If we just delete this dictionary, it is entirely
958 possible that base Python modules are removed from the dictionary
959 *before* some IMP objects. This will prevent the IMP objects' Python
960 destructors from running properly, so C++ objects will not be
961 cleaned up. This class proxies the base dict class, and on deletion
962 attempts to remove keys from the dictionary in an order that allows
963 IMP destructors to fire."""
964 def __init__(self, d):
968 module_type = type(IMP)
971 if type(d[k]) != module_type:
974 for meth
in [
'__contains__',
'__getitem__',
'__iter__',
'__len__',
975 'get',
'has_key',
'items',
'keys',
'values']:
976 exec(
"def %s(self, *args, **keys): "
977 "return self._d.%s(*args, **keys)" % (meth, meth))
980 class _TestResult(unittest.TextTestResult):
982 def __init__(self, stream=None, descriptions=None, verbosity=None):
983 super(_TestResult, self).__init__(stream, descriptions, verbosity)
986 def stopTestRun(self):
987 if 'IMP_TEST_DETAIL_DIR' in os.environ:
988 fname = os.path.join(os.environ[
'IMP_TEST_DETAIL_DIR'],
989 os.path.basename(sys.argv[0]))
990 with open(fname,
'wb')
as fh:
991 pickle.dump(self.all_tests, fh, -1)
992 super(_TestResult, self).stopTestRun()
994 def startTest(self, test):
995 super(_TestResult, self).startTest(test)
996 test.start_time=datetime.datetime.now()
998 def _test_finished(self, test, state, detail=None):
999 delta = datetime.datetime.now() - test.start_time
1001 pv= delta.total_seconds()
1002 except AttributeError:
1003 pv = (float(delta.microseconds) \
1004 + (delta.seconds + delta.days * 24 * 3600) * 10**6) / 10**6
1006 self.stream.write(
"in %.3fs ... " % pv)
1007 if detail
is not None and not isinstance(detail, str):
1008 detail = self._exc_info_to_string(detail, test)
1009 test_doc = self.getDescription(test)
1010 test_name = test.id()
1011 if test_name.startswith(
'__main__.'):
1012 test_name = test_name[9:]
1013 self.all_tests.append({
'name': test_name,
1014 'docstring': test_doc,
1015 'time': pv,
'state': state,
'detail': detail})
1017 def addSuccess(self, test):
1018 self._test_finished(test,
'OK')
1019 super(_TestResult, self).addSuccess(test)
1021 def addError(self, test, err):
1022 self._test_finished(test,
'ERROR', err)
1023 super(_TestResult, self).addError(test, err)
1025 def addFailure(self, test, err):
1026 self._test_finished(test,
'FAIL', err)
1027 super(_TestResult, self).addFailure(test, err)
1029 def addSkip(self, test, reason):
1030 self._test_finished(test,
'SKIP', reason)
1031 super(_TestResult, self).addSkip(test, reason)
1033 def addExpectedFailure(self, test, err):
1034 self._test_finished(test,
'EXPFAIL', err)
1035 super(_TestResult, self).addExpectedFailure(test, err)
1037 def addUnexpectedSuccess(self, test):
1038 self._test_finished(test,
'UNEXPSUC')
1039 super(_TestResult, self).addUnexpectedSuccess(test)
1041 def getDescription(self, test):
1042 doc_first_line = test.shortDescription()
1043 if self.descriptions
and doc_first_line:
1044 return doc_first_line
1049 class _TestRunner(unittest.TextTestRunner):
1050 def _makeResult(self):
1051 return _TestResult(self.stream, self.descriptions, self.verbosity)
1055 """Run a set of tests; similar to unittest.main().
1056 Obviates the need to separately import the 'unittest' module, and
1057 ensures that main() is from the same unittest module that the
1058 IMP.test testcases are. In addition, turns on some extra checks
1059 (e.g. trying to use deprecated code will cause an exception
1063 return unittest.main(testRunner=_TestRunner, *args, **keys)
1066 class _SubprocessWrapper(subprocess.Popen):
1067 def __init__(self, app, args):
1070 if sys.platform ==
'win32' and app != sys.executable:
1072 libdir = os.environ[
'PYTHONPATH'].split(
';')[0]
1073 env = os.environ.copy()
1074 env[
'PATH'] +=
';' + libdir
1077 subprocess.Popen.__init__(self, [app]+list(args),
1078 stdin=subprocess.PIPE,
1079 stdout=subprocess.PIPE,
1080 stderr=subprocess.PIPE, env=env,
1081 universal_newlines=
True)
1085 """Super class for simple IMP application test cases"""
1086 def _get_application_file_name(self, filename):
1089 if sys.platform ==
'win32':
1097 """Run an application with the given list of arguments.
1098 @return a subprocess.Popen-like object containing the child stdin,
1101 filename = self._get_application_file_name(app)
1102 if sys.platform ==
'win32':
1104 return _SubprocessWrapper(os.path.join(os.environ[
'IMP_BIN_DIR'],
1107 return _SubprocessWrapper(filename, args)
1110 """Run a Python application with the given list of arguments.
1111 The Python application should be self-runnable (i.e. it should
1112 be executable and with a #! on the first line).
1113 @return a subprocess.Popen-like object containing the child stdin,
1117 if sys.executable !=
'/usr/bin/python' and 'IMP_BIN_DIR' in os.environ:
1118 return _SubprocessWrapper(sys.executable,
1119 [os.path.join(os.environ[
'IMP_BIN_DIR'], app)] + args)
1121 return _SubprocessWrapper(app, args)
1124 """Import an installed Python application, rather than running it.
1125 This is useful to directly test components of the application.
1126 @return the Python module object."""
1128 import importlib.machinery
1132 name = os.path.splitext(app)[0]
1133 pathname = os.path.join(os.environ[
'IMP_BIN_DIR'], app)
1135 return importlib.machinery.SourceFileLoader(name,
1136 pathname).load_module()
1138 return imp.load_source(name, pathname)
1141 """Run an application with the given list of arguments.
1142 @return a subprocess.Popen-like object containing the child stdin,
1145 return _SubprocessWrapper(sys.executable, [app]+args)
1148 """Assert that the application exited cleanly (return value = 0)."""
1150 raise OSError(
"Application exited with signal %d\n" % -ret\
1153 self.assertEqual(ret, 0,
1154 "Application exited uncleanly, with exit code %d\n" % ret\
1158 """Read and return a set of shell commands from a doxygen file.
1159 Each command is assumed to be in a \\code{.sh}...\\endcode block.
1160 The doxygen file is specified relative to the test file itself.
1161 This is used to make sure the commands shown in an application
1162 example actually work (the testcase can also check the resulting
1163 files for correctness)."""
1164 def win32_normpath(p):
1167 return " ".join([os.path.normpath(x)
for x
in p.split()])
1168 def fix_win32_command(cmd):
1170 if cmd.startswith(
'cp -r '):
1171 return 'xcopy /E ' + win32_normpath(cmd[6:])
1172 elif cmd.startswith(
'cp '):
1173 return 'copy ' + win32_normpath(cmd[3:])
1176 d = os.path.dirname(sys.argv[0])
1177 doc = os.path.join(d, doxfile)
1181 with open(doc)
as fh:
1182 for line
in fh.readlines():
1183 if '\code{.sh}' in line:
1185 elif '\endcode' in line:
1188 cmds.append(line.rstrip(
'\r\n').replace(
1189 '<imp_example_path>', example_path))
1190 if sys.platform ==
'win32':
1191 cmds = [fix_win32_command(x)
for x
in cmds]
1195 "Print and run a shell command, as returned by read_shell_commands()"
1198 p = subprocess.call(cmd, shell=
True)
1200 raise OSError(
"%s failed with exit value %d" % (cmd, p))
1204 """Check to make sure the number of C++ object references is as expected"""
1206 def __init__(self, testcase):
1210 IMP._director_objects.cleanup()
1211 self.__testcase = testcase
1213 self.__basenum = IMP.Object.get_number_of_live_objects()
1217 "Make sure that the number of references matches the expected value."
1219 IMP._director_objects.cleanup()
1222 newnum=IMP.Object.get_number_of_live_objects()-self.__basenum
1223 t.assertEqual(newnum, expected,
1224 "Number of objects don't match: "\
1226 +
" != "+ str(expected) +
" found "+\
1232 """Check to make sure the number of director references is as expected"""
1234 def __init__(self, testcase):
1235 IMP._director_objects.cleanup()
1236 self.__testcase = testcase
1237 self.__basenum = IMP._director_objects.get_object_count()
1240 """Make sure that the number of references matches the expected value.
1241 If force_cleanup is set, clean up any unused references first before
1242 doing the assertion.
1246 IMP._director_objects.cleanup()
1247 t.assertEqual(IMP._director_objects.get_object_count() \
1248 - self.__basenum, expected)
1256 if sys.platform ==
'win32' and 'PYTHONPATH' in os.environ \
1257 and 'IMP_BIN_DIR' in os.environ:
1258 libdir = os.environ[
'PYTHONPATH'].split(
';')[0]
1259 bindir = os.environ[
'IMP_BIN_DIR']
1260 path = os.environ[
'PATH']
1261 if libdir
not in path
or bindir
not in path:
1262 os.environ[
'PATH'] = bindir +
';' + libdir +
';' + path
1265 def get_module_version():
1266 """get_module_version() -> std::string const"""
1267 return _IMP_test.get_module_version()
1270 """get_example_path(std::string fname) -> std::string"""
1271 return _IMP_test.get_example_path(fname)
1274 """get_data_path(std::string fname) -> std::string"""
1275 return _IMP_test.get_data_path(fname)
1277 from .
import _version_check
1278 _version_check.check_version(get_module_version())
1279 __version__ = get_module_version()
def run_python_module
Run a Python module as if with "python -m <modname>", with the given list of arguments as sys...
def assertApplicationExitedCleanly
Assert that the application exited cleanly (return value = 0).
def check_get_from
Check that the get_from() static method works correctly.
CheckLevel get_check_level()
Get the current audit mode.
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.
def main
Run a set of tests; similar to unittest.main().
An exception for an invalid usage of IMP.
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.
Class for storing model, its restraints, constraints, and particles.
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.
Simple RAII-style class to run in a temporary directory.
Strings get_live_object_names()
Return the names of all live objects.
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.
def run_example
Run the named example script.
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_test
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.
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.
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 model particles.
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.
Simple RAII-style class to make a temporary directory.
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 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.