Test cases pass; Spack supports Python 2.6!

This commit is contained in:
Todd Gamblin 2014-08-10 18:00:20 -07:00
parent 7082b0a59a
commit 48d5281e3a
7 changed files with 104 additions and 102 deletions

View file

@ -24,8 +24,8 @@
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
import sys import sys
if not sys.version_info[:2] >= (2,7): if not sys.version_info[:2] >= (2,6):
sys.exit("Spack requires Python 2.7. Version was %s." % sys.version_info) sys.exit("Spack requires Python 2.6. Version was %s." % sys.version_info)
import os import os

View file

@ -120,8 +120,7 @@ def _need_to_create_path(self):
if spack.use_tmp_stage: if spack.use_tmp_stage:
# If we're using a tmp dir, it's a link, and it points at the right spot, # If we're using a tmp dir, it's a link, and it points at the right spot,
# then keep it. # then keep it.
if (os.path.commonprefix((real_path, real_tmp)) == real_tmp if (real_path.startswith(real_tmp) and os.path.exists(real_path)):
and os.path.exists(real_path)):
return False return False
else: else:
# otherwise, just unlink it and start over. # otherwise, just unlink it and start over.

View file

@ -72,7 +72,7 @@ def run(names, verbose=False):
runner = unittest.TextTestRunner(verbosity=verbosity) runner = unittest.TextTestRunner(verbosity=verbosity)
testsRun = errors = failures = skipped = 0 testsRun = errors = failures = 0
for test in names: for test in names:
module = 'spack.test.' + test module = 'spack.test.' + test
print module print module
@ -83,12 +83,10 @@ def run(names, verbose=False):
testsRun += result.testsRun testsRun += result.testsRun
errors += len(result.errors) errors += len(result.errors)
failures += len(result.failures) failures += len(result.failures)
skipped += len(result.skipped)
succeeded = not errors and not failures succeeded = not errors and not failures
tty.msg("Tests Complete.", tty.msg("Tests Complete.",
"%5d tests run" % testsRun, "%5d tests run" % testsRun,
"%5d skipped" % skipped,
"%5d failures" % failures, "%5d failures" % failures,
"%5d errors" % errors) "%5d errors" % errors)

View file

@ -134,29 +134,29 @@ def test_concretize_with_provides_when(self):
def test_virtual_is_fully_expanded_for_callpath(self): def test_virtual_is_fully_expanded_for_callpath(self):
# force dependence on fake "zmpi" by asking for MPI 10.0 # force dependence on fake "zmpi" by asking for MPI 10.0
spec = Spec('callpath ^mpi@10.0') spec = Spec('callpath ^mpi@10.0')
self.assertIn('mpi', spec.dependencies) self.assertTrue('mpi' in spec.dependencies)
self.assertNotIn('fake', spec) self.assertFalse('fake' in spec)
spec.concretize() spec.concretize()
self.assertIn('zmpi', spec.dependencies) self.assertTrue('zmpi' in spec.dependencies)
self.assertNotIn('mpi', spec) self.assertFalse('mpi' in spec)
self.assertIn('fake', spec.dependencies['zmpi']) self.assertTrue('fake' in spec.dependencies['zmpi'])
def test_virtual_is_fully_expanded_for_mpileaks(self): def test_virtual_is_fully_expanded_for_mpileaks(self):
spec = Spec('mpileaks ^mpi@10.0') spec = Spec('mpileaks ^mpi@10.0')
self.assertIn('mpi', spec.dependencies) self.assertTrue('mpi' in spec.dependencies)
self.assertNotIn('fake', spec) self.assertFalse('fake' in spec)
spec.concretize() spec.concretize()
self.assertIn('zmpi', spec.dependencies) self.assertTrue('zmpi' in spec.dependencies)
self.assertIn('callpath', spec.dependencies) self.assertTrue('callpath' in spec.dependencies)
self.assertIn('zmpi', spec.dependencies['callpath'].dependencies) self.assertTrue('zmpi' in spec.dependencies['callpath'].dependencies)
self.assertIn('fake', spec.dependencies['callpath'].dependencies['zmpi'].dependencies) self.assertTrue('fake' in spec.dependencies['callpath'].dependencies['zmpi'].dependencies)
self.assertNotIn('mpi', spec) self.assertFalse('mpi' in spec)
def test_my_dep_depends_on_provider_of_my_virtual_dep(self): def test_my_dep_depends_on_provider_of_my_virtual_dep(self):

