11 from sys
import version_info
12 if version_info >= (2,6,0):
13 def swig_import_helper():
14 from os.path
import dirname
18 fp, pathname, description = imp.find_module(
'_IMP_test', [dirname(__file__)])
24 _mod = imp.load_module(
'_IMP_test', fp, pathname, description)
28 _IMP_test = swig_import_helper()
29 del swig_import_helper
34 _swig_property = property
37 def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
38 if (name ==
"thisown"):
return self.this.own(value)
40 if type(value).__name__ ==
'SwigPyObject':
41 self.__dict__[name] = value
43 method = class_type.__swig_setmethods__.get(name,
None)
44 if method:
return method(self,value)
46 self.__dict__[name] = value
48 raise AttributeError(
"You cannot add attributes to %s" % self)
50 def _swig_setattr(self,class_type,name,value):
51 return _swig_setattr_nondynamic(self,class_type,name,value,0)
53 def _swig_getattr(self,class_type,name):
54 if (name ==
"thisown"):
return self.this.own()
55 method = class_type.__swig_getmethods__.get(name,
None)
56 if method:
return method(self)
57 raise AttributeError(name)
60 try: strthis =
"proxy of " + self.this.__repr__()
62 return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
67 except AttributeError:
74 weakref_proxy = weakref.proxy
76 weakref_proxy =
lambda x: x
79 class IMP_TEST_SwigPyIterator(_object):
80 """Proxy of C++ swig::IMP_TEST_SwigPyIterator class"""
81 __swig_setmethods__ = {}
82 __setattr__ =
lambda self, name, value: _swig_setattr(self, IMP_TEST_SwigPyIterator, name, value)
83 __swig_getmethods__ = {}
84 __getattr__ =
lambda self, name: _swig_getattr(self, IMP_TEST_SwigPyIterator, name)
85 def __init__(self, *args, **kwargs):
raise AttributeError(
"No constructor defined - class is abstract")
87 __swig_destroy__ = _IMP_test.delete_IMP_TEST_SwigPyIterator
88 __del__ =
lambda self :
None;
90 """value(IMP_TEST_SwigPyIterator self) -> PyObject *"""
91 return _IMP_test.IMP_TEST_SwigPyIterator_value(self)
95 incr(IMP_TEST_SwigPyIterator self, size_t n=1) -> IMP_TEST_SwigPyIterator
96 incr(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator
98 return _IMP_test.IMP_TEST_SwigPyIterator_incr(self, n)
102 decr(IMP_TEST_SwigPyIterator self, size_t n=1) -> IMP_TEST_SwigPyIterator
103 decr(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator
105 return _IMP_test.IMP_TEST_SwigPyIterator_decr(self, n)
107 def distance(self, *args):
108 """distance(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> ptrdiff_t"""
109 return _IMP_test.IMP_TEST_SwigPyIterator_distance(self, *args)
111 def equal(self, *args):
112 """equal(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
113 return _IMP_test.IMP_TEST_SwigPyIterator_equal(self, *args)
116 """copy(IMP_TEST_SwigPyIterator self) -> IMP_TEST_SwigPyIterator"""
117 return _IMP_test.IMP_TEST_SwigPyIterator_copy(self)
120 """next(IMP_TEST_SwigPyIterator self) -> PyObject *"""
121 return _IMP_test.IMP_TEST_SwigPyIterator_next(self)
124 """__next__(IMP_TEST_SwigPyIterator self) -> PyObject *"""
125 return _IMP_test.IMP_TEST_SwigPyIterator___next__(self)
128 """previous(IMP_TEST_SwigPyIterator self) -> PyObject *"""
129 return _IMP_test.IMP_TEST_SwigPyIterator_previous(self)
131 def advance(self, *args):
132 """advance(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
133 return _IMP_test.IMP_TEST_SwigPyIterator_advance(self, *args)
135 def __eq__(self, *args):
136 """__eq__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
137 return _IMP_test.IMP_TEST_SwigPyIterator___eq__(self, *args)
139 def __ne__(self, *args):
140 """__ne__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> bool"""
141 return _IMP_test.IMP_TEST_SwigPyIterator___ne__(self, *args)
143 def __iadd__(self, *args):
144 """__iadd__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
145 return _IMP_test.IMP_TEST_SwigPyIterator___iadd__(self, *args)
147 def __isub__(self, *args):
148 """__isub__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
149 return _IMP_test.IMP_TEST_SwigPyIterator___isub__(self, *args)
151 def __add__(self, *args):
152 """__add__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator"""
153 return _IMP_test.IMP_TEST_SwigPyIterator___add__(self, *args)
155 def __sub__(self, *args):
157 __sub__(IMP_TEST_SwigPyIterator self, ptrdiff_t n) -> IMP_TEST_SwigPyIterator
158 __sub__(IMP_TEST_SwigPyIterator self, IMP_TEST_SwigPyIterator x) -> ptrdiff_t
160 return _IMP_test.IMP_TEST_SwigPyIterator___sub__(self, *args)
162 def __iter__(self):
return self
163 IMP_TEST_SwigPyIterator_swigregister = _IMP_test.IMP_TEST_SwigPyIterator_swigregister
164 IMP_TEST_SwigPyIterator_swigregister(IMP_TEST_SwigPyIterator)
171 IMP_DEBUG = _IMP_test.IMP_DEBUG
172 IMP_RELEASE = _IMP_test.IMP_RELEASE
173 IMP_SILENT = _IMP_test.IMP_SILENT
174 IMP_PROGRESS = _IMP_test.IMP_PROGRESS
175 IMP_TERSE = _IMP_test.IMP_TERSE
176 IMP_VERBOSE = _IMP_test.IMP_VERBOSE
177 IMP_MEMORY = _IMP_test.IMP_MEMORY
178 IMP_NONE = _IMP_test.IMP_NONE
179 IMP_USAGE = _IMP_test.IMP_USAGE
180 IMP_INTERNAL = _IMP_test.IMP_INTERNAL
181 IMP_BASE_HAS_LOG4CXX = _IMP_test.IMP_BASE_HAS_LOG4CXX
182 IMP_COMPILER_HAS_AUTO = _IMP_test.IMP_COMPILER_HAS_AUTO
183 IMP_COMPILER_HAS_DEBUG_VECTOR = _IMP_test.IMP_COMPILER_HAS_DEBUG_VECTOR
184 IMP_BASE_HAS_BOOST_RANDOM = _IMP_test.IMP_BASE_HAS_BOOST_RANDOM
185 IMP_BASE_HAS_GPERFTOOLS = _IMP_test.IMP_BASE_HAS_GPERFTOOLS
186 IMP_BASE_HAS_TCMALLOC_HEAPCHECKER = _IMP_test.IMP_BASE_HAS_TCMALLOC_HEAPCHECKER
187 IMP_BASE_HAS_TCMALLOC_HEAPPROFILER = _IMP_test.IMP_BASE_HAS_TCMALLOC_HEAPPROFILER
188 IMPBASE_SHOW_WARNINGS = _IMP_test.IMPBASE_SHOW_WARNINGS
190 class _DirectorObjects(object):
191 """@internal Simple class to keep references to director objects
192 to prevent premature deletion."""
195 def register(self, obj):
196 """Take a reference to a director object; will only work for
197 refcounted C++ classes"""
198 if hasattr(obj,
'get_ref_count'):
199 self._objects.append(obj)
201 """Only drop our reference and allow cleanup by Python if no other
202 Python references exist (we hold 3 references: one in self._objects,
203 one in x, and one in the argument list for getrefcount) *and* no
204 other C++ references exist (the Python object always holds one)"""
205 objs = [x
for x
in self._objects
if sys.getrefcount(x) > 3 \
206 or x.get_ref_count() > 1]
210 def get_object_count(self):
211 """Get number of director objects (useful for testing only)"""
212 return len(self._objects)
213 _director_objects = _DirectorObjects()
215 DEFAULT_CHECK = _IMP_test.DEFAULT_CHECK
216 NONE = _IMP_test.NONE
217 USAGE = _IMP_test.USAGE
218 USAGE_AND_INTERNAL = _IMP_test.USAGE_AND_INTERNAL
221 """set_check_level(IMP::base::CheckLevel tf)"""
222 return _IMP_test.set_check_level(*args)
225 """get_check_level() -> IMP::base::CheckLevel"""
226 return _IMP_test.get_check_level()
227 class _ostream(_object):
228 """Proxy of C++ std::ostream class"""
229 __swig_setmethods__ = {}
230 __setattr__ =
lambda self, name, value: _swig_setattr(self, _ostream, name, value)
231 __swig_getmethods__ = {}
232 __getattr__ =
lambda self, name: _swig_getattr(self, _ostream, name)
233 def __init__(self, *args, **kwargs):
raise AttributeError(
"No constructor defined")
234 __repr__ = _swig_repr
235 def write(self, *args):
236 """write(_ostream self, char const * osa_buf)"""
237 return _IMP_test._ostream_write(self, *args)
239 _ostream_swigregister = _IMP_test._ostream_swigregister
240 _ostream_swigregister(_ostream)
242 IMP_COMPILER_HAS_OVERRIDE = _IMP_test.IMP_COMPILER_HAS_OVERRIDE
243 IMP_COMPILER_HAS_FINAL = _IMP_test.IMP_COMPILER_HAS_FINAL
244 IMP_HAS_NOEXCEPT = _IMP_test.IMP_HAS_NOEXCEPT
246 IMP_TEST_HAS_BOOST_FILESYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_FILESYSTEM
247 IMP_TEST_HAS_BOOST_PROGRAMOPTIONS = _IMP_test.IMP_TEST_HAS_BOOST_PROGRAMOPTIONS
248 IMP_TEST_HAS_BOOST_RANDOM = _IMP_test.IMP_TEST_HAS_BOOST_RANDOM
249 IMP_TEST_HAS_BOOST_SYSTEM = _IMP_test.IMP_TEST_HAS_BOOST_SYSTEM
250 IMPTEST_SHOW_WARNINGS = _IMP_test.IMPTEST_SHOW_WARNINGS
251 """@namespace IMP::test
252 @brief Methods and classes for testing the IMP kernel and modules.
266 import _compat_python
267 import _compat_python.unittest2
283 def __load_unittest_package():
285 for modname, fromlist
in ((
'unittest', []),
289 u = __import__(modname, {}, {}, fromlist)
290 if hasattr(u,
'skip'):
293 errors.append(
"'%s' does not have the 'skip' decorator" \
295 except ImportError, e:
296 errors.append(str(e))
298 return _compat_python.unittest2
299 raise ImportError(
"IMP.test requires a newer version of Python's unittest "
300 "package than is available. Either upgrade to a new "
301 "enough Python (at least 2.7 or 3.2) or install the "
302 "unittest2 package. Encountered errors: %s" \
304 unittest = __load_unittest_package()
307 expectedFailure = unittest.expectedFailure
309 skipIf = unittest.skipIf
310 skipUnless = unittest.skipUnless
313 """Simple RAII-style class to run in a temporary directory.
314 When the object is created, the temporary directory is created
315 and becomes the current working directory. When the object goes out
316 of scope, the working directory is reset and the temporary directory
319 self.origdir = os.getcwd()
320 self.tmpdir = tempfile.mkdtemp()
321 os.chdir(self.tmpdir)
323 os.chdir(self.origdir)
324 shutil.rmtree(self.tmpdir, ignore_errors=
True)
328 """Calculate the derivative of the single-value function `func` at
329 point `val`. The derivative is calculated using simple finite
330 differences starting with the given `step`; Richardson extrapolation
331 is then used to extrapolate the derivative at step=0."""
336 f1 = func(val + step)
337 f2 = func(val - step)
339 d = [[(f1 - f2) / (2.0 * step)]]
341 for i
in range(1, maxsteps):
342 d.append([0.] * (i + 1))
344 f1 = func(val + step)
345 f2 = func(val - step)
346 d[i][0] = (f1 - f2) / (2.0 * step)
348 for j
in range(1, i + 1):
349 d[i][j] = (d[i][j-1] * fac - d[i-1][j-1]) / (fac - 1.)
351 errt = max(abs(d[i][j] - d[i][j-1]),
352 abs(d[i][j] - d[i-1][j-1]))
356 if abs(d[i][i] - d[i-1][i-1]) >= safe * err:
359 raise ValueError(
"Cannot calculate numerical derivative")
364 """Calculate the x,y and z derivatives of `model`'s scoring function
365 on the `xyz` particle. The derivatives are approximated numerically
366 using the numerical_derivatives() function."""
367 class _XYZDerivativeFunc(object):
368 def __init__(self, xyz, basis_vector):
370 self._model = xyz.get_particle().get_model()
371 self._basis_vector = basis_vector
372 self._starting_coordinates = xyz.get_coordinates()
374 def __call__(self, val):
375 self._xyz.set_coordinates(self._starting_coordinates + \
376 self._basis_vector * val)
377 return self._model.evaluate(
False)
381 for x
in ((1,0,0), (0,1,0), (0,0,1))])
385 """Super class for IMP test cases"""
393 IMP.base.random_number_generator.seed(hash(time.time())%2**30)
400 """Get the full name of an input file in the top-level
402 testdir = os.path.dirname(os.path.abspath(sys.argv[0]))
403 dirs = testdir.split(os.path.sep)
404 for i
in range(len(dirs), 0, -1):
405 input = os.path.sep.join(dirs[:i] + [
'input'])
406 if os.path.isdir(input):
407 ret = os.path.join(input, filename)
408 if not open(ret,
"r"):
409 raise IOError(
"Test input file "+ret+
" does not exist")
411 raise IOError(
"No test input directory found")
414 """Open and return an input file in the top-level test directory."""
418 """Get the full name of an output file in the build/tmp directory."""
419 dirpath=os.environ[
'IMP_TMP_DIR']
420 if not os.path.exists(dirpath):
422 return os.path.join(dirpath, filename)
424 def get_magnitude(self, vector):
425 return sum([x*x
for x
in vector], 0)**.5
429 """Assert that x,y,z analytical derivatives match numerical within
430 a tolerance, or a percentage (of the analytical value), whichever
433 derivs = xyz.get_derivatives()
435 pct = percentage / 100.0
436 self.assertAlmostEqual(self.get_magnitude(derivs-num_derivs),0,
437 delta=tolerance+percentage*self.get_magnitude(num_derivs),
438 msg=
"Don't match "+str(derivs) + str(num_derivs))
439 self.assertAlmostEqual(derivs[0], num_derivs[0],
440 delta=max(tolerance, abs(derivs[0]) * pct))
441 self.assertAlmostEqual(derivs[1], num_derivs[1],
442 delta=max(tolerance, abs(derivs[1]) * pct))
443 self.assertAlmostEqual(derivs[2], num_derivs[2],
444 delta=max(tolerance, abs(derivs[2]) * pct))
447 """Make a particle with optimizable x, y and z attributes, and
448 add it to the model."""
456 """Help handle a test which is expected to fail some fraction of
457 the time. The test is run multiple times and an exception
458 is thrown only if it fails too many times."""
459 prob=chance_of_failure
463 prob= prob*chance_of_failure
464 for i
in range(0, tries):
472 raise AssertError(
"Too many failures")
475 """Estimate how likely a given block of code is to raise an
479 while failures < 10
and tries <1000:
485 return failures/tries
488 """Randomize the xyz coordinates of a list of particles"""
494 p.set_value(xkey, random.uniform(-deviation, deviation))
495 p.set_value(ykey, random.uniform(-deviation, deviation))
496 p.set_value(zkey, random.uniform(-deviation, deviation))
499 """Return distance between two given particles"""
503 dx = p1.get_value(xkey) - p2.get_value(xkey)
504 dy = p1.get_value(ykey) - p2.get_value(ykey)
505 dz = p1.get_value(zkey) - p2.get_value(zkey)
506 return math.sqrt(dx*dx + dy*dy + dz*dz)
509 """Check the unary function func's derivatives against numerical
510 approximations between lb and ub"""
511 for f
in [lb + i * step
for i
in range(1, int((ub-lb)/step))]:
512 (v,d)= func.evaluate_with_derivative(f)
514 self.assertAlmostEqual(d, da, delta=max(abs(.1 *d), 0.01))
517 """Make sure that the minimum of the unary function func over the
518 range between lb and ub is at expected_fmin"""
519 fmin, vmin = lb, func.evaluate(lb)
520 for f
in [lb + i * step
for i
in range(1, int((ub-lb)/step))]:
524 self.assertAlmostEqual(fmin, expected_fmin, delta=step)
529 """Create a bunch of particles in a box"""
534 for i
in range(0,num):
539 def _get_type(self, module, name):
540 return eval(
'type('+module+
"."+name+
')')
542 "Check that all the C++ classes in the module are values or objects."
546 if self._get_type(module.__name__, name)==types.TypeType
and not name.startswith(
"_"):
547 if name.find(
"SwigPyIterator") != -1:
550 if not eval(
'hasattr(%s.%s, "__swig_destroy__")' \
551 % (module.__name__, name)):
553 if name
in exceptions:
555 if name
not in eval(module.__name__+
"._value_types")\
556 and name
not in eval(module.__name__+
"._object_types")\
557 and name
not in eval(module.__name__+
"._raii_types")\
558 and name
not in eval(module.__name__+
"._plural_types"):
560 message=
"All IMP classes should be labeled values or as 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." \
562 self.assertEquals(len(bad), 0,
565 self.assertTrue(e
not in eval(module.__name__+
"._value_types")\
566 + eval(module.__name__+
"._object_types")\
567 + eval(module.__name__+
"._raii_types")\
568 + eval(module.__name__+
"._plural_types"),
569 "Value/Object exception "+e+
" is not an exception")
571 def _check_spelling(self, word, words):
572 """Check that the word is spelled correctly"""
573 if "words" not in dir(self):
576 custom_words=[
"info",
"prechange",
"int",
"ints",
"optimizeds",
"graphviz",
577 "voxel",
"voxels",
"endian",
'rna',
'dna',
578 "xyzr",
"pdbs",
"fft",
"ccc"]
579 self.words=set(wordlist+custom_words)
581 for i
in "0123456789":
586 if word
in self.words:
593 """Check that all the classes in the module follow the imp naming conventions."""
597 cc=re.compile(
"([A-Z][a-z]*)")
599 if self._get_type(module.__name__, name)==types.TypeType
and not name.startswith(
"_"):
600 if name.find(
"SwigPyIterator") != -1:
602 for t
in re.findall(cc, name):
603 if not self._check_spelling(t.lower(), words):
604 misspelled.append(t.lower())
607 self.assertEquals(len(bad), 0,
608 "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." \
609 % (str(bad),
", ".join(set(misspelled))))
612 if self._get_type(module.__name__, name)==types.TypeType
and not name.startswith(
"_"):
613 if name.find(
"SwigPyIterator") != -1:
615 if name.find(
'_') != -1:
617 if name.lower== name:
619 for t
in re.findall(cc, name):
620 if not self._check_spelling(t.lower(), words):
621 print "misspelled", t,
"in", name
623 message=
"All IMP classes should have CamelCase names. The following do not: %s." \
625 self.assertEquals(len(bad), 0,
629 def _check_function_name(self, prefix, name, verbs, all, exceptions, words,
632 fullname=prefix+
"."+name
635 old_exceptions=[
'unprotected_evaluate',
"unprotected_evaluate_if_good",
636 "unprotected_evaluate_if_below",
637 "after_evaluate",
"before_evaluate",
"has_attribute",
638 "decorate_particle",
"particle_is_instance"]
639 if name
in old_exceptions:
642 if fullname
in exceptions:
644 if name.endswith(
"swigregister"):
646 if name.lower() != name:
647 if name[0].lower() != name[0]
and name.split(
'_')[0]
in all:
654 if name.startswith(v):
659 tokens= name.split(
"_")
661 if not self._check_spelling(t, words):
663 print "misspelled", t,
"in", name
666 def _check_function_names(self, module, prefix, names, verbs, all, exceptions, words, misspelled):
670 if name.startswith(
"_")
or name ==
"weakref_proxy":
672 if self._get_type(module, name)==types.BuiltinMethodType\
673 or self._get_type(module, name)==types.MethodType:
674 bad.extend(self._check_function_name(prefix, name, verbs, all, exceptions, words, misspelled))
675 if self._get_type(module, name)==types.TypeType
and name.find(
"SwigPyIterator")==-1:
677 members=eval(
"dir("+module+
"."+name+
")")
679 bad.extend(self._check_function_names(module+
"."+name,
682 verbs, [], exceptions, words, misspelled))
688 """Check that all the functions in the module follow the imp naming conventions."""
690 verbs=[
"add",
"remove",
"get",
"set",
"evaluate",
"compute",
"show",
"create",
"destroy",
691 "push",
"pop",
"write",
"read",
"do",
"show",
"load",
"save",
"reset",
693 "clear",
"handle",
"update",
"apply",
"optimize",
"reserve",
"dump",
694 "propose",
"setup",
"teardown",
"visit",
"find",
"run",
"swap",
"link",
697 bad=self._check_function_names(module.__name__,
None, all, verbs, all, exceptions, words, misspelled)
698 message=
"All IMP methods 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 IMPModuleTest call. Otherwise, please fix. The current verb list is %(verbs)s" \
699 % {
"bad":
"\n".join(bad),
"verbs":verbs}
700 if len(misspelled) > 0:
701 message +=
"\nMisspelled words: " +
", ".join(set(misspelled)) \
702 +
". Add words to the spelling_exceptions variable " \
703 +
"of the IMPModuleTest if needed."
704 self.assertEquals(len(bad), 0,
709 """Check that all the classes in modulename have a show method"""
714 if not eval(
'hasattr(%s.%s, "__swig_destroy__")' \
715 % (modulename.__name__, f)):
717 if self._get_type(modulename.__name__, f) == types.TypeType\
718 and not f.startswith(
"_") \
719 and not f.endswith(
"_swigregister")\
720 and f
not in exceptions\
721 and not f.endswith(
"Temp")
and not f.endswith(
"Iterator")\
722 and not f.endswith(
"Exception")
and\
723 f
not in eval(modulename.__name__+
"._raii_types")
and \
724 f
not in eval(modulename.__name__+
"._plural_types"):
725 if not hasattr(getattr(modulename, f),
'show'):
727 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." \
728 %
"\n".join(not_found)
729 self.assertEquals(len(not_found), 0,
732 self.assertIn(e, all,
"Show exception "+e+
" is not a class in module")
733 self.assertTrue(
not hasattr(getattr(modulename, e),
'show'),
734 "Exception "+e+
" is not really a show exception")
737 """Run the named example script.
738 A dictionary of all the script's global variables is returned.
739 This can be queried in a test case to make sure the example
740 performed correctly."""
741 class _FatalError(Exception):
pass
745 path, name = os.path.split(filename)
746 oldsyspath = sys.path[:]
747 olssysargv= sys.argv[:]
748 sys.path.insert(0, path)
753 exec open(filename)
in vars
756 except SystemExit, e:
757 if e.code != 0
and e.code
is not None:
758 raise _FatalError(
"Example exit with code %s" % str(e.code))
762 sys.path = oldsyspath
765 return _ExecDictProxy(vars)
768 """Run a Python module as if with "python -m <modname>",
769 with the given list of arguments as sys.argv.
771 If module is an already-imported Python module, run its 'main'
772 function and return the result.
774 If module is a string, run the module in a subprocess and return
775 a subprocess.Popen-like object containing the child stdin,
779 if type(module) == type(os):
782 mod = __import__(module, {}, {}, [
''])
783 modpath = mod.__file__
784 if modpath.endswith(
'.pyc'):
785 modpath = modpath[:-1]
786 if type(module) == type(os):
787 old_sys_argv = sys.argv
789 IMP.kernel.OptionParser._use_boost_parser =
False
791 sys.argv = [modpath] + args
794 IMP.kernel.OptionParser._use_boost_parser =
True
795 sys.argv = old_sys_argv
797 return _SubprocessWrapper(sys.executable, [modpath] + args)
800 """Check a Python module designed to be runnable with 'python -m'
801 to make sure it supports standard command line options."""
804 out, err = r.communicate()
805 self.assertEqual(r.returncode, 0)
806 self.assertNotEqual(err,
"")
807 self.assertEqual(out,
"")
810 class _ExecDictProxy(object):
811 """exec returns a Python dictionary, which contains IMP objects, other
812 Python objects, as well as base Python modules (such as sys and
813 __builtins__). If we just delete this dictionary, it is entirely
814 possible that base Python modules are removed from the dictionary
815 *before* some IMP objects. This will prevent the IMP objects' Python
816 destructors from running properly, so C++ objects will not be
817 cleaned up. This class proxies the base dict class, and on deletion
818 attempts to remove keys from the dictionary in an order that allows
819 IMP destructors to fire."""
820 def __init__(self, d):
824 module_type = type(IMP)
827 if type(d[k]) != module_type:
830 for meth
in [
'__contains__',
'__getitem__',
'__iter__',
'__len__',
831 'get',
'has_key',
'items',
'keys',
'values']:
832 exec(
"def %s(self, *args, **keys): "
833 "return self._d.%s(*args, **keys)" % (meth, meth))
836 class _TestResult(unittest.TextTestResult):
838 def __init__(self, stream=None, descriptions=None, verbosity=None):
839 super(_TestResult, self).__init__(stream, descriptions, verbosity)
842 def stopTestRun(self):
843 if 'IMP_TEST_DETAIL_DIR' in os.environ:
844 fname = os.path.join(os.environ[
'IMP_TEST_DETAIL_DIR'],
845 os.path.basename(sys.argv[0]))
846 pickle.dump(self.all_tests, open(fname,
'wb'), -1)
847 super(_TestResult, self).stopTestRun()
849 def startTest(self, test):
850 super(_TestResult, self).startTest(test)
851 test.start_time=datetime.datetime.now()
853 def _test_finished(self, test, state, detail=None):
854 delta = datetime.datetime.now() - test.start_time
856 pv= delta.total_seconds()
857 except AttributeError:
858 pv = (float(delta.microseconds) \
859 + (delta.seconds + delta.days * 24 * 3600) * 10**6) / 10**6
861 self.stream.write(
"in %.3fs ... " % pv)
862 if detail
is not None and not isinstance(detail, str):
863 detail = self._exc_info_to_string(detail, test)
864 test_doc = self.getDescription(test)
865 test_name = test.id()
866 if test_name.startswith(
'__main__.'):
867 test_name = test_name[9:]
868 self.all_tests.append({
'name': test_name,
869 'docstring': test_doc,
870 'time': pv,
'state': state,
'detail': detail})
872 def addSuccess(self, test):
873 self._test_finished(test,
'OK')
874 super(_TestResult, self).addSuccess(test)
876 def addError(self, test, err):
877 self._test_finished(test,
'ERROR', err)
878 super(_TestResult, self).addError(test, err)
880 def addFailure(self, test, err):
881 self._test_finished(test,
'FAIL', err)
882 super(_TestResult, self).addFailure(test, err)
884 def addSkip(self, test, reason):
885 self._test_finished(test,
'SKIP', reason)
886 super(_TestResult, self).addSkip(test, reason)
888 def addExpectedFailure(self, test, err):
889 self._test_finished(test,
'EXPFAIL', err)
890 super(_TestResult, self).addExpectedFailure(test, err)
892 def addUnexpectedSuccess(self, test):
893 self._test_finished(test,
'UNEXPSUC', err)
894 super(_TestResult, self).addUnexpectedSuccess(test)
896 def getDescription(self, test):
897 doc_first_line = test.shortDescription()
898 if self.descriptions
and doc_first_line:
899 return doc_first_line
904 class _TestRunner(unittest.TextTestRunner):
905 def _makeResult(self):
906 return _TestResult(self.stream, self.descriptions, self.verbosity)
909 def main(*args, **keys):
910 """Run a set of tests; essentially the same as unittest.main(). Obviates
911 the need to separately import the 'unittest' module, and ensures that
912 main() is from the same unittest module that the IMP.test testcases
914 return unittest.main(testRunner=_TestRunner, *args, **keys)
918 class _SubprocessWrapper(subprocess.Popen):
919 def __init__(self, app, args):
922 if sys.platform ==
'win32' and app != sys.executable:
924 libdir = os.environ[
'PYTHONPATH'].split(
';')[0]
925 env = os.environ.copy()
926 env[
'PATH'] +=
';' + libdir
929 subprocess.Popen.__init__(self, [app]+list(args),
930 stdin=subprocess.PIPE,
931 stdout=subprocess.PIPE,
932 stderr=subprocess.PIPE, env=env)
937 class _SubprocessWrapper(object):
938 def __init__(self, app, args):
939 self.popen = popen2.Popen3(app +
" " +
" ".join(args),
True)
940 self.stdin = self.popen.tochild
941 self.stdout = self.popen.fromchild
942 self.stderr = self.popen.childerr
944 def _readerthread(self, fh, buffer):
945 buffer.append(fh.read())
947 def communicate(self, input=None):
950 stdout_thread = threading.Thread(target=self._readerthread,
951 args=(self.stdout, stdout))
952 stdout_thread.setDaemon(
True)
953 stdout_thread.start()
954 stderr_thread = threading.Thread(target=self._readerthread,
955 args=(self.stderr, stderr))
956 stderr_thread.setDaemon(
True)
957 stderr_thread.start()
960 self.stdin.write(input)
964 self.returncode = self.popen.wait()
965 return stdout[0], stderr[0]
969 """Super class for simple IMP application test cases"""
970 def _get_application_file_name(self, filename):
973 if sys.platform ==
'win32':
981 """Run an application with the given list of arguments.
982 @return a subprocess.Popen-like object containing the child stdin,
985 filename = self._get_application_file_name(app)
986 if sys.platform ==
'win32':
988 return _SubprocessWrapper(os.path.join(os.environ[
'IMP_BIN_DIR'],
991 return _SubprocessWrapper(filename, args)
994 """Run a Python application with the given list of arguments.
995 The Python application should be self-runnable (i.e. it should
996 be executable and with a #! on the first line).
997 @return a subprocess.Popen-like object containing the child stdin,
1001 if sys.executable !=
'/usr/bin/python':
1002 return _SubprocessWrapper(sys.executable,
1003 [os.path.join(os.environ[
'IMP_BIN_DIR'], app)] + args)
1005 return _SubprocessWrapper(app, args)
1008 """Import an installed Python application, rather than running it.
1009 This is useful to directly test components of the application.
1010 @return the Python module object."""
1012 return imp.load_source(os.path.splitext(app)[0],
1013 os.path.join(os.environ[
'IMP_BIN_DIR'], app))
1016 """Run an application with the given list of arguments.
1017 @return a subprocess.Popen-like object containing the child stdin,
1020 return _SubprocessWrapper(sys.executable, [app]+args)
1023 """Assert that the application exited cleanly (return value = 0)."""
1025 raise OSError(
"Application exited with signal %d\n" % -ret\
1028 self.assertEqual(ret, 0,
1029 "Application exited uncleanly, with exit code %d\n" % ret\
1033 """Read and return a set of shell commands from a doxygen file.
1034 Each command is assumed to be in a \\code{.sh}...\\endcode block.
1035 The doxygen file is specified relative to the test file itself.
1036 This is used to make sure the commands shown in an application
1037 example actually work (the testcase can also check the resulting
1038 files for correctness)."""
1039 def fix_win32_command(cmd):
1041 if cmd.startswith(
'cp -r '):
1042 return 'xcopy /E ' + cmd[6:]
1043 elif cmd.startswith(
'cp '):
1044 return 'copy ' + cmd[3:]
1047 d = os.path.dirname(sys.argv[0])
1048 doc = os.path.join(d, doxfile)
1051 example_path = os.path.abspath(IMP.get_example_path(
'..'))
1052 for line
in open(doc).readlines():
1053 if '\code{.sh}' in line:
1055 elif '\endcode' in line:
1058 cmds.append(line.rstrip(
'\r\n').replace(
'<imp_example_path>',
1060 if sys.platform ==
'win32':
1061 cmds = [fix_win32_command(x)
for x
in cmds]
1065 "Print and run a shell command, as returned by read_shell_commands()"
1068 p = subprocess.call(cmd, shell=
True)
1070 raise OSError(
"%s failed with exit value %d" % (cmd, p))
1074 """Check to make sure the number of C++ object references is as expected"""
1076 def __init__(self, testcase):
1080 IMP.base._director_objects.cleanup()
1081 self.__testcase = testcase
1083 self.__basenum = IMP.base.Object.get_number_of_live_objects()
1087 "Make sure that the number of references matches the expected value."
1089 IMP.base._director_objects.cleanup()
1092 newnum=IMP.base.Object.get_number_of_live_objects()-self.__basenum
1093 t.assertEqual(newnum, expected,
1094 "Number of objects don't match: "\
1096 +
" != "+ str(expected) +
" found "+\
1102 """Check to make sure the number of director references is as expected"""
1104 def __init__(self, testcase):
1105 IMP.base._director_objects.cleanup()
1106 self.__testcase = testcase
1107 self.__basenum = IMP.base._director_objects.get_object_count()
1110 """Make sure that the number of references matches the expected value.
1111 If force_cleanup is set, clean up any unused references first before
1112 doing the assertion.
1116 IMP.base._director_objects.cleanup()
1117 t.assertEqual(IMP.base._director_objects.get_object_count() \
1118 - self.__basenum, expected)
1126 if sys.platform ==
'win32' and 'PYTHONPATH' in os.environ \
1127 and 'IMP_BIN_DIR' in os.environ:
1128 libdir = os.environ[
'PYTHONPATH'].split(
';')[0]
1129 bindir = os.environ[
'IMP_BIN_DIR']
1130 path = os.environ[
'PATH']
1131 if libdir
not in path
or bindir
not in path:
1132 os.environ[
'PATH'] = bindir +
';' + libdir +
';' + path
1135 def get_module_version():
1136 """get_module_version() -> std::string const"""
1137 return _IMP_test.get_module_version()
1140 """get_example_path(std::string fname) -> std::string"""
1141 return _IMP_test.get_example_path(*args)
1144 """get_data_path(std::string fname) -> std::string"""
1145 return _IMP_test.get_data_path(*args)
1146 import _version_check
1147 _version_check.check_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 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.
Super class for simple IMP application test cases.
void set_check_level(CheckLevel tf)
Control runtime checks in the code.
See IMP.base for more information.
std::string get_example_path(std::string file_name)
Return the path to installed example data for this module.
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()
Vector3D get_random_vector_in(const Cylinder3D &c)
Generate a random vector in a cylinder with uniform density.
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.
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 build/tmp directory.
See IMP.kernel for more information.
def run_example
Run the named example script.
Class to handle individual model particles.
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.
See IMP.algebra for more information.
def numerical_derivative
Calculate the derivative of the single-value function func at point val.
def xyz_numerical_derivatives
Calculate the x,y and z derivatives of model's scoring function 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.
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 installed data.
Check to make sure the number of C++ object references is as expected.
def assertFunctionNames
Check that all the functions in the module follow the imp naming conventions.
def assertValueObjects
Check that all the C++ classes in the module are values or objects.
CheckLevel get_check_level()
Get the current audit mode.
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...
Strings get_live_object_names()