From 5df51d99bb711ebef7e063830e7289fb8ace20c9 Mon Sep 17 00:00:00 2001
From: Gerardo Tauriello <gerardo.tauriello@unibas.ch>
Date: Fri, 7 Jul 2017 09:51:27 +0200
Subject: [PATCH] Unified handling for compound lib dependent python unittests.

This also enabled test_cleanup, test_nonstandard and test_aligntoseqres which
were previously skipped with 'make check' indep. of compound lib availability
(simply because unittests are launched with 'python' and not with 'ost').
---
 modules/base/doc/testutils.rst              |  4 +-
 modules/base/pymod/testutils.py             | 55 ++++++++++++++++++++-
 modules/conop/doc/compoundlib.rst           |  2 +-
 modules/conop/tests/CMakeLists.txt          |  6 +--
 modules/conop/tests/test_cleanup.py         | 15 +++---
 modules/conop/tests/test_compound.py        | 19 ++-----
 modules/conop/tests/test_nonstandard.py     | 12 ++---
 modules/mol/alg/tests/test_qsscoring.py     | 25 +++-------
 modules/seq/alg/tests/CMakeLists.txt        |  5 +-
 modules/seq/alg/tests/test_aligntoseqres.py | 15 +++---
 10 files changed, 98 insertions(+), 60 deletions(-)

diff --git a/modules/base/doc/testutils.rst b/modules/base/doc/testutils.rst
index 649a0b3b3..df61f56e7 100644
--- a/modules/base/doc/testutils.rst
+++ b/modules/base/doc/testutils.rst
@@ -4,4 +4,6 @@
 .. module:: ost.testutils
   :synopsis: Helper Functions to Run Python Unittests
 
-.. autofunction:: ost.testutils.RunTests
\ No newline at end of file
+.. autofunction:: ost.testutils.RunTests
+
+.. autofunction:: ost.testutils.SetDefaultCompoundLib
diff --git a/modules/base/pymod/testutils.py b/modules/base/pymod/testutils.py
index fe3e7a024..5dd8762e2 100644
--- a/modules/base/pymod/testutils.py
+++ b/modules/base/pymod/testutils.py
@@ -51,4 +51,57 @@ def RunTests():
     else:
       unittest.main()
   except Exception, e:
-    print e
\ No newline at end of file
+    print e
+
+
+def SetDefaultCompoundLib():
+  '''
+  This function tries to ensure that a default compound library is set.
+  When calling scripts with ``ost`` this is not needed, but since unit tests are
+  called with ``python`` we need to ensure that it is set. The function is only
+  expected to succeed (and return True) if ``COMPOUND_LIB`` was set when
+  :ref:`configuring the compilation <cmake-flags>`.
+
+  It tries the following:
+
+  - get it with :func:`ost.conop.GetDefaultLib`
+  - look for ``compounds.chemlib`` in ``$OST_ROOT/share/openstructure``
+  - if ``OST_ROOT`` not set in the above, try to guess it based on the path of
+    the ``conop`` module
+
+  To use this check modify the :func:`RunTests` call to read:
+
+  .. code-block:: python
+
+    if __name__ == "__main__":
+      from ost import testutils
+      if testutils.SetDefaultCompoundLib():
+        testutils.RunTests()
+      else:
+        print 'No compound library available. Ignoring test_XXX.py tests.'
+
+  :return: True, if a compound library was found and set to be accessed with
+           :func:`ost.conop.GetDefaultLib`. False otherwise.
+  '''
+  import os
+  from ost import conop, GetSharedDataPath, SetPrefixPath
+  # check if already there
+  if conop.GetDefaultLib():
+    return True
+  else:
+    # try to get the shared data path?
+    try:
+      shared_data_path = GetSharedDataPath()
+    except Exception, e:
+      SetPrefixPath(os.path.abspath(os.path.join(conop.__path__[0], os.pardir,
+                                                 os.pardir, os.pardir,
+                                                 os.pardir, os.pardir)))
+      shared_data_path = GetSharedDataPath()
+    # look for compounds.chemlib in there
+    compound_lib_path = os.path.join(shared_data_path, 'compounds.chemlib')
+    if os.path.exists(compound_lib_path):
+      compound_lib = conop.CompoundLib.Load(compound_lib_path)
+      conop.SetDefaultLib(compound_lib)
+      return True
+    else:
+      return False
diff --git a/modules/conop/doc/compoundlib.rst b/modules/conop/doc/compoundlib.rst
index f88f04709..caca8445b 100644
--- a/modules/conop/doc/compoundlib.rst
+++ b/modules/conop/doc/compoundlib.rst
@@ -25,7 +25,7 @@ build the compound library manually.
            OpenStructure as a bundle or you :ref:`compiled <cmake-flags>`  it
            with a specified ``COMPOUND_LIB`` flag, this will return a compound
            library when executing scripts with ``ost``.