View file

@ -39,7 +39,6 @@ def set_pkg_dep(pkg, spec):
class MockPackagesTest(unittest.TestCase): class MockPackagesTest(unittest.TestCase):
@classmethod
def setUp(self): def setUp(self):
# Use the mock packages database for these tests. This allows # Use the mock packages database for these tests. This allows
# us to set up contrived packages that don't interfere with # us to set up contrived packages that don't interfere with
@ -52,7 +51,7 @@ def setUp(self):
'site' : spack.mock_site_config, 'site' : spack.mock_site_config,
'user' : spack.mock_user_config } 'user' : spack.mock_user_config }
@classmethod
def tearDown(self): def tearDown(self):
"""Restore the real packages path after any test.""" """Restore the real packages path after any test."""
spack.db = self.real_db spack.db = self.real_db

View file

@ -57,10 +57,10 @@ def test_preorder_node_traversal(self):
pairs = zip([0,1,2,3,4,2,3], names) pairs = zip([0,1,2,3,4,2,3], names)
traversal = dag.traverse() traversal = dag.traverse()
self.assertListEqual([x.name for x in traversal], names) self.assertEqual([x.name for x in traversal], names)
traversal = dag.traverse(depth=True) traversal = dag.traverse(depth=True)
self.assertListEqual([(x, y.name) for x,y in traversal], pairs) self.assertEqual([(x, y.name) for x,y in traversal], pairs)
def test_preorder_edge_traversal(self): def test_preorder_edge_traversal(self):
@ -72,10 +72,10 @@ def test_preorder_edge_traversal(self):
pairs = zip([0,1,2,3,4,3,2,3,1], names) pairs = zip([0,1,2,3,4,3,2,3,1], names)
traversal = dag.traverse(cover='edges') traversal = dag.traverse(cover='edges')
self.assertListEqual([x.name for x in traversal], names) self.assertEqual([x.name for x in traversal], names)
traversal = dag.traverse(cover='edges', depth=True) traversal = dag.traverse(cover='edges', depth=True)
self.assertListEqual([(x, y.name) for x,y in traversal], pairs) self.assertEqual([(x, y.name) for x,y in traversal], pairs)
def test_preorder_path_traversal(self): def test_preorder_path_traversal(self):
@ -87,10 +87,10 @@ def test_preorder_path_traversal(self):
pairs = zip([0,1,2,3,4,3,2,3,1,2], names) pairs = zip([0,1,2,3,4,3,2,3,1,2], names)
traversal = dag.traverse(cover='paths') traversal = dag.traverse(cover='paths')
self.assertListEqual([x.name for x in traversal], names) self.assertEqual([x.name for x in traversal], names)
traversal = dag.traverse(cover='paths', depth=True) traversal = dag.traverse(cover='paths', depth=True)
self.assertListEqual([(x, y.name) for x,y in traversal], pairs) self.assertEqual([(x, y.name) for x,y in traversal], pairs)
def test_postorder_node_traversal(self): def test_postorder_node_traversal(self):
@ -102,10 +102,10 @@ def test_postorder_node_traversal(self):
pairs = zip([4,3,2,3,2,1,0], names) pairs = zip([4,3,2,3,2,1,0], names)
traversal = dag.traverse(order='post') traversal = dag.traverse(order='post')
self.assertListEqual([x.name for x in traversal], names) self.assertEqual([x.name for x in traversal], names)
traversal = dag.traverse(depth=True, order='post') traversal = dag.traverse(depth=True, order='post')
self.assertListEqual([(x, y.name) for x,y in traversal], pairs) self.assertEqual([(x, y.name) for x,y in traversal], pairs)
def test_postorder_edge_traversal(self): def test_postorder_edge_traversal(self):
@ -117,10 +117,10 @@ def test_postorder_edge_traversal(self):
pairs = zip([4,3,3,2,3,2,1,1,0], names) pairs = zip([4,3,3,2,3,2,1,1,0], names)
traversal = dag.traverse(cover='edges', order='post') traversal = dag.traverse(cover='edges', order='post')
self.assertListEqual([x.name for x in traversal], names) self.assertEqual([x.name for x in traversal], names)
traversal = dag.traverse(cover='edges', depth=True, order='post') traversal = dag.traverse(cover='edges', depth=True, order='post')
self.assertListEqual([(x, y.name) for x,y in traversal], pairs) self.assertEqual([(x, y.name) for x,y in traversal], pairs)
def test_postorder_path_traversal(self): def test_postorder_path_traversal(self):
@ -132,10 +132,10 @@ def test_postorder_path_traversal(self):
pairs = zip([4,3,3,2,3,2,1,2,1,0], names) pairs = zip([4,3,3,2,3,2,1,2,1,0], names)
traversal = dag.traverse(cover='paths', order='post') traversal = dag.traverse(cover='paths', order='post')
self.assertListEqual([x.name for x in traversal], names) self.assertEqual([x.name for x in traversal], names)
traversal = dag.traverse(cover='paths', depth=True, order='post') traversal = dag.traverse(cover='paths', depth=True, order='post')
self.assertListEqual([(x, y.name) for x,y in traversal], pairs) self.assertEqual([(x, y.name) for x,y in traversal], pairs)
def test_conflicting_spec_constraints(self): def test_conflicting_spec_constraints(self):
@ -199,13 +199,13 @@ def test_normalize_with_virtual_spec(self):
def check_links(self, spec_to_check): def check_links(self, spec_to_check):
for spec in spec_to_check.traverse(): for spec in spec_to_check.traverse():
for dependent in spec.dependents.values(): for dependent in spec.dependents.values():
self.assertIn( self.assertTrue(
spec.name, dependent.dependencies, spec.name in dependent.dependencies,
"%s not in dependencies of %s" % (spec.name, dependent.name)) "%s not in dependencies of %s" % (spec.name, dependent.name))
for dependency in spec.dependencies.values(): for dependency in spec.dependencies.values():
self.assertIn( self.assertTrue(
spec.name, dependency.dependents, spec.name in dependency.dependents,
"%s not in dependents of %s" % (spec.name, dependency.name)) "%s not in dependents of %s" % (spec.name, dependency.name))
@ -385,13 +385,13 @@ def test_normalize_with_virtual_package(self):
def test_contains(self): def test_contains(self):
spec = Spec('mpileaks ^mpi ^libelf@1.8.11 ^libdwarf') spec = Spec('mpileaks ^mpi ^libelf@1.8.11 ^libdwarf')
self.assertIn(Spec('mpi'), spec) self.assertTrue(Spec('mpi') in spec)
self.assertIn(Spec('libelf'), spec) self.assertTrue(Spec('libelf') in spec)
self.assertIn(Spec('libelf@1.8.11'), spec) self.assertTrue(Spec('libelf@1.8.11') in spec)
self.assertNotIn(Spec('libelf@1.8.12'), spec) self.assertFalse(Spec('libelf@1.8.12') in spec)
self.assertIn(Spec('libdwarf'), spec) self.assertTrue(Spec('libdwarf') in spec)
self.assertNotIn(Spec('libgoblin'), spec) self.assertFalse(Spec('libgoblin') in spec)
self.assertIn(Spec('mpileaks'), spec) self.assertTrue(Spec('mpileaks') in spec)
def test_copy_simple(self): def test_copy_simple(self):

View file

@ -51,28 +51,20 @@
stage_name = 'spack-test-stage' stage_name = 'spack-test-stage'
class with_tmp(object): @contextmanager
"""Decorator that executes a function with or without spack set to use def use_tmp(use_tmp):
a temp dir. Spack allows builds to happen directly in the """Allow some test code to be executed with spack.use_tmp_stage
stage directory or in a tmp dir and symlinked into the stage set to a certain value. Context manager makes sure it's reset
directory, so this lets us use the same test in both cases. on failure.
""" """
def __init__(self, use_tmp): old_tmp = spack.use_tmp_stage
self.use_tmp = use_tmp spack.use_tmp_stage = use_tmp
yield
def __call__(self, fun): spack.use_tmp_stage = old_tmp
use_tmp = self.use_tmp
def new_test_function(self):
old_tmp = spack.use_tmp_stage
spack.use_tmp_stage = use_tmp
fun(self)
spack.use_tmp_stage = old_tmp
return new_test_function
class StageTest(unittest.TestCase): class StageTest(unittest.TestCase):
@classmethod def setUp(self):
def setUpClass(cls):
"""This sets up a mock archive to fetch, and a mock temp space for use """This sets up a mock archive to fetch, and a mock temp space for use
by the Stage class. It doesn't actually create the Stage -- that by the Stage class. It doesn't actually create the Stage -- that
is done by individual tests. is done by individual tests.
@ -92,52 +84,58 @@ def setUpClass(cls):
tar('czf', archive_name, archive_dir) tar('czf', archive_name, archive_dir)
# Make spack use the test environment for tmp stuff. # Make spack use the test environment for tmp stuff.
cls.old_tmp_dirs = spack.tmp_dirs self.old_tmp_dirs = spack.tmp_dirs
spack.tmp_dirs = [test_tmp_path] spack.tmp_dirs = [test_tmp_path]
# record this since this test changes to directories that will
# be removed.
self.working_dir = os.getcwd()
@classmethod
def tearDownClass(cls): def tearDown(self):
"""Blows away the test environment directory.""" """Blows away the test environment directory."""
shutil.rmtree(test_files_dir) shutil.rmtree(test_files_dir)
# chdir back to original working dir
os.chdir(self.working_dir)
# restore spack's original tmp environment # restore spack's original tmp environment
spack.tmp_dirs = cls.old_tmp_dirs spack.tmp_dirs = self.old_tmp_dirs
def get_stage_path(self, stage, stage_name): def get_stage_path(self, stage, stage_name):
"""Figure out based on a stage and an intended name where it should """Figure out where a stage should be living. This depends on
be living. This depends on whether it's named or not. whether it's named.
""" """
if stage_name: if stage_name is not None:
# If it is a named stage, we know where the stage should be # If it is a named stage, we know where the stage should be
stage_path = join_path(spack.stage_path, stage_name) return join_path(spack.stage_path, stage_name)
else: else:
# If it's unnamed, ensure that we ran mkdtemp in the right spot. # If it's unnamed, ensure that we ran mkdtemp in the right spot.
stage_path = stage.path self.assertTrue(stage.path is not None)
self.assertIsNotNone(stage_path) self.assertTrue(stage.path.startswith(spack.stage_path))
self.assertEqual( return stage.path
os.path.commonprefix((stage_path, spack.stage_path)),
spack.stage_path)
return stage_path
def check_setup(self, stage, stage_name): def check_setup(self, stage, stage_name):
"""Figure out whether a stage was set up correctly.""" """Figure out whether a stage was set up correctly."""
stage_path = self.get_stage_path(stage, stage_name) stage_path = self.get_stage_path(stage, stage_name)
# Ensure stage was created in the spack stage directory
self.assertTrue(os.path.isdir(stage_path)) self.assertTrue(os.path.isdir(stage_path))
if spack.use_tmp_stage: if spack.use_tmp_stage:
# Make sure everything was created and linked correctly for # Check that the stage dir is really a symlink.
# a tmp stage.
self.assertTrue(os.path.islink(stage_path)) self.assertTrue(os.path.islink(stage_path))
# Make sure it points to a valid directory
target = os.path.realpath(stage_path) target = os.path.realpath(stage_path)
self.assertTrue(os.path.isdir(target)) self.assertTrue(os.path.isdir(target))
self.assertFalse(os.path.islink(target)) self.assertFalse(os.path.islink(target))
self.assertEqual(
os.path.commonprefix((target, test_tmp_path)), # Make sure the directory is in the place we asked it to
test_tmp_path) # be (see setUp and tearDown)
self.assertTrue(target.startswith(test_tmp_path))
else: else:
# Make sure the stage path is NOT a link for a non-tmp stage # Make sure the stage path is NOT a link for a non-tmp stage
@ -146,15 +144,15 @@ def check_setup(self, stage, stage_name):
def check_fetch(self, stage, stage_name): def check_fetch(self, stage, stage_name):
stage_path = self.get_stage_path(stage, stage_name) stage_path = self.get_stage_path(stage, stage_name)
self.assertIn(archive_name, os.listdir(stage_path)) self.assertTrue(archive_name in os.listdir(stage_path))
self.assertEqual(join_path(stage_path, archive_name), self.assertEqual(join_path(stage_path, archive_name),
stage.archive_file) stage.archive_file)
def check_expand_archive(self, stage, stage_name): def check_expand_archive(self, stage, stage_name):
stage_path = self.get_stage_path(stage, stage_name) stage_path = self.get_stage_path(stage, stage_name)
self.assertIn(archive_name, os.listdir(stage_path)) self.assertTrue(archive_name in os.listdir(stage_path))
self.assertIn(archive_dir, os.listdir(stage_path)) self.assertTrue(archive_dir in os.listdir(stage_path))
self.assertEqual( self.assertEqual(
join_path(stage_path, archive_dir), join_path(stage_path, archive_dir),
@ -192,32 +190,40 @@ def check_destroy(self, stage, stage_name):
self.assertFalse(os.path.exists(target)) self.assertFalse(os.path.exists(target))
def checkSetupAndDestroy(self, stage_name=None):
stage = Stage(archive_url, name=stage_name)
self.check_setup(stage, stage_name)
stage.destroy()
self.check_destroy(stage, stage_name)
@with_tmp(True)
def test_setup_and_destroy_name_with_tmp(self): def test_setup_and_destroy_name_with_tmp(self):
self.checkSetupAndDestroy(stage_name) with use_tmp(True):
stage = Stage(archive_url, name=stage_name)
self.check_setup(stage, stage_name)
stage.destroy()
self.check_destroy(stage, stage_name)
@with_tmp(False)
def test_setup_and_destroy_name_without_tmp(self): def test_setup_and_destroy_name_without_tmp(self):
self.checkSetupAndDestroy(stage_name) with use_tmp(False):
stage = Stage(archive_url, name=stage_name)
self.check_setup(stage, stage_name)
stage.destroy()
self.check_destroy(stage, stage_name)
@with_tmp(True)
def test_setup_and_destroy_no_name_with_tmp(self): def test_setup_and_destroy_no_name_with_tmp(self):
self.checkSetupAndDestroy(None) with use_tmp(True):
stage = Stage(archive_url)
self.check_setup(stage, None)
stage.destroy()
self.check_destroy(stage, None)
@with_tmp(False)
def test_setup_and_destroy_no_name_without_tmp(self): def test_setup_and_destroy_no_name_without_tmp(self):
self.checkSetupAndDestroy(None) with use_tmp(False):
stage = Stage(archive_url)
self.check_setup(stage, None)
stage.destroy()
self.check_destroy(stage, None)
def test_chdir(self): def test_chdir(self):
@ -286,7 +292,7 @@ def test_restage(self):
with closing(open('foobar', 'w')) as file: with closing(open('foobar', 'w')) as file:
file.write("this file is to be destroyed.") file.write("this file is to be destroyed.")
self.assertIn('foobar', os.listdir(stage.expanded_archive_path)) self.assertTrue('foobar' in os.listdir(stage.expanded_archive_path))
# Make sure the file is not there after restage. # Make sure the file is not there after restage.
stage.restage() stage.restage()
@ -295,7 +301,7 @@ def test_restage(self):
stage.chdir_to_archive() stage.chdir_to_archive()
self.check_chdir_to_archive(stage, stage_name) self.check_chdir_to_archive(stage, stage_name)
self.assertNotIn('foobar', os.listdir(stage.expanded_archive_path)) self.assertFalse('foobar' in os.listdir(stage.expanded_archive_path))
stage.destroy() stage.destroy()
self.check_destroy(stage, stage_name) self.check_destroy(stage, stage_name)