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."""
116 thisown = _swig_property(
lambda x: x.this.own(),
lambda x, v: x.this.own(v), doc=
'The membership flag')
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
125 """value(IMP_TEST_SwigPyIterator self) -> PyObject *"""
126 return _IMP_test.IMP_TEST_SwigPyIterator_value(self)
131 incr(IMP_TEST_SwigPyIterator self, size_t n=1) -> IMP_TEST_SwigPyIterator
132 incr(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator
134 return _IMP_test.IMP_TEST_SwigPyIterator_incr(self, n)
139 decr(IMP_TEST_SwigPyIterator self, size_t n=1) -> IMP_TEST_SwigPyIterator
140 decr(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator
142 return _IMP_test.IMP_TEST_SwigPyIterator_decr(self, n)
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)
151 """equal(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
152 return _IMP_test.IMP_TEST_SwigPyIterator_equal(self, x)
156 """copy(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator"""
157 return _IMP_test.IMP_TEST_SwigPyIterator_copy(self)
161 """next(IMP_TEST_SwigPyIterator self) -> PyObject *"""
162 return _IMP_test.IMP_TEST_SwigPyIterator_next(self)
166 """__next__(IMP_TEST_SwigPyIterator self) -> PyObject *"""
167 return _IMP_test.IMP_TEST_SwigPyIterator___next__(self)
171 """previous(IMP_TEST_SwigPyIterator self) -> PyObject *"""
172 return _IMP_test.IMP_TEST_SwigPyIterator_previous(self)
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)
181 """__eq__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
182 return _IMP_test.IMP_TEST_SwigPyIterator___eq__(self, x)
186 """__ne__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
187 return _IMP_test.IMP_TEST_SwigPyIterator___ne__(self, x)
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)
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)
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)
205 def __sub__(self, *args):
207 __sub__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator
208 __sub__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> ptrdiff_t
210 return _IMP_test.IMP_TEST_SwigPyIterator___sub__(self, *args)
214 IMP_TEST_SwigPyIterator_swigregister = _IMP_test.IMP_TEST_SwigPyIterator_swigregister
215 IMP_TEST_SwigPyIterator_swigregister(IMP_TEST_SwigPyIterator)
224 _IMP_test.IMP_DEBUG_swigconstant(_IMP_test)
225 IMP_DEBUG = _IMP_test.IMP_DEBUG
227 _IMP_test.IMP_RELEASE_swigconstant(_IMP_test)
228 IMP_RELEASE = _IMP_test.IMP_RELEASE
230 _IMP_test.IMP_SILENT_swigconstant(_IMP_test)
231 IMP_SILENT = _IMP_test.IMP_SILENT
233 _IMP_test.IMP_PROGRESS_swigconstant(_IMP_test)
234 IMP_PROGRESS = _IMP_test.IMP_PROGRESS
236 _IMP_test.IMP_TERSE_swigconstant(_IMP_test)
237 IMP_TERSE = _IMP_test.IMP_TERSE
239 _IMP_test.IMP_VERBOSE_swigconstant(_IMP_test)
240 IMP_VERBOSE = _IMP_test.IMP_VERBOSE
242 _IMP_test.IMP_MEMORY_swigconstant(_IMP_test)
243 IMP_MEMORY = _IMP_test.IMP_MEMORY
245 _IMP_test.IMP_NONE_swigconstant(_IMP_test)
246 IMP_NONE = _IMP_test.IMP_NONE
248 _IMP_test.IMP_USAGE_swigconstant(_IMP_test)
249 IMP_USAGE = _IMP_test.IMP_USAGE
251 _IMP_test.IMP_INTERNAL_swigconstant(_IMP_test)
252 IMP_INTERNAL = _IMP_test.IMP_INTERNAL
254 _IMP_test.IMP_KERNEL_HAS_LOG4CXX_swigconstant(_IMP_test)
255 IMP_KERNEL_HAS_LOG4CXX = _IMP_test.IMP_KERNEL_HAS_LOG4CXX
257 _IMP_test.IMP_COMPILER_HAS_AUTO_swigconstant(_IMP_test)
258 IMP_COMPILER_HAS_AUTO = _IMP_test.IMP_COMPILER_HAS_AUTO
260 _IMP_test.IMP_COMPILER_HAS_DEBUG_VECTOR_swigconstant(_IMP_test)
261 IMP_COMPILER_HAS_DEBUG_VECTOR = _IMP_test.IMP_COMPILER_HAS_DEBUG_VECTOR
263 _IMP_test.IMP_COMPILER_HAS_UNIQUE_PTR_swigconstant(_IMP_test)
264 IMP_COMPILER_HAS_UNIQUE_PTR = _IMP_test.IMP_COMPILER_HAS_UNIQUE_PTR
266 _IMP_test.IMP_KERNEL_HAS_BOOST_RANDOM_swigconstant(_IMP_test)
267 IMP_KERNEL_HAS_BOOST_RANDOM = _IMP_test.IMP_KERNEL_HAS_BOOST_RANDOM
269 _IMP_test.IMP_KERNEL_HAS_GPERFTOOLS_swigconstant(_IMP_test)
270 IMP_KERNEL_HAS_GPERFTOOLS = _IMP_test.IMP_KERNEL_HAS_GPERFTOOLS
272 _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER_swigconstant(_IMP_test)
273 IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER = _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER
275 _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER_swigconstant(_IMP_test)
276 IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER = _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER
278 _IMP_test.IMPKERNEL_SHOW_WARNINGS_swigconstant(_IMP_test)
279 IMPKERNEL_SHOW_WARNINGS = _IMP_test.IMPKERNEL_SHOW_WARNINGS
282 class _DirectorObjects(object):
283 """@internal Simple class to keep references to director objects
284 to prevent premature deletion."""
287 def register(self, obj):
288 """Take a reference to a director object; will only work for
289 refcounted C++ classes"""
290 if hasattr(obj,
'get_ref_count'):
291 self._objects.append(obj)
293 """Only drop our reference and allow cleanup by Python if no other
294 Python references exist (we hold 3 references: one in self._objects,
295 one in x, and one in the argument list for getrefcount) *and* no
296 other C++ references exist (the Python object always holds one)"""
297 objs = [x
for x
in self._objects
if sys.getrefcount(x) > 3 \
298 or x.get_ref_count() > 1]
302 def get_object_count(self):
303 """Get number of director objects (useful for testing only)"""
304 return len(self._objects)
305 _director_objects = _DirectorObjects()
307 class _ostream(object):
308 """Proxy of C++ std::ostream class."""
310 thisown = _swig_property(
lambda x: x.this.own(),
lambda x, v: x.this.own(v), doc=
'The membership flag')
312 def __init__(self, *args, **kwargs):
313 raise AttributeError(
"No constructor defined")
314 __repr__ = _swig_repr
316 def write(self, osa_buf):
317 """write(_ostream self, char const * osa_buf)"""
318 return _IMP_test._ostream_write(self, osa_buf)
320 _ostream_swigregister = _IMP_test._ostream_swigregister
321 _ostream_swigregister(_ostream)
324 _IMP_test.IMP_COMPILER_HAS_OVERRIDE_swigconstant(_IMP_test)
325 IMP_COMPILER_HAS_OVERRIDE = _IMP_test.IMP_COMPILER_HAS_OVERRIDE
327 _IMP_test.IMP_COMPILER_HAS_FINAL_swigconstant(_IMP_test)
328 IMP_COMPILER_HAS_FINAL = _IMP_test.IMP_COMPILER_HAS_FINAL
330 _IMP_test.IMP_HAS_NOEXCEPT_swigconstant(_IMP_test)
331 IMP_HAS_NOEXCEPT = _IMP_test.IMP_HAS_NOEXCEPT
334 _IMP_test.IMP_TEST_HAS_BOOST_FILESYSTEM_swigconstant(_IMP_test)
335 IMP_TEST_HAS_BOOST_FILESYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_FILESYSTEM
337 _IMP_test.IMP_TEST_HAS_BOOST_PROGRAMOPTIONS_swigconstant(_IMP_test)
338 IMP_TEST_HAS_BOOST_PROGRAMOPTIONS = _IMP_test.IMP_TEST_HAS_BOOST_PROGRAMOPTIONS
340 _IMP_test.IMP_TEST_HAS_BOOST_RANDOM_swigconstant(_IMP_test)
341 IMP_TEST_HAS_BOOST_RANDOM = _IMP_test.IMP_TEST_HAS_BOOST_RANDOM
343 _IMP_test.IMP_TEST_HAS_BOOST_SYSTEM_swigconstant(_IMP_test)
344 IMP_TEST_HAS_BOOST_SYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_SYSTEM
346 _IMP_test.IMPTEST_SHOW_WARNINGS_swigconstant(_IMP_test)
347 IMPTEST_SHOW_WARNINGS = _IMP_test.IMPTEST_SHOW_WARNINGS
350 """@namespace IMP::test
351 @brief Methods and classes for testing the IMP kernel and modules.
365 from .
import _compat_python
366 from ._compat_python
import unittest2
382 def __load_unittest_package():
384 for modname, fromlist
in ((
'unittest', []),
388 u = __import__(modname, {}, {}, fromlist)
389 if hasattr(u,
'skip'):
392 errors.append(
"'%s' does not have the 'skip' decorator" \
394 except ImportError
as e:
395 errors.append(str(e))
397 return _compat_python.unittest2
398 raise ImportError(
"IMP.test requires a newer version of Python's unittest "
399 "package than is available. Either upgrade to a new "
400 "enough Python (at least 2.7 or 3.2) or install the "
401 "unittest2 package. Encountered errors: %s" \
403 unittest = __load_unittest_package()
406 expectedFailure = unittest.expectedFailure
408 skipIf = unittest.skipIf
409 skipUnless = unittest.skipUnless
412 """Simple RAII-style class to run in a temporary directory.
413 When the object is created, the temporary directory is created
414 and becomes the current working directory. When the object goes out
415 of scope, the working directory is reset and the temporary directory
418 self.origdir = os.getcwd()
419 self.tmpdir = tempfile.mkdtemp()
420 os.chdir(self.tmpdir)
422 os.chdir(self.origdir)
423 shutil.rmtree(self.tmpdir, ignore_errors=
True)
427 """Simple RAII-style class to make a temporary directory. When the object
428 is created, the temporary directory is created. When the object goes
429 out of scope, the temporary directory is deleted."""
430 def __init__(self, dir=None):
431 self.tmpdir = tempfile.mkdtemp(dir=dir)
433 shutil.rmtree(self.tmpdir, ignore_errors=
True)
437 """Calculate the derivative of the single-value function `func` at
438 point `val`. The derivative is calculated using simple finite
439 differences starting with the given `step`; Richardson extrapolation
440 is then used to extrapolate the derivative at step=0."""
445 f1 = func(val + step)
446 f2 = func(val - step)
448 d = [[(f1 - f2) / (2.0 * step)]]
450 for i
in range(1, maxsteps):
451 d.append([0.] * (i + 1))
453 f1 = func(val + step)
454 f2 = func(val - step)
455 d[i][0] = (f1 - f2) / (2.0 * step)
457 for j
in range(1, i + 1):
458 d[i][j] = (d[i][j-1] * fac - d[i-1][j-1]) / (fac - 1.)
460 errt = max(abs(d[i][j] - d[i][j-1]),
461 abs(d[i][j] - d[i-1][j-1]))
465 if abs(d[i][i] - d[i-1][i-1]) >= safe * err:
468 raise ValueError(
"Cannot calculate numerical derivative")
473 """Calculate the x,y and z derivatives of the scoring function `sf`
474 on the `xyz` particle. The derivatives are approximated numerically
475 using the numerical_derivatives() function."""
476 class _XYZDerivativeFunc(object):
477 def __init__(self, sf, xyz, basis_vector):
480 self._basis_vector = basis_vector
481 self._starting_coordinates = xyz.get_coordinates()
483 def __call__(self, val):
484 self._xyz.set_coordinates(self._starting_coordinates + \
485 self._basis_vector * val)
486 return self._sf.evaluate(
False)
490 for x
in ((1,0,0), (0,1,0), (0,0,1))])
494 """Super class for IMP test cases"""
496 def __init__(self, *args, **keys):
497 unittest.TestCase.__init__(self, *args, **keys)
498 self._progname = os.path.abspath(sys.argv[0])
506 IMP.random_number_generator.seed(hash(time.time())%2**30)
513 """Get the full name of an input file in the top-level
515 testdir = os.path.dirname(self._progname)
516 dirs = testdir.split(os.path.sep)
517 for i
in range(len(dirs), 0, -1):
518 input = os.path.sep.join(dirs[:i] + [
'input'])
519 if os.path.isdir(input):
520 ret = os.path.join(input, filename)
521 if not os.path.exists(ret):
522 raise IOError(
"Test input file "+ret+
" does not exist")
524 raise IOError(
"No test input directory found")
527 """Open and return an input file in the top-level test directory."""
531 """Get the full name of an output file in the tmp directory."""
532 if not hasattr(self,
'_tmpdir'):
533 self._tmpdir =
TempDir(os.environ[
'IMP_TMP_DIR'])
534 tmpdir = self._tmpdir.tmpdir
535 return os.path.join(tmpdir, filename)
537 def get_magnitude(self, vector):
538 return sum([x*x
for x
in vector], 0)**.5
541 """Assert that the given callable object raises UsageException.
542 This differs from unittest's assertRaises in that the test
543 is skipped in fast mode (where usage checks are turned off)."""
548 """Assert that the given callable object raises InternalException.
549 This differs from unittest's assertRaises in that the test
550 is skipped in fast mode (where internal checks are turned off)."""
555 """Assert that the given callable object is not implemented."""
560 """Assert that x,y,z analytical derivatives match numerical within
561 a tolerance, or a percentage (of the analytical value), whichever
562 is larger. `sf` should be a ScoringFunction or Restraint,
563 although for backwards compatibility a Model is also accepted."""
565 derivs = xyz.get_derivatives()
567 pct = percentage / 100.0
568 self.assertAlmostEqual(self.get_magnitude(derivs-num_derivs),0,
569 delta=tolerance+percentage*self.get_magnitude(num_derivs),
570 msg=
"Don't match "+str(derivs) + str(num_derivs))
571 self.assertAlmostEqual(derivs[0], num_derivs[0],
572 delta=max(tolerance, abs(derivs[0]) * pct))
573 self.assertAlmostEqual(derivs[1], num_derivs[1],
574 delta=max(tolerance, abs(derivs[1]) * pct))
575 self.assertAlmostEqual(derivs[2], num_derivs[2],
576 delta=max(tolerance, abs(derivs[2]) * pct))
579 """Make a particle with optimizable x, y and z attributes, and
580 add it to the model."""
588 """Help handle a test which is expected to fail some fraction of
589 the time. The test is run multiple times and an exception
590 is thrown only if it fails too many times."""
591 prob=chance_of_failure
595 prob= prob*chance_of_failure
596 for i
in range(0, tries):
604 raise AssertError(
"Too many failures")
607 """Estimate how likely a given block of code is to raise an
611 while failures < 10
and tries <1000:
617 return failures/tries
620 """Randomize the xyz coordinates of a list of particles"""
626 p.set_value(xkey, random.uniform(-deviation, deviation))
627 p.set_value(ykey, random.uniform(-deviation, deviation))
628 p.set_value(zkey, random.uniform(-deviation, deviation))
631 """Return distance between two given particles"""
635 dx = p1.get_value(xkey) - p2.get_value(xkey)
636 dy = p1.get_value(ykey) - p2.get_value(ykey)
637 dz = p1.get_value(zkey) - p2.get_value(zkey)
638 return math.sqrt(dx*dx + dy*dy + dz*dz)
641 """Check the unary function func's derivatives against numerical
642 approximations between lb and ub"""
643 for f
in [lb + i * step
for i
in range(1, int((ub-lb)/step))]:
644 (v,d)= func.evaluate_with_derivative(f)
646 self.assertAlmostEqual(d, da, delta=max(abs(.1 *d), 0.01))
649 """Make sure that the minimum of the unary function func over the
650 range between lb and ub is at expected_fmin"""
651 fmin, vmin = lb, func.evaluate(lb)
652 for f
in [lb + i * step
for i
in range(1, int((ub-lb)/step))]:
656 self.assertAlmostEqual(fmin, expected_fmin, delta=step)
659 """Check that the get_from() static method works correctly"""
661 self.assertIsNotNone(cls.get_from(obj))
662 self.assertRaises(ValueError, cls.get_from,
IMP.Model())
667 """Create a bunch of particles in a box"""
672 for i
in range(0,num):
677 def _get_type(self, module, name):
678 return eval(
'type('+module+
"."+name+
')')
680 "Check that all the C++ classes in the module are values or objects."
682 ok = set(exceptions_list + module._value_types + module._object_types + module._raii_types + module._plural_types)
686 if self._get_type(module.__name__, name)==type
and not name.startswith(
"_"):
687 if name.find(
"SwigPyIterator") != -1:
690 if not eval(
'hasattr(%s.%s, "__swig_destroy__")' \
691 % (module.__name__, name)):
696 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." \
698 self.assertEqual(len(bad), 0, message)
699 for e
in exceptions_list:
700 self.assertTrue(e
not in module._value_types
701 + module._object_types
703 + module._plural_types,
704 "Value/Object exception "+e+
" is not an exception")
706 def _check_spelling(self, word, words):
707 """Check that the word is spelled correctly"""
708 if "words" not in dir(self):
710 wordlist= fh.read().split("\n")
712 custom_words=[
"info",
"prechange",
"int",
"ints",
"optimizeds",
"graphviz",
713 "voxel",
"voxels",
"endian",
'rna',
'dna',
714 "xyzr",
"pdbs",
"fft",
"ccc",
"gaussian"]
717 exclude_words = set([
"adapter",
"grey"])
718 self.words=set(wordlist+custom_words) - exclude_words
720 for i
in "0123456789":
725 if word
in self.words:
732 """Check that all the classes in the module follow the imp naming conventions."""
736 cc=re.compile(
"([A-Z][a-z]*)")
738 if self._get_type(module.__name__, name)==type
and not name.startswith(
"_"):
739 if name.find(
"SwigPyIterator") != -1:
741 for t
in re.findall(cc, name):
742 if not self._check_spelling(t.lower(), words):
743 misspelled.append(t.lower())
746 self.assertEqual(len(bad), 0,
747 "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." \
748 % (str(bad),
", ".join(set(misspelled))))
751 if self._get_type(module.__name__, name)==type
and not name.startswith(
"_"):
752 if name.find(
"SwigPyIterator") != -1:
754 if name.find(
'_') != -1:
756 if name.lower== name:
758 for t
in re.findall(cc, name):
759 if not self._check_spelling(t.lower(), words):
760 print(
"misspelled %s in %s" % (t, name))
762 message=
"All IMP classes should have CamelCase names. The following do not: %s." \
764 self.assertEqual(len(bad), 0, message)
766 def _check_function_name(self, prefix, name, verbs, all, exceptions, words,
769 fullname=prefix+
"."+name
772 old_exceptions=[
'unprotected_evaluate',
"unprotected_evaluate_if_good",
773 "unprotected_evaluate_if_below",
774 "after_evaluate",
"before_evaluate",
"has_attribute",
775 "decorate_particle",
"particle_is_instance"]
776 if name
in old_exceptions:
779 if fullname
in exceptions:
781 if name.endswith(
"swigregister"):
783 if name.lower() != name:
784 if name[0].lower() != name[0]
and name.split(
'_')[0]
in all:
789 tokens= name.split(
"_")
790 if tokens[0]
not in verbs:
793 if not self._check_spelling(t, words):
795 print(
"misspelled %s in %s" % (t, name))
799 def _static_method(self, module, prefix, name):
800 """For static methods of the form Foo.bar SWIG creates free functions
801 named Foo_bar. Exclude these from spelling checks since the method
802 Foo.bar has already been checked."""
803 if prefix
is None and '_' in name:
804 modobj = eval(module)
805 cls, meth = name.split(
'_', 1)
806 if hasattr(modobj, cls):
807 clsobj = eval(module +
'.' + cls)
808 if hasattr(clsobj, meth):
811 def _check_function_names(self, module, prefix, names, verbs, all,
812 exceptions, words, misspelled):
815 typ = self._get_type(module, name)
816 if name.startswith(
"_")
or name ==
"weakref_proxy":
818 if typ
in (types.BuiltinMethodType, types.MethodType) \
819 or (typ == types.FunctionType
and \
820 not self._static_method(module, prefix, name)):
821 bad.extend(self._check_function_name(prefix, name, verbs, all,
824 if typ == type
and "SwigPyIterator" not in name:
825 members=eval(
"dir("+module+
"."+name+
")")
826 bad.extend(self._check_function_names(module+
"."+name,
827 name, members, verbs, [],
833 """Check that all the functions in the module follow the IMP
834 naming conventions."""
836 verbs=set([
"add",
"remove",
"get",
"set",
"evaluate",
"compute",
"show",
"create",
"destroy",
837 "push",
"pop",
"write",
"read",
"do",
"show",
"load",
"save",
"reset",
839 "clear",
"handle",
"update",
"apply",
"optimize",
"reserve",
"dump",
840 "propose",
"setup",
"teardown",
"visit",
"find",
"run",
"swap",
"link",
843 bad=self._check_function_names(module.__name__,
None, all, verbs, all, exceptions, words, misspelled)
844 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" \
845 % {
"bad":
"\n".join(bad),
"verbs":verbs}
846 if len(misspelled) > 0:
847 message +=
"\nMisspelled words: " +
", ".join(set(misspelled)) \
848 +
". Add words to the spelling_exceptions variable " \
849 +
"of the standards_exceptions file if needed."
850 self.assertEqual(len(bad), 0, message)
854 """Check that all the classes in modulename have a show method"""
862 if not eval(
'hasattr(%s.%s, "__swig_destroy__")' \
863 % (modulename.__name__, f)):
865 if self._get_type(modulename.__name__, f) == type \
866 and not f.startswith(
"_") \
867 and not f.endswith(
"_swigregister")\
868 and f
not in exceptions\
869 and not f.endswith(
"Temp")
and not f.endswith(
"Iterator")\
870 and not f.endswith(
"Exception")
and\
871 f
not in modulename._raii_types
and \
872 f
not in modulename._plural_types:
873 if not hasattr(getattr(modulename, f),
'show'):
875 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." \
876 %
"\n".join(not_found)
877 self.assertEqual(len(not_found), 0, message)
879 self.assertIn(e, all,
"Show exception "+e+
" is not a class in module")
880 self.assertTrue(
not hasattr(getattr(modulename, e),
'show'),
881 "Exception "+e+
" is not really a show exception")
884 """Run the named example script.
885 A dictionary of all the script's global variables is returned.
886 This can be queried in a test case to make sure the example
887 performed correctly."""
892 path, name = os.path.split(filename)
893 oldsyspath = sys.path[:]
894 olssysargv= sys.argv[:]
895 sys.path.insert(0, path)
900 exec(open(filename).read(), vars)
903 except SystemExit
as e:
904 if e.code != 0
and e.code
is not None:
905 raise _FatalError(
"Example exit with code %s" % str(e.code))
909 sys.path = oldsyspath
912 return _ExecDictProxy(vars)
915 """Run a Python module as if with "python -m <modname>",
916 with the given list of arguments as sys.argv.
918 If module is an already-imported Python module, run its 'main'
919 function and return the result.
921 If module is a string, run the module in a subprocess and return
922 a subprocess.Popen-like object containing the child stdin,
925 if type(module) == type(os):
928 mod = __import__(module, {}, {}, [
''])
929 modpath = mod.__file__
930 if modpath.endswith(
'.pyc'):
931 modpath = modpath[:-1]
932 if type(module) == type(os):
933 old_sys_argv = sys.argv
935 IMP.OptionParser._use_boost_parser =
False
937 sys.argv = [modpath] + args
940 IMP.OptionParser._use_boost_parser =
True
941 sys.argv = old_sys_argv
943 return _SubprocessWrapper(sys.executable, [modpath] + args)
946 """Check a Python module designed to be runnable with 'python -m'
947 to make sure it supports standard command line options."""
950 out, err = r.communicate()
951 self.assertEqual(r.returncode, 0)
952 self.assertNotEqual(err,
"")
953 self.assertEqual(out,
"")
956 class _ExecDictProxy(object):
957 """exec returns a Python dictionary, which contains IMP objects, other
958 Python objects, as well as base Python modules (such as sys and
959 __builtins__). If we just delete this dictionary, it is entirely
960 possible that base Python modules are removed from the dictionary
961 *before* some IMP objects. This will prevent the IMP objects' Python
962 destructors from running properly, so C++ objects will not be
963 cleaned up. This class proxies the base dict class, and on deletion
964 attempts to remove keys from the dictionary in an order that allows
965 IMP destructors to fire."""
966 def __init__(self, d):
970 module_type = type(IMP)
973 if type(d[k]) != module_type:
976 for meth
in [
'__contains__',
'__getitem__',
'__iter__',
'__len__',
977 'get',
'has_key',
'items',
'keys',
'values']:
978 exec(
"def %s(self, *args, **keys): "
979 "return self._d.%s(*args, **keys)" % (meth, meth))
982 class _TestResult(unittest.TextTestResult):
984 def __init__(self, stream=None, descriptions=None, verbosity=None):
985 super(_TestResult, self).__init__(stream, descriptions, verbosity)
988 def stopTestRun(self):
989 if 'IMP_TEST_DETAIL_DIR' in os.environ:
990 fname = os.path.join(os.environ[
'IMP_TEST_DETAIL_DIR'],
991 os.path.basename(sys.argv[0]))
992 with open(fname,
'wb')
as fh:
993 pickle.dump(self.all_tests, fh, -1)
994 super(_TestResult, self).stopTestRun()
996 def startTest(self, test):
997 super(_TestResult, self).startTest(test)
998 test.start_time=datetime.datetime.now()
1000 def _test_finished(self, test, state, detail=None):
1001 delta = datetime.datetime.now() - test.start_time
1003 pv= delta.total_seconds()
1004 except AttributeError:
1005 pv = (float(delta.microseconds) \
1006 + (delta.seconds + delta.days * 24 * 3600) * 10**6) / 10**6
1008 self.stream.write(
"in %.3fs ... " % pv)
1009 if detail
is not None and not isinstance(detail, str):
1010 detail = self._exc_info_to_string(detail, test)
1011 test_doc = self.getDescription(test)
1012 test_name = test.id()
1013 if test_name.startswith(
'__main__.'):
1014 test_name = test_name[9:]
1015 self.all_tests.append({
'name': test_name,
1016 'docstring': test_doc,
1017 'time': pv,
'state': state,
'detail': detail})
1019 def addSuccess(self, test):
1020 self._test_finished(test,
'OK')
1021 super(_TestResult, self).addSuccess(test)
1023 def addError(self, test, err):
1024 self._test_finished(test,
'ERROR', err)
1025 super(_TestResult, self).addError(test, err)
1027 def addFailure(self, test, err):
1028 self._test_finished(test,
'FAIL', err)
1029 super(_TestResult, self).addFailure(test, err)
1031 def addSkip(self, test, reason):
1032 self._test_finished(test,
'SKIP', reason)
1033 super(_TestResult, self).addSkip(test, reason)
1035 def addExpectedFailure(self, test, err):
1036 self._test_finished(test,
'EXPFAIL', err)
1037 super(_TestResult, self).addExpectedFailure(test, err)
1039 def addUnexpectedSuccess(self, test):
1040 self._test_finished(test,
'UNEXPSUC')
1041 super(_TestResult, self).addUnexpectedSuccess(test)
1043 def getDescription(self, test):
1044 doc_first_line = test.shortDescription()
1045 if self.descriptions
and doc_first_line:
1046 return doc_first_line
1051 class _TestRunner(unittest.TextTestRunner):
1052 def _makeResult(self):
1053 return _TestResult(self.stream, self.descriptions, self.verbosity)
1057 """Run a set of tests; similar to unittest.main().
1058 Obviates the need to separately import the 'unittest' module, and
1059 ensures that main() is from the same unittest module that the
1060 IMP.test testcases are. In addition, turns on some extra checks
1061 (e.g. trying to use deprecated code will cause an exception
1065 return unittest.main(testRunner=_TestRunner, *args, **keys)
1068 class _SubprocessWrapper(subprocess.Popen):
1069 def __init__(self, app, args):
1072 if sys.platform ==
'win32' and app != sys.executable:
1074 libdir = os.environ[
'PYTHONPATH'].split(
';')[0]
1075 env = os.environ.copy()
1076 env[
'PATH'] +=
';' + libdir
1079 subprocess.Popen.__init__(self, [app]+list(args),
1080 stdin=subprocess.PIPE,
1081 stdout=subprocess.PIPE,
1082 stderr=subprocess.PIPE, env=env,
1083 universal_newlines=
True)
1087 """Super class for simple IMP application test cases"""
1088 def _get_application_file_name(self, filename):
1091 if sys.platform ==
'win32':
1099 """Run an application with the given list of arguments.
1100 @return a subprocess.Popen-like object containing the child stdin,
1103 filename = self._get_application_file_name(app)
1104 if sys.platform ==
'win32':
1106 return _SubprocessWrapper(os.path.join(os.environ[
'IMP_BIN_DIR'],
1109 return _SubprocessWrapper(filename, args)
1112 """Run a Python application with the given list of arguments.
1113 The Python application should be self-runnable (i.e. it should
1114 be executable and with a #! on the first line).
1115 @return a subprocess.Popen-like object containing the child stdin,
1119 if sys.executable !=
'/usr/bin/python' and 'IMP_BIN_DIR' in os.environ:
1120 return _SubprocessWrapper(sys.executable,
1121 [os.path.join(os.environ[
'IMP_BIN_DIR'], app)] + args)
1123 return _SubprocessWrapper(app, args)
1126 """Import an installed Python application, rather than running it.
1127 This is useful to directly test components of the application.
1128 @return the Python module object."""
1130 import importlib.machinery
1134 name = os.path.splitext(app)[0]
1135 pathname = os.path.join(os.environ[
'IMP_BIN_DIR'], app)
1137 return importlib.machinery.SourceFileLoader(name,
1138 pathname).load_module()
1140 return imp.load_source(name, pathname)
1143 """Run an application with the given list of arguments.
1144 @return a subprocess.Popen-like object containing the child stdin,
1147 return _SubprocessWrapper(sys.executable, [app]+args)
1150 """Assert that the application exited cleanly (return value = 0)."""
1152 raise OSError(
"Application exited with signal %d\n" % -ret\
1155 self.assertEqual(ret, 0,
1156 "Application exited uncleanly, with exit code %d\n" % ret\
1160 """Read and return a set of shell commands from a doxygen file.
1161 Each command is assumed to be in a \\code{.sh}...\\endcode block.
1162 The doxygen file is specified relative to the test file itself.
1163 This is used to make sure the commands shown in an application
1164 example actually work (the testcase can also check the resulting
1165 files for correctness)."""
1166 def win32_normpath(p):
1169 return " ".join([os.path.normpath(x)
for x
in p.split()])
1170 def fix_win32_command(cmd):
1172 if cmd.startswith(
'cp -r '):
1173 return 'xcopy /E ' + win32_normpath(cmd[6:])
1174 elif cmd.startswith(
'cp '):
1175 return 'copy ' + win32_normpath(cmd[3:])
1178 d = os.path.dirname(sys.argv[0])
1179 doc = os.path.join(d, doxfile)
1183 with open(doc)
as fh:
1184 for line
in fh.readlines():
1185 if '\code{.sh}' in line:
1187 elif '\endcode' in line:
1190 cmds.append(line.rstrip(
'\r\n').replace(
1191 '<imp_example_path>', example_path))
1192 if sys.platform ==
'win32':
1193 cmds = [fix_win32_command(x)
for x
in cmds]
1197 "Print and run a shell command, as returned by read_shell_commands()"
1200 p = subprocess.call(cmd, shell=
True)
1202 raise OSError(
"%s failed with exit value %d" % (cmd, p))
1206 """Check to make sure the number of C++ object references is as expected"""
1208 def __init__(self, testcase):
1212 IMP._director_objects.cleanup()
1213 self.__testcase = testcase
1215 self.__basenum = IMP.Object.get_number_of_live_objects()
1219 "Make sure that the number of references matches the expected value."
1221 IMP._director_objects.cleanup()
1224 newnum=IMP.Object.get_number_of_live_objects()-self.__basenum
1225 t.assertEqual(newnum, expected,
1226 "Number of objects don't match: "\
1228 +
" != "+ str(expected) +
" found "+\
1234 """Check to make sure the number of director references is as expected"""
1236 def __init__(self, testcase):
1237 IMP._director_objects.cleanup()
1238 self.__testcase = testcase
1239 self.__basenum = IMP._director_objects.get_object_count()
1242 """Make sure that the number of references matches the expected value.
1243 If force_cleanup is set, clean up any unused references first before
1244 doing the assertion.
1248 IMP._director_objects.cleanup()
1249 t.assertEqual(IMP._director_objects.get_object_count() \
1250 - self.__basenum, expected)
1258 if sys.platform ==
'win32' and 'PYTHONPATH' in os.environ \
1259 and 'IMP_BIN_DIR' in os.environ:
1260 libdir = os.environ[
'PYTHONPATH'].split(
';')[0]
1261 bindir = os.environ[
'IMP_BIN_DIR']
1262 path = os.environ[
'PATH']
1263 if libdir
not in path
or bindir
not in path:
1264 os.environ[
'PATH'] = bindir +
';' + libdir +
';' + path
1267 def get_module_version():
1268 """get_module_version() -> std::string const"""
1269 return _IMP_test.get_module_version()
1272 """get_example_path(std::string fname) -> std::string"""
1273 return _IMP_test.get_example_path(fname)
1276 """get_data_path(std::string fname) -> std::string"""
1277 return _IMP_test.get_data_path(fname)
1279 from .
import _version_check
1280 _version_check.check_version(get_module_version())
1281 __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.