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)
222 _IMP_test.IMP_DEBUG_swigconstant(_IMP_test)
223 IMP_DEBUG = _IMP_test.IMP_DEBUG
225 _IMP_test.IMP_RELEASE_swigconstant(_IMP_test)
226 IMP_RELEASE = _IMP_test.IMP_RELEASE
228 _IMP_test.IMP_SILENT_swigconstant(_IMP_test)
229 IMP_SILENT = _IMP_test.IMP_SILENT
231 _IMP_test.IMP_PROGRESS_swigconstant(_IMP_test)
232 IMP_PROGRESS = _IMP_test.IMP_PROGRESS
234 _IMP_test.IMP_TERSE_swigconstant(_IMP_test)
235 IMP_TERSE = _IMP_test.IMP_TERSE
237 _IMP_test.IMP_VERBOSE_swigconstant(_IMP_test)
238 IMP_VERBOSE = _IMP_test.IMP_VERBOSE
240 _IMP_test.IMP_MEMORY_swigconstant(_IMP_test)
241 IMP_MEMORY = _IMP_test.IMP_MEMORY
243 _IMP_test.IMP_NONE_swigconstant(_IMP_test)
244 IMP_NONE = _IMP_test.IMP_NONE
246 _IMP_test.IMP_USAGE_swigconstant(_IMP_test)
247 IMP_USAGE = _IMP_test.IMP_USAGE
249 _IMP_test.IMP_INTERNAL_swigconstant(_IMP_test)
250 IMP_INTERNAL = _IMP_test.IMP_INTERNAL
252 _IMP_test.IMP_KERNEL_HAS_LOG4CXX_swigconstant(_IMP_test)
253 IMP_KERNEL_HAS_LOG4CXX = _IMP_test.IMP_KERNEL_HAS_LOG4CXX
255 _IMP_test.IMP_COMPILER_HAS_AUTO_swigconstant(_IMP_test)
256 IMP_COMPILER_HAS_AUTO = _IMP_test.IMP_COMPILER_HAS_AUTO
258 _IMP_test.IMP_COMPILER_HAS_DEBUG_VECTOR_swigconstant(_IMP_test)
259 IMP_COMPILER_HAS_DEBUG_VECTOR = _IMP_test.IMP_COMPILER_HAS_DEBUG_VECTOR
261 _IMP_test.IMP_KERNEL_HAS_BOOST_RANDOM_swigconstant(_IMP_test)
262 IMP_KERNEL_HAS_BOOST_RANDOM = _IMP_test.IMP_KERNEL_HAS_BOOST_RANDOM
264 _IMP_test.IMP_KERNEL_HAS_GPERFTOOLS_swigconstant(_IMP_test)
265 IMP_KERNEL_HAS_GPERFTOOLS = _IMP_test.IMP_KERNEL_HAS_GPERFTOOLS
267 _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER_swigconstant(_IMP_test)
268 IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER = _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPCHECKER
270 _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER_swigconstant(_IMP_test)
271 IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER = _IMP_test.IMP_KERNEL_HAS_TCMALLOC_HEAPPROFILER
273 _IMP_test.IMPKERNEL_SHOW_WARNINGS_swigconstant(_IMP_test)
274 IMPKERNEL_SHOW_WARNINGS = _IMP_test.IMPKERNEL_SHOW_WARNINGS
276 class _DirectorObjects(object):
277 """@internal Simple class to keep references to director objects
278 to prevent premature deletion."""
281 def register(self, obj):
282 """Take a reference to a director object; will only work for
283 refcounted C++ classes"""
284 if hasattr(obj,
'get_ref_count'):
285 self._objects.append(obj)
287 """Only drop our reference and allow cleanup by Python if no other
288 Python references exist (we hold 3 references: one in self._objects,
289 one in x, and one in the argument list for getrefcount) *and* no
290 other C++ references exist (the Python object always holds one)"""
291 objs = [x
for x
in self._objects
if sys.getrefcount(x) > 3 \
292 or x.get_ref_count() > 1]
296 def get_object_count(self):
297 """Get number of director objects (useful for testing only)"""
298 return len(self._objects)
299 _director_objects = _DirectorObjects()
301 class _ostream(object):
302 """Proxy of C++ std::ostream class"""
303 thisown = _swig_property(
lambda x: x.this.own(),
lambda x, v: x.this.own(v), doc=
'The membership flag')
305 def __init__(self, *args, **kwargs):
306 raise AttributeError(
"No constructor defined")
307 __repr__ = _swig_repr
309 def write(self, osa_buf):
310 """write(_ostream self, char const * osa_buf)"""
311 return _IMP_test._ostream_write(self, osa_buf)
313 _ostream_swigregister = _IMP_test._ostream_swigregister
314 _ostream_swigregister(_ostream)
317 _IMP_test.IMP_COMPILER_HAS_OVERRIDE_swigconstant(_IMP_test)
318 IMP_COMPILER_HAS_OVERRIDE = _IMP_test.IMP_COMPILER_HAS_OVERRIDE
320 _IMP_test.IMP_COMPILER_HAS_FINAL_swigconstant(_IMP_test)
321 IMP_COMPILER_HAS_FINAL = _IMP_test.IMP_COMPILER_HAS_FINAL
323 _IMP_test.IMP_HAS_NOEXCEPT_swigconstant(_IMP_test)
324 IMP_HAS_NOEXCEPT = _IMP_test.IMP_HAS_NOEXCEPT
327 _IMP_test.IMP_TEST_HAS_BOOST_FILESYSTEM_swigconstant(_IMP_test)
328 IMP_TEST_HAS_BOOST_FILESYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_FILESYSTEM
330 _IMP_test.IMP_TEST_HAS_BOOST_PROGRAMOPTIONS_swigconstant(_IMP_test)
331 IMP_TEST_HAS_BOOST_PROGRAMOPTIONS = _IMP_test.IMP_TEST_HAS_BOOST_PROGRAMOPTIONS
333 _IMP_test.IMP_TEST_HAS_BOOST_RANDOM_swigconstant(_IMP_test)
334 IMP_TEST_HAS_BOOST_RANDOM = _IMP_test.IMP_TEST_HAS_BOOST_RANDOM
336 _IMP_test.IMP_TEST_HAS_BOOST_SYSTEM_swigconstant(_IMP_test)
337 IMP_TEST_HAS_BOOST_SYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_SYSTEM
339 _IMP_test.IMPTEST_SHOW_WARNINGS_swigconstant(_IMP_test)
340 IMPTEST_SHOW_WARNINGS = _IMP_test.IMPTEST_SHOW_WARNINGS
341 """@namespace IMP::test
342 @brief Methods and classes for testing the IMP kernel and modules.
356 from .
import _compat_python
357 from ._compat_python
import unittest2
373 def __load_unittest_package():
375 for modname, fromlist
in ((
'unittest', []),
379 u = __import__(modname, {}, {}, fromlist)
380 if hasattr(u,
'skip'):
383 errors.append(
"'%s' does not have the 'skip' decorator" \
385 except ImportError
as e:
386 errors.append(str(e))
388 return _compat_python.unittest2
389 raise ImportError(
"IMP.test requires a newer version of Python's unittest "
390 "package than is available. Either upgrade to a new "
391 "enough Python (at least 2.7 or 3.2) or install the "
392 "unittest2 package. Encountered errors: %s" \
394 unittest = __load_unittest_package()
397 expectedFailure = unittest.expectedFailure
399 skipIf = unittest.skipIf
400 skipUnless = unittest.skipUnless
403 """Simple RAII-style class to run in a temporary directory.
404 When the object is created, the temporary directory is created
405 and becomes the current working directory. When the object goes out
406 of scope, the working directory is reset and the temporary directory
409 self.origdir = os.getcwd()
410 self.tmpdir = tempfile.mkdtemp()
411 os.chdir(self.tmpdir)
413 os.chdir(self.origdir)
414 shutil.rmtree(self.tmpdir, ignore_errors=
True)
418 """Simple RAII-style class to make a temporary directory. When the object
419 is created, the temporary directory is created. When the object goes
420 out of scope, the temporary directory is deleted."""
421 def __init__(self, dir):
422 self.tmpdir = tempfile.mkdtemp(dir=dir)
424 shutil.rmtree(self.tmpdir, ignore_errors=
True)
428 """Calculate the derivative of the single-value function `func` at
429 point `val`. The derivative is calculated using simple finite
430 differences starting with the given `step`; Richardson extrapolation
431 is then used to extrapolate the derivative at step=0."""
436 f1 = func(val + step)
437 f2 = func(val - step)
439 d = [[(f1 - f2) / (2.0 * step)]]
441 for i
in range(1, maxsteps):
442 d.append([0.] * (i + 1))
444 f1 = func(val + step)
445 f2 = func(val - step)
446 d[i][0] = (f1 - f2) / (2.0 * step)
448 for j
in range(1, i + 1):
449 d[i][j] = (d[i][j-1] * fac - d[i-1][j-1]) / (fac - 1.)
451 errt = max(abs(d[i][j] - d[i][j-1]),
452 abs(d[i][j] - d[i-1][j-1]))
456 if abs(d[i][i] - d[i-1][i-1]) >= safe * err:
459 raise ValueError(
"Cannot calculate numerical derivative")
464 """Calculate the x,y and z derivatives of the scoring function `sf`
465 on the `xyz` particle. The derivatives are approximated numerically
466 using the numerical_derivatives() function."""
467 class _XYZDerivativeFunc(object):
468 def __init__(self, sf, xyz, basis_vector):
471 self._basis_vector = basis_vector
472 self._starting_coordinates = xyz.get_coordinates()
474 def __call__(self, val):
475 self._xyz.set_coordinates(self._starting_coordinates + \
476 self._basis_vector * val)
477 return self._sf.evaluate(
False)
481 for x
in ((1,0,0), (0,1,0), (0,0,1))])
485 """Super class for IMP test cases"""
487 def __init__(self, *args, **keys):
488 unittest.TestCase.__init__(self, *args, **keys)
489 self._progname = os.path.abspath(sys.argv[0])
497 IMP.random_number_generator.seed(hash(time.time())%2**30)
504 """Get the full name of an input file in the top-level
506 testdir = os.path.dirname(self._progname)
507 dirs = testdir.split(os.path.sep)
508 for i
in range(len(dirs), 0, -1):
509 input = os.path.sep.join(dirs[:i] + [
'input'])
510 if os.path.isdir(input):
511 ret = os.path.join(input, filename)
512 if not os.path.exists(ret):
513 raise IOError(
"Test input file "+ret+
" does not exist")
515 raise IOError(
"No test input directory found")
518 """Open and return an input file in the top-level test directory."""
522 """Get the full name of an output file in the tmp directory."""
523 if not hasattr(self,
'_tmpdir'):
524 self._tmpdir =
TempDir(os.environ[
'IMP_TMP_DIR'])
525 tmpdir = self._tmpdir.tmpdir
526 return os.path.join(tmpdir, filename)
528 def get_magnitude(self, vector):
529 return sum([x*x
for x
in vector], 0)**.5
532 """Assert that the given callable object raises UsageException.
533 This differs from unittest's assertRaises in that the test
534 is skipped in fast mode (where usage checks are turned off)."""
540 """Assert that x,y,z analytical derivatives match numerical within
541 a tolerance, or a percentage (of the analytical value), whichever
542 is larger. `sf` should be a ScoringFunction or Restraint,
543 although for backwards compatibility a Model is also accepted."""
545 derivs = xyz.get_derivatives()
547 pct = percentage / 100.0
548 self.assertAlmostEqual(self.get_magnitude(derivs-num_derivs),0,
549 delta=tolerance+percentage*self.get_magnitude(num_derivs),
550 msg=
"Don't match "+str(derivs) + str(num_derivs))
551 self.assertAlmostEqual(derivs[0], num_derivs[0],
552 delta=max(tolerance, abs(derivs[0]) * pct))
553 self.assertAlmostEqual(derivs[1], num_derivs[1],
554 delta=max(tolerance, abs(derivs[1]) * pct))
555 self.assertAlmostEqual(derivs[2], num_derivs[2],
556 delta=max(tolerance, abs(derivs[2]) * pct))
559 """Make a particle with optimizable x, y and z attributes, and
560 add it to the model."""
568 """Help handle a test which is expected to fail some fraction of
569 the time. The test is run multiple times and an exception
570 is thrown only if it fails too many times."""
571 prob=chance_of_failure
575 prob= prob*chance_of_failure
576 for i
in range(0, tries):
584 raise AssertError(
"Too many failures")
587 """Estimate how likely a given block of code is to raise an
591 while failures < 10
and tries <1000:
597 return failures/tries
600 """Randomize the xyz coordinates of a list of particles"""
606 p.set_value(xkey, random.uniform(-deviation, deviation))
607 p.set_value(ykey, random.uniform(-deviation, deviation))
608 p.set_value(zkey, random.uniform(-deviation, deviation))
611 """Return distance between two given particles"""
615 dx = p1.get_value(xkey) - p2.get_value(xkey)
616 dy = p1.get_value(ykey) - p2.get_value(ykey)
617 dz = p1.get_value(zkey) - p2.get_value(zkey)
618 return math.sqrt(dx*dx + dy*dy + dz*dz)
621 """Check the unary function func's derivatives against numerical
622 approximations between lb and ub"""
623 for f
in [lb + i * step
for i
in range(1, int((ub-lb)/step))]:
624 (v,d)= func.evaluate_with_derivative(f)
626 self.assertAlmostEqual(d, da, delta=max(abs(.1 *d), 0.01))
629 """Make sure that the minimum of the unary function func over the
630 range between lb and ub is at expected_fmin"""
631 fmin, vmin = lb, func.evaluate(lb)
632 for f
in [lb + i * step
for i
in range(1, int((ub-lb)/step))]:
636 self.assertAlmostEqual(fmin, expected_fmin, delta=step)
639 """Check that the get_from() static method works correctly"""
641 self.assertIsNotNone(cls.get_from(obj))
642 self.assertRaises(ValueError, cls.get_from,
IMP.Model())
647 """Create a bunch of particles in a box"""
652 for i
in range(0,num):
657 def _get_type(self, module, name):
658 return eval(
'type('+module+
"."+name+
')')
660 "Check that all the C++ classes in the module are values or objects."
662 ok = set(exceptions_list + module._value_types + module._object_types + module._raii_types + module._plural_types)
666 if self._get_type(module.__name__, name)==type
and not name.startswith(
"_"):
667 if name.find(
"SwigPyIterator") != -1:
670 if not eval(
'hasattr(%s.%s, "__swig_destroy__")' \
671 % (module.__name__, name)):
676 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." \
678 self.assertEqual(len(bad), 0, message)
679 for e
in exceptions_list:
680 self.assertTrue(e
not in module._value_types
681 + module._object_types
683 + module._plural_types,
684 "Value/Object exception "+e+
" is not an exception")
686 def _check_spelling(self, word, words):
687 """Check that the word is spelled correctly"""
688 if "words" not in dir(self):
690 wordlist= fh.read().split("\n")
692 custom_words=[
"info",
"prechange",
"int",
"ints",
"optimizeds",
"graphviz",
693 "voxel",
"voxels",
"endian",
'rna',
'dna',
694 "xyzr",
"pdbs",
"fft",
"ccc",
"gaussian"]
697 exclude_words = set([
"adapter",
"grey"])
698 self.words=set(wordlist+custom_words) - exclude_words
700 for i
in "0123456789":
705 if word
in self.words:
712 """Check that all the classes in the module follow the imp naming conventions."""
716 cc=re.compile(
"([A-Z][a-z]*)")
718 if self._get_type(module.__name__, name)==type
and not name.startswith(
"_"):
719 if name.find(
"SwigPyIterator") != -1:
721 for t
in re.findall(cc, name):
722 if not self._check_spelling(t.lower(), words):
723 misspelled.append(t.lower())
726 self.assertEqual(len(bad), 0,
727 "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." \
728 % (str(bad),
", ".join(set(misspelled))))
731 if self._get_type(module.__name__, name)==type
and not name.startswith(
"_"):
732 if name.find(
"SwigPyIterator") != -1:
734 if name.find(
'_') != -1:
736 if name.lower== name:
738 for t
in re.findall(cc, name):
739 if not self._check_spelling(t.lower(), words):
740 print(
"misspelled %s in %s" % (t, name))
742 message=
"All IMP classes should have CamelCase names. The following do not: %s." \
744 self.assertEqual(len(bad), 0, message)
746 def _check_function_name(self, prefix, name, verbs, all, exceptions, words,
749 fullname=prefix+
"."+name
752 old_exceptions=[
'unprotected_evaluate',
"unprotected_evaluate_if_good",
753 "unprotected_evaluate_if_below",
754 "after_evaluate",
"before_evaluate",
"has_attribute",
755 "decorate_particle",
"particle_is_instance"]
756 if name
in old_exceptions:
759 if fullname
in exceptions:
761 if name.endswith(
"swigregister"):
763 if name.lower() != name:
764 if name[0].lower() != name[0]
and name.split(
'_')[0]
in all:
769 tokens= name.split(
"_")
770 if tokens[0]
not in verbs:
773 if not self._check_spelling(t, words):
775 print(
"misspelled %s in %s" % (t, name))
779 def _static_method(self, module, prefix, name):
780 """For static methods of the form Foo.bar SWIG creates free functions
781 named Foo_bar. Exclude these from spelling checks since the method
782 Foo.bar has already been checked."""
783 if prefix
is None and '_' in name:
784 modobj = eval(module)
785 cls, meth = name.split(
'_', 1)
786 if hasattr(modobj, cls):
787 clsobj = eval(module +
'.' + cls)
788 if hasattr(clsobj, meth):
791 def _check_function_names(self, module, prefix, names, verbs, all,
792 exceptions, words, misspelled):
795 typ = self._get_type(module, name)
796 if name.startswith(
"_")
or name ==
"weakref_proxy":
798 if typ
in (types.BuiltinMethodType, types.MethodType) \
799 or (typ == types.FunctionType
and \
800 not self._static_method(module, prefix, name)):
801 bad.extend(self._check_function_name(prefix, name, verbs, all,
804 if typ == type
and "SwigPyIterator" not in name:
805 members=eval(
"dir("+module+
"."+name+
")")
806 bad.extend(self._check_function_names(module+
"."+name,
807 name, members, verbs, [],
813 """Check that all the functions in the module follow the IMP
814 naming conventions."""
816 verbs=set([
"add",
"remove",
"get",
"set",
"evaluate",
"compute",
"show",
"create",
"destroy",
817 "push",
"pop",
"write",
"read",
"do",
"show",
"load",
"save",
"reset",
819 "clear",
"handle",
"update",
"apply",
"optimize",
"reserve",
"dump",
820 "propose",
"setup",
"teardown",
"visit",
"find",
"run",
"swap",
"link",
823 bad=self._check_function_names(module.__name__,
None, all, verbs, all, exceptions, words, misspelled)
824 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" \
825 % {
"bad":
"\n".join(bad),
"verbs":verbs}
826 if len(misspelled) > 0:
827 message +=
"\nMisspelled words: " +
", ".join(set(misspelled)) \
828 +
". Add words to the spelling_exceptions variable " \
829 +
"of the standards_exceptions file if needed."
830 self.assertEqual(len(bad), 0, message)
834 """Check that all the classes in modulename have a show method"""
842 if not eval(
'hasattr(%s.%s, "__swig_destroy__")' \
843 % (modulename.__name__, f)):
845 if self._get_type(modulename.__name__, f) == type \
846 and not f.startswith(
"_") \
847 and not f.endswith(
"_swigregister")\
848 and f
not in exceptions\
849 and not f.endswith(
"Temp")
and not f.endswith(
"Iterator")\
850 and not f.endswith(
"Exception")
and\
851 f
not in modulename._raii_types
and \
852 f
not in modulename._plural_types:
853 if not hasattr(getattr(modulename, f),
'show'):
855 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." \
856 %
"\n".join(not_found)
857 self.assertEqual(len(not_found), 0, message)
859 self.assertIn(e, all,
"Show exception "+e+
" is not a class in module")
860 self.assertTrue(
not hasattr(getattr(modulename, e),
'show'),
861 "Exception "+e+
" is not really a show exception")
864 """Run the named example script.
865 A dictionary of all the script's global variables is returned.
866 This can be queried in a test case to make sure the example
867 performed correctly."""
872 path, name = os.path.split(filename)
873 oldsyspath = sys.path[:]
874 olssysargv= sys.argv[:]
875 sys.path.insert(0, path)
880 exec(open(filename).read(), vars)
883 except SystemExit
as e:
884 if e.code != 0
and e.code
is not None:
885 raise _FatalError(
"Example exit with code %s" % str(e.code))
889 sys.path = oldsyspath
892 return _ExecDictProxy(vars)
895 """Run a Python module as if with "python -m <modname>",
896 with the given list of arguments as sys.argv.
898 If module is an already-imported Python module, run its 'main'
899 function and return the result.
901 If module is a string, run the module in a subprocess and return
902 a subprocess.Popen-like object containing the child stdin,
905 if type(module) == type(os):
908 mod = __import__(module, {}, {}, [
''])
909 modpath = mod.__file__
910 if modpath.endswith(
'.pyc'):
911 modpath = modpath[:-1]
912 if type(module) == type(os):
913 old_sys_argv = sys.argv
915 IMP.OptionParser._use_boost_parser =
False
917 sys.argv = [modpath] + args
920 IMP.OptionParser._use_boost_parser =
True
921 sys.argv = old_sys_argv
923 return _SubprocessWrapper(sys.executable, [modpath] + args)
926 """Check a Python module designed to be runnable with 'python -m'
927 to make sure it supports standard command line options."""
930 out, err = r.communicate()
931 self.assertEqual(r.returncode, 0)
932 self.assertNotEqual(err,
"")
933 self.assertEqual(out,
"")
936 class _ExecDictProxy(object):
937 """exec returns a Python dictionary, which contains IMP objects, other
938 Python objects, as well as base Python modules (such as sys and
939 __builtins__). If we just delete this dictionary, it is entirely
940 possible that base Python modules are removed from the dictionary
941 *before* some IMP objects. This will prevent the IMP objects' Python
942 destructors from running properly, so C++ objects will not be
943 cleaned up. This class proxies the base dict class, and on deletion
944 attempts to remove keys from the dictionary in an order that allows
945 IMP destructors to fire."""
946 def __init__(self, d):
950 module_type = type(IMP)
953 if type(d[k]) != module_type:
956 for meth
in [
'__contains__',
'__getitem__',
'__iter__',
'__len__',
957 'get',
'has_key',
'items',
'keys',
'values']:
958 exec(
"def %s(self, *args, **keys): "
959 "return self._d.%s(*args, **keys)" % (meth, meth))
962 class _TestResult(unittest.TextTestResult):
964 def __init__(self, stream=None, descriptions=None, verbosity=None):
965 super(_TestResult, self).__init__(stream, descriptions, verbosity)
968 def stopTestRun(self):
969 if 'IMP_TEST_DETAIL_DIR' in os.environ:
970 fname = os.path.join(os.environ[
'IMP_TEST_DETAIL_DIR'],
971 os.path.basename(sys.argv[0]))
972 with open(fname,
'wb')
as fh:
973 pickle.dump(self.all_tests, fh, -1)
974 super(_TestResult, self).stopTestRun()
976 def startTest(self, test):
977 super(_TestResult, self).startTest(test)
978 test.start_time=datetime.datetime.now()
980 def _test_finished(self, test, state, detail=None):
981 delta = datetime.datetime.now() - test.start_time
983 pv= delta.total_seconds()
984 except AttributeError:
985 pv = (float(delta.microseconds) \
986 + (delta.seconds + delta.days * 24 * 3600) * 10**6) / 10**6
988 self.stream.write(
"in %.3fs ... " % pv)
989 if detail
is not None and not isinstance(detail, str):
990 detail = self._exc_info_to_string(detail, test)
991 test_doc = self.getDescription(test)
992 test_name = test.id()
993 if test_name.startswith(
'__main__.'):
994 test_name = test_name[9:]
995 self.all_tests.append({
'name': test_name,
996 'docstring': test_doc,
997 'time': pv,
'state': state,
'detail': detail})
999 def addSuccess(self, test):
1000 self._test_finished(test,
'OK')
1001 super(_TestResult, self).addSuccess(test)
1003 def addError(self, test, err):
1004 self._test_finished(test,
'ERROR', err)
1005 super(_TestResult, self).addError(test, err)
1007 def addFailure(self, test, err):
1008 self._test_finished(test,
'FAIL', err)
1009 super(_TestResult, self).addFailure(test, err)
1011 def addSkip(self, test, reason):
1012 self._test_finished(test,
'SKIP', reason)
1013 super(_TestResult, self).addSkip(test, reason)
1015 def addExpectedFailure(self, test, err):
1016 self._test_finished(test,
'EXPFAIL', err)
1017 super(_TestResult, self).addExpectedFailure(test, err)
1019 def addUnexpectedSuccess(self, test):
1020 self._test_finished(test,
'UNEXPSUC')
1021 super(_TestResult, self).addUnexpectedSuccess(test)
1023 def getDescription(self, test):
1024 doc_first_line = test.shortDescription()
1025 if self.descriptions
and doc_first_line:
1026 return doc_first_line
1031 class _TestRunner(unittest.TextTestRunner):
1032 def _makeResult(self):
1033 return _TestResult(self.stream, self.descriptions, self.verbosity)
1037 """Run a set of tests; similar to unittest.main().
1038 Obviates the need to separately import the 'unittest' module, and
1039 ensures that main() is from the same unittest module that the
1040 IMP.test testcases are. In addition, turns on some extra checks
1041 (e.g. trying to use deprecated code will cause an exception
1045 return unittest.main(testRunner=_TestRunner, *args, **keys)
1048 class _SubprocessWrapper(subprocess.Popen):
1049 def __init__(self, app, args):
1052 if sys.platform ==
'win32' and app != sys.executable:
1054 libdir = os.environ[
'PYTHONPATH'].split(
';')[0]
1055 env = os.environ.copy()
1056 env[
'PATH'] +=
';' + libdir
1059 subprocess.Popen.__init__(self, [app]+list(args),
1060 stdin=subprocess.PIPE,
1061 stdout=subprocess.PIPE,
1062 stderr=subprocess.PIPE, env=env,
1063 universal_newlines=
True)
1067 """Super class for simple IMP application test cases"""
1068 def _get_application_file_name(self, filename):
1071 if sys.platform ==
'win32':
1079 """Run an application with the given list of arguments.
1080 @return a subprocess.Popen-like object containing the child stdin,
1083 filename = self._get_application_file_name(app)
1084 if sys.platform ==
'win32':
1086 return _SubprocessWrapper(os.path.join(os.environ[
'IMP_BIN_DIR'],
1089 return _SubprocessWrapper(filename, args)
1092 """Run a Python application with the given list of arguments.
1093 The Python application should be self-runnable (i.e. it should
1094 be executable and with a #! on the first line).
1095 @return a subprocess.Popen-like object containing the child stdin,
1099 if sys.executable !=
'/usr/bin/python':
1100 return _SubprocessWrapper(sys.executable,
1101 [os.path.join(os.environ[
'IMP_BIN_DIR'], app)] + args)
1103 return _SubprocessWrapper(app, args)
1106 """Import an installed Python application, rather than running it.
1107 This is useful to directly test components of the application.
1108 @return the Python module object."""
1110 import importlib.machinery
1114 name = os.path.splitext(app)[0]
1115 pathname = os.path.join(os.environ[
'IMP_BIN_DIR'], app)
1117 return importlib.machinery.SourceFileLoader(name,
1118 pathname).load_module()
1120 return imp.load_source(name, pathname)
1123 """Run an application with the given list of arguments.
1124 @return a subprocess.Popen-like object containing the child stdin,
1127 return _SubprocessWrapper(sys.executable, [app]+args)
1130 """Assert that the application exited cleanly (return value = 0)."""
1132 raise OSError(
"Application exited with signal %d\n" % -ret\
1135 self.assertEqual(ret, 0,
1136 "Application exited uncleanly, with exit code %d\n" % ret\
1140 """Read and return a set of shell commands from a doxygen file.
1141 Each command is assumed to be in a \\code{.sh}...\\endcode block.
1142 The doxygen file is specified relative to the test file itself.
1143 This is used to make sure the commands shown in an application
1144 example actually work (the testcase can also check the resulting
1145 files for correctness)."""
1146 def win32_normpath(p):
1149 return " ".join([os.path.normpath(x)
for x
in p.split()])
1150 def fix_win32_command(cmd):
1152 if cmd.startswith(
'cp -r '):
1153 return 'xcopy /E ' + win32_normpath(cmd[6:])
1154 elif cmd.startswith(
'cp '):
1155 return 'copy ' + win32_normpath(cmd[3:])
1158 d = os.path.dirname(sys.argv[0])
1159 doc = os.path.join(d, doxfile)
1163 with open(doc)
as fh:
1164 for line
in fh.readlines():
1165 if '\code{.sh}' in line:
1167 elif '\endcode' in line:
1170 cmds.append(line.rstrip(
'\r\n').replace(
1171 '<imp_example_path>', example_path))
1172 if sys.platform ==
'win32':
1173 cmds = [fix_win32_command(x)
for x
in cmds]
1177 "Print and run a shell command, as returned by read_shell_commands()"
1180 p = subprocess.call(cmd, shell=
True)
1182 raise OSError(
"%s failed with exit value %d" % (cmd, p))
1186 """Check to make sure the number of C++ object references is as expected"""
1188 def __init__(self, testcase):
1192 IMP._director_objects.cleanup()
1193 self.__testcase = testcase
1195 self.__basenum = IMP.Object.get_number_of_live_objects()
1199 "Make sure that the number of references matches the expected value."
1201 IMP._director_objects.cleanup()
1204 newnum=IMP.Object.get_number_of_live_objects()-self.__basenum
1205 t.assertEqual(newnum, expected,
1206 "Number of objects don't match: "\
1208 +
" != "+ str(expected) +
" found "+\
1214 """Check to make sure the number of director references is as expected"""
1216 def __init__(self, testcase):
1217 IMP._director_objects.cleanup()
1218 self.__testcase = testcase
1219 self.__basenum = IMP._director_objects.get_object_count()
1222 """Make sure that the number of references matches the expected value.
1223 If force_cleanup is set, clean up any unused references first before
1224 doing the assertion.
1228 IMP._director_objects.cleanup()
1229 t.assertEqual(IMP._director_objects.get_object_count() \
1230 - self.__basenum, expected)
1238 if sys.platform ==
'win32' and 'PYTHONPATH' in os.environ \
1239 and 'IMP_BIN_DIR' in os.environ:
1240 libdir = os.environ[
'PYTHONPATH'].split(
';')[0]
1241 bindir = os.environ[
'IMP_BIN_DIR']
1242 path = os.environ[
'PATH']
1243 if libdir
not in path
or bindir
not in path:
1244 os.environ[
'PATH'] = bindir +
';' + libdir +
';' + path
1247 def get_module_version():
1248 """get_module_version() -> std::string const"""
1249 return _IMP_test.get_module_version()
1252 """get_example_path(std::string fname) -> std::string"""
1253 return _IMP_test.get_example_path(fname)
1256 """get_data_path(std::string fname) -> std::string"""
1257 return _IMP_test.get_data_path(fname)
1258 from .
import _version_check
1259 _version_check.check_version(get_module_version())
1260 __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.
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.
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...
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.