-  :rtype:  :class:`CompoundLib`
+  :rtype:  :class:`CompoundLib` or None if no library set
 
 .. function:: SetDefaultLib(lib)
 
diff --git a/modules/conop/tests/CMakeLists.txt b/modules/conop/tests/CMakeLists.txt
index 58a605268..964006509 100644
--- a/modules/conop/tests/CMakeLists.txt
+++ b/modules/conop/tests/CMakeLists.txt
@@ -4,13 +4,13 @@ set(OST_CONOP_UNIT_TESTS
   tests.cc
   test_rule_based_conop.cc 
   helper.cc
-  test_cleanup.py
   test_processor.py
-  test_nonstandard.py
 )
 
 if (COMPOUND_LIB)
-  list(APPEND OST_CONOP_UNIT_TESTS test_compound.py)
+  list(APPEND OST_CONOP_UNIT_TESTS test_compound.py
+                                   test_cleanup.py
+                                   test_nonstandard.py)
 endif()
 
 ost_unittest(MODULE conop
diff --git a/modules/conop/tests/test_cleanup.py b/modules/conop/tests/test_cleanup.py
index 9c5f0cf27..b0579127a 100644
--- a/modules/conop/tests/test_cleanup.py
+++ b/modules/conop/tests/test_cleanup.py
@@ -1,12 +1,13 @@
 import sys
 import unittest
-from ost import geom, conop
+from ost import geom, conop, io
 from ost.conop import cleanup
 
 class TestCleanUp(unittest.TestCase):
 
   def setUp(self):
-    self.comp_lib=conop.GetDefaultLib()
+    self.comp_lib = conop.GetDefaultLib()
+    io.profiles['DEFAULT'].processor = conop.RuleBasedProcessor(self.comp_lib)
     self.ent = io.LoadPDB("sample_test_cleanup.pdb")
     self.ent_no_wat = io.LoadPDB("sample_nowater.pdb")
     self.ent_no_lig = io.LoadPDB("sample_noligands.pdb")
@@ -156,10 +157,10 @@ class TestCleanUp(unittest.TestCase):
     self.assertFalse(self.new_ent.residues[6].IsPeptideLinking()) # here assertFalse instead of assertTrue
     self.assertTrue(self.new_ent.residues[6].atoms[0].is_hetatom)
 
-if not conop.GetDefaultLib():
-  print 'No compound library available. Ignoring test_cleanup.py tests'
-  sys.exit()
 
-if __name__== '__main__':
+if __name__ == "__main__":
   from ost import testutils
-  testutils.RunTests()
+  if testutils.SetDefaultCompoundLib():
+    testutils.RunTests()
+  else:
+    print 'No compound library available. Ignoring test_cleanup.py tests.'
diff --git a/modules/conop/tests/test_compound.py b/modules/conop/tests/test_compound.py
index fd480a54b..bd54b7dfa 100644
--- a/modules/conop/tests/test_compound.py
+++ b/modules/conop/tests/test_compound.py
@@ -1,17 +1,6 @@
 import unittest
-import os
-from ost import GetSharedDataPath, SetPrefixPath
-from ost import mol
-from ost import conop
+from ost import mol, conop
 
-def setUpModule():
-    SetPrefixPath(os.path.abspath(os.path.join(conop.__path__[0], os.pardir,
-                                               os.pardir, os.pardir,
-                                               os.pardir, os.pardir)))
-    compound_lib_path = os.path.join(GetSharedDataPath(),
-                                     'compounds.chemlib')
-    compound_lib = conop.CompoundLib.Load(compound_lib_path)
-    conop.SetDefaultLib(compound_lib)
 
 class TestCompound(unittest.TestCase):
     def setUp(self):
@@ -36,5 +25,7 @@ class TestCompound(unittest.TestCase):
      
 if __name__=='__main__':
     from ost import testutils
-    testutils.RunTests()
-
+    if testutils.SetDefaultCompoundLib():
+        testutils.RunTests()
+    else:
+        print 'No compound library available. Ignoring test_compound.py tests.'
\ No newline at end of file
diff --git a/modules/conop/tests/test_nonstandard.py b/modules/conop/tests/test_nonstandard.py
index f10b7d9d0..566db9a2b 100644
--- a/modules/conop/tests/test_nonstandard.py
+++ b/modules/conop/tests/test_nonstandard.py
@@ -1,5 +1,5 @@
 import unittest
-from ost import conop
+from ost import conop, io, mol
 
 
 class TestNonStandard(unittest.TestCase):
@@ -117,10 +117,8 @@ class TestNonStandard(unittest.TestCase):
     
 
 if __name__ == "__main__":
-  if not conop.GetDefaultLib():
-    print 'No compound library available. Ignoring unit tests'
-  else:
-    from ost import testutils
+  from ost import testutils
+  if testutils.SetDefaultCompoundLib():
     testutils.RunTests()
-
-
+  else:
+    print 'No compound library available. Ignoring test_nonstandard.py tests.'
diff --git a/modules/mol/alg/tests/test_qsscoring.py b/modules/mol/alg/tests/test_qsscoring.py
index b883f2f34..a860a0528 100644
--- a/modules/mol/alg/tests/test_qsscoring.py
+++ b/modules/mol/alg/tests/test_qsscoring.py
@@ -1,24 +1,12 @@
-import unittest
-import ost, os
-from ost import io, conop
-from ost import GetSharedDataPath, SetPrefixPath
+import unittest, os
+from ost import io
 from ost.mol.alg.qsscoring import *
 
+
 def _LoadFile(file_name):
   """Helper to avoid repeating input path over and over."""
   return io.LoadPDB(os.path.join('testfiles', file_name))
 
-def setUpModule():
-  """Called once by unittest: ensures that we have a compound library."""
-  if not conop.GetDefaultLib():
-    SetPrefixPath(os.path.abspath(os.path.join(conop.__path__[0], os.pardir,
-                                               os.pardir, os.pardir,
-                                               os.pardir, os.pardir)))
-    compound_lib_path = os.path.join(GetSharedDataPath(),
-                                     'compounds.chemlib')
-    compound_lib = conop.CompoundLib.Load(compound_lib_path)
-    conop.SetDefaultLib(compound_lib)
-
 
 class TestQSscore(unittest.TestCase):
 
@@ -192,6 +180,9 @@ class TestQSscore(unittest.TestCase):
     self.assertAlmostEqual(qs_scorer.best_score, 0.975, 2)
 
 
-if __name__== '__main__':
+if __name__ == "__main__":
   from ost import testutils
-  testutils.RunTests()
+  if testutils.SetDefaultCompoundLib():
+    testutils.RunTests()
+  else:
+    print 'No compound library available. Ignoring test_qsscoring.py tests.'
diff --git a/modules/seq/alg/tests/CMakeLists.txt b/modules/seq/alg/tests/CMakeLists.txt
index 529a3eb62..81b69d15f 100644
--- a/modules/seq/alg/tests/CMakeLists.txt
+++ b/modules/seq/alg/tests/CMakeLists.txt
@@ -8,9 +8,12 @@ set(OST_SEQ_ALG_UNIT_TESTS
   test_global_align.py
   test_semiglobal_align.py
   test_weight_matrix.py
-  test_aligntoseqres.py
 )
 
+if (COMPOUND_LIB)
+  list(APPEND OST_SEQ_ALG_UNIT_TESTS test_aligntoseqres.py)
+endif()
+
 ost_unittest(MODULE seq_alg SOURCES "${OST_SEQ_ALG_UNIT_TESTS}"
              LINK ost_mol ost_io)
 
diff --git a/modules/seq/alg/tests/test_aligntoseqres.py b/modules/seq/alg/tests/test_aligntoseqres.py
index 126c7f047..2aa1bb4fe 100644
--- a/modules/seq/alg/tests/test_aligntoseqres.py
+++ b/modules/seq/alg/tests/test_aligntoseqres.py
@@ -1,8 +1,6 @@
 import unittest
-from ost import *
-from ost import settings
-from ost import seq
-from ost import io
+import ost
+from ost import seq, io, mol
 
 class TestAlignToSeqRes(unittest.TestCase):
   def testAlignWorking(self):
@@ -67,9 +65,10 @@ class TestAlignToSeqRes(unittest.TestCase):
                                        validate = False)
     self.assertEqual(seq.alg.ValidateSEQRESAlignment(seqres_aln, chain), False)
 
+
 if __name__ == "__main__":
-  if not conop.GetDefaultLib():
-    print 'No compound library available. Ignoring unit tests'
-  else:
-    from ost import testutils
+  from ost import testutils
+  if testutils.SetDefaultCompoundLib():
     testutils.RunTests()
+  else:
+    print 'No compound library available. Ignoring test_aligntoseqres.py tests.'
-- 
GitLab