From 50718fe57f225e45331deccd24eb53dbccbad685 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Sun, 28 Apr 2013 11:27:33 -0700 Subject: [PATCH] Tests can be run via spack test --- lib/spack/spack/cmd/test.py | 33 ++++ lib/spack/spack/globals.py | 1 + lib/spack/spack/packages/__init__.py | 6 +- lib/spack/spack/test/__init__.py | 13 ++ lib/spack/spack/test/test_versions.py | 192 -------------------- lib/spack/spack/test/versions.py | 245 ++++++++++++++++++++++++++ lib/spack/spack/utils.py | 10 ++ lib/spack/spack/version.py | 42 ++--- 8 files changed, 325 insertions(+), 217 deletions(-) create mode 100755 lib/spack/spack/cmd/test.py create mode 100644 lib/spack/spack/test/__init__.py delete mode 100755 lib/spack/spack/test/test_versions.py create mode 100644 lib/spack/spack/test/versions.py diff --git a/lib/spack/spack/cmd/test.py b/lib/spack/spack/cmd/test.py new file mode 100755 index 0000000000..bc62798dda --- /dev/null +++ b/lib/spack/spack/cmd/test.py @@ -0,0 +1,33 @@ +import spack +import spack.packages as packages +import spack.test +from spack.utils import list_modules +from spack.colify import colify +from pprint import pprint + +description ="Run unit tests" + +def setup_parser(subparser): + subparser.add_argument( + 'names', nargs='*', help="Names of packages to install") + subparser.add_argument( + '-a', '--all', action='store_true', dest='all', help="Run all tests") + subparser.add_argument( + '-v', '--verbose', action='store_true', dest='verbose', + help="verbose output") + + +def test(parser, args): + if args.all: + for name in list_modules(spack.test_path): + print "Running Tests: %s" % name + spack.test.run(name, verbose=args.verbose) + + elif not args.names: + print parser._subparsers + print "Available tests:" + colify(list_modules(spack.test_path)) + + else: + for name in args.names: + spack.test.run(name, verbose=args.verbose) diff --git a/lib/spack/spack/globals.py b/lib/spack/spack/globals.py index b864c08533..34b9be5713 100644 --- a/lib/spack/spack/globals.py +++ b/lib/spack/spack/globals.py @@ -14,6 +14,7 @@ env_path = new_path(lib_path, "env") module_path = new_path(lib_path, "spack") packages_path = new_path(module_path, "packages") +test_path = new_path(module_path, "test") var_path = new_path(prefix, "var", "spack") stage_path = new_path(var_path, "stage") diff --git a/lib/spack/spack/packages/__init__.py b/lib/spack/spack/packages/__init__.py index c32738bd6a..7a43fcb52f 100644 --- a/lib/spack/spack/packages/__init__.py +++ b/lib/spack/spack/packages/__init__.py @@ -61,10 +61,8 @@ def installed_packages(**kwargs): def all_package_names(): """Generator function for all packages.""" - os.chdir(spack.packages_path) - for name in glob.glob("*.py"): - if name != '__init__.py': - yield re.sub('.py$', '', name) + for mod in list_modules(spack.packages_path): + yield mod def all_packages(): diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py new file mode 100644 index 0000000000..4b74c7642a --- /dev/null +++ b/lib/spack/spack/test/__init__.py @@ -0,0 +1,13 @@ +import sys +import unittest +import spack + +def run(test_name, verbose=False): + __import__(__package__ + "." + test_name) + + # This just runs unittest.main on the module with the provided name + test_module = getattr(spack.test, test_name) + + verbosity=1 + if verbose: verbosity = 2 + unittest.main(module=test_module, argv=sys.argv[:1], verbosity=verbosity) diff --git a/lib/spack/spack/test/test_versions.py b/lib/spack/spack/test/test_versions.py deleted file mode 100755 index da3b61ec62..0000000000 --- a/lib/spack/spack/test/test_versions.py +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/env python2.7 -"""\ -This file has a bunch of versions tests taken from the excellent version -detection in Homebrew. -""" -import unittest -import spack.version as version -from spack.exception import * - - -class VersionTest(unittest.TestCase): - - def assert_not_detected(self, string): - self.assertRaises(UndetectableVersionException, version.parse, string) - - def assert_detected(self, name, v, string): - parsed_name, parsed_v = version.parse(string) - self.assertEqual(parsed_name, name) - self.assertEqual(parsed_v, version.Version(v)) - - - def test_wwwoffle_version(self): - self.assert_detected( - 'wwwoffle', '2.9h', 'http://www.gedanken.demon.co.uk/download-wwwoffle/wwwoffle-2.9h.tgz') - - def test_version_sourceforge_download(self): - self.assert_detected( - 'foo_bar', '1.21', 'http://sourceforge.net/foo_bar-1.21.tar.gz/download') - self.assert_detected( - 'foo_bar', '1.21', 'http://sf.net/foo_bar-1.21.tar.gz/download') - - def test_no_version(self): - self.assert_not_detected('http://example.com/blah.tar') - self.assert_not_detected('foo') - - def test_version_all_dots(self): - self.assert_detected( - 'foo.bar.la', '1.14','http://example.com/foo.bar.la.1.14.zip') - - def test_version_underscore_separator(self): - self.assert_detected( - 'grc', '1.1', 'http://example.com/grc_1.1.tar.gz') - - def test_boost_version_style(self): - self.assert_detected( - 'boost', '1.39.0', 'http://example.com/boost_1_39_0.tar.bz2') - - def test_erlang_version_style(self): - self.assert_detected( - 'otp', 'R13B', 'http://erlang.org/download/otp_src_R13B.tar.gz') - - def test_another_erlang_version_style(self): - self.assert_detected( - 'otp', 'R15B01', 'https://github.com/erlang/otp/tarball/OTP_R15B01') - - def test_yet_another_erlang_version_style(self): - self.assert_detected( - 'otp', 'R15B03-1', 'https://github.com/erlang/otp/tarball/OTP_R15B03-1') - - def test_p7zip_version_style(self): - self.assert_detected( - 'p7zip', '9.04', 'http://kent.dl.sourceforge.net/sourceforge/p7zip/p7zip_9.04_src_all.tar.bz2') - - def test_new_github_style(self): - self.assert_detected( - 'libnet', '1.1.4', 'https://github.com/sam-github/libnet/tarball/libnet-1.1.4') - - def test_gloox_beta_style(self): - self.assert_detected( - 'gloox', '1.0-beta7', 'http://camaya.net/download/gloox-1.0-beta7.tar.bz2') - - def test_sphinx_beta_style(self): - self.assert_detected( - 'sphinx', '1.10-beta', 'http://sphinxsearch.com/downloads/sphinx-1.10-beta.tar.gz') - - def test_astyle_verson_style(self): - self.assert_detected( - 'astyle', '1.23', 'http://kent.dl.sourceforge.net/sourceforge/astyle/astyle_1.23_macosx.tar.gz') - - def test_version_dos2unix(self): - self.assert_detected( - 'dos2unix', '3.1', 'http://www.sfr-fresh.com/linux/misc/dos2unix-3.1.tar.gz') - - def test_version_internal_dash(self): - self.assert_detected( - 'foo-arse', '1.1-2', 'http://example.com/foo-arse-1.1-2.tar.gz') - - def test_version_single_digit(self): - self.assert_detected( - 'foo_bar', '45', 'http://example.com/foo_bar.45.tar.gz') - - def test_noseparator_single_digit(self): - self.assert_detected( - 'foo_bar', '45', 'http://example.com/foo_bar45.tar.gz') - - def test_version_developer_that_hates_us_format(self): - self.assert_detected( - 'foo-bar-la', '1.2.3', 'http://example.com/foo-bar-la.1.2.3.tar.gz') - - def test_version_regular(self): - self.assert_detected( - 'foo_bar', '1.21', 'http://example.com/foo_bar-1.21.tar.gz') - - def test_version_github(self): - self.assert_detected( - 'yajl', '1.0.5', 'http://github.com/lloyd/yajl/tarball/1.0.5') - - def test_version_github_with_high_patch_number(self): - self.assert_detected( - 'yajl', '1.2.34', 'http://github.com/lloyd/yajl/tarball/v1.2.34') - - def test_yet_another_version(self): - self.assert_detected( - 'mad', '0.15.1b', 'http://example.com/mad-0.15.1b.tar.gz') - - def test_lame_version_style(self): - self.assert_detected( - 'lame', '398-2', 'http://kent.dl.sourceforge.net/sourceforge/lame/lame-398-2.tar.gz') - - def test_ruby_version_style(self): - self.assert_detected( - 'ruby', '1.9.1-p243', 'ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p243.tar.gz') - - def test_omega_version_style(self): - self.assert_detected( - 'omega', '0.80.2', 'http://www.alcyone.com/binaries/omega/omega-0.80.2-src.tar.gz') - - def test_rc_style(self): - self.assert_detected( - 'libvorbis', '1.2.2rc1', 'http://downloads.xiph.org/releases/vorbis/libvorbis-1.2.2rc1.tar.bz2') - - def test_dash_rc_style(self): - self.assert_detected( - 'js', '1.8.0-rc1', 'http://ftp.mozilla.org/pub/mozilla.org/js/js-1.8.0-rc1.tar.gz') - - def test_angband_version_style(self): - self.assert_detected( - 'angband', '3.0.9b', 'http://rephial.org/downloads/3.0/angband-3.0.9b-src.tar.gz') - - def test_stable_suffix(self): - self.assert_detected( - 'libevent', '1.4.14b', 'http://www.monkey.org/~provos/libevent-1.4.14b-stable.tar.gz') - - def test_debian_style_1(self): - self.assert_detected( - 'sl', '3.03', 'http://ftp.de.debian.org/debian/pool/main/s/sl/sl_3.03.orig.tar.gz') - - def test_debian_style_2(self): - self.assert_detected( - 'mmv', '1.01b', 'http://ftp.de.debian.org/debian/pool/main/m/mmv/mmv_1.01b.orig.tar.gz') - - def test_imagemagick_style(self): - self.assert_detected( - 'ImageMagick', '6.7.5-7', 'http://downloads.sf.net/project/machomebrew/mirror/ImageMagick-6.7.5-7.tar.bz2') - - def test_dash_version_dash_style(self): - self.assert_detected( - 'antlr', '3.4', 'http://www.antlr.org/download/antlr-3.4-complete.jar') - - def test_apache_version_style(self): - self.assert_detected( - 'apache-cassandra', '1.2.0-rc2', 'http://www.apache.org/dyn/closer.cgi?path=/cassandra/1.2.0/apache-cassandra-1.2.0-rc2-bin.tar.gz') - - def test_jpeg_style(self): - self.assert_detected( - 'jpegsrc', '8d', 'http://www.ijg.org/files/jpegsrc.v8d.tar.gz') - - def test_more_versions(self): - self.assert_detected( - 'pypy', '1.4.1', 'http://pypy.org/download/pypy-1.4.1-osx.tar.bz2') - self.assert_detected( - 'openssl', '0.9.8s', 'http://www.openssl.org/source/openssl-0.9.8s.tar.gz') - self.assert_detected( - 'Xaw3d', '1.5E', 'ftp://ftp.visi.com/users/hawkeyd/X/Xaw3d-1.5E.tar.gz') - self.assert_detected( - 'fann', '2.1.0beta', 'http://downloads.sourceforge.net/project/fann/fann/2.1.0beta/fann-2.1.0beta.zip') - self.assert_detected( - 'grads', '2.0.1', 'ftp://iges.org/grads/2.0/grads-2.0.1-bin-darwin9.8-intel.tar.gz') - self.assert_detected( - 'haxe', '2.08', 'http://haxe.org/file/haxe-2.08-osx.tar.gz') - self.assert_detected( - 'imap', '2007f', 'ftp://ftp.cac.washington.edu/imap/imap-2007f.tar.gz') - self.assert_detected( - 'suite3270', '3.3.12ga7', 'http://sourceforge.net/projects/x3270/files/x3270/3.3.12ga7/suite3270-3.3.12ga7-src.tgz') - self.assert_detected( - 'synergy', '1.3.6p2', 'http://synergy.googlecode.com/files/synergy-1.3.6p2-MacOSX-Universal.zip') - - - - -if __name__ == "__main__": - unittest.main(failfast=True) diff --git a/lib/spack/spack/test/versions.py b/lib/spack/spack/test/versions.py new file mode 100644 index 0000000000..78900dd0eb --- /dev/null +++ b/lib/spack/spack/test/versions.py @@ -0,0 +1,245 @@ +#!/usr/bin/env python2.7 +"""\ +This file has a bunch of versions tests taken from the excellent version +detection in Homebrew. +""" +import unittest +import spack.version as ver +from pprint import pprint + + +class VersionTest(unittest.TestCase): + def assert_not_detected(self, string): + self.assertRaises(ver.UndetectableVersionError, ver.parse, string) + + def assert_detected(self, name, v, string): + parsed_name, parsed_v = ver.parse(string) + self.assertEqual(parsed_name, name) + self.assertEqual(parsed_v, ver.Version(v)) + + def test_wwwoffle_version(self): + self.assert_detected( + 'wwwoffle', '2.9h', + 'http://www.gedanken.demon.co.uk/download-wwwoffle/wwwoffle-2.9h.tgz') + + def test_version_sourceforge_download(self): + self.assert_detected( + 'foo_bar', '1.21', + 'http://sourceforge.net/foo_bar-1.21.tar.gz/download') + self.assert_detected( + 'foo_bar', '1.21', + 'http://sf.net/foo_bar-1.21.tar.gz/download') + + def test_no_version(self): + self.assert_not_detected('http://example.com/blah.tar') + self.assert_not_detected('foo') + + def test_version_all_dots(self): + self.assert_detected( + 'foo.bar.la', '1.14','http://example.com/foo.bar.la.1.14.zip') + + def test_version_underscore_separator(self): + self.assert_detected( + 'grc', '1.1', + 'http://example.com/grc_1.1.tar.gz') + + def test_boost_version_style(self): + self.assert_detected( + 'boost', '1.39.0', + 'http://example.com/boost_1_39_0.tar.bz2') + + def test_erlang_version_style(self): + self.assert_detected( + 'otp', 'R13B', + 'http://erlang.org/download/otp_src_R13B.tar.gz') + + def test_another_erlang_version_style(self): + self.assert_detected( + 'otp', 'R15B01', + 'https://github.com/erlang/otp/tarball/OTP_R15B01') + + def test_yet_another_erlang_version_style(self): + self.assert_detected( + 'otp', 'R15B03-1', + 'https://github.com/erlang/otp/tarball/OTP_R15B03-1') + + def test_p7zip_version_style(self): + self.assert_detected( + 'p7zip', '9.04', + 'http://kent.dl.sourceforge.net/sourceforge/p7zip/p7zip_9.04_src_all.tar.bz2') + + def test_new_github_style(self): + self.assert_detected( + 'libnet', '1.1.4', + 'https://github.com/sam-github/libnet/tarball/libnet-1.1.4') + + def test_gloox_beta_style(self): + self.assert_detected( + 'gloox', '1.0-beta7', + 'http://camaya.net/download/gloox-1.0-beta7.tar.bz2') + + def test_sphinx_beta_style(self): + self.assert_detected( + 'sphinx', '1.10-beta', + 'http://sphinxsearch.com/downloads/sphinx-1.10-beta.tar.gz') + + def test_astyle_verson_style(self): + self.assert_detected( + 'astyle', '1.23', + 'http://kent.dl.sourceforge.net/sourceforge/astyle/astyle_1.23_macosx.tar.gz') + + def test_version_dos2unix(self): + self.assert_detected( + 'dos2unix', '3.1', + 'http://www.sfr-fresh.com/linux/misc/dos2unix-3.1.tar.gz') + + def test_version_internal_dash(self): + self.assert_detected( + 'foo-arse', '1.1-2', + 'http://example.com/foo-arse-1.1-2.tar.gz') + + def test_version_single_digit(self): + self.assert_detected( + 'foo_bar', '45', + 'http://example.com/foo_bar.45.tar.gz') + + def test_noseparator_single_digit(self): + self.assert_detected( + 'foo_bar', '45', + 'http://example.com/foo_bar45.tar.gz') + + def test_version_developer_that_hates_us_format(self): + self.assert_detected( + 'foo-bar-la', '1.2.3', + 'http://example.com/foo-bar-la.1.2.3.tar.gz') + + def test_version_regular(self): + self.assert_detected( + 'foo_bar', '1.21', + 'http://example.com/foo_bar-1.21.tar.gz') + + def test_version_github(self): + self.assert_detected( + 'yajl', '1.0.5', + 'http://github.com/lloyd/yajl/tarball/1.0.5') + + def test_version_github_with_high_patch_number(self): + self.assert_detected( + 'yajl', '1.2.34', + 'http://github.com/lloyd/yajl/tarball/v1.2.34') + + def test_yet_another_version(self): + self.assert_detected( + 'mad', '0.15.1b', + 'http://example.com/mad-0.15.1b.tar.gz') + + def test_lame_version_style(self): + self.assert_detected( + 'lame', '398-2', + 'http://kent.dl.sourceforge.net/sourceforge/lame/lame-398-2.tar.gz') + + def test_ruby_version_style(self): + self.assert_detected( + 'ruby', '1.9.1-p243', + 'ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p243.tar.gz') + + def test_omega_version_style(self): + self.assert_detected( + 'omega', '0.80.2', + 'http://www.alcyone.com/binaries/omega/omega-0.80.2-src.tar.gz') + + def test_rc_style(self): + self.assert_detected( + 'libvorbis', '1.2.2rc1', + 'http://downloads.xiph.org/releases/vorbis/libvorbis-1.2.2rc1.tar.bz2') + + def test_dash_rc_style(self): + self.assert_detected( + 'js', '1.8.0-rc1', + 'http://ftp.mozilla.org/pub/mozilla.org/js/js-1.8.0-rc1.tar.gz') + + def test_angband_version_style(self): + self.assert_detected( + 'angband', '3.0.9b', + 'http://rephial.org/downloads/3.0/angband-3.0.9b-src.tar.gz') + + def test_stable_suffix(self): + self.assert_detected( + 'libevent', '1.4.14b', + 'http://www.monkey.org/~provos/libevent-1.4.14b-stable.tar.gz') + + def test_debian_style_1(self): + self.assert_detected( + 'sl', '3.03', + 'http://ftp.de.debian.org/debian/pool/main/s/sl/sl_3.03.orig.tar.gz') + + def test_debian_style_2(self): + self.assert_detected( + 'mmv', '1.01b', + 'http://ftp.de.debian.org/debian/pool/main/m/mmv/mmv_1.01b.orig.tar.gz') + + def test_imagemagick_style(self): + self.assert_detected( + 'ImageMagick', '6.7.5-7', + + 'http://downloads.sf.net/project/machomebrew/mirror/ImageMagick-6.7.5-7.tar.bz2') + + def test_dash_version_dash_style(self): + self.assert_detected( + 'antlr', '3.4', + 'http://www.antlr.org/download/antlr-3.4-complete.jar') + + def test_apache_version_style(self): + self.assert_detected( + 'apache-cassandra', '1.2.0-rc2', + 'http://www.apache.org/dyn/closer.cgi?path=/cassandra/1.2.0/apache-cassandra-1.2.0-rc2-bin.tar.gz') + + def test_jpeg_style(self): + self.assert_detected( + 'jpegsrc', '8d', + 'http://www.ijg.org/files/jpegsrc.v8d.tar.gz') + + def test_pypy_version(self): + self.assert_detected( + 'pypy', '1.4.1', + 'http://pypy.org/download/pypy-1.4.1-osx.tar.bz2') + + def test_openssl_version(self): + self.assert_detected( + 'openssl', '0.9.8s', + 'http://www.openssl.org/source/openssl-0.9.8s.tar.gz') + + def test_xaw3d_version(self): + self.assert_detected( + 'Xaw3d', '1.5E', + 'ftp://ftp.visi.com/users/hawkeyd/X/Xaw3d-1.5E.tar.gz') + + def test_fann_version(self): + self.assert_detected( + 'fann', '2.1.0beta', + 'http://downloads.sourceforge.net/project/fann/fann/2.1.0beta/fann-2.1.0beta.zip') + + def test_iges_version(self): + self.assert_detected( + 'grads', '2.0.1', + 'ftp://iges.org/grads/2.0/grads-2.0.1-bin-darwin9.8-intel.tar.gz') + + def test_haxe_version(self): + self.assert_detected( + 'haxe', '2.08', + 'http://haxe.org/file/haxe-2.08-osx.tar.gz') + + def test_imap_version(self): + self.assert_detected( + 'imap', '2007f', + 'ftp://ftp.cac.washington.edu/imap/imap-2007f.tar.gz') + + def test_suite3270_version(self): + self.assert_detected( + 'suite3270', '3.3.12ga7', + 'http://sourceforge.net/projects/x3270/files/x3270/3.3.12ga7/suite3270-3.3.12ga7-src.tgz') + + def test_synergy_version(self): + self.assert_detected( + 'synergy', '1.3.6p2', + 'http://synergy.googlecode.com/files/synergy-1.3.6p2-MacOSX-Universal.zip') diff --git a/lib/spack/spack/utils.py b/lib/spack/spack/utils.py index 09e4985275..465c83caf9 100644 --- a/lib/spack/spack/utils.py +++ b/lib/spack/spack/utils.py @@ -1,6 +1,7 @@ import os import re import errno +import glob import shutil import subprocess import multiprocessing @@ -35,6 +36,15 @@ def install(src, dest): shutil.copy(src, dest) +def list_modules(directory): + """Lists all of the modules, excluding __init__.py, in + a particular directory.""" + os.chdir(directory) + for name in glob.glob("*.py"): + if name != '__init__.py': + yield re.sub('.py$', '', name) + + @contextmanager def working_dir(dirname): orig_dir = os.getcwd() diff --git a/lib/spack/spack/version.py b/lib/spack/spack/version.py index 52b89883f7..e35dfe7297 100644 --- a/lib/spack/spack/version.py +++ b/lib/spack/spack/version.py @@ -5,27 +5,6 @@ import spack.error as serr -class VersionParseError(serr.SpackError): - """Raised when the version module can't parse something.""" - def __init__(self, msg, spec): - super(VersionParseError, self).__init__(msg) - self.spec = spec - - -class UndetectableVersionError(VersionParseError): - """Raised when we can't parse a version from a string.""" - def __init__(self, spec): - super(UndetectableVersionError, self).__init__( - "Couldn't detect version in: " + spec, spec) - - -class UndetectableNameError(VersionParseError): - """Raised when we can't parse a package name from a string.""" - def __init__(self, spec): - super(UndetectableNameError, self).__init__( - "Couldn't parse package name in: " + spec) - - class Version(object): """Class to represent versions""" def __init__(self, version_string): @@ -81,6 +60,27 @@ def intify(part): return tuple(intify(v) for v in re.split(r'[_.-]+', v)) +class VersionParseError(serr.SpackError): + """Raised when the version module can't parse something.""" + def __init__(self, msg, spec): + super(VersionParseError, self).__init__(msg) + self.spec = spec + + +class UndetectableVersionError(VersionParseError): + """Raised when we can't parse a version from a string.""" + def __init__(self, spec): + super(UndetectableVersionError, self).__init__( + "Couldn't detect version in: " + spec, spec) + + +class UndetectableNameError(VersionParseError): + """Raised when we can't parse a package name from a string.""" + def __init__(self, spec): + super(UndetectableNameError, self).__init__( + "Couldn't parse package name in: " + spec) + + def parse_version_string_with_indices(spec): """Try to extract a version string from a filename or URL. This is taken largely from Homebrew's Version class."""