tests: add tests for spack extensions
command
- add tests for `spack extensions` - refactor `test_activations` test to use real extensions.
This commit is contained in:
parent
1b877e8e0f
commit
da7fed86a8
@ -10,6 +10,7 @@
|
||||
|
||||
import spack.environment as ev
|
||||
import spack.cmd as cmd
|
||||
import spack.cmd.common.arguments as arguments
|
||||
import spack.repo
|
||||
import spack.store
|
||||
from spack.filesystem_view import YamlFilesystemView
|
||||
@ -20,20 +21,16 @@
|
||||
|
||||
|
||||
def setup_parser(subparser):
|
||||
subparser.add_argument(
|
||||
'-l', '--long', action='store_true', dest='long',
|
||||
help='show dependency hashes as well as versions')
|
||||
|
||||
arguments.add_common_arguments(subparser, ['long', 'very_long'])
|
||||
subparser.add_argument('-d', '--deps', action='store_true',
|
||||
help='output dependencies along with found specs')
|
||||
|
||||
subparser.add_argument('-p', '--paths', action='store_true',
|
||||
help='show paths to package install directories')
|
||||
|
||||
subparser.add_argument(
|
||||
'-s', '--show', dest='show', metavar='TYPE', type=str,
|
||||
default='all',
|
||||
help="one of packages, installed, activated, all")
|
||||
'-s', '--show', action='store', default='all',
|
||||
choices=("packages", "installed", "activated", "all"),
|
||||
help="show only part of output")
|
||||
subparser.add_argument(
|
||||
'-v', '--view', metavar='VIEW', type=str,
|
||||
help="the view to operate on")
|
||||
@ -47,27 +44,7 @@ def extensions(parser, args):
|
||||
if not args.spec:
|
||||
tty.die("extensions requires a package spec.")
|
||||
|
||||
show_packages = False
|
||||
show_installed = False
|
||||
show_activated = False
|
||||
show_all = False
|
||||
if args.show == 'packages':
|
||||
show_packages = True
|
||||
elif args.show == 'installed':
|
||||
show_installed = True
|
||||
elif args.show == 'activated':
|
||||
show_activated = True
|
||||
elif args.show == 'all':
|
||||
show_packages = True
|
||||
show_installed = True
|
||||
show_activated = True
|
||||
show_all = True
|
||||
else:
|
||||
tty.die('unrecognized show type: %s' % args.show)
|
||||
|
||||
#
|
||||
# Checks
|
||||
#
|
||||
spec = cmd.parse_specs(args.spec)
|
||||
if len(spec) > 1:
|
||||
tty.die("Can only list extensions for one package.")
|
||||
@ -81,8 +58,7 @@ def extensions(parser, args):
|
||||
if not spec.package.extendable:
|
||||
tty.die("%s does not have extensions." % spec.short_spec)
|
||||
|
||||
if show_packages:
|
||||
#
|
||||
if args.show in ("packages", "all"):
|
||||
# List package names of extensions
|
||||
extensions = spack.repo.path.extensions_for(spec)
|
||||
if not extensions:
|
||||
@ -99,14 +75,12 @@ def extensions(parser, args):
|
||||
|
||||
view = YamlFilesystemView(target, spack.store.layout)
|
||||
|
||||
if show_installed:
|
||||
#
|
||||
if args.show in ("installed", "all"):
|
||||
# List specs of installed extensions.
|
||||
#
|
||||
installed = [
|
||||
s.spec for s in spack.store.db.installed_extensions_for(spec)]
|
||||
|
||||
if show_all:
|
||||
if args.show == "all":
|
||||
print
|
||||
if not installed:
|
||||
tty.msg("None installed.")
|
||||
@ -114,15 +88,13 @@ def extensions(parser, args):
|
||||
tty.msg("%d installed:" % len(installed))
|
||||
cmd.display_specs(installed, args)
|
||||
|
||||
if show_activated:
|
||||
#
|
||||
if args.show in ("activated", "all"):
|
||||
# List specs of activated extensions.
|
||||
#
|
||||
activated = view.extensions_layout.extension_map(spec)
|
||||
if show_all:
|
||||
if args.show == "all":
|
||||
print
|
||||
if not activated:
|
||||
tty.msg("None activated.")
|
||||
else:
|
||||
tty.msg("%d currently activated:" % len(activated))
|
||||
tty.msg("%d activated:" % len(activated))
|
||||
cmd.display_specs(activated.values(), args)
|
||||
|
79
lib/spack/spack/test/cmd/extensions.py
Normal file
79
lib/spack/spack/test/cmd/extensions.py
Normal file
@ -0,0 +1,79 @@
|
||||
# Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
|
||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
import pytest
|
||||
|
||||
from spack.main import SpackCommand, SpackCommandError
|
||||
from spack.spec import Spec
|
||||
|
||||
|
||||
extensions = SpackCommand('extensions')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def python_database(mock_packages, mutable_database):
|
||||
specs = [Spec(s).concretized() for s in [
|
||||
'python',
|
||||
'py-extension1',
|
||||
'py-extension2',
|
||||
]]
|
||||
|
||||
for spec in specs:
|
||||
spec.package.do_install(fake=True, explicit=True)
|
||||
|
||||
yield
|
||||
|
||||
|
||||
@pytest.mark.db
|
||||
def test_extensions(mock_packages, python_database, capsys):
|
||||
ext2 = Spec("py-extension2").concretized()
|
||||
|
||||
def check_output(ni, na):
|
||||
with capsys.disabled():
|
||||
output = extensions("python")
|
||||
packages = extensions("-s", "packages", "python")
|
||||
installed = extensions("-s", "installed", "python")
|
||||
activated = extensions("-s", "activated", "python")
|
||||
assert "==> python@2.7.11" in output
|
||||
assert "==> 3 extensions" in output
|
||||
assert "flake8" in output
|
||||
assert "py-extension1" in output
|
||||
assert "py-extension2" in output
|
||||
|
||||
assert "==> 3 extensions" in packages
|
||||
assert "flake8" in packages
|
||||
assert "py-extension1" in packages
|
||||
assert "py-extension2" in packages
|
||||
assert "installed" not in packages
|
||||
assert "activated" not in packages
|
||||
|
||||
assert ("%s installed" % (ni if ni else "None")) in output
|
||||
assert ("%s activated" % (na if na else "None")) in output
|
||||
assert ("%s installed" % (ni if ni else "None")) in installed
|
||||
assert ("%s activated" % (na if na else "None")) in activated
|
||||
|
||||
check_output(2, 0)
|
||||
|
||||
ext2.package.do_activate()
|
||||
check_output(2, 2)
|
||||
|
||||
ext2.package.do_deactivate(force=True)
|
||||
check_output(2, 1)
|
||||
|
||||
ext2.package.do_activate()
|
||||
check_output(2, 2)
|
||||
|
||||
ext2.package.do_uninstall(force=True)
|
||||
check_output(1, 1)
|
||||
|
||||
|
||||
def test_extensions_raises_if_not_extendable(mock_packages):
|
||||
with pytest.raises(SpackCommandError):
|
||||
extensions("flake8")
|
||||
|
||||
|
||||
def test_extensions_raises_if_multiple_specs(mock_packages):
|
||||
with pytest.raises(SpackCommandError):
|
||||
extensions("python", "flake8")
|
@ -3,6 +3,10 @@
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
"""This includes tests for customized activation logic for specific packages
|
||||
(e.g. python and perl).
|
||||
"""
|
||||
|
||||
import os
|
||||
import pytest
|
||||
|
||||
@ -13,23 +17,23 @@
|
||||
from spack.filesystem_view import YamlFilesystemView
|
||||
from spack.repo import RepoPath
|
||||
|
||||
"""This includes tests for customized activation logic for specific packages
|
||||
(e.g. python and perl).
|
||||
"""
|
||||
|
||||
|
||||
def create_ext_pkg(name, prefix, extendee_spec):
|
||||
def create_ext_pkg(name, prefix, extendee_spec, monkeypatch):
|
||||
ext_spec = spack.spec.Spec(name)
|
||||
ext_spec._concrete = True
|
||||
|
||||
ext_spec.package.spec.prefix = prefix
|
||||
ext_pkg = ext_spec.package
|
||||
ext_pkg.extends_spec = extendee_spec
|
||||
|
||||
# temporarily override extendee_spec property on the package
|
||||
monkeypatch.setattr(ext_pkg.__class__, "extendee_spec", extendee_spec)
|
||||
|
||||
return ext_pkg
|
||||
|
||||
|
||||
def create_python_ext_pkg(name, prefix, python_spec, namespace=None):
|
||||
ext_pkg = create_ext_pkg(name, prefix, python_spec)
|
||||
def create_python_ext_pkg(name, prefix, python_spec, monkeypatch,
|
||||
namespace=None):
|
||||
ext_pkg = create_ext_pkg(name, prefix, python_spec, monkeypatch)
|
||||
ext_pkg.py_namespace = namespace
|
||||
return ext_pkg
|
||||
|
||||
@ -148,14 +152,15 @@ def namespace_extensions(tmpdir, builtin_and_mock_packages):
|
||||
|
||||
|
||||
def test_python_activation_with_files(tmpdir, python_and_extension_dirs,
|
||||
builtin_and_mock_packages):
|
||||
monkeypatch, builtin_and_mock_packages):
|
||||
python_prefix, ext_prefix = python_and_extension_dirs
|
||||
|
||||
python_spec = spack.spec.Spec('python@2.7.12')
|
||||
python_spec._concrete = True
|
||||
python_spec.package.spec.prefix = python_prefix
|
||||
|
||||
ext_pkg = create_python_ext_pkg('py-extension1', ext_prefix, python_spec)
|
||||
ext_pkg = create_python_ext_pkg(
|
||||
'py-extension1', ext_prefix, python_spec, monkeypatch)
|
||||
|
||||
python_pkg = python_spec.package
|
||||
python_pkg.activate(ext_pkg, python_pkg.view())
|
||||
@ -171,14 +176,15 @@ def test_python_activation_with_files(tmpdir, python_and_extension_dirs,
|
||||
|
||||
|
||||
def test_python_activation_view(tmpdir, python_and_extension_dirs,
|
||||
builtin_and_mock_packages):
|
||||
builtin_and_mock_packages, monkeypatch):
|
||||
python_prefix, ext_prefix = python_and_extension_dirs
|
||||
|
||||
python_spec = spack.spec.Spec('python@2.7.12')
|
||||
python_spec._concrete = True
|
||||
python_spec.package.spec.prefix = python_prefix
|
||||
|
||||
ext_pkg = create_python_ext_pkg('py-extension1', ext_prefix, python_spec)
|
||||
ext_pkg = create_python_ext_pkg('py-extension1', ext_prefix, python_spec,
|
||||
monkeypatch)
|
||||
|
||||
view_dir = str(tmpdir.join('view'))
|
||||
layout = YamlDirectoryLayout(view_dir)
|
||||
@ -192,8 +198,8 @@ def test_python_activation_view(tmpdir, python_and_extension_dirs,
|
||||
assert os.path.exists(os.path.join(view_dir, 'bin/py-ext-tool'))
|
||||
|
||||
|
||||
def test_python_ignore_namespace_init_conflict(tmpdir, namespace_extensions,
|
||||
builtin_and_mock_packages):
|
||||
def test_python_ignore_namespace_init_conflict(
|
||||
tmpdir, namespace_extensions, builtin_and_mock_packages, monkeypatch):
|
||||
"""Test the view update logic in PythonPackage ignores conflicting
|
||||
instances of __init__ for packages which are in the same namespace.
|
||||
"""
|
||||
@ -203,9 +209,9 @@ def test_python_ignore_namespace_init_conflict(tmpdir, namespace_extensions,
|
||||
python_spec._concrete = True
|
||||
|
||||
ext1_pkg = create_python_ext_pkg('py-extension1', ext1_prefix, python_spec,
|
||||
py_namespace)
|
||||
monkeypatch, py_namespace)
|
||||
ext2_pkg = create_python_ext_pkg('py-extension2', ext2_prefix, python_spec,
|
||||
py_namespace)
|
||||
monkeypatch, py_namespace)
|
||||
|
||||
view_dir = str(tmpdir.join('view'))
|
||||
layout = YamlDirectoryLayout(view_dir)
|
||||
@ -226,8 +232,8 @@ def test_python_ignore_namespace_init_conflict(tmpdir, namespace_extensions,
|
||||
assert os.path.exists(os.path.join(view_dir, init_file))
|
||||
|
||||
|
||||
def test_python_keep_namespace_init(tmpdir, namespace_extensions,
|
||||
builtin_and_mock_packages):
|
||||
def test_python_keep_namespace_init(
|
||||
tmpdir, namespace_extensions, builtin_and_mock_packages, monkeypatch):
|
||||
"""Test the view update logic in PythonPackage keeps the namespace
|
||||
__init__ file as long as one package in the namespace still
|
||||
exists.
|
||||
@ -238,9 +244,9 @@ def test_python_keep_namespace_init(tmpdir, namespace_extensions,
|
||||
python_spec._concrete = True
|
||||
|
||||
ext1_pkg = create_python_ext_pkg('py-extension1', ext1_prefix, python_spec,
|
||||
py_namespace)
|
||||
monkeypatch, py_namespace)
|
||||
ext2_pkg = create_python_ext_pkg('py-extension2', ext2_prefix, python_spec,
|
||||
py_namespace)
|
||||
monkeypatch, py_namespace)
|
||||
|
||||
view_dir = str(tmpdir.join('view'))
|
||||
layout = YamlDirectoryLayout(view_dir)
|
||||
@ -269,7 +275,7 @@ def test_python_keep_namespace_init(tmpdir, namespace_extensions,
|
||||
|
||||
|
||||
def test_python_namespace_conflict(tmpdir, namespace_extensions,
|
||||
builtin_and_mock_packages):
|
||||
monkeypatch, builtin_and_mock_packages):
|
||||
"""Test the view update logic in PythonPackage reports an error when two
|
||||
python extensions with different namespaces have a conflicting __init__
|
||||
file.
|
||||
@ -281,9 +287,9 @@ def test_python_namespace_conflict(tmpdir, namespace_extensions,
|
||||
python_spec._concrete = True
|
||||
|
||||
ext1_pkg = create_python_ext_pkg('py-extension1', ext1_prefix, python_spec,
|
||||
py_namespace)
|
||||
monkeypatch, py_namespace)
|
||||
ext2_pkg = create_python_ext_pkg('py-extension2', ext2_prefix, python_spec,
|
||||
other_namespace)
|
||||
monkeypatch, other_namespace)
|
||||
|
||||
view_dir = str(tmpdir.join('view'))
|
||||
layout = YamlDirectoryLayout(view_dir)
|
||||
@ -342,7 +348,7 @@ def perl_and_extension_dirs(tmpdir, builtin_and_mock_packages):
|
||||
return str(perl_prefix), str(ext_prefix)
|
||||
|
||||
|
||||
def test_perl_activation(tmpdir, builtin_and_mock_packages):
|
||||
def test_perl_activation(tmpdir, builtin_and_mock_packages, monkeypatch):
|
||||
# Note the lib directory is based partly on the perl version
|
||||
perl_spec = spack.spec.Spec('perl@5.24.1')
|
||||
perl_spec._concrete = True
|
||||
@ -357,21 +363,23 @@ def test_perl_activation(tmpdir, builtin_and_mock_packages):
|
||||
|
||||
ext_name = 'perl-extension'
|
||||
tmpdir.ensure(ext_name, dir=True)
|
||||
ext_pkg = create_ext_pkg(ext_name, str(tmpdir.join(ext_name)), perl_spec)
|
||||
ext_pkg = create_ext_pkg(
|
||||
ext_name, str(tmpdir.join(ext_name)), perl_spec, monkeypatch)
|
||||
|
||||
perl_pkg = perl_spec.package
|
||||
perl_pkg.activate(ext_pkg, perl_pkg.view())
|
||||
|
||||
|
||||
def test_perl_activation_with_files(tmpdir, perl_and_extension_dirs,
|
||||
builtin_and_mock_packages):
|
||||
monkeypatch, builtin_and_mock_packages):
|
||||
perl_prefix, ext_prefix = perl_and_extension_dirs
|
||||
|
||||
perl_spec = spack.spec.Spec('perl@5.24.1')
|
||||
perl_spec._concrete = True
|
||||
perl_spec.package.spec.prefix = perl_prefix
|
||||
|
||||
ext_pkg = create_ext_pkg('perl-extension', ext_prefix, perl_spec)
|
||||
ext_pkg = create_ext_pkg(
|
||||
'perl-extension', ext_prefix, perl_spec, monkeypatch)
|
||||
|
||||
perl_pkg = perl_spec.package
|
||||
perl_pkg.activate(ext_pkg, perl_pkg.view())
|
||||
@ -380,14 +388,15 @@ def test_perl_activation_with_files(tmpdir, perl_and_extension_dirs,
|
||||
|
||||
|
||||
def test_perl_activation_view(tmpdir, perl_and_extension_dirs,
|
||||
builtin_and_mock_packages):
|
||||
monkeypatch, builtin_and_mock_packages):
|
||||
perl_prefix, ext_prefix = perl_and_extension_dirs
|
||||
|
||||
perl_spec = spack.spec.Spec('perl@5.24.1')
|
||||
perl_spec._concrete = True
|
||||
perl_spec.package.spec.prefix = perl_prefix
|
||||
|
||||
ext_pkg = create_ext_pkg('perl-extension', ext_prefix, perl_spec)
|
||||
ext_pkg = create_ext_pkg(
|
||||
'perl-extension', ext_prefix, perl_spec, monkeypatch)
|
||||
|
||||
view_dir = str(tmpdir.join('view'))
|
||||
layout = YamlDirectoryLayout(view_dir)
|
||||
|
@ -15,14 +15,9 @@ class PerlExtension(PerlPackage):
|
||||
version('1.0', 'hash-extension-1.0')
|
||||
version('2.0', 'hash-extension-2.0')
|
||||
|
||||
extends("perl")
|
||||
|
||||
def install(self, spec, prefix):
|
||||
mkdirp(prefix.bin)
|
||||
with open(os.path.join(prefix.bin, 'perl-extension'), 'w+') as fout:
|
||||
fout.write(str(spec.version))
|
||||
|
||||
# Give the package a hook to set the extendee spec
|
||||
extends_spec = 'perl'
|
||||
|
||||
@property
|
||||
def extendee_spec(self):
|
||||
return self.extends_spec
|
||||
|
@ -20,9 +20,4 @@ def install(self, spec, prefix):
|
||||
with open(os.path.join(prefix.bin, 'py-extension1'), 'w+') as fout:
|
||||
fout.write(str(spec.version))
|
||||
|
||||
# Give the package a hook to set the extendee spec
|
||||
extends_spec = 'python'
|
||||
|
||||
@property
|
||||
def extendee_spec(self):
|
||||
return self.extends_spec
|
||||
extends('python')
|
||||
|
@ -13,6 +13,7 @@ class PyExtension2(PythonPackage):
|
||||
homepage = "http://www.example.com"
|
||||
url = "http://www.example.com/extension2-1.0.tar.gz"
|
||||
|
||||
extends("python")
|
||||
depends_on('py-extension1', type=('build', 'run'))
|
||||
|
||||
version('1.0', 'hash-extension2-1.0')
|
||||
@ -21,10 +22,3 @@ def install(self, spec, prefix):
|
||||
mkdirp(prefix.bin)
|
||||
with open(os.path.join(prefix.bin, 'py-extension2'), 'w+') as fout:
|
||||
fout.write(str(spec.version))
|
||||
|
||||
# Give the package a hook to set the extendee spec
|
||||
extends_spec = 'python'
|
||||
|
||||
@property
|
||||
def extendee_spec(self):
|
||||
return self.extends_spec
|
||||
|
Loading…
Reference in New Issue
Block a user