Skip to content

Commit

Permalink
spack test: now the command is a wrapper around pytest
Browse files Browse the repository at this point in the history
  • Loading branch information
alalazo committed Dec 9, 2016
1 parent 469ca51 commit 6dd64da
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 194 deletions.
85 changes: 54 additions & 31 deletions bin/spack
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,6 @@ sys.path.insert(0, SPACK_LIB_PATH)
SPACK_EXTERNAL_LIBS = os.path.join(SPACK_LIB_PATH, "external")
sys.path.insert(0, SPACK_EXTERNAL_LIBS)

import warnings
# Avoid warnings when nose is installed with the python exe being used to run
# spack. Note this must be done after Spack's external libs directory is added
# to sys.path.
with warnings.catch_warnings():
warnings.filterwarnings("ignore", ".*nose was already imported")
import nose

# Quick and dirty check to clean orphaned .pyc files left over from
# previous revisions. These files were present in earlier versions of
# Spack, were removed, but shadow system modules that Spack still
Expand Down Expand Up @@ -91,6 +83,14 @@ from llnl.util.tty.color import *
import spack
from spack.error import SpackError
import argparse
import llnl.util.filesystem

try:
import pytest
test_command = pytest.main
except ImportError as e:
def test_command(x):
tty.error('Install \'pytest\' to have the \'spack test\' command available')

# Command parsing
parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -131,21 +131,33 @@ subparsers = parser.add_subparsers(metavar='SUBCOMMAND', dest="command")

import spack.cmd
for cmd in spack.cmd.commands:
module = spack.cmd.get_module(cmd)
cmd_name = cmd.replace('_', '-')
subparser = subparsers.add_parser(cmd_name, help=module.description)
module.setup_parser(subparser)
if cmd == 'test':
# Add the test command, which wraps pytest
subparsers.add_parser(
'test',
help="Thin wrapper around pytest to run unit, functional and integration tests",
add_help=False
)
else:
module = spack.cmd.get_module(cmd)
cmd_name = cmd.replace('_', '-')
subparser = subparsers.add_parser(cmd_name, help=module.description)
module.setup_parser(subparser)

# Just print help and exit if run with no arguments at all
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)

# actually parse the args.
args = parser.parse_args()
# A non-strict parsing is needed because the test command
# is a wrapper around pytest.main, and as such we need to
# forward unknown_args to it
args, unknown_args = parser.parse_known_args()


def main():
global args

# Set up environment based on args.
tty.set_verbose(args.verbose)
tty.set_debug(args.debug)
Expand All @@ -169,24 +181,35 @@ def main():
tty.warn("You asked for --insecure. Will NOT check SSL certificates.")
spack.insecure = True

# Try to load the particular command asked for and run it
command = spack.cmd.get_command(args.command.replace('-', '_'))
try:
return_val = command(parser, args)
except SpackError as e:
e.die()
except KeyboardInterrupt:
sys.stderr.write('\n')
tty.die("Keyboard interrupt.")

# Allow commands to return values if they want to exit with some other code.
if return_val is None:
sys.exit(0)
elif isinstance(return_val, int):
sys.exit(return_val)
# Differentiate test from other commands
if args.command == 'test':
# Change to root directory
with llnl.util.filesystem.working_dir(spack.spack_root):
# Needed to get an help which seems almost correct...
sys.argv[0] = 'spack test'
exit_code = test_command(unknown_args)
raise SystemExit(exit_code)
else:
tty.die("Bad return value from command %s: %s"
% (args.command, return_val))
# If we are not running tests then we want strict parsing of the arguments
args = parser.parse_args()
# Try to load the particular command asked for and run it
command = spack.cmd.get_command(args.command.replace('-', '_'))
try:
return_val = command(parser, args)
except SpackError as e:
e.die()
except KeyboardInterrupt:
sys.stderr.write('\n')
tty.die("Keyboard interrupt.")

# Allow commands to return values if they want to exit with some other code.
if return_val is None:
sys.exit(0)
elif isinstance(return_val, int):
sys.exit(return_val)
else:
tty.die("Bad return value from command %s: %s"
% (args.command, return_val))

if args.profile:
import cProfile
Expand Down
2 changes: 1 addition & 1 deletion lib/spack/docs/contribution_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ This allows you to develop iteratively: make a change, test that change, make
another change, test that change, etc. To get a list of all available unit
tests, run:

.. command-output:: spack test --list
.. command-output:: spack test --collect-only

Unit tests are crucial to making sure bugs aren't introduced into Spack. If you
are modifying core Spack libraries or adding new functionality, please consider
Expand Down
1 change: 1 addition & 0 deletions lib/spack/spack/cmd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
if file.endswith(".py") and not re.search(ignore_files, file):
cmd = re.sub(r'.py$', '', file)
commands.append(cmd)
commands.append('test')
commands.sort()


Expand Down
68 changes: 0 additions & 68 deletions lib/spack/spack/cmd/test.py

This file was deleted.

94 changes: 0 additions & 94 deletions lib/spack/spack/test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,97 +22,3 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################

import llnl.util.tty as tty
import pytest
import spack
from llnl.util.filesystem import join_path
from llnl.util.tty.colify import colify

"""Names of tests to be included in Spack's test suite"""

# All the tests Spack knows about.
# Keep these one per line so that it's easy to see changes in diffs.
test_names = [
'architecture',
'build_system_guess',
'cc',
join_path('cmd', 'find'),
join_path('cmd', 'module'),
join_path('cmd', 'install'),
join_path('cmd', 'uninstall'),
'concretize',
'concretize_preferences',
'config',
'database',
'directory_layout',
'environment',
'file_cache',
'git_fetch',
'hg_fetch',
'install',
'library_list',
'link_tree',
'lock',
'make_executable',
'mirror',
'modules',
'multimethod',
'namespace_trie',
'optional_deps',
'package_sanity',
'packages',
'pattern',
'python_version',
'sbang',
'spec_dag',
'spec_semantics',
'spec_syntax',
'spec_yaml',
'stage',
'svn_fetch',
'url_extrapolate',
'url_parse',
'url_substitution',
'versions',
'provider_index',
'spack_yaml',
# This test needs to be last until global compiler cache is fixed.
join_path('cmd', 'test_compiler_cmd')
]


def list_tests():
"""Return names of all tests that can be run for Spack."""
return test_names


def run(names, outputDir, verbose=False):
"""Run tests with the supplied names. Names should be a list.
If it's empty, run ALL of Spack's tests.
"""
argv = []
# Print output to stdout if verbose is 1.
if verbose:
argv += ['-v']

if not names:
names = test_names
else:
for test in names:
if test not in test_names:
tty.error("%s is not a valid spack test name." % test,
"Valid names are:")
colify(sorted(test_names), indent=4)
raise SystemExit()

modules = [join_path(spack.test_path, test + '.py') for test in names]

if outputDir:
xml_output_path = join_path(outputDir, 'unittests.xml')
argv += [
'--junit-xml={0}'.format(xml_output_path)
]

argv += ['--durations=20', '--tb=auto'] + modules
pytest.main(argv)
5 changes: 5 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# content of pytest.ini
[pytest]
addopts = --durations=20 -ra
testpaths = lib/spack/spack/test
python_files = *.py

0 comments on commit 6dd64da

Please sign in to comment.