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."
544 ok = set(exceptions_list + eval(module.__name__+
"._value_types") + eval(module.__name__+
"._object_types") + eval(module.__name__+
"._raii_types") +eval(module.__name__+
"._plural_types"))
548 if self._get_type(module.__name__, name)==types.TypeType
and not name.startswith(
"_"):
549 if name.find(
"SwigPyIterator") != -1:
552 if not eval(
'hasattr(%s.%s, "__swig_destroy__")' \
553 % (module.__name__, name)):
558 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." \
560 self.assertEquals(len(bad), 0,
562 for e
in exceptions_list:
563 self.assertTrue(e
not in eval(module.__name__+
"._value_types")\
564 + eval(module.__name__+
"._object_types")\
565 + eval(module.__name__+
"._raii_types")\
566 + eval(module.__name__+
"._plural_types"),
567 "Value/Object exception "+e+
" is not an exception")
569 def _check_spelling(self, word, words):
570 """Check that the word is spelled correctly"""
571 if "words" not in dir(self):
574 custom_words=[
"info",
"prechange",
"int",
"ints",
"optimizeds",
"graphviz",
575 "voxel",
"voxels",
"endian",
'rna',
'dna',
576 "xyzr",
"pdbs",
"fft",
"ccc",
"gaussian"]
577 self.words=set(wordlist+custom_words)
579 for i
in "0123456789":
584 if word
in self.words:
591 """Check that all the classes in the module follow the imp naming conventions."""
595 cc=re.compile(
"([A-Z][a-z]*)")
597 if self._get_type(module.__name__, name)==types.TypeType
and not name.startswith(
"_"):
598 if name.find(
"SwigPyIterator") != -1:
600 for t
in re.findall(cc, name):
601 if not self._check_spelling(t.lower(), words):
602 misspelled.append(t.lower())
605 self.assertEquals(len(bad), 0,
606 "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." \
607 % (str(bad),
", ".join(set(misspelled))))
610 if self._get_type(module.__name__, name)==types.TypeType
and not name.startswith(
"_"):
611 if name.find(
"SwigPyIterator") != -1:
613 if name.find(
'_') != -1:
615 if name.lower== name:
617 for t
in re.findall(cc, name):
618 if not self._check_spelling(t.lower(), words):
619 print "misspelled", t,
"in", name
621 message=
"All IMP classes should have CamelCase names. The following do not: %s." \
623 self.assertEquals(len(bad), 0,
627 def _check_function_name(self, prefix, name, verbs, all, exceptions, words,
630 fullname=prefix+
"."+name
633 old_exceptions=[
'unprotected_evaluate',
"unprotected_evaluate_if_good",
634 "unprotected_evaluate_if_below",
635 "after_evaluate",
"before_evaluate",
"has_attribute",
636 "decorate_particle",
"particle_is_instance"]
637 if name
in old_exceptions:
640 if fullname
in exceptions:
642 if name.endswith(
"swigregister"):
644 if name.lower() != name:
645 if name[0].lower() != name[0]
and name.split(
'_')[0]
in all:
650 tokens= name.split(
"_")
651 if tokens[0]
not in verbs:
654 if not self._check_spelling(t, words):
656 print "misspelled", t,
"in", name
659 def _check_function_names(self, module, prefix, names, verbs, all, exceptions, words, misspelled):
663 if name.startswith(
"_")
or name ==
"weakref_proxy":
665 if self._get_type(module, name)==types.BuiltinMethodType\
666 or self._get_type(module, name)==types.MethodType:
667 bad.extend(self._check_function_name(prefix, name, verbs, all, exceptions, words, misspelled))
668 if self._get_type(module, name)==types.TypeType
and name.find(
"SwigPyIterator")==-1:
670 members=eval(
"dir("+module+
"."+name+
")")
672 bad.extend(self._check_function_names(module+
"."+name,
675 verbs, [], exceptions, words, misspelled))
681 """Check that all the functions in the module follow the imp naming conventions."""
683 verbs=set([
"add",
"remove",
"get",
"set",
"evaluate",
"compute",
"show",
"create",
"destroy",
684 "push",
"pop",
"write",
"read",
"do",
"show",
"load",
"save",
"reset",
686 "clear",
"handle",
"update",
"apply",
"optimize",
"reserve",
"dump",
687 "propose",
"setup",
"teardown",
"visit",
"find",
"run",
"swap",
"link",
690 bad=self._check_function_names(module.__name__,
None, all, verbs, all, exceptions, words, misspelled)
691 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 standards_exceptions file. Otherwise, please fix. The current verb list is %(verbs)s" \
692 % {
"bad":
"\n".join(bad),
"verbs":verbs}
693 if len(misspelled) > 0:
694 message +=
"\nMisspelled words: " +
", ".join(set(misspelled)) \
695 +
". Add words to the spelling_exceptions variable " \
696 +
"of the standards_exceptions file if needed."
697 self.assertEquals(len(bad), 0,
702 """Check that all the classes in modulename have a show method"""
707 if not eval(
'hasattr(%s.%s, "__swig_destroy__")' \
708 % (modulename.__name__, f)):
710 if self._get_type(modulename.__name__, f) == types.TypeType\
711 and not f.startswith(
"_") \
712 and not f.endswith(
"_swigregister")\
713 and f
not in exceptions\
714 and not f.endswith(
"Temp")
and not f.endswith(
"Iterator")\
715 and not f.endswith(
"Exception")
and\
716 f
not in eval(modulename.__name__+
"._raii_types")
and \
717 f
not in eval(modulename.__name__+
"._plural_types"):
718 if not hasattr(getattr(modulename, f),
'show'):
720 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." \
721 %
"\n".join(not_found)
722 self.assertEquals(len(not_found), 0,
725 self.assertIn(e, all,
"Show exception "+e+
" is not a class in module")
726 self.assertTrue(
not hasattr(getattr(modulename, e),
'show'),
727 "Exception "+e+
" is not really a show exception")
730 """Run the named example script.
731 A dictionary of all the script's global variables is returned.
732 This can be queried in a test case to make sure the example
733 performed correctly."""
734 class _FatalError(Exception):
pass
738 path, name = os.path.split(filename)
739 oldsyspath = sys.path[:]
740 olssysargv= sys.argv[:]
741 sys.path.insert(0, path)
746 exec open(filename)
in vars
749 except SystemExit, e:
750 if e.code != 0
and e.code
is not None:
751 raise _FatalError(
"Example exit with code %s" % str(e.code))
755 sys.path = oldsyspath
758 return _ExecDictProxy(vars)
761 """Run a Python module as if with "python -m <modname>",
762 with the given list of arguments as sys.argv.
764 If module is an already-imported Python module, run its 'main'
765 function and return the result.
767 If module is a string, run the module in a subprocess and return
768 a subprocess.Popen-like object containing the child stdin,
772 if type(module) == type(os):
775 mod = __import__(module, {}, {}, [
''])
776 modpath = mod.__file__
777 if modpath.endswith(
'.pyc'):
778 modpath = modpath[:-1]
779 if type(module) == type(os):
780 old_sys_argv = sys.argv
782 IMP.kernel.OptionParser._use_boost_parser =
False
784 sys.argv = [modpath] + args
787 IMP.kernel.OptionParser._use_boost_parser =
True
788 sys.argv = old_sys_argv
790 return _SubprocessWrapper(sys.executable, [modpath] + args)
793 """Check a Python module designed to be runnable with 'python -m'
794 to make sure it supports standard command line options."""
797 out, err = r.communicate()
798 self.assertEqual(r.returncode, 0)
799 self.assertNotEqual(err,
"")
800 self.assertEqual(out,
"")
803 class _ExecDictProxy(object):
804 """exec returns a Python dictionary, which contains IMP objects, other
805 Python objects, as well as base Python modules (such as sys and
806 __builtins__). If we just delete this dictionary, it is entirely
807 possible that base Python modules are removed from the dictionary
808 *before* some IMP objects. This will prevent the IMP objects' Python
809 destructors from running properly, so C++ objects will not be
810 cleaned up. This class proxies the base dict class, and on deletion
811 attempts to remove keys from the dictionary in an order that allows
812 IMP destructors to fire."""
813 def __init__(self, d):
817 module_type = type(IMP)
820 if type(d[k]) != module_type:
823 for meth
in [
'__contains__',
'__getitem__',
'__iter__',
'__len__',
824 'get',
'has_key',
'items',
'keys',
'values']:
825 exec(
"def %s(self, *args, **keys): "
826 "return self._d.%s(*args, **keys)" % (meth, meth))
829 class _TestResult(unittest.TextTestResult):
831 def __init__(self, stream=None, descriptions=None, verbosity=None):
832 super(_TestResult, self).__init__(stream, descriptions, verbosity)
835 def stopTestRun(self):
836 if 'IMP_TEST_DETAIL_DIR' in os.environ:
837 fname = os.path.join(os.environ[
'IMP_TEST_DETAIL_DIR'],
838 os.path.basename(sys.argv[0]))
839 pickle.dump(self.all_tests, open(fname,
'wb'), -1)
840 super(_TestResult, self).stopTestRun()
842 def startTest(self, test):
843 super(_TestResult, self).startTest(test)
844 test.start_time=datetime.datetime.now()
846 def _test_finished(self, test, state, detail=None):
847 delta = datetime.datetime.now() - test.start_time
849 pv= delta.total_seconds()
850 except AttributeError:
851 pv = (float(delta.microseconds) \
852 + (delta.seconds + delta.days * 24 * 3600) * 10**6) / 10**6
854 self.stream.write(
"in %.3fs ... " % pv)
855 if detail
is not None and not isinstance(detail, str):
856 detail = self._exc_info_to_string(detail, test)
857 test_doc = self.getDescription(test)
858 test_name = test.id()
859 if test_name.startswith(
'__main__.'):
860 test_name = test_name[9:]
861 self.all_tests.append({
'name': test_name,
862 'docstring': test_doc,
863 'time': pv,
'state': state,
'detail': detail})
865 def addSuccess(self, test):
866 self._test_finished(test,
'OK')
867 super(_TestResult, self).addSuccess(test)
869 def addError(self, test, err):
870 self._test_finished(test,
'ERROR', err)
871 super(_TestResult, self).addError(test, err)
873 def addFailure(self, test, err):
874 self._test_finished(test,
'FAIL', err)
875 super(_TestResult, self).addFailure(test, err)
877 def addSkip(self, test, reason):
878 self._test_finished(test,
'SKIP', reason)
879 super(_TestResult, self).addSkip(test, reason)
881 def addExpectedFailure(self, test, err):
882 self._test_finished(test,
'EXPFAIL', err)
883 super(_TestResult, self).addExpectedFailure(test, err)
885 def addUnexpectedSuccess(self, test):
886 self._test_finished(test,
'UNEXPSUC')
887 super(_TestResult, self).addUnexpectedSuccess(test)
889 def getDescription(self, test):
890 doc_first_line = test.shortDescription()
891 if self.descriptions
and doc_first_line:
892 return doc_first_line
897 class _TestRunner(unittest.TextTestRunner):
898 def _makeResult(self):
899 return _TestResult(self.stream, self.descriptions, self.verbosity)
902 def main(*args, **keys):
903 """Run a set of tests; essentially the same as unittest.main(). Obviates
904 the need to separately import the 'unittest' module, and ensures that
905 main() is from the same unittest module that the IMP.test testcases
907 return unittest.main(testRunner=_TestRunner, *args, **keys)
911 class _SubprocessWrapper(subprocess.Popen):
912 def __init__(self, app, args):
915 if sys.platform ==
'win32' and app != sys.executable:
917 libdir = os.environ[
'PYTHONPATH'].split(
';')[0]
918 env = os.environ.copy()
919 env[
'PATH'] +=
';' + libdir
922 subprocess.Popen.__init__(self, [app]+list(args),
923 stdin=subprocess.PIPE,
924 stdout=subprocess.PIPE,
925 stderr=subprocess.PIPE, env=env)
930 class _SubprocessWrapper(object):
931 def __init__(self, app, args):
932 self.popen = popen2.Popen3(app +
" " +
" ".join(args),
True)
933 self.stdin = self.popen.tochild
934 self.stdout = self.popen.fromchild
935 self.stderr = self.popen.childerr
937 def _readerthread(self, fh, buffer):
938 buffer.append(fh.read())
940 def communicate(self, input=None):
943 stdout_thread = threading.Thread(target=self._readerthread,
944 args=(self.stdout, stdout))
945 stdout_thread.setDaemon(
True)
946 stdout_thread.start()
947 stderr_thread = threading.Thread(target=self._readerthread,
948 args=(self.stderr, stderr))
949 stderr_thread.setDaemon(
True)
950 stderr_thread.start()
953 self.stdin.write(input)
957 self.returncode = self.popen.wait()
958 return stdout[0], stderr[0]
962 """Super class for simple IMP application test cases"""
963 def _get_application_file_name(self, filename):
966 if sys.platform ==
'win32':
974 """Run an application with the given list of arguments.
975 @return a subprocess.Popen-like object containing the child stdin,
978 filename = self._get_application_file_name(app)
979 if sys.platform ==
'win32':
981 return _SubprocessWrapper(os.path.join(os.environ[
'IMP_BIN_DIR'],
984 return _SubprocessWrapper(filename, args)
987 """Run a Python application with the given list of arguments.
988 The Python application should be self-runnable (i.e. it should
989 be executable and with a #! on the first line).
990 @return a subprocess.Popen-like object containing the child stdin,
994 if sys.executable !=
'/usr/bin/python':
995 return _SubprocessWrapper(sys.executable,
996 [os.path.join(os.environ[
'IMP_BIN_DIR'], app)] + args)
998 return _SubprocessWrapper(app, args)
1001 """Import an installed Python application, rather than running it.
1002 This is useful to directly test components of the application.
1003 @return the Python module object."""
1005 return imp.load_source(os.path.splitext(app)[0],
1006 os.path.join(os.environ[
'IMP_BIN_DIR'], app))
1009 """Run an application with the given list of arguments.
1010 @return a subprocess.Popen-like object containing the child stdin,
1013 return _SubprocessWrapper(sys.executable, [app]+args)
1016 """Assert that the application exited cleanly (return value = 0)."""
1018 raise OSError(
"Application exited with signal %d\n" % -ret\
1021 self.assertEqual(ret, 0,
1022 "Application exited uncleanly, with exit code %d\n" % ret\
1026 """Read and return a set of shell commands from a doxygen file.
1027 Each command is assumed to be in a \\code{.sh}...\\endcode block.
1028 The doxygen file is specified relative to the test file itself.
1029 This is used to make sure the commands shown in an application
1030 example actually work (the testcase can also check the resulting
1031 files for correctness)."""
1032 def fix_win32_command(cmd):
1034 if cmd.startswith(
'cp -r '):
1035 return 'xcopy /E ' + cmd[6:]
1036 elif cmd.startswith(
'cp '):
1037 return 'copy ' + cmd[3:]
1040 d = os.path.dirname(sys.argv[0])
1041 doc = os.path.join(d, doxfile)
1044 example_path = os.path.abspath(IMP.get_example_path(
'..'))
1045 for line
in open(doc).readlines():
1046 if '\code{.sh}' in line:
1048 elif '\endcode' in line:
1051 cmds.append(line.rstrip(
'\r\n').replace(
'<imp_example_path>',
1053 if sys.platform ==
'win32':
1054 cmds = [fix_win32_command(x)
for x
in cmds]
1058 "Print and run a shell command, as returned by read_shell_commands()"
1061 p = subprocess.call(cmd, shell=
True)
1063 raise OSError(
"%s failed with exit value %d" % (cmd, p))
1067 """Check to make sure the number of C++ object references is as expected"""
1069 def __init__(self, testcase):
1073 IMP.base._director_objects.cleanup()
1074 self.__testcase = testcase
1076 self.__basenum = IMP.base.Object.get_number_of_live_objects()
1080 "Make sure that the number of references matches the expected value."
1082 IMP.base._director_objects.cleanup()
1085 newnum=IMP.base.Object.get_number_of_live_objects()-self.__basenum
1086 t.assertEqual(newnum, expected,
1087 "Number of objects don't match: "\
1089 +
" != "+ str(expected) +
" found "+\
1095 """Check to make sure the number of director references is as expected"""
1097 def __init__(self, testcase):
1098 IMP.base._director_objects.cleanup()
1099 self.__testcase = testcase
1100 self.__basenum = IMP.base._director_objects.get_object_count()
1103 """Make sure that the number of references matches the expected value.
1104 If force_cleanup is set, clean up any unused references first before
1105 doing the assertion.
1109 IMP.base._director_objects.cleanup()
1110 t.assertEqual(IMP.base._director_objects.get_object_count() \
1111 - self.__basenum, expected)
1119 if sys.platform ==
'win32' and 'PYTHONPATH' in os.environ \
1120 and 'IMP_BIN_DIR' in os.environ:
1121 libdir = os.environ[
'PYTHONPATH'].split(
';')[0]
1122 bindir = os.environ[
'IMP_BIN_DIR']
1123 path = os.environ[
'PATH']
1124 if libdir
not in path
or bindir
not in path:
1125 os.environ[
'PATH'] = bindir +
';' + libdir +
';' + path
1128 def get_module_version():
1129 """get_module_version() -> std::string const"""
1130 return _IMP_test.get_module_version()
1133 """get_example_path(std::string fname) -> std::string"""
1134 return _IMP_test.get_example_path(*args)
1137 """get_data_path(std::string fname) -> std::string"""
1138 return _IMP_test.get_data_path(*args)
1139 import _version_check
1140 _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()