Windows Support: Testing Suite integration

Broaden support for execution of the test suite
on Windows.
General bug and review fixups
This commit is contained in:
John Parent 2022-03-16 16:41:34 -04:00 committed by Peter Scheibel
parent e63b4f752a
commit 4aee27816e
102 changed files with 771 additions and 1066 deletions

View file

@ -3,13 +3,12 @@ name: windows tests
on:
push:
branches:
- features/windows-support
- windows-ci*
- develop
- releases/**
pull_request:
branches:
- features/windows-support
- windows-ci*
- develop
- releases/**
defaults:
run:
shell:
@ -70,7 +69,7 @@ jobs:
- name: Unit Test
run: |
echo F|xcopy .\spack\share\spack\qa\configuration\windows_config.yaml $env:USERPROFILE\.spack\windows\config.yaml
spack unit-test -x --verbose --ignore=lib/spack/spack/test/cmd
spack unit-test --verbose --ignore=lib/spack/spack/test/cmd
unittest-cmd:
runs-on: windows-latest
steps:
@ -89,7 +88,7 @@ jobs:
- name: Command Unit Test
run: |
echo F|xcopy .\spack\share\spack\qa\configuration\windows_config.yaml $env:USERPROFILE\.spack\windows\config.yaml
spack unit-test lib/spack/spack/test/cmd -x --verbose
spack unit-test lib/spack/spack/test/cmd --verbose
buildtest:
runs-on: windows-latest
steps:

5
.gitignore vendored
View file

@ -269,11 +269,6 @@ local.properties
# CDT-specific (C/C++ Development Tooling)
.cproject
# VSCode files
.vs
.vscode
.devcontainer
# CDT- autotools
.autotools

View file

@ -68,4 +68,5 @@ set
GOTO:EOF
:continue
set PROMPT=[spack] %PROMPT%
%comspec% /k

View file

@ -1580,8 +1580,8 @@ Python 3 can be downloaded and installed from the Windows Store, and will be aut
to your ``PATH`` in this case.
.. note::
Spack currently supports Python versions later than 3.2 inclusive.
"""
Git
"""
@ -1594,12 +1594,10 @@ When given the option of adjusting your ``PATH``, choose the ``Git from the
command line and also from 3rd-party software`` option. This will automatically
update your ``PATH`` variable to include the ``git`` command.
.. note::
Spack support on Windows is currently dependent on installing the Git for Windows project
as the project providing Git support on Windows. This is additionally the recommended method
for installing Git on Windows, a link to which can be found above. Spack requires the
utilities vendored by this project.
Spack support on Windows is currently dependent on installing the Git for Windows project
as the project providing Git support on Windows. This is additionally the recommended method
for installing Git on Windows, a link to which can be found above. Spack requires the
utilities vendored by this project.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Step 2: Install and setup Spack
@ -1609,32 +1607,20 @@ We are now ready to get the Spack environment set up on our machine. We
begin by using Git to clone the Spack repo, hosted at https://github.com/spack/spack.git
into a desired directory, for our purposes today, called ``spack_install``.
Presently, Windows operations are supported by Spack soley through the
features/windows-support branch on the upstream Spack repository,
located at the above url.
In order to install Spack with Windows support, run the following one liner
in a Windows CMD prompt.
.. code-block:: console
git clone https://github.com/spack/spack.git -b features/windows-support win_spack
or if working from a previous clone of Spack, simply checkout the Windows support feature branch
with
.. code-block:: console
git checkout -b features/windows-support --track <spack_upstream>/features/windows-support
git clone https://github.com/spack/spack.git
.. note::
If you chose to install Spack into a directory on Windows that is set up to require Administrative
Privleges, Spack will require elevated privleges to run.
Administrative Privleges can be denoted either by default such as
``C:\Program Files``, or aministrator applied administrative restrictions
on a directory that spack installs files to such as ``C:\Users``
If you chose to install Spack into a directory on Windows that is set up to require Administrative
Privleges*, Spack will require elevated privleges to run.
*Administrative Privleges can be denoted either by default such as
`C:\Program Files`, or aministrator applied administrative restrictions
on a directory that spack installs files to such as `C:\Users\`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Step 3: Run and configure Spack
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -1646,6 +1632,9 @@ and its prerequisites. If you receive a warning message that Python is not in yo
of the Python executable to your ``PATH`` now. You can permanently add Python to your ``PATH`` variable
by using the ``Edit the system environment variables`` utility in Windows Control Panel.
.. note::
Alternatively, Powershell can be used in place of CMD
To configure Spack, first run the following command inside the Spack console:
.. code-block:: console
@ -1712,6 +1701,7 @@ and not tabs, so ensure that this is the case when editing one directly.
The use of Cygwin is not officially supported by Spack and is not tested.
However Spack will not throw an error, so use if choosing to use Spack
with Cygwin, know that no functionality is garunteed.
^^^^^^^^^^^^^^^^^
Step 4: Use Spack
^^^^^^^^^^^^^^^^^

View file

@ -71,8 +71,6 @@
import re
import math
import multiprocessing
import sys
import threading
import time
from contextlib import contextmanager
@ -411,12 +409,7 @@ def parse(self, stream, context=6, jobs=None):
pool = multiprocessing.Pool(jobs)
try:
# this is a workaround for a Python bug in Pool with ctrl-C
if sys.version_info >= (3, 2):
max_timeout = threading.TIMEOUT_MAX
else:
max_timeout = 9999999
results = pool.map_async(_parse_unpack, args, 1).get(max_timeout)
results = pool.map_async(_parse_unpack, args, 1).get(9999999)
errors, warnings, timings = zip(*results)
finally:
pool.terminate()

View file

@ -6,8 +6,6 @@
from macholib import mach_o
from llnl.util.symlink import symlink
MAGIC = [
struct.pack("!L", getattr(mach_o, "MH_" + _))
for _ in ["MAGIC", "CIGAM", "MAGIC_64", "CIGAM_64"]
@ -142,7 +140,7 @@ def mergetree(src, dst, condition=None, copyfn=mergecopy, srcbase=None):
try:
if os.path.islink(srcname):
realsrc = os.readlink(srcname)
symlink(realsrc, dstname)
os.symlink(realsrc, dstname)
elif os.path.isdir(srcname):
mergetree(
srcname,

View file

@ -12,8 +12,6 @@
from os.path import abspath, normpath, isabs, exists, isdir, isfile, islink, dirname
from llnl.util.symlink import symlink
if sys.version_info > (3,0):
def map_as_list(func, iter):
return list(map(func, iter))
@ -81,7 +79,7 @@ def mklinkto(self, oldname):
def mksymlinkto(self, value, absolute=1):
""" create a symbolic link with the given value (pointing to another name). """
if absolute:
py.error.checked_call(symlink, str(value), self.strpath)
py.error.checked_call(os.symlink, str(value), self.strpath)
else:
base = self.common(value)
# with posix local paths '/' is always a common base
@ -89,7 +87,7 @@ def mksymlinkto(self, value, absolute=1):
reldest = self.relto(base)
n = reldest.count(self.sep)
target = self.sep.join(('..', )*n + (relsource, ))
py.error.checked_call(symlink, target, self.strpath)
py.error.checked_call(os.symlink, target, self.strpath)
def getuserid(user):
import pwd
@ -894,7 +892,7 @@ def try_remove_lockfile():
except OSError:
pass
try:
symlink(src, dest)
os.symlink(src, dest)
except (OSError, AttributeError, NotImplementedError):
pass

View file

@ -1094,12 +1094,23 @@ def remove_linked_tree(path):
Parameters:
path (str): Directory to be removed
"""
# On windows, cleaning a Git stage can be an issue
# as git leaves readonly files that Python handles
# poorly on Windows. Remove readonly status and try again
def onerror(func, path, exe_info):
os.chmod(path, stat.S_IWUSR)
try:
func(path)
except Exception as e:
tty.warn(e)
pass
if os.path.exists(path):
if os.path.islink(path):
shutil.rmtree(os.path.realpath(path), True)
shutil.rmtree(os.path.realpath(path), onerror=onerror)
os.unlink(path)
else:
shutil.rmtree(path, True)
shutil.rmtree(path, onerror=onerror)
@contextmanager
@ -1237,9 +1248,6 @@ def find(root, files, recursive=True):
return _find_non_recursive(root, files)
# here and in _find_non_recursive below we only take the first
# index to check for system path safety as glob handles this
# w.r.t. search_files
@system_path_filter
def _find_recursive(root, search_files):

View file

@ -191,6 +191,7 @@ def is_valid(op):
return op == LockType.READ \
or op == LockType.WRITE
class Lock(object):
"""This is an implementation of a filesystem lock using Python's lockf.
@ -617,6 +618,12 @@ def release_write(self, release_fn=None):
else:
return False
def cleanup(self):
if self._reads == 0 and self._writes == 0:
os.unlink(self.path)
else:
raise LockError("Attempting to cleanup active lock.")
def _get_counts_desc(self):
return '(reads {0}, writes {1})'.format(self._reads, self._writes) \
if tty.is_verbose() else ''

View file

@ -395,7 +395,7 @@ def ioctl_gwinsz(fd):
return int(rc[0]), int(rc[1])
else:
if sys.version_info[0] < 3:
raise RuntimeError("""Terminal size not obtainable on Windows with a
Python version older than 3""")
raise RuntimeError("Terminal size not obtainable on Windows with a\
Python version older than 3")
rc = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80))
return int(rc[0]), int(rc[1])

View file

@ -418,6 +418,7 @@ def log_output(*args, **kwargs):
with log_output('logfile.txt', echo=True):
# do things ... output will be logged and printed out
The following is available on Unix only. No-op on Windows.
And, if you just want to echo *some* stuff from the parent, use
``force_echo``::
@ -427,20 +428,11 @@ def log_output(*args, **kwargs):
with logger.force_echo():
# things here will be echoed *and* logged
Under the hood, we spawn a daemon and set up a pipe between this
process and the daemon. The daemon writes our output to both the
file and to stdout (if echoing). The parent process can communicate
with the daemon to tell it when and when not to echo; this is what
force_echo does. You can also enable/disable echoing by typing 'v'.
We try to use OS-level file descriptors to do the redirection, but if
stdout or stderr has been set to some Python-level file object, we
use Python-level redirection instead. This allows the redirection to
work within test frameworks like nose and pytest.
See individual log classes for more information.
This method is actually a factory serving a per platform
(nix vs windows) log_output class
(unix vs windows) log_output class
"""
if sys.platform == 'win32':
return winlog(*args, **kwargs)
@ -449,29 +441,7 @@ def log_output(*args, **kwargs):
class nixlog(object):
"""Context manager that logs its output to a file.
In the simplest case, the usage looks like this::
with log_output('logfile.txt'):
# do things ... output will be logged
Any output from the with block will be redirected to ``logfile.txt``.
If you also want the output to be echoed to ``stdout``, use the
``echo`` parameter::
with log_output('logfile.txt', echo=True):
# do things ... output will be logged and printed out
And, if you just want to echo *some* stuff from the parent, use
``force_echo``::
with log_output('logfile.txt', echo=False) as logger:
# do things ... output will be logged
with logger.force_echo():
# things here will be echoed *and* logged
"""
Under the hood, we spawn a daemon and set up a pipe between this
process and the daemon. The daemon writes our output to both the
file and to stdout (if echoing). The parent process can communicate
@ -748,7 +718,6 @@ def __init__(self, sys_attr):
self.libc = libc
self.c_stream = c_stdout
else:
# The original fd stdout points to. Usually 1 on POSIX systems for stdout.
self.libc = ctypes.CDLL(None)
self.c_stream = ctypes.c_void_p.in_dll(self.libc, self.sys_attr)
self.sys_stream = getattr(sys, self.sys_attr)
@ -793,6 +762,12 @@ def close(self):
class winlog(object):
"""
Similar to nixlog, with underlying
functionality ported to support Windows.
Does not support the use of 'v' toggling as nixlog does.
"""
def __init__(self, file_like=None, echo=False, debug=0, buffer=False,
env=None, filter_fn=None):
self.env = env

View file

@ -19,6 +19,7 @@
import spack.build_environment
from spack.directives import conflicts, depends_on, variant
from spack.package import InstallError, PackageBase, run_after
from spack.util.path import convert_to_posix_path
# Regex to extract the primary generator from the CMake generator
# string.
@ -173,7 +174,7 @@ def _std_args(pkg):
define = CMakePackage.define
args = [
'-G', generator,
define('CMAKE_INSTALL_PREFIX', pkg.prefix.replace('\\', '/')),
define('CMAKE_INSTALL_PREFIX', convert_to_posix_path(pkg.prefix)),
define('CMAKE_BUILD_TYPE', build_type),
]

View file

@ -758,7 +758,15 @@ def get_versions(args, name):
# Default guesser
guesser = BuildSystemGuesser()
if args.url is not None and args.template != 'bundle':
valid_url = True
try:
spack.util.url.require_url_format(args.url)
if args.url.startswith('file://'):
valid_url = False # No point in spidering these
except AssertionError:
valid_url = False
if args.url is not None and args.template != 'bundle' and valid_url:
# Find available versions
try:
url_dict = spack.util.web.find_versions_of_archive(args.url)

View file

@ -9,6 +9,7 @@
import spack.paths
import spack.util.executable
from spack.spec import Spec
from spack.util.path import convert_to_posix_path
description = "generate Windows installer"
section = "admin"
@ -77,13 +78,13 @@ def make_installer(parser, args):
else:
if not os.path.isabs(spack_source):
spack_source = posixpath.abspath(spack_source)
spack_source = spack_source.replace('\\', '/')
spack_source = convert_to_posix_path(spack_source)
spack_version = args.spack_version
here = os.path.dirname(os.path.abspath(__file__))
source_dir = os.path.join(here, "installer")
posix_root = spack.paths.spack_root.replace('\\', '/')
posix_root = convert_to_posix_path(spack.paths.spack_root)
spack_license = posixpath.join(posix_root, "LICENSE-APACHE")
rtf_spack_license = txt_to_rtf(spack_license)
spack_license = posixpath.join(source_dir, "LICENSE.rtf")

View file

@ -83,13 +83,13 @@ def __init__(self, *args, **kwargs):
self.setvarsfile = os.path.join(
os.getenv("ONEAPI_ROOT"), "setvars.bat")
else:
# The long relative path below points six directories up
# to the root of the MSVC tree associated with this (self)
# vesion of MSVC, so that we can then find the relevant
# VCVARS file. Note: This is done in the opposite order
# that this procedure typically goes on Windows
# However it is done this way here with great intent to conform
# with how Spack discovers compilers.
# To use the MSVC compilers, VCVARS must be invoked
# VCVARS is located at a fixed location, referencable
# idiomatically by the following relative path from the
# compiler.
# Spack first finds the compilers via VSWHERE
# and stores their path, but their respective VCVARS
# file must be invoked before useage.
self.setvarsfile = os.path.abspath(
os.path.join(self.cc, '../../../../../../..'))
self.setvarsfile = os.path.join(

View file

@ -42,12 +42,12 @@ def executables_in_path(path_hints=None):
path_hints (list): list of paths to be searched. If None the list will be
constructed based on the PATH environment variable.
"""
# build_environment.py::1013: If we're on a Windows box, run vswhere,
# If we're on a Windows box, run vswhere,
# steal the installationPath using windows_os.py logic,
# construct paths to CMake and Ninja, add to PATH
path_hints = path_hints or spack.util.environment.get_path('PATH')
if sys.platform == 'win32':
msvc_paths = winOs.WindowsOs.vs_install_paths
msvc_paths = list(winOs.WindowsOs.vs_install_paths)
msvc_cmake_paths = [
os.path.join(path, "Common7", "IDE", "CommonExtensions", "Microsoft",
"CMake", "CMake", "bin")
@ -91,8 +91,9 @@ def by_executable(packages_to_check, path_hints=None):
path_hints = [] if path_hints is None else path_hints
exe_pattern_to_pkgs = collections.defaultdict(list)
for pkg in packages_to_check:
for exe in pkg.platform_executables:
exe_pattern_to_pkgs[exe].append(pkg)
if hasattr(pkg, 'executables'):
for exe in pkg.platform_executables:
exe_pattern_to_pkgs[exe].append(pkg)
# Add Windows specific, package related paths to the search paths
path_hints.extend(compute_windows_program_path_for_package(pkg))

View file

@ -16,8 +16,9 @@
import llnl.util.filesystem as fs
import llnl.util.tty as tty
from llnl.util.filesystem import rename
from llnl.util.lang import dedupe
from llnl.util.symlink import islink, symlink
from llnl.util.symlink import symlink
import spack.bootstrap
import spack.compilers
@ -530,14 +531,14 @@ def regenerate(self, concretized_specs):
tmp_symlink_name = os.path.join(root_dirname, '._view_link')
if os.path.exists(tmp_symlink_name):
os.unlink(tmp_symlink_name)
os.symlink(new_root, tmp_symlink_name)
symlink(new_root, tmp_symlink_name)
# mv symlink atomically over root symlink to old_root
if os.path.exists(self.root) and not os.path.islink(self.root):
msg = "Cannot create view: "
msg += "file already exists and is not a link: %s" % self.root
raise SpackEnvironmentViewError(msg)
os.rename(tmp_symlink_name, self.root)
rename(tmp_symlink_name, self.root)
# remove old_root
if old_root and os.path.exists(old_root):

View file

@ -634,7 +634,6 @@ class CacheURLFetchStrategy(URLFetchStrategy):
@_needs_stage
def fetch(self):
reg_str = r'^file://'
reg_str += '/' if is_windows else ''
path = re.sub(reg_str, '', self.url)
# check whether the cache file exists.

View file

@ -30,7 +30,7 @@
#: Groupdb does not exist on Windows, prevent imports
#: on supported systems
is_windows = str(spack.platforms.host()) == 'windows'
is_windows = sys.platform == 'win32'
if not is_windows:
import grp

View file

@ -65,9 +65,10 @@ class WindowsOs(OperatingSystem):
compiler_search_paths = comp_search_paths
def __init__(self):
if Version(platform.release()) < Version('10'):
plat_ver = platform.release()
if Version(plat_ver) < Version('10'):
raise SpackError("Spack is not supported on Windows versions older than 10")
super(WindowsOs, self).__init__('Windows10', '10')
super(WindowsOs, self).__init__('windows{}'.format(plat_ver), plat_ver)
def __str__(self):
return self.name

View file

@ -59,6 +59,7 @@
from spack.stage import ResourceStage, Stage, StageComposite, stage_prefix
from spack.util.executable import ProcessError, which
from spack.util.package_hash import package_hash
from spack.util.path import win_exe_ext
from spack.util.prefix import Prefix
from spack.version import Version
@ -176,9 +177,29 @@ class DetectablePackageMeta(object):
for the detection function.
"""
def __init__(cls, name, bases, attr_dict):
# If a package has the executables attribute then it's
# assumed to be detectable
# On windows, extend the list of regular expressions to look for
# filenames ending with ".exe"
# (in some cases these regular expressions include "$" to avoid
# pulling in filenames with unexpected suffixes, but this allows
# for example detecting "foo.exe" when the package writer specified
# that "foo" was a possible executable.
if hasattr(cls, 'executables'):
@property
def platform_executables(self):
def to_windows_exe(exe):
if exe.endswith('$'):
exe = exe.replace('$', '%s$' % win_exe_ext())
else:
exe += win_exe_ext()
return exe
plat_exe = []
if hasattr(self, 'executables'):
for exe in self.executables:
if sys.platform == 'win32':
exe = to_windows_exe(exe)
plat_exe.append(exe)
return plat_exe
@classmethod
def determine_spec_details(cls, prefix, exes_in_prefix):
"""Allow ``spack external find ...`` to locate installations.
@ -264,6 +285,13 @@ def determine_variants(cls, exes, version_str):
if default and not hasattr(cls, 'determine_variants'):
cls.determine_variants = determine_variants
# This function should not be overridden by subclasses,
# as it is not designed for bespoke pkg detection but rather
# on a per-platform basis
if hasattr(cls, 'platform_executables'):
raise PackageError("Packages should not override platform_executables")
cls.platform_executables = platform_executables
super(DetectablePackageMeta, cls).__init__(name, bases, attr_dict)
@ -898,16 +926,6 @@ def version(self):
" does not have a concrete version.")
return self.spec.versions[0]
@property
def platform_executables(self):
plat_exe = []
if hasattr(self, 'executables'):
for exe in self.executables:
if sys.platform == 'win32':
exe = exe.replace('$', r'\.exe$')
plat_exe.append(exe)
return plat_exe
@memoized
def version_urls(self):
"""OrderedDict of explicitly defined URLs for versions of this package.

View file

@ -13,6 +13,7 @@
import spack.error
import spack.util.path as sp
class Token(object):
"""Represents tokens; generated from input by lexer and fed to parse()."""

View file

@ -81,7 +81,8 @@
# setting `SPACK_USER_CACHE_PATH`. Otherwise it defaults to ~/.spack.
#
def _get_user_cache_path():
return os.path.expanduser(os.getenv('SPACK_USER_CACHE_PATH') or "~/.spack")
return os.path.expanduser(os.getenv('SPACK_USER_CACHE_PATH')
or "~%s.spack" % os.sep)
user_cache_path = _get_user_cache_path()
@ -116,12 +117,14 @@ def _get_user_cache_path():
# User configuration and caches in $HOME/.spack
def _get_user_config_path():
return os.path.expanduser(os.getenv('SPACK_USER_CONFIG_PATH') or "~/.spack")
return os.path.expanduser(os.getenv('SPACK_USER_CONFIG_PATH') or
"~%s.spack" % os.sep)
# Configuration in /etc/spack on the system
def _get_system_config_path():
return os.path.expanduser(os.getenv('SPACK_SYSTEM_CONFIG_PATH') or "/etc/spack")
return os.path.expanduser(os.getenv('SPACK_SYSTEM_CONFIG_PATH') or
os.sep + os.path.join('etc', 'spack'))
#: User configuration location

View file

@ -16,8 +16,6 @@
class Windows(Platform):
priority = 101
# binary_formats = ['macho']
def __init__(self):
super(Windows, self).__init__('windows')

View file

@ -330,7 +330,8 @@ def __init__(self, package_checker, namespace):
self.checker = package_checker
self.packages_path = self.checker.packages_path
if sys.platform == 'win32':
self.packages_path = self.packages_path.replace("\\", "/")
self.packages_path = \
spack.util.path.convert_to_posix_path(self.packages_path)
self.namespace = namespace
self.indexers = {}

View file

@ -111,6 +111,7 @@
import spack.util.executable
import spack.util.hash
import spack.util.module_cmd as md
import spack.util.path as pth
import spack.util.prefix
import spack.util.spack_json as sjson
import spack.util.spack_yaml as syaml
@ -1724,7 +1725,7 @@ def prefix(self):
@prefix.setter
def prefix(self, value):
self._prefix = spack.util.prefix.Prefix(value)
self._prefix = spack.util.prefix.Prefix(pth.convert_to_platform_path(value))
def _spec_hash(self, hash):
"""Utility method for computing different types of Spec hashes.
@ -4876,6 +4877,10 @@ class SpecLexer(spack.parse.Lexer):
"""Parses tokens that make up spack specs."""
def __init__(self):
# Spec strings require posix-style paths on Windows
# because the result is later passed to shlex
filename_reg = r'[/\w.-]*/[/\w/-]+\.(yaml|json)[^\b]*' if not is_windows\
else r'([A-Za-z]:)*?[/\w.-]*/[/\w/-]+\.(yaml|json)[^\b]*'
super(SpecLexer, self).__init__([
(r'\^', lambda scanner, val: self.token(DEP, val)),
(r'\@', lambda scanner, val: self.token(AT, val)),
@ -4889,10 +4894,7 @@ def __init__(self):
# Filenames match before identifiers, so no initial filename
# component is parsed as a spec (e.g., in subdir/spec.yaml/json)
# posixpath on Windows here because this string will be fed through
# shlex
(r'[/\w.-]*/[/\w/-]+\.(yaml|json)[^\b]*' if not is_windows\
else r'([A-Za-z]:)*?[/\w.-]*/[/\w/-]+\.(yaml|json)[^\b]*',
(filename_reg,
lambda scanner, v: self.token(FILE, v)),
# Hash match after filename. No valid filename can be a hash

View file

@ -4,6 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import platform
import sys
import pytest
@ -58,8 +59,8 @@ def test_platform(current_host_platform):
assert str(detected_platform) == str(current_host_platform)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Test unsupported on Windows")
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_user_input_combination(config, target_str, os_str):
"""Test for all the valid user input combinations that both the target and
the operating system match.

View file

@ -18,6 +18,15 @@
reason="does not run on windows")
def _validate_url(url):
return
@pytest.fixture(autouse=True)
def url_check(monkeypatch):
monkeypatch.setattr(spack.util.url, 'require_url_format', _validate_url)
def test_build_tarball_overwrite(
install_mockery, mock_fetch, monkeypatch, tmpdir):

View file

@ -24,6 +24,18 @@
from spack.paths import build_env_path
from spack.util.environment import EnvironmentModifications
from spack.util.executable import Executable
from spack.util.path import Path, convert_to_platform_path
def os_pathsep_join(path, *pths):
out_pth = path
for pth in pths:
out_pth = os.pathsep.join([out_pth, pth])
return out_pth
def prep_and_join(path, *pths):
return os.path.sep + os.path.join(path, *pths)
@pytest.fixture
@ -84,7 +96,7 @@ def _ensure(env_mods):
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
reason="Static to Shared not supported on Win (yet)")
def test_static_to_shared_library(build_environment):
os.environ['SPACK_TEST_COMMAND'] = 'dump-args'
@ -139,8 +151,6 @@ def _set_wrong_cc(x):
assert os.environ['ANOTHER_VAR'] == 'THIS_IS_SET'
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('initial,modifications,expected', [
# Set and unset variables
({'SOME_VAR_STR': '', 'SOME_VAR_NUM': '0'},
@ -153,25 +163,32 @@ def _set_wrong_cc(x):
{'set': {'SOME_VAR_STR': 'SOME_STR'}},
{'SOME_VAR_STR': 'SOME_STR'}),
# Append and prepend to the same variable
({'EMPTY_PATH_LIST': '/path/middle'},
{'prepend_path': {'EMPTY_PATH_LIST': '/path/first'},
'append_path': {'EMPTY_PATH_LIST': '/path/last'}},
{'EMPTY_PATH_LIST': '/path/first:/path/middle:/path/last'}),
({'EMPTY_PATH_LIST': prep_and_join('path', 'middle')},
{'prepend_path': {'EMPTY_PATH_LIST': prep_and_join('path', 'first')},
'append_path': {'EMPTY_PATH_LIST': prep_and_join('path', 'last')}},
{'EMPTY_PATH_LIST': os_pathsep_join(prep_and_join('path', 'first'),
prep_and_join('path', 'middle'),
prep_and_join('path', 'last'))}),
# Append and prepend from empty variables
({'EMPTY_PATH_LIST': '', 'SOME_VAR_STR': ''},
{'prepend_path': {'EMPTY_PATH_LIST': '/path/first'},
'append_path': {'SOME_VAR_STR': '/path/last'}},
{'EMPTY_PATH_LIST': '/path/first', 'SOME_VAR_STR': '/path/last'}),
{'prepend_path': {'EMPTY_PATH_LIST': prep_and_join('path', 'first')},
'append_path': {'SOME_VAR_STR': prep_and_join('path', 'last')}},
{'EMPTY_PATH_LIST': prep_and_join('path', 'first'),
'SOME_VAR_STR': prep_and_join('path', 'last')}),
({}, # Same as before but on variables that were not defined
{'prepend_path': {'EMPTY_PATH_LIST': '/path/first'},
'append_path': {'SOME_VAR_STR': '/path/last'}},
{'EMPTY_PATH_LIST': '/path/first', 'SOME_VAR_STR': '/path/last'}),
{'prepend_path': {'EMPTY_PATH_LIST': prep_and_join('path', 'first')},
'append_path': {'SOME_VAR_STR': prep_and_join('path', 'last')}},
{'EMPTY_PATH_LIST': prep_and_join('path', 'first'),
'SOME_VAR_STR': prep_and_join('path', 'last')}),
# Remove a path from a list
({'EMPTY_PATH_LIST': '/path/first:/path/middle:/path/last'},
{'remove_path': {'EMPTY_PATH_LIST': '/path/middle'}},
{'EMPTY_PATH_LIST': '/path/first:/path/last'}),
({'EMPTY_PATH_LIST': '/only/path'},
{'remove_path': {'EMPTY_PATH_LIST': '/only/path'}},
({'EMPTY_PATH_LIST': os_pathsep_join(prep_and_join('path', 'first'),
prep_and_join('path', 'middle'),
prep_and_join('path', 'last'))},
{'remove_path': {'EMPTY_PATH_LIST': prep_and_join('path', 'middle')}},
{'EMPTY_PATH_LIST': os_pathsep_join(prep_and_join('path', 'first'),
prep_and_join('path', 'last'))}),
({'EMPTY_PATH_LIST': prep_and_join('only', 'path')},
{'remove_path': {'EMPTY_PATH_LIST': prep_and_join('only', 'path')}},
{'EMPTY_PATH_LIST': ''}),
])
def test_compiler_config_modifications(
@ -180,16 +197,22 @@ def test_compiler_config_modifications(
# Set the environment as per prerequisites
ensure_env_variables(initial)
def platform_pathsep(pathlist):
if Path.platform_path == Path.windows:
pathlist = pathlist.replace(':', ';')
return convert_to_platform_path(pathlist)
# Monkeypatch a pkg.compiler.environment with the required modifications
pkg = spack.spec.Spec('cmake').concretized().package
monkeypatch.setattr(pkg.compiler, 'environment', modifications)
# Trigger the modifications
spack.build_environment.setup_package(pkg, False)
# Check they were applied
for name, value in expected.items():
if value is not None:
value = platform_pathsep(value)
assert os.environ[name] == value
continue
assert name not in os.environ

View file

@ -11,9 +11,10 @@
import spack.repo
import spack.spec
# Functionality supported on windows however tests are currently failing
# due to compatibility issues, or due to dependent components currently
# being unsupported on Windows
# Spack functionality tested here should work on Windows,
# however, tests are currently failing because support
# for Spack on Windows has not been extended to this
# module yet.
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")

View file

@ -4,6 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import sys
import pytest
@ -13,13 +14,17 @@
from spack.fetch_strategy import CacheURLFetchStrategy, NoCacheError
from spack.stage import Stage
is_windows = sys.platform == 'win32'
@pytest.mark.parametrize('_fetch_method', ['curl', 'urllib'])
def test_fetch_missing_cache(tmpdir, _fetch_method):
"""Ensure raise a missing cache file."""
testpath = str(tmpdir)
with spack.config.override('config:url_fetch_method', _fetch_method):
fetcher = CacheURLFetchStrategy(url='file:///not-a-real-cache-file')
abs_pref = '' if is_windows else '/'
url = 'file://' + abs_pref + 'not-a-real-cache-file'
fetcher = CacheURLFetchStrategy(url=url)
with Stage(fetcher, path=testpath):
with pytest.raises(NoCacheError, match=r'No cache'):
fetcher.fetch()
@ -31,7 +36,11 @@ def test_fetch(tmpdir, _fetch_method):
testpath = str(tmpdir)
cache = os.path.join(testpath, 'cache.tar.gz')
touch(cache)
url = 'file:///{0}'.format(cache)
if is_windows:
url_stub = '{0}'
else:
url_stub = '/{0}'
url = 'file://' + url_stub.format(cache)
with spack.config.override('config:url_fetch_method', _fetch_method):
fetcher = CacheURLFetchStrategy(url=url)
with Stage(fetcher, path=testpath) as stage:

View file

@ -4,7 +4,6 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import argparse
import sys
import pytest
@ -63,8 +62,6 @@ def test_parse_spec_flags_with_spaces(
assert all(x in s.variants for x in expected_variants)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('config')
def test_match_spec_env(mock_packages, mutable_mock_env_path):
"""
@ -87,8 +84,6 @@ def test_match_spec_env(mock_packages, mutable_mock_env_path):
assert env_spec.concrete
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('config')
def test_multiple_env_match_raises_error(mock_packages, mutable_mock_env_path):
e = ev.create('test')
@ -102,8 +97,6 @@ def test_multiple_env_match_raises_error(mock_packages, mutable_mock_env_path):
assert 'matches multiple specs' in exc_info.value.message
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('config')
def test_root_and_dep_match_returns_root(mock_packages, mutable_mock_env_path):
e = ev.create('test')

View file

@ -105,7 +105,8 @@ def test_compiler_remove(mutable_config, mock_packages):
assert spack.spec.CompilerSpec("gcc@4.5.0") not in compilers
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.skipif(sys.platform == 'win32', reason="Cannot execute bash \
script on Windows")
def test_compiler_add(
mutable_config, mock_packages, mock_compiler_dir, mock_compiler_version
):

View file

@ -3,7 +3,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
import pytest
@ -19,7 +18,6 @@
concretize = SpackCommand('concretize')
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.parametrize('concretization', ['separately', 'together'])
def test_concretize_all_test_dependencies(concretization):
"""Check all test dependencies are concretized."""
@ -32,7 +30,6 @@ def test_concretize_all_test_dependencies(concretization):
assert e.matching_spec('test-dependency')
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.parametrize('concretization', ['separately', 'together'])
def test_concretize_root_test_dependencies_not_recursive(concretization):
"""Check that test dependencies are not concretized recursively."""
@ -45,7 +42,6 @@ def test_concretize_root_test_dependencies_not_recursive(concretization):
assert e.matching_spec('test-dependency') is None
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.parametrize('concretization', ['separately', 'together'])
def test_concretize_root_test_dependencies_are_concretized(concretization):
"""Check that root test dependencies are concretized."""

View file

@ -4,7 +4,6 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import functools
import os
import sys
import pytest
@ -426,11 +425,8 @@ def test_remove_list(mutable_empty_config):
"""
@pytest.mark.skipif(sys.platform == 'win32',
reason="Lockfiles not support on Windows (yet)")
def test_config_add_to_env(mutable_empty_config, mutable_mock_env_path):
ev.create('test')
env('create', 'test')
with ev.read('test'):
config('add', 'config:dirty:true')
output = config('get')

View file

@ -27,10 +27,12 @@
from spack.util.mock_package import MockPackageMultiRepo
from spack.util.path import substitute_path_variables
# TODO-27021
# everything here uses the mock_env_path
pytestmark = [
pytest.mark.usefixtures('mutable_mock_env_path', 'config', 'mutable_mock_repo'),
pytest.mark.maybeslow
pytest.mark.maybeslow,
pytest.mark.skipif(sys.platform == 'win32', reason='Envs unsupported on Window')
]
env = SpackCommand('env')
@ -42,10 +44,7 @@
uninstall = SpackCommand('uninstall')
find = SpackCommand('find')
if sys.platform == 'win32':
sep = 'C:\\'
else:
sep = os.sep
sep = os.sep
def check_mpileaks_and_deps_in_view(viewdir):
@ -66,8 +65,6 @@ def test_add():
assert Spec('mpileaks') in e.user_specs
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_env_add_virtual():
env('create', 'test')
@ -136,8 +133,6 @@ def test_env_remove(capfd):
assert 'bar' not in out
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_concretize():
e = ev.create('test')
e.add('mpileaks')
@ -146,8 +141,6 @@ def test_concretize():
assert any(x.name == 'mpileaks' for x in env_specs)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="InstallError:Wrong cmake was in environment")
def test_env_uninstalled_specs(install_mockery, mock_fetch):
e = ev.create('test')
e.add('cmake-client')
@ -161,8 +154,6 @@ def test_env_uninstalled_specs(install_mockery, mock_fetch):
assert any(s.name == 'mpileaks' for s in e.uninstalled_specs())
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='InstallError: Wrong cmake was in environment')
def test_env_install_all(install_mockery, mock_fetch):
e = ev.create('test')
e.add('cmake-client')
@ -173,8 +164,6 @@ def test_env_install_all(install_mockery, mock_fetch):
assert spec.package.installed
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='InstallError: Wrong cmake was in environment')
def test_env_install_single_spec(install_mockery, mock_fetch):
env('create', 'test')
install = SpackCommand('install')
@ -189,7 +178,6 @@ def test_env_install_single_spec(install_mockery, mock_fetch):
assert e.specs_by_hash[e.concretized_order[0]].name == 'cmake-client'
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_env_roots_marked_explicit(install_mockery, mock_fetch):
install = SpackCommand('install')
install('dependent-install')
@ -211,8 +199,6 @@ def test_env_roots_marked_explicit(install_mockery, mock_fetch):
assert len(explicit) == 2
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='InstallError: Wrong cmake was in environment')
def test_env_modifications_error_on_activate(
install_mockery, mock_fetch, monkeypatch, capfd):
env('create', 'test')
@ -235,8 +221,6 @@ def setup_error(pkg, env):
assert "Warning: couldn't get environment settings" in err
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Error: filename or extension is too long')
def test_activate_adds_transitive_run_deps_to_path(
install_mockery, mock_fetch, monkeypatch):
env('create', 'test')
@ -251,8 +235,6 @@ def test_activate_adds_transitive_run_deps_to_path(
assert env_variables['DEPENDENCY_ENV_VAR'] == '1'
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='InstallError: Wrong cmake was in environment:')
def test_env_install_same_spec_twice(install_mockery, mock_fetch):
env('create', 'test')
@ -267,8 +249,6 @@ def test_env_install_same_spec_twice(install_mockery, mock_fetch):
assert 'already installed' in out
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_env_definition_symlink(install_mockery, mock_fetch, tmpdir):
filepath = str(tmpdir.join('spack.yaml'))
filepath_mid = str(tmpdir.join('spack_mid.yaml'))
@ -288,8 +268,6 @@ def test_env_definition_symlink(install_mockery, mock_fetch, tmpdir):
assert os.path.islink(filepath_mid)
@pytest.mark.skipif(sys.platform == "win32",
reason='Logging error')
def test_env_install_two_specs_same_dep(
install_mockery, mock_fetch, tmpdir, capsys):
"""Test installation of two packages that share a dependency with no
@ -325,8 +303,6 @@ def test_env_install_two_specs_same_dep(
assert a, 'Expected a to be installed'
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_remove_after_concretize():
e = ev.create('test')
@ -350,8 +326,6 @@ def test_remove_after_concretize():
assert not any(s.name == 'mpileaks' for s in env_specs)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_remove_command():
env('create', 'test')
assert 'test' in env('list')
@ -415,8 +389,6 @@ def test_environment_status(capsys, tmpdir):
assert 'in current directory' in env('status')
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows - uses pkgconf')
def test_env_status_broken_view(
mutable_mock_env_path, mock_archive, mock_fetch, mock_packages,
install_mockery, tmpdir
@ -438,8 +410,6 @@ def test_env_status_broken_view(
assert 'includes out of date packages or repos' not in output
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows - uses pkgconf')
def test_env_activate_broken_view(
mutable_mock_env_path, mock_archive, mock_fetch, mock_packages,
install_mockery
@ -458,8 +428,6 @@ def test_env_activate_broken_view(
env('activate', '--sh', 'test')
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_to_lockfile_dict():
e = ev.create('test')
e.add('mpileaks')
@ -472,8 +440,6 @@ def test_to_lockfile_dict():
assert e.specs_by_hash == e_copy.specs_by_hash
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_env_repo():
e = ev.create('test')
e.add('mpileaks')
@ -487,8 +453,6 @@ def test_env_repo():
assert package.namespace == 'builtin.mock'
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_user_removed_spec():
"""Ensure a user can remove from any position in the spack.yaml file."""
initial_yaml = StringIO("""\
@ -523,8 +487,6 @@ def test_user_removed_spec():
assert not any(x.name == 'hypre' for x in env_specs)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_init_from_lockfile(tmpdir):
"""Test that an environment can be instantiated from a lockfile."""
initial_yaml = StringIO("""\
@ -551,8 +513,6 @@ def test_init_from_lockfile(tmpdir):
assert s1 == s2
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_init_from_yaml(tmpdir):
"""Test that an environment can be instantiated from a lockfile."""
initial_yaml = StringIO("""\
@ -576,8 +536,6 @@ def test_init_from_yaml(tmpdir):
assert not e2.specs_by_hash
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows - uses pkgconf')
@pytest.mark.usefixtures('config')
def test_env_view_external_prefix(
tmpdir_factory, mutable_database, mock_packages
@ -650,8 +608,6 @@ def test_init_with_file_and_remove(tmpdir):
assert 'test' not in out
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_env_with_config():
test_config = """\
env:
@ -671,8 +627,6 @@ def test_env_with_config():
for x in e._get_environment_specs())
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_with_config_bad_include(capfd):
env_name = 'test_bad_include'
test_config = """\
@ -696,8 +650,6 @@ def test_with_config_bad_include(capfd):
assert ev.active_environment() is None
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_env_with_include_config_files_same_basename():
test_config = """\
env:
@ -740,8 +692,6 @@ def test_env_with_include_config_files_same_basename():
assert(environment_specs[1].satisfies('mpileaks@2.2'))
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_env_with_included_config_file():
test_config = """\
env:
@ -767,8 +717,6 @@ def test_env_with_included_config_file():
for x in e._get_environment_specs())
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_env_with_included_config_scope():
config_scope_path = os.path.join(ev.root('test'), 'config')
test_config = """\
@ -798,8 +746,6 @@ def test_env_with_included_config_scope():
for x in e._get_environment_specs())
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_env_with_included_config_var_path():
config_var_path = os.path.join('$tempdir', 'included-config.yaml')
test_config = """\
@ -829,8 +775,6 @@ def test_env_with_included_config_var_path():
for x in e._get_environment_specs())
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_env_config_precedence():
test_config = """\
env:
@ -866,8 +810,6 @@ def test_env_config_precedence():
x.satisfies('libelf@0.8.12') for x in e._get_environment_specs())
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_included_config_precedence():
test_config = """\
env:
@ -922,8 +864,6 @@ def test_bad_env_yaml_format(tmpdir):
assert "'spacks' was unexpected" in str(e)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows (yet)')
def test_env_loads(install_mockery, mock_fetch):
env('create', 'test')
@ -945,8 +885,6 @@ def test_env_loads(install_mockery, mock_fetch):
assert 'module load mpileaks' in contents
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
@pytest.mark.disable_clean_stage_check
def test_stage(mock_stage, mock_fetch, install_mockery):
env('create', 'test')
@ -985,8 +923,6 @@ def test_env_commands_die_with_no_env_arg():
env('status')
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_env_blocks_uninstall(mock_stage, mock_fetch, install_mockery):
env('create', 'test')
with ev.read('test'):
@ -1009,8 +945,6 @@ def test_roots_display_with_variants():
assert "boost +shared" in out
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_uninstall_removes_from_env(mock_stage, mock_fetch, install_mockery):
env('create', 'test')
with ev.read('test'):
@ -1053,8 +987,6 @@ def create_v1_lockfile_dict(roots, all_specs):
return test_lockfile_dict
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows - uses pkgconf")
@pytest.mark.usefixtures('config')
def test_read_old_lock_and_write_new(tmpdir):
build_only = ('build',)
@ -1086,8 +1018,6 @@ def test_read_old_lock_and_write_new(tmpdir):
y.build_hash()])
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows - uses pkgconf")
@pytest.mark.usefixtures('config')
def test_read_old_lock_creates_backup(tmpdir):
"""When reading a version-1 lockfile, make sure that a backup of that file
@ -1116,8 +1046,6 @@ def test_read_old_lock_creates_backup(tmpdir):
assert y.dag_hash() in lockfile_dict_v1['concrete_specs']
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows - uses pkgconf")
@pytest.mark.usefixtures('config')
def test_indirect_build_dep():
"""Simple case of X->Y->Z where Y is a build/link dep and Z is a
@ -1153,8 +1081,6 @@ def noop(*args):
assert x_env_spec == x_concretized
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows - uses pkgconf")
@pytest.mark.usefixtures('config')
def test_store_different_build_deps():
r"""Ensure that an environment can store two instances of a build-only
@ -1208,8 +1134,6 @@ def noop(*args):
assert x_read['z'] != y_read['z']
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Fails on windows')
def test_env_updates_view_install(
tmpdir, mock_stage, mock_fetch, install_mockery):
view_dir = tmpdir.join('view')
@ -1221,8 +1145,6 @@ def test_env_updates_view_install(
check_mpileaks_and_deps_in_view(view_dir)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Fails on windows')
def test_env_view_fails(
tmpdir, mock_packages, mock_stage, mock_fetch, install_mockery):
view_dir = tmpdir.join('view')
@ -1235,8 +1157,6 @@ def test_env_view_fails(
install('--fake')
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows (yet)')
def test_env_without_view_install(
tmpdir, mock_stage, mock_fetch, install_mockery):
# Test enabling a view after installing specs
@ -1259,8 +1179,6 @@ def test_env_without_view_install(
check_mpileaks_and_deps_in_view(view_dir)
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_env_config_view_default(
tmpdir, mock_stage, mock_fetch, install_mockery):
# This config doesn't mention whether a view is enabled
@ -1280,8 +1198,6 @@ def test_env_config_view_default(
assert view.get_spec('mpileaks')
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows (yet)')
def test_env_updates_view_install_package(
tmpdir, mock_stage, mock_fetch, install_mockery):
view_dir = tmpdir.join('view')
@ -1292,8 +1208,6 @@ def test_env_updates_view_install_package(
assert os.path.exists(str(view_dir.join('.spack/mpileaks')))
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows (yet)')
def test_env_updates_view_add_concretize(
tmpdir, mock_stage, mock_fetch, install_mockery):
view_dir = tmpdir.join('view')
@ -1306,8 +1220,6 @@ def test_env_updates_view_add_concretize(
check_mpileaks_and_deps_in_view(view_dir)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows (yet)')
def test_env_updates_view_uninstall(
tmpdir, mock_stage, mock_fetch, install_mockery):
view_dir = tmpdir.join('view')
@ -1323,8 +1235,6 @@ def test_env_updates_view_uninstall(
check_viewdir_removal(view_dir)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows (yet)')
def test_env_updates_view_uninstall_referenced_elsewhere(
tmpdir, mock_stage, mock_fetch, install_mockery):
view_dir = tmpdir.join('view')
@ -1342,8 +1252,6 @@ def test_env_updates_view_uninstall_referenced_elsewhere(
check_viewdir_removal(view_dir)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows (yet)')
def test_env_updates_view_remove_concretize(
tmpdir, mock_stage, mock_fetch, install_mockery):
view_dir = tmpdir.join('view')
@ -1362,8 +1270,6 @@ def test_env_updates_view_remove_concretize(
check_viewdir_removal(view_dir)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows (yet)')
def test_env_updates_view_force_remove(
tmpdir, mock_stage, mock_fetch, install_mockery):
view_dir = tmpdir.join('view')
@ -1379,8 +1285,6 @@ def test_env_updates_view_force_remove(
check_viewdir_removal(view_dir)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason='Not supported on Windows (yet)')
def test_env_activate_view_fails(
tmpdir, mock_stage, mock_fetch, install_mockery):
"""Sanity check on env activate to make sure it requires shell support"""
@ -1455,8 +1359,6 @@ def test_stack_yaml_definitions_as_constraints_on_matrix(tmpdir):
assert Spec('callpath^mpich@3.0.3') in test.user_specs
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
@pytest.mark.regression('12095')
def test_stack_yaml_definitions_write_reference(tmpdir):
filename = str(tmpdir.join('spack.yaml'))
@ -1523,8 +1425,6 @@ def test_stack_yaml_remove_from_list(tmpdir):
assert Spec('callpath') in test.user_specs
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_stack_yaml_remove_from_list_force(tmpdir):
filename = str(tmpdir.join('spack.yaml'))
with open(filename, 'w') as f:
@ -1575,8 +1475,6 @@ def test_stack_yaml_remove_from_matrix_no_effect(tmpdir):
assert before == after
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_stack_yaml_force_remove_from_matrix(tmpdir):
filename = str(tmpdir.join('spack.yaml'))
with open(filename, 'w') as f:
@ -1610,8 +1508,6 @@ def test_stack_yaml_force_remove_from_matrix(tmpdir):
assert mpileaks_spec not in after_conc
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_stack_concretize_extraneous_deps(tmpdir, config, mock_packages):
# FIXME: The new concretizer doesn't handle yet soft
# FIXME: constraints for stacks
@ -1647,8 +1543,6 @@ def test_stack_concretize_extraneous_deps(tmpdir, config, mock_packages):
assert concrete.satisfies('^mpi', strict=True)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_stack_concretize_extraneous_variants(tmpdir, config, mock_packages):
filename = str(tmpdir.join('spack.yaml'))
with open(filename, 'w') as f:
@ -1680,8 +1574,6 @@ def test_stack_concretize_extraneous_variants(tmpdir, config, mock_packages):
user.variants['shared'].value)
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_stack_concretize_extraneous_variants_with_dash(tmpdir, config,
mock_packages):
filename = str(tmpdir.join('spack.yaml'))
@ -1730,8 +1622,6 @@ def test_stack_definition_extension(tmpdir):
assert Spec('callpath') in test.user_specs
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_stack_definition_conditional_false(tmpdir):
filename = str(tmpdir.join('spack.yaml'))
with open(filename, 'w') as f:
@ -1889,8 +1779,6 @@ def test_stack_definition_conditional_add_write(tmpdir):
assert 'zmpi' not in packages_lists[1]['packages']
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_stack_combinatorial_view(tmpdir, mock_fetch, mock_packages,
mock_archive, install_mockery):
filename = str(tmpdir.join('spack.yaml'))
@ -1923,8 +1811,6 @@ def test_stack_combinatorial_view(tmpdir, mock_fetch, mock_packages,
(spec.version, spec.compiler.name)))
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_stack_view_select(tmpdir, mock_fetch, mock_packages,
mock_archive, install_mockery):
filename = str(tmpdir.join('spack.yaml'))
@ -1963,8 +1849,6 @@ def test_stack_view_select(tmpdir, mock_fetch, mock_packages,
(spec.version, spec.compiler.name)))
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_stack_view_exclude(tmpdir, mock_fetch, mock_packages,
mock_archive, install_mockery):
filename = str(tmpdir.join('spack.yaml'))
@ -2003,8 +1887,6 @@ def test_stack_view_exclude(tmpdir, mock_fetch, mock_packages,
(spec.version, spec.compiler.name)))
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_stack_view_select_and_exclude(tmpdir, mock_fetch, mock_packages,
mock_archive, install_mockery):
filename = str(tmpdir.join('spack.yaml'))
@ -2044,8 +1926,6 @@ def test_stack_view_select_and_exclude(tmpdir, mock_fetch, mock_packages,
(spec.version, spec.compiler.name)))
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_view_link_roots(tmpdir, mock_fetch, mock_packages, mock_archive,
install_mockery):
filename = str(tmpdir.join('spack.yaml'))
@ -2087,8 +1967,6 @@ def test_view_link_roots(tmpdir, mock_fetch, mock_packages, mock_archive,
(spec.version, spec.compiler.name)))
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_view_link_run(tmpdir, mock_fetch, mock_packages, mock_archive,
install_mockery):
yaml = str(tmpdir.join('spack.yaml'))
@ -2120,8 +1998,6 @@ def test_view_link_run(tmpdir, mock_fetch, mock_packages, mock_archive,
assert not os.path.exists(os.path.join(viewdir, pkg))
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
@pytest.mark.parametrize('link_type', ['hardlink', 'copy', 'symlink'])
def test_view_link_type(link_type, tmpdir, mock_fetch, mock_packages, mock_archive,
install_mockery):
@ -2151,8 +2027,6 @@ def test_view_link_type(link_type, tmpdir, mock_fetch, mock_packages, mock_archi
assert os.path.islink(file_to_test) == (link_type == 'symlink')
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_view_link_all(tmpdir, mock_fetch, mock_packages, mock_archive,
install_mockery):
filename = str(tmpdir.join('spack.yaml'))
@ -2193,8 +2067,6 @@ def test_view_link_all(tmpdir, mock_fetch, mock_packages, mock_archive,
(spec.version, spec.compiler.name)))
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_stack_view_activate_from_default(tmpdir, mock_fetch, mock_packages,
mock_archive, install_mockery):
filename = str(tmpdir.join('spack.yaml'))
@ -2226,8 +2098,6 @@ def test_stack_view_activate_from_default(tmpdir, mock_fetch, mock_packages,
assert 'FOOBAR=mpileaks' in shell
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_stack_view_no_activate_without_default(tmpdir, mock_fetch,
mock_packages, mock_archive,
install_mockery):
@ -2258,8 +2128,6 @@ def test_stack_view_no_activate_without_default(tmpdir, mock_fetch,
assert viewdir not in shell
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_stack_view_multiple_views(tmpdir, mock_fetch, mock_packages,
mock_archive, install_mockery):
filename = str(tmpdir.join('spack.yaml'))
@ -2362,8 +2230,6 @@ def test_env_activate_default_view_root_unconditional(mutable_mock_env_path):
'export PATH="{0}'.format(viewdir_bin) in out
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_concretize_user_specs_together():
e = ev.create('coconcretization')
e.concretization = 'together'
@ -2392,8 +2258,6 @@ def test_concretize_user_specs_together():
assert all('mpich' not in spec for _, spec in e.concretized_specs())
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_cant_install_single_spec_when_concretizing_together():
e = ev.create('coconcretization')
e.concretization = 'together'
@ -2403,8 +2267,6 @@ def test_cant_install_single_spec_when_concretizing_together():
e.install_all()
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_duplicate_packages_raise_when_concretizing_together():
e = ev.create('coconcretization')
e.concretization = 'together'
@ -2417,8 +2279,6 @@ def test_duplicate_packages_raise_when_concretizing_together():
e.concretize()
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
def test_env_write_only_non_default():
env('create', 'test')
@ -2429,8 +2289,6 @@ def test_env_write_only_non_default():
assert yaml == ev.default_manifest_yaml
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
@pytest.mark.regression('20526')
def test_env_write_only_non_default_nested(tmpdir):
# setup an environment file
@ -2465,8 +2323,6 @@ def test_env_write_only_non_default_nested(tmpdir):
assert manifest == contents
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
@pytest.fixture
def packages_yaml_v015(tmpdir):
"""Return the path to an existing manifest in the v0.15.x format
@ -2557,8 +2413,6 @@ def test_can_update_attributes_with_override(tmpdir):
env('update', '-y', str(abspath.dirname))
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
@pytest.mark.regression('18338')
def test_newline_in_commented_sequence_is_not_an_issue(tmpdir):
spack_yaml = """
@ -2594,8 +2448,6 @@ def extract_build_hash(environment):
assert libelf_first_hash == libelf_second_hash
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
reason="Not supported on Windows (yet)")
@pytest.mark.regression('18441')
def test_lockfile_not_deleted_on_write_error(tmpdir, monkeypatch):
raw_yaml = """
@ -2729,8 +2581,6 @@ def test_custom_version_concretize_together(tmpdir):
assert any('hdf5@myversion' in spec for _, spec in e.concretized_specs())
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_modules_relative_to_views(tmpdir, install_mockery, mock_fetch):
spack_yaml = """
spack:
@ -2762,8 +2612,6 @@ def test_modules_relative_to_views(tmpdir, install_mockery, mock_fetch):
assert spec.prefix not in contents
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_multiple_modules_post_env_hook(tmpdir, install_mockery, mock_fetch):
spack_yaml = """
spack:

View file

@ -14,6 +14,8 @@
from spack.main import SpackCommand
from spack.spec import Spec
is_windows = sys.platform == 'win32'
@pytest.fixture
def executables_found(monkeypatch):
@ -25,11 +27,26 @@ def _mock_search(path_hints=None):
return _factory
@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows")
def test_find_external_single_package(mock_executable, executables_found):
@pytest.fixture
def _platform_executables(monkeypatch):
def _win_exe_ext():
return '.bat'
monkeypatch.setattr(spack.package, 'win_exe_ext', _win_exe_ext)
def define_plat_exe(exe):
if is_windows:
exe += '.bat'
return exe
def test_find_external_single_package(mock_executable, executables_found,
_platform_executables):
pkgs_to_check = [spack.repo.get('cmake')]
executables_found({
mock_executable("cmake", output='echo "cmake version 1.foo"'): 'cmake'
mock_executable("cmake", output='echo cmake version 1.foo'):
define_plat_exe('cmake')
})
pkg_to_entries = spack.detection.by_executable(pkgs_to_check)
@ -40,20 +57,23 @@ def test_find_external_single_package(mock_executable, executables_found):
assert single_entry.spec == Spec('cmake@1.foo')
@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows")
def test_find_external_two_instances_same_package(mock_executable, executables_found):
def test_find_external_two_instances_same_package(mock_executable, executables_found,
_platform_executables):
pkgs_to_check = [spack.repo.get('cmake')]
# Each of these cmake instances is created in a different prefix
# In Windows, quoted strings are echo'd with quotes includes
# we need to avoid that for proper regex.
cmake_path1 = mock_executable(
"cmake", output='echo "cmake version 1.foo"', subdir=('base1', 'bin')
"cmake", output='echo cmake version 1.foo', subdir=('base1', 'bin')
)
cmake_path2 = mock_executable(
"cmake", output='echo "cmake version 3.17.2"', subdir=('base2', 'bin')
"cmake", output='echo cmake version 3.17.2', subdir=('base2', 'bin')
)
cmake_exe = define_plat_exe('cmake')
executables_found({
cmake_path1: 'cmake',
cmake_path2: 'cmake'
cmake_path1: cmake_exe,
cmake_path2: cmake_exe
})
pkg_to_entries = spack.detection.by_executable(pkgs_to_check)
@ -87,23 +107,24 @@ def test_find_external_update_config(mutable_config):
def test_get_executables(working_env, mock_executable):
cmake_path1 = mock_executable("cmake", output="echo cmake version 1.foo")
os.environ['PATH'] = ':'.join([os.path.dirname(cmake_path1)])
os.environ['PATH'] = os.pathsep.join([os.path.dirname(cmake_path1)])
path_to_exe = spack.detection.executables_in_path()
assert path_to_exe[cmake_path1] == 'cmake'
cmake_exe = define_plat_exe('cmake')
assert path_to_exe[cmake_path1] == cmake_exe
external = SpackCommand('external')
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_find_external_cmd(mutable_config, working_env, mock_executable):
def test_find_external_cmd(mutable_config, working_env, mock_executable,
_platform_executables):
"""Test invoking 'spack external find' with additional package arguments,
which restricts the set of packages that Spack looks for.
"""
cmake_path1 = mock_executable("cmake", output="echo cmake version 1.foo")
prefix = os.path.dirname(os.path.dirname(cmake_path1))
os.environ['PATH'] = ':'.join([os.path.dirname(cmake_path1)])
os.environ['PATH'] = os.pathsep.join([os.path.dirname(cmake_path1)])
external('find', 'cmake')
pkgs_cfg = spack.config.get('packages')
@ -113,7 +134,6 @@ def test_find_external_cmd(mutable_config, working_env, mock_executable):
assert {'spec': 'cmake@1.foo', 'prefix': prefix} in cmake_externals
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_find_external_cmd_not_buildable(
mutable_config, working_env, mock_executable):
"""When the user invokes 'spack external find --not-buildable', the config
@ -121,25 +141,23 @@ def test_find_external_cmd_not_buildable(
not buildable.
"""
cmake_path1 = mock_executable("cmake", output="echo cmake version 1.foo")
os.environ['PATH'] = ':'.join([os.path.dirname(cmake_path1)])
os.environ['PATH'] = os.pathsep.join([os.path.dirname(cmake_path1)])
external('find', '--not-buildable', 'cmake')
pkgs_cfg = spack.config.get('packages')
assert not pkgs_cfg['cmake']['buildable']
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_find_external_cmd_full_repo(
mutable_config, working_env, mock_executable, mutable_mock_repo):
"""Test invoking 'spack external find --all' with no additional arguments
mutable_config, working_env, mock_executable, mutable_mock_repo,
_platform_executables):
"""Test invoking 'spack external find' with no additional arguments, which
iterates through each package in the repository.
"""
exe_path1 = mock_executable(
"find-externals1-exe", output="echo find-externals1 version 1.foo"
)
prefix = os.path.dirname(os.path.dirname(exe_path1))
os.environ['PATH'] = ':'.join([os.path.dirname(exe_path1)])
os.environ['PATH'] = os.pathsep.join([os.path.dirname(exe_path1)])
external('find', '--all')
pkgs_cfg = spack.config.get('packages')
@ -186,14 +204,13 @@ def test_find_external_merge(mutable_config, mutable_mock_repo):
'prefix': '/x/y2/'} in pkg_externals
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_list_detectable_packages(mutable_config, mutable_mock_repo):
external("list")
assert external.returncode == 0
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_packages_yaml_format(mock_executable, mutable_config, monkeypatch):
def test_packages_yaml_format(
mock_executable, mutable_config, monkeypatch, _platform_executables):
# Prepare an environment to detect a fake gcc
gcc_exe = mock_executable('gcc', output="echo 4.2.1")
prefix = os.path.dirname(gcc_exe)
@ -217,8 +234,8 @@ def test_packages_yaml_format(mock_executable, mutable_config, monkeypatch):
assert extra_attributes['compilers']['c'] == gcc_exe
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_overriding_prefix(mock_executable, mutable_config, monkeypatch):
def test_overriding_prefix(
mock_executable, mutable_config, monkeypatch, _platform_executables):
# Prepare an environment to detect a fake gcc that
# override its external prefix
gcc_exe = mock_executable('gcc', output="echo 4.2.1")
@ -247,9 +264,8 @@ def _determine_variants(cls, exes, version_str):
assert externals[0]['prefix'] == '/opt/gcc/bin'
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_new_entries_are_reported_correctly(
mock_executable, mutable_config, monkeypatch
mock_executable, mutable_config, monkeypatch, _platform_executables
):
# Prepare an environment to detect a fake gcc
gcc_exe = mock_executable('gcc', output="echo 4.2.1")
@ -266,7 +282,6 @@ def test_new_entries_are_reported_correctly(
assert 'No new external packages detected' in output
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.parametrize('command_args', [
('-t', 'build-tools'),
('-t', 'build-tools', 'cmake'),

View file

@ -3,18 +3,15 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
import pytest
import spack.environment as ev
from spack.main import SpackCommand, SpackCommandError
# everything here uses the mock_env_path
pytestmark = [pytest.mark.usefixtures(
"mutable_mock_env_path", "config", "mutable_mock_repo"),
pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")]
pytestmark = pytest.mark.usefixtures(
"mutable_mock_env_path", "config", "mutable_mock_repo"
)
@pytest.mark.disable_clean_stage_check

View file

@ -13,6 +13,9 @@
info = SpackCommand('info')
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="Not yet implemented on Windows")
@pytest.fixture(scope='module')
def parser():
@ -37,7 +40,6 @@ def _print(*args):
monkeypatch.setattr(spack.cmd.info.color, 'cprint', _print, raising=False)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.parametrize('pkg', [
'openmpi',
'trilinos',
@ -50,7 +52,6 @@ def test_it_just_runs(pkg):
info(pkg)
@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows")
def test_info_noversion(mock_packages, info_lines, mock_print):
"""Check that a mock package with no versions or variants outputs None."""
info('noversion')
@ -83,7 +84,6 @@ def test_is_externally_detectable(pkg_query, expected, parser, info_lines):
assert is_externally_detectable == expected
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.parametrize('pkg_query', [
'hdf5',
'cloverleaf3d',

View file

@ -45,6 +45,10 @@ def git_tmp_worktree(tmpdir):
"""Create new worktree in a temporary folder and monkeypatch
spack.paths.prefix to point to it.
"""
# TODO: This is fragile and should be high priority for
# follow up fixes. 27021
# Path length is occasionally too long on Windows
# the following reduces the path length to acceptable levels
if sys.platform == 'win32':
long_pth = str(tmpdir).split(os.path.sep)
tmp_worktree = os.path.sep.join(long_pth[:-1])

View file

@ -3,23 +3,17 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
import pytest
from spack.main import SpackCommand
list = SpackCommand('list')
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_list():
output = list()
assert 'cloverleaf3d' in output
assert 'hdf5' in output
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_list_filter(mock_packages):
output = list('py-*')
assert 'py-extension1' in output
@ -36,20 +30,17 @@ def test_list_filter(mock_packages):
assert 'mpich' not in output
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_list_search_description(mock_packages):
output = list('--search-description', 'one build dependency')
assert 'depb' in output
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_list_format_name_only(mock_packages):
output = list('--format', 'name_only')
assert 'zmpi' in output
assert 'hdf5' in output
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_list_format_version_json(mock_packages):
output = list('--format', 'version_json')
assert '{"name": "zmpi",' in output
@ -58,7 +49,6 @@ def test_list_format_version_json(mock_packages):
json.loads(output)
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_list_format_html(mock_packages):
output = list('--format', 'html')
assert '<div class="section" id="zmpi">' in output

View file

@ -43,6 +43,15 @@ def tmp_scope():
yield scope_name
def _validate_url(url):
return
@pytest.fixture(autouse=True)
def url_check(monkeypatch):
monkeypatch.setattr(spack.util.url, 'require_url_format', _validate_url)
@pytest.mark.disable_clean_stage_check
@pytest.mark.regression('8083')
def test_regression_8083(tmpdir, capfd, mock_packages, mock_fetch, config):

View file

@ -105,7 +105,6 @@ def split(output):
pkg = spack.main.SpackCommand('pkg')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_packages_path():
assert (spack.cmd.pkg.packages_path() ==
spack.repo.path.get_repo('builtin').packages_path)
@ -139,6 +138,7 @@ def test_pkg_add(mock_pkg_git_repo):
pkg('add', 'does-not-exist')
@pytest.mark.skipif(sys.platform == 'win32', reason="stdout format conflict")
def test_pkg_list(mock_pkg_git_repo, mock_pkg_names):
out = split(pkg('list', 'HEAD^^'))
assert sorted(mock_pkg_names) == sorted(out)
@ -156,6 +156,7 @@ def test_pkg_list(mock_pkg_git_repo, mock_pkg_names):
assert sorted(mock_pkg_names) == sorted(out)
@pytest.mark.skipif(sys.platform == 'win32', reason="stdout format conflict")
def test_pkg_diff(mock_pkg_git_repo, mock_pkg_names):
out = split(pkg('diff', 'HEAD^^', 'HEAD^'))
assert out == ['HEAD^:', 'pkg-a', 'pkg-b', 'pkg-c']
@ -167,20 +168,22 @@ def test_pkg_diff(mock_pkg_git_repo, mock_pkg_names):
assert out == ['HEAD^:', 'pkg-c', 'HEAD:', 'pkg-d']
@pytest.mark.skipif(sys.platform == 'win32', reason="stdout format conflict")
def test_pkg_added(mock_pkg_git_repo):
out = split(pkg('added', 'HEAD^^', 'HEAD^'))
assert out == ['pkg-a', 'pkg-b', 'pkg-c']
assert ['pkg-a', 'pkg-b', 'pkg-c'] == out
out = split(pkg('added', 'HEAD^^', 'HEAD'))
assert out == ['pkg-a', 'pkg-b', 'pkg-d']
assert ['pkg-a', 'pkg-b', 'pkg-d'] == out
out = split(pkg('added', 'HEAD^', 'HEAD'))
assert out == ['pkg-d']
assert ['pkg-d'] == out
out = split(pkg('added', 'HEAD', 'HEAD'))
assert out == []
@pytest.mark.skipif(sys.platform == 'win32', reason="stdout format conflict")
def test_pkg_removed(mock_pkg_git_repo):
out = split(pkg('removed', 'HEAD^^', 'HEAD^'))
assert out == []
@ -192,7 +195,7 @@ def test_pkg_removed(mock_pkg_git_repo):
assert out == ['pkg-c']
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.skipif(sys.platform == 'win32', reason="stdout format conflict")
def test_pkg_changed(mock_pkg_git_repo):
out = split(pkg('changed', 'HEAD^^', 'HEAD^'))
assert out == []

View file

@ -12,8 +12,10 @@
providers = SpackCommand('providers')
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="Providers not currently supported on Windows")
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.parametrize('pkg', [
('mpi',),
('mpi@2',),
@ -24,7 +26,6 @@ def test_it_just_runs(pkg):
providers(*pkg)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.parametrize('vpkg,provider_list', [
(('mpi',), ['intel-mpi',
'intel-parallel-studio',

View file

@ -2,12 +2,12 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import sys
import pytest
from spack.main import SpackCommand
is_windows = sys.platform == 'win32'
resource = SpackCommand('resource')
#: these are hashes used in mock packages
@ -22,11 +22,17 @@
'208fcfb50e5a965d5757d151b675ca4af4ce2dfd56401721b6168fae60ab798f',
'bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c',
'7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730',
] if not is_windows else [
'abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234',
'1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd',
'd0df7988457ec999c148a4a2af25ce831bfaad13954ba18a4446374cb0aef55e',
'aeb16c4dec1087e39f2330542d59d9b456dd26d791338ae6d80b6ffd10c89dfa',
'mid21234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234',
'ff34cb21271d16dbf928374f610bb5dd593d293d311036ddae86c4846ff79070',
'bf874c7dd3a83cf370fdc17e496e341de06cd596b5c66dbf3c9bb7f6c139e3ee',
'3c5b65abcd6a3b2c714dbf7c31ff65fe3748a1adc371f030c283007ca5534f11'
]
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
def test_resource_list(mock_packages, capfd):
with capfd.disabled():
@ -40,7 +46,8 @@ def test_resource_list(mock_packages, capfd):
assert 'patched by:' in out
assert 'path:' in out
assert 'repos/builtin.mock/packages/patch-a-dependency/libelf.patch' in out
assert os.path.join('repos', 'builtin.mock', 'packages',
'patch-a-dependency', 'libelf.patch') in out
assert 'applies to: builtin.mock.libelf' in out
assert 'patched by: builtin.mock.patch-a-dependency' in out
@ -54,11 +61,19 @@ def test_resource_list_only_hashes(mock_packages, capfd):
def test_resource_show(mock_packages, capfd):
test_hash = 'c45c1564f70def3fc1a6e22139f62cb21cd190cc3a7dbe6f4120fa59ce33dcb8' \
if not is_windows \
else '3c5b65abcd6a3b2c714dbf7c31ff65fe3748a1adc371f030c283007ca5534f11'
with capfd.disabled():
out = resource('show', 'c45c1564f70def3fc1a6e22139f62cb21cd190cc3a7dbe6f4120fa59ce33dcb8')
out = resource('show', test_hash)
assert out.startswith('c45c1564f70def3fc1a6e22139f62cb21cd190cc3a7dbe6f4120fa59ce33dcb8')
assert 'repos/builtin.mock/packages/patch-a-dependency/libelf.patch' in out
assert out.startswith(test_hash)
assert os.path.join(
'repos',
'builtin.mock',
'packages',
'patch-a-dependency',
'libelf.patch') in out
assert 'applies to: builtin.mock.libelf' in out
assert 'patched by: builtin.mock.patch-a-dependency' in out

View file

@ -234,7 +234,7 @@ def test_test_list(
reason="Not supported on Windows (yet)")
def test_has_test_method_fails(capsys):
with pytest.raises(SystemExit):
has_test_method('printing-package')
spack.package.has_test_method('printing-package')
captured = capsys.readouterr()[1]
assert 'is not a class' in captured

View file

@ -13,9 +13,6 @@
uninstall = SpackCommand('uninstall')
install = SpackCommand('install')
# pytestmark = pytest.mark.skipif(sys.platform == "win32",
# reason="does not run on windows")
class MockArgs(object):

View file

@ -14,6 +14,8 @@
import spack.extensions
import spack.main
is_windows = sys.platform == 'win32'
class Extension:
"""Helper class to simplify the creation of simple command extension
@ -259,12 +261,14 @@ def test_get_command_paths(config):
def test_variable_in_extension_path(config, working_env):
"""Test variables in extension paths."""
os.environ['_MY_VAR'] = "my/var"
os.environ['_MY_VAR'] = os.path.join('my', 'var')
ext_paths = [
os.path.join("~", "${_MY_VAR}", "spack-extension-1")
]
# Home env variable is USERPROFILE on Windows
home_env = 'USERPROFILE' if is_windows else 'HOME'
expected_ext_paths = [
os.path.join(os.environ['HOME'], os.environ['_MY_VAR'], "spack-extension-1")
os.path.join(os.environ[home_env], os.environ['_MY_VAR'], "spack-extension-1")
]
with spack.config.override('config:extensions', ext_paths):
assert spack.extensions.get_extension_paths() == expected_ext_paths

View file

@ -2,6 +2,7 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import sys
import jinja2
@ -22,8 +23,7 @@
from spack.util.mock_package import MockPackageMultiRepo
from spack.version import ver
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
is_windows = sys.platform == 'win32'
def check_spec(abstract, concrete):
@ -370,6 +370,7 @@ def test_concretize_two_virtuals_with_dual_provider_and_a_conflict(
with pytest.raises(spack.error.SpackError):
s.concretize()
@pytest.mark.skipif(sys.platform == 'win32', reason='No Compiler for Arch on Win')
def test_no_matching_compiler_specs(self, mock_low_high_config):
# only relevant when not building compilers as needed
with spack.concretize.enable_compiler_existence_check():
@ -435,15 +436,17 @@ def test_compiler_inheritance(self, compiler_str):
def test_external_package(self):
spec = Spec('externaltool%gcc')
spec.concretize()
assert spec['externaltool'].external_path == '/path/to/external_tool'
assert spec['externaltool'].external_path == \
os.path.sep + os.path.join('path', 'to', 'external_tool')
assert 'externalprereq' not in spec
assert spec['externaltool'].compiler.satisfies('gcc')
def test_external_package_module(self):
# No tcl modules on darwin/linux machines
# and Windows does not (currently) allow for bash calls
# TODO: improved way to check for this.
platform = spack.platforms.real_host().name
if platform == 'darwin' or platform == 'linux':
if platform == 'darwin' or platform == 'linux' or platform == 'windows':
return
spec = Spec('externalmodule')
@ -463,8 +466,10 @@ def test_nobuild_package(self):
def test_external_and_virtual(self):
spec = Spec('externaltest')
spec.concretize()
assert spec['externaltool'].external_path == '/path/to/external_tool'
assert spec['stuff'].external_path == '/path/to/external_virtual_gcc'
assert spec['externaltool'].external_path == \
os.path.sep + os.path.join('path', 'to', 'external_tool')
assert spec['stuff'].external_path == \
os.path.sep + os.path.join('path', 'to', 'external_virtual_gcc')
assert spec['externaltool'].compiler.satisfies('gcc')
assert spec['stuff'].compiler.satisfies('gcc')
@ -707,6 +712,8 @@ def test_noversion_pkg(self, spec):
with pytest.raises(spack.error.SpackError):
Spec(spec).concretized()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
# Include targets to prevent regression on 20537
@pytest.mark.parametrize('spec, best_achievable', [
('mpileaks%gcc@4.4.7 ^dyninst@10.2.1 target=x86_64:', 'core2'),
@ -1116,7 +1123,7 @@ def test_custom_compiler_version(self):
assert '%gcc@foo' in s
def test_all_patches_applied(self):
uuidpatch = 'a60a42b73e03f207433c5579de207c6ed61d58e4d12dd3b5142eb525728d89ea'
uuidpatch = 'a60a42b73e03f207433c5579de207c6ed61d58e4d12dd3b5142eb525728d89ea' if not is_windows else 'd0df7988457ec999c148a4a2af25ce831bfaad13954ba18a4446374cb0aef55e'
localpatch = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
spec = spack.spec.Spec('conditionally-patch-dependency+jasper')
spec.concretize()

View file

@ -5,7 +5,6 @@
import os
import stat
import sys
import pytest

View file

@ -92,6 +92,13 @@ def env_yaml(tmpdir):
return env_yaml
def cross_plat_join(*pths):
"""os.path.join does not prepend paths to other paths
beginning with a Windows drive label i.e. D:\\
"""
return os.sep.join([pth for pth in pths])
def check_compiler_config(comps, *compiler_names):
"""Check that named compilers in comps match Spack's config."""
config = spack.config.get('compilers')
@ -334,65 +341,66 @@ def __init__(self, path):
self.path = path
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_substitute_config_variables(mock_low_high_config, monkeypatch):
prefix = spack.paths.prefix.lstrip('/')
assert os.path.join(
'/foo/bar/baz', prefix
assert cross_plat_join(
os.sep + os.path.join('foo', 'bar', 'baz'), prefix
) == spack_path.canonicalize_path('/foo/bar/baz/$spack')
assert os.path.join(
spack.paths.prefix, 'foo/bar/baz'
assert cross_plat_join(
spack.paths.prefix, os.path.join('foo', 'bar', 'baz')
) == spack_path.canonicalize_path('$spack/foo/bar/baz/')
assert os.path.join(
'/foo/bar/baz', prefix, 'foo/bar/baz'
assert cross_plat_join(
os.sep + os.path.join('foo', 'bar', 'baz'),
prefix, os.path.join('foo', 'bar', 'baz')
) == spack_path.canonicalize_path('/foo/bar/baz/$spack/foo/bar/baz/')
assert os.path.join(
'/foo/bar/baz', prefix
assert cross_plat_join(
os.sep + os.path.join('foo', 'bar', 'baz'), prefix
) == spack_path.canonicalize_path('/foo/bar/baz/${spack}')
assert os.path.join(
spack.paths.prefix, 'foo/bar/baz'
assert cross_plat_join(
spack.paths.prefix, os.path.join('foo', 'bar', 'baz')
) == spack_path.canonicalize_path('${spack}/foo/bar/baz/')
assert os.path.join(
'/foo/bar/baz', prefix, 'foo/bar/baz'
assert cross_plat_join(
os.sep + os.path.join('foo', 'bar', 'baz'),
prefix, os.path.join('foo', 'bar', 'baz')
) == spack_path.canonicalize_path('/foo/bar/baz/${spack}/foo/bar/baz/')
assert os.path.join(
'/foo/bar/baz', prefix, 'foo/bar/baz'
assert cross_plat_join(
os.sep + os.path.join('foo', 'bar', 'baz'),
prefix, os.path.join('foo', 'bar', 'baz')
) != spack_path.canonicalize_path('/foo/bar/baz/${spack/foo/bar/baz/')
# $env replacement is a no-op when no environment is active
assert spack_path.canonicalize_path(
'/foo/bar/baz/$env'
) == '/foo/bar/baz/$env'
os.sep + os.path.join('foo', 'bar', 'baz', '$env')
) == os.sep + os.path.join('foo', 'bar', 'baz', '$env')
# Fake an active environment and $env is replaced properly
fake_env_path = '/quux/quuux'
fake_env_path = os.sep + os.path.join('quux', 'quuux')
monkeypatch.setattr(ev, 'active_environment',
lambda: MockEnv(fake_env_path))
assert spack_path.canonicalize_path(
'$env/foo/bar/baz'
) == os.path.join(fake_env_path, 'foo/bar/baz')
) == os.path.join(fake_env_path, os.path.join('foo', 'bar', 'baz'))
# relative paths without source information are relative to cwd
assert spack_path.canonicalize_path(
'foo/bar/baz'
) == os.path.abspath('foo/bar/baz')
os.path.join('foo', 'bar', 'baz')
) == os.path.abspath(os.path.join('foo', 'bar', 'baz'))
# relative paths with source information are relative to the file
spack.config.set(
'modules:default', {'roots': {'lmod': 'foo/bar/baz'}}, scope='low')
'modules:default',
{'roots': {'lmod': os.path.join('foo', 'bar', 'baz')}}, scope='low')
spack.config.config.clear_caches()
path = spack.config.get('modules:default:roots:lmod')
assert spack_path.canonicalize_path(path) == os.path.normpath(
os.path.join(mock_low_high_config.scopes['low'].path,
'foo/bar/baz'))
os.path.join('foo', 'bar', 'baz')))
packages_merge_low = {
@ -439,41 +447,29 @@ def test_merge_with_defaults(mock_low_high_config, write_config_file):
assert cfg['baz']['version'] == ['c']
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_substitute_user(mock_low_high_config):
user = getpass.getuser()
assert '/foo/bar/' + user + '/baz' == spack_path.canonicalize_path(
'/foo/bar/$user/baz'
assert os.sep + os.path.join('foo', 'bar') + os.sep \
+ user + os.sep \
+ 'baz' == spack_path.canonicalize_path(
os.sep + os.path.join('foo', 'bar', '$user', 'baz')
)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_substitute_user_config(mock_low_high_config):
user_config_path = spack.paths.user_config_path
assert user_config_path + '/baz' == spack_path.canonicalize_path(
'$user_cache_path/baz'
)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_substitute_user_cache(mock_low_high_config):
user_cache_path = spack.paths.user_cache_path
assert user_cache_path + '/baz' == spack_path.canonicalize_path(
'$user_cache_path/baz'
assert user_cache_path + os.sep + 'baz' == spack_path.canonicalize_path(
os.path.join('$user_cache_path', 'baz')
)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_substitute_tempdir(mock_low_high_config):
tempdir = tempfile.gettempdir()
assert tempdir == spack_path.canonicalize_path('$tempdir')
assert tempdir + '/foo/bar/baz' == spack_path.canonicalize_path(
'$tempdir/foo/bar/baz'
)
assert tempdir + os.sep + \
os.path.join('foo', 'bar', 'baz') == spack_path.canonicalize_path(
os.path.join('$tempdir', 'foo', 'bar', 'baz')
)
PAD_STRING = spack.util.path.SPACK_PATH_PADDING_CHARS
@ -481,34 +477,17 @@ def test_substitute_tempdir(mock_low_high_config):
MAX_PADDED_LEN = MAX_PATH_LEN - spack.util.path.SPACK_MAX_INSTALL_PATH_LENGTH
reps = [PAD_STRING for _ in range((MAX_PADDED_LEN // len(PAD_STRING) + 1) + 2)]
full_padded_string = os.path.join(
'/path', os.path.sep.join(reps))[:MAX_PADDED_LEN]
os.sep + 'path', os.sep.join(reps))[:MAX_PADDED_LEN]
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('config_settings,expected', [
([], [None, None, None]),
([['config:install_tree:root', '/path']], ['/path', None, None]),
([['config:install_tree', '/path']], ['/path', None, None]),
([['config:install_tree:root', os.sep + 'path']], [os.sep + 'path', None, None]),
([['config:install_tree', os.sep + 'path']], [os.sep + 'path', None, None]),
([['config:install_tree:projections', {'all': '{name}'}]],
[None, None, {'all': '{name}'}]),
([['config:install_path_scheme', '{name}']],
[None, None, {'all': '{name}'}]),
([['config:install_tree:root', '/path'],
['config:install_tree:padded_length', 11]],
[os.path.join('/path', PAD_STRING[:5]), '/path', None]),
([['config:install_tree:root', '/path/$padding:11']],
[os.path.join('/path', PAD_STRING[:5]), '/path', None]),
([['config:install_tree', '/path/${padding:11}']],
[os.path.join('/path', PAD_STRING[:5]), '/path', None]),
([['config:install_tree:padded_length', False]], [None, None, None]),
([['config:install_tree:padded_length', True],
['config:install_tree:root', '/path']],
[full_padded_string, '/path', None]),
([['config:install_tree:', '/path$padding']],
[full_padded_string, '/path', None]),
([['config:install_tree:', '/path/${padding}']],
[full_padded_string, '/path', None]),
])
def test_parse_install_tree(config_settings, expected, mutable_config):
expected_root = expected[0] or spack.store.default_install_tree_root
@ -524,7 +503,44 @@ def test_parse_install_tree(config_settings, expected, mutable_config):
config_dict = mutable_config.get('config')
root, unpadded_root, projections = spack.store.parse_install_tree(
config_dict)
assert root == expected_root
assert unpadded_root == expected_unpadded_root
assert projections == expected_proj
@pytest.mark.skipif(sys.platform == 'win32',
reason='Padding unsupported on Windows')
@pytest.mark.parametrize('config_settings,expected', [
([['config:install_tree:root', os.sep + 'path'],
['config:install_tree:padded_length', 11]],
[os.path.join(os.sep + 'path', PAD_STRING[:5]), os.sep + 'path', None]),
([['config:install_tree:root', '/path/$padding:11']],
[os.path.join(os.sep + 'path', PAD_STRING[:5]), os.sep + 'path', None]),
([['config:install_tree', '/path/${padding:11}']],
[os.path.join(os.sep + 'path', PAD_STRING[:5]), os.sep + 'path', None]),
([['config:install_tree:padded_length', False]], [None, None, None]),
([['config:install_tree:padded_length', True],
['config:install_tree:root', os.sep + 'path']],
[full_padded_string, os.sep + 'path', None]),
([['config:install_tree:', os.sep + 'path$padding']],
[full_padded_string, os.sep + 'path', None]),
([['config:install_tree:', os.sep + 'path' + os.sep + '${padding}']],
[full_padded_string, os.sep + 'path', None]),
])
def test_parse_install_tree_padded(config_settings, expected, mutable_config):
expected_root = expected[0] or spack.store.default_install_tree_root
expected_unpadded_root = expected[1] or expected_root
expected_proj = expected[2] or spack.directory_layout.default_projections
# config settings is a list of 2-element lists, [path, value]
# where path is a config path and value is the value to set at that path
# these can be "splatted" in as the arguments to config.set
for config_setting in config_settings:
mutable_config.set(*config_setting)
config_dict = mutable_config.get('config')
root, unpadded_root, projections = spack.store.parse_install_tree(
config_dict)
assert root == expected_root
assert unpadded_root == expected_unpadded_root
assert projections == expected_proj
@ -1217,7 +1233,8 @@ def test_system_config_path_is_overridable(working_env):
def test_system_config_path_is_default_when_env_var_is_empty(working_env):
os.environ['SPACK_SYSTEM_CONFIG_PATH'] = ''
assert "/etc/spack" == spack.paths._get_system_config_path()
assert os.sep + os.path.join('etc', 'spack') == \
spack.paths._get_system_config_path()
def test_user_config_path_is_overridable(working_env):
@ -1228,7 +1245,8 @@ def test_user_config_path_is_overridable(working_env):
def test_user_config_path_is_default_when_env_var_is_empty(working_env):
os.environ['SPACK_USER_CONFIG_PATH'] = ''
assert os.path.expanduser("~/.spack") == spack.paths._get_user_config_path()
assert os.path.expanduser("~%s.spack" % os.sep) == \
spack.paths._get_user_config_path()
def test_local_config_can_be_disabled(working_env):
@ -1262,4 +1280,5 @@ def test_user_cache_path_is_overridable(working_env):
def test_user_cache_path_is_default_when_env_var_is_empty(working_env):
os.environ['SPACK_USER_CACHE_PATH'] = ''
assert os.path.expanduser("~/.spack") == spack.paths._get_user_cache_path()
assert os.path.expanduser("~%s.spack" % os.sep) == \
spack.paths._get_user_cache_path()

View file

@ -13,6 +13,7 @@
import os.path
import re
import shutil
import stat
import sys
import tempfile
import xml.etree.ElementTree
@ -297,6 +298,14 @@ def reset_compiler_cache():
spack.compilers._compiler_cache = {}
def onerror(func, path, error_info):
# Python on Windows is unable to remvove paths without
# write (IWUSR) permissions (such as those generated by Git on Windows)
# This method changes file permissions to allow removal by Python
os.chmod(path, stat.S_IWUSR)
func(path)
@pytest.fixture(scope='function', autouse=True)
def mock_stage(tmpdir_factory, monkeypatch, request):
"""Establish the temporary build_stage for the mock archive."""
@ -320,7 +329,7 @@ def mock_stage(tmpdir_factory, monkeypatch, request):
# Clean up the test stage directory
if os.path.isdir(new_stage_path):
shutil.rmtree(new_stage_path)
shutil.rmtree(new_stage_path, onerror=onerror)
else:
# Must yield a path to avoid a TypeError on test teardown
yield str(tmpdir_factory)
@ -343,7 +352,7 @@ def remove_whatever_it_is(path):
elif os.path.islink(path):
remove_linked_tree(path)
else:
shutil.rmtree(path)
shutil.rmtree(path, onerror=onerror)
@pytest.fixture
@ -902,7 +911,7 @@ def __init__(self, root):
self.root = root
def path_for_spec(self, spec):
return '/'.join([self.root, spec.name + '-' + spec.dag_hash()])
return os.path.sep.join([self.root, spec.name + '-' + spec.dag_hash()])
def ensure_installed(self, spec):
pass
@ -1048,10 +1057,7 @@ def mock_archive(request, tmpdir_factory):
['url', 'path', 'archive_file',
'expanded_archive_basedir'])
archive_file = str(tmpdir.join(archive_name))
if sys.platform == 'win32':
url = ('file:///' + archive_file)
else:
url = ('file://' + archive_file)
url = ('file://' + archive_file)
# Return the url
yield Archive(
@ -1540,11 +1546,14 @@ def mock_executable(tmpdir):
output a custom string when run.
"""
import jinja2
shebang = '#!/bin/bash\n' if not is_windows else '@ECHO OFF'
def _factory(name, output, subdir=('bin',)):
f = tmpdir.ensure(*subdir, dir=True).join(name)
t = jinja2.Template('#!/bin/bash\n{{ output }}\n')
f.write(t.render(output=output))
if is_windows:
f += '.bat'
t = jinja2.Template('{{ shebang }}{{ output }}\n')
f.write(t.render(shebang=shebang, output=output))
f.chmod(0o755)
return str(f)

View file

@ -65,7 +65,7 @@ def upstream_and_downstream_db(tmpdir_factory, gen_mock_layout):
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
reason="Upstreams currently unsupported on Windows")
@pytest.mark.usefixtures('config')
def test_installed_upstream(upstream_and_downstream_db):
upstream_write_db, upstream_db, upstream_layout,\
@ -110,7 +110,7 @@ def test_installed_upstream(upstream_and_downstream_db):
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
reason="Upstreams currently unsupported on Windows")
@pytest.mark.usefixtures('config')
def test_removed_upstream_dep(upstream_and_downstream_db):
upstream_write_db, upstream_db, upstream_layout,\
@ -143,7 +143,7 @@ def test_removed_upstream_dep(upstream_and_downstream_db):
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
reason="Upstreams currently unsupported on Windows")
@pytest.mark.usefixtures('config')
def test_add_to_upstream_after_downstream(upstream_and_downstream_db):
"""An upstream DB can add a package after it is installed in the downstream
@ -182,7 +182,7 @@ def test_add_to_upstream_after_downstream(upstream_and_downstream_db):
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
reason="Upstreams currently unsupported on Windows")
@pytest.mark.usefixtures('config', 'temporary_store')
def test_cannot_write_upstream(tmpdir_factory, gen_mock_layout):
roots = [str(tmpdir_factory.mktemp(x)) for x in ['a', 'b']]
@ -209,7 +209,7 @@ def test_cannot_write_upstream(tmpdir_factory, gen_mock_layout):
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
reason="Upstreams currently unsupported on Windows")
@pytest.mark.usefixtures('config', 'temporary_store')
def test_recursive_upstream_dbs(tmpdir_factory, gen_mock_layout):
roots = [str(tmpdir_factory.mktemp(x)) for x in ['a', 'b', 'c']]
@ -687,8 +687,6 @@ def fail_while_writing():
# reload DB and make sure cmake was not written.
with database.read_transaction():
# import pdb; pdb.set_trace()
assert database.query('cmake', installed=any) == []

View file

@ -8,7 +8,6 @@
"""
import os
import os.path
import sys
import pytest
@ -19,13 +18,12 @@
InvalidDirectoryLayoutParametersError,
)
from spack.spec import Spec
from spack.util.path import path_to_os_path
# number of packages to test (to reduce test time)
max_packages = 10
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_yaml_directory_layout_parameters(tmpdir, config):
"""This tests the various parameters that can be used to configure
the install location """
@ -81,8 +79,6 @@ def test_yaml_directory_layout_parameters(tmpdir, config):
projections=projections_package7)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_read_and_write_spec(temporary_store, config, mock_packages):
"""This goes through each package in spack and creates a directory for
it. It then ensures that the spec for the directory's
@ -108,7 +104,7 @@ def test_read_and_write_spec(temporary_store, config, mock_packages):
layout.create_install_directory(spec)
install_dir = layout.path_for_spec(spec)
install_dir = path_to_os_path(layout.path_for_spec(spec))[0]
spec_path = layout.spec_file_path(spec)
# Ensure directory has been created in right place.
@ -208,8 +204,6 @@ def test_handle_unknown_package(temporary_store, config, mock_packages):
assert spec.dag_hash() == spec_from_file.dag_hash()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_find(temporary_store, config, mock_packages):
"""Test that finding specs within an install layout works."""
layout = temporary_store.layout
@ -233,8 +227,6 @@ def test_find(temporary_store, config, mock_packages):
assert found_specs[name].eq_dag(spec)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_yaml_directory_layout_build_path(tmpdir, config):
"""This tests build path method."""
spec = Spec('python')

View file

@ -178,6 +178,7 @@ def test_filter_system_paths(miscellaneous_paths):
assert filtered == expected
# TODO 27021
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_set_path(env):
@ -417,8 +418,6 @@ def test_sanitize_regex(env, blacklist, whitelist, expected, deleted):
assert all(x not in after for x in deleted)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.regression('12085')
@pytest.mark.parametrize('before,after,search_list', [
# Set environment variables
@ -428,8 +427,8 @@ def test_sanitize_regex(env, blacklist, whitelist, expected, deleted):
# Append paths to an environment variable
({'FOO_PATH': '/a/path'}, {'FOO_PATH': '/a/path:/b/path'},
[environment.AppendPath('FOO_PATH', '/b/path')]),
({}, {'FOO_PATH': '/a/path:/b/path'}, [
environment.AppendPath('FOO_PATH', '/a/path:/b/path')
({}, {'FOO_PATH': '/a/path' + os.sep + '/b/path'}, [
environment.AppendPath('FOO_PATH', '/a/path' + os.sep + '/b/path')
]),
({'FOO_PATH': '/a/path:/b/path'}, {'FOO_PATH': '/b/path'}, [
environment.RemovePath('FOO_PATH', '/a/path')
@ -459,7 +458,7 @@ def test_from_environment_diff(before, after, search_list):
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
reason="LMod not supported on Windows")
@pytest.mark.regression('15775')
def test_blacklist_lmod_variables():
# Construct the list of environment modifications

View file

@ -19,6 +19,10 @@
from spack.util.executable import which
from spack.version import ver
pytestmark = pytest.mark.skipif(
not which('git'), reason='requires git to be installed')
_mock_transport_error = 'Mock HTTP transport error'
@ -71,7 +75,6 @@ def bad_git(*args, **kwargs):
def test_bad_git(tmpdir, mock_bad_git):
"""Trigger a SpackError when attempt a fetch with a bad git."""
testpath = str(tmpdir)
print(spack.config.get('config:locks'))
with pytest.raises(spack.error.SpackError):
fetcher = GitFetchStrategy(git='file:///not-a-real-git-repo')

View file

@ -5,7 +5,6 @@
import os
import shutil
import sys
import pytest
@ -32,8 +31,6 @@ def find_nothing(*args):
'Repo package access is disabled for test')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_and_uninstall(install_mockery, mock_fetch, monkeypatch):
# Get a basic concrete spec for the trivial install package.
spec = Spec('trivial-install-test-package')
@ -42,7 +39,6 @@ def test_install_and_uninstall(install_mockery, mock_fetch, monkeypatch):
# Get the package
pkg = spec.package
try:
pkg.do_install()
@ -100,8 +96,6 @@ def __getattr__(self, attr):
return getattr(self.wrapped_stage, attr)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_partial_install_delete_prefix_and_stage(install_mockery, mock_fetch):
spec = Spec('canfail').concretized()
pkg = spack.repo.get(spec)
@ -131,8 +125,6 @@ def test_partial_install_delete_prefix_and_stage(install_mockery, mock_fetch):
pkg.remove_prefix = instance_rm_prefix
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.disable_clean_stage_check
def test_failing_overwrite_install_should_keep_previous_installation(
mock_fetch, install_mockery
@ -158,8 +150,6 @@ def test_failing_overwrite_install_should_keep_previous_installation(
assert os.path.exists(spec.prefix)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_dont_add_patches_to_installed_package(
install_mockery, mock_fetch, monkeypatch
):
@ -180,8 +170,6 @@ def test_dont_add_patches_to_installed_package(
assert dependent['dependency-install'] == dependency
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_installed_dependency_request_conflicts(
install_mockery, mock_fetch, mutable_mock_repo):
dependency = Spec('dependency-install')
@ -195,8 +183,6 @@ def test_installed_dependency_request_conflicts(
dependent.concretize()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_dependency_symlinks_pkg(
install_mockery, mock_fetch, mutable_mock_repo):
"""Test dependency flattening/symlinks mock package."""
@ -210,8 +196,6 @@ def test_install_dependency_symlinks_pkg(
assert os.path.isdir(dependency_dir)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_times(
install_mockery, mock_fetch, mutable_mock_repo):
"""Test install times added."""
@ -238,8 +222,6 @@ def test_install_times(
assert abs(total - times['total']['seconds']) < 5
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_flatten_deps(
install_mockery, mock_fetch, mutable_mock_repo):
"""Explicitly test the flattening code for coverage purposes."""
@ -289,8 +271,6 @@ def _install_upstream(*specs):
return _install_upstream
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_installed_upstream_external(install_upstream, mock_fetch):
"""Check that when a dependency package is recorded as installed in
an upstream database that it is not reinstalled.
@ -302,7 +282,8 @@ def test_installed_upstream_external(install_upstream, mock_fetch):
new_dependency = dependent['externaltool']
assert new_dependency.external
assert new_dependency.prefix == '/path/to/external_tool'
assert new_dependency.prefix == \
os.path.sep + os.path.join('path', 'to', 'external_tool')
dependent.package.do_install()
@ -310,8 +291,6 @@ def test_installed_upstream_external(install_upstream, mock_fetch):
assert os.path.exists(dependent.prefix)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_installed_upstream(install_upstream, mock_fetch):
"""Check that when a dependency package is recorded as installed in
an upstream database that it is not reinstalled.
@ -332,8 +311,6 @@ def test_installed_upstream(install_upstream, mock_fetch):
assert os.path.exists(dependent.prefix)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.disable_clean_stage_check
def test_partial_install_keep_prefix(install_mockery, mock_fetch, monkeypatch):
spec = Spec('canfail').concretized()
@ -360,8 +337,6 @@ def test_partial_install_keep_prefix(install_mockery, mock_fetch, monkeypatch):
assert not pkg.stage.test_destroyed
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_second_install_no_overwrite_first(install_mockery, mock_fetch, monkeypatch):
spec = Spec('canfail').concretized()
pkg = spack.repo.get(spec)
@ -376,8 +351,6 @@ def test_second_install_no_overwrite_first(install_mockery, mock_fetch, monkeypa
pkg.do_install()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_prefix_collision_fails(config, mock_fetch, mock_packages, tmpdir):
"""
Test that different specs with coinciding install prefixes will fail
@ -395,16 +368,12 @@ def test_install_prefix_collision_fails(config, mock_fetch, mock_packages, tmpdi
pkg_b.do_install()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Package ninja not found")
def test_store(install_mockery, mock_fetch):
spec = Spec('cmake-client').concretized()
pkg = spec.package
pkg.do_install()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.disable_clean_stage_check
def test_failing_build(install_mockery, mock_fetch, capfd):
spec = Spec('failing-build').concretized()
@ -419,8 +388,6 @@ class MockInstallError(spack.error.SpackError):
pass
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_uninstall_by_spec_errors(mutable_database):
"""Test exceptional cases with the uninstall command."""
@ -436,8 +403,6 @@ def test_uninstall_by_spec_errors(mutable_database):
PackageBase.uninstall_by_spec(rec.spec)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.disable_clean_stage_check
def test_nosource_pkg_install(
install_mockery, mock_fetch, mock_packages, capfd):
@ -452,8 +417,6 @@ def test_nosource_pkg_install(
assert "Missing a source id for nosource" in out[1]
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_nosource_pkg_install_post_install(
install_mockery, mock_fetch, mock_packages):
"""Test install phases with the nosource package with post-install."""
@ -472,8 +435,6 @@ def test_nosource_pkg_install_post_install(
assert os.path.isfile(post_install_txt)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_pkg_build_paths(install_mockery):
# Get a basic concrete spec for the trivial install package.
spec = Spec('trivial-install-test-package').concretized()
@ -507,8 +468,6 @@ def test_pkg_build_paths(install_mockery):
shutil.rmtree(log_dir)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_pkg_install_paths(install_mockery):
# Get a basic concrete spec for the trivial install package.
spec = Spec('trivial-install-test-package').concretized()
@ -545,8 +504,6 @@ def test_pkg_install_paths(install_mockery):
shutil.rmtree(log_dir)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_log_install_without_build_files(install_mockery):
"""Test the installer log function when no build files are present."""
# Get a basic concrete spec for the trivial install package.
@ -557,8 +514,6 @@ def test_log_install_without_build_files(install_mockery):
spack.installer.log(spec.package)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_log_install_with_build_files(install_mockery, monkeypatch):
"""Test the installer's log function when have build files."""
config_log = 'config.log'

View file

@ -23,6 +23,8 @@
import spack.store
import spack.util.lock as lk
is_windows = sys.platform == 'win32'
def _mock_repo(root, namespace):
"""Create an empty repository at the specified root
@ -119,8 +121,6 @@ def test_hms(sec, result):
assert inst._hms(sec) == result
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_get_dependent_ids(install_mockery, mock_packages):
# Concretize the parent package, which handle dependency too
spec = spack.spec.Spec('a')
@ -154,8 +154,6 @@ def test_install_msg(monkeypatch):
assert inst.install_msg(name, pid) == expected
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_from_cache_errors(install_mockery, capsys):
"""Test to ensure cover _install_from_cache errors."""
spec = spack.spec.Spec('trivial-install-test-package')
@ -176,8 +174,6 @@ def test_install_from_cache_errors(install_mockery, capsys):
assert not spec.package.installed_from_binary_cache
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_from_cache_ok(install_mockery, monkeypatch):
"""Test to ensure cover _install_from_cache to the return."""
spec = spack.spec.Spec('trivial-install-test-package')
@ -188,8 +184,6 @@ def test_install_from_cache_ok(install_mockery, monkeypatch):
assert inst._install_from_cache(spec.package, True, True, False)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_process_external_package_module(install_mockery, monkeypatch, capfd):
"""Test to simply cover the external module message path."""
spec = spack.spec.Spec('trivial-install-test-package')
@ -218,8 +212,6 @@ def test_process_binary_cache_tarball_none(install_mockery, monkeypatch,
assert 'exists in binary cache but' in capfd.readouterr()[0]
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_process_binary_cache_tarball_tar(install_mockery, monkeypatch, capfd):
"""Tests of _process_binary_cache_tarball with a tar file."""
def _spec(spec, preferred_mirrors=None):
@ -240,8 +232,6 @@ def _spec(spec, preferred_mirrors=None):
assert 'from binary cache' in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_try_install_from_binary_cache(install_mockery, mock_packages,
monkeypatch):
"""Test return false when no match exists in the mirror"""
@ -251,8 +241,6 @@ def test_try_install_from_binary_cache(install_mockery, mock_packages,
assert(not result)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_installer_repr(install_mockery):
const_arg = installer_args(['trivial-install-test-package'], {})
installer = create_installer(const_arg)
@ -263,8 +251,6 @@ def test_installer_repr(install_mockery):
assert "failed=" in irep
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_installer_str(install_mockery):
const_arg = installer_args(['trivial-install-test-package'], {})
installer = create_installer(const_arg)
@ -298,8 +284,6 @@ def test_check_last_phase_error(install_mockery):
assert pkg.last_phase in err
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_installer_ensure_ready_errors(install_mockery):
const_arg = installer_args(['trivial-install-test-package'], {})
installer = create_installer(const_arg)
@ -329,8 +313,6 @@ def test_installer_ensure_ready_errors(install_mockery):
installer._ensure_install_ready(spec.package)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_ensure_locked_err(install_mockery, monkeypatch, tmpdir, capsys):
"""Test _ensure_locked when a non-lock exception is raised."""
mock_err_msg = 'Mock exception error'
@ -352,8 +334,6 @@ def _raise(lock, timeout):
assert mock_err_msg in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_ensure_locked_have(install_mockery, tmpdir, capsys):
"""Test _ensure_locked when already have lock."""
const_arg = installer_args(['trivial-install-test-package'], {})
@ -390,8 +370,6 @@ def test_ensure_locked_have(install_mockery, tmpdir, capsys):
assert installer._ensure_locked(lock_type, spec.package) == tpl
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('lock_type,reads,writes', [
('read', 1, 0),
('write', 0, 1)])
@ -409,8 +387,6 @@ def test_ensure_locked_new_lock(
assert lock._writes == writes
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_ensure_locked_new_warn(install_mockery, monkeypatch, tmpdir, capsys):
orig_pl = spack.database.Database.prefix_lock
@ -441,8 +417,6 @@ def test_package_id_err(install_mockery):
inst.package_id(pkg)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_package_id_ok(install_mockery):
spec = spack.spec.Spec('trivial-install-test-package')
spec.concretize()
@ -461,8 +435,6 @@ def test_fake_install(install_mockery):
assert os.path.isdir(pkg.prefix.lib)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_packages_needed_to_bootstrap_compiler_none(install_mockery):
spec = spack.spec.Spec('trivial-install-test-package')
spec.concretize()
@ -473,8 +445,6 @@ def test_packages_needed_to_bootstrap_compiler_none(install_mockery):
assert not packages
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_packages_needed_to_bootstrap_compiler_packages(install_mockery,
monkeypatch):
spec = spack.spec.Spec('trivial-install-test-package')
@ -494,8 +464,6 @@ def _conc_spec(compiler):
assert packages
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_dump_packages_deps_ok(install_mockery, tmpdir, mock_packages):
"""Test happy path for dump_packages with dependencies."""
@ -508,8 +476,6 @@ def test_dump_packages_deps_ok(install_mockery, tmpdir, mock_packages):
assert os.path.isfile(dest_pkg)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_dump_packages_deps_errs(install_mockery, tmpdir, monkeypatch, capsys):
"""Test error paths for dump_packages with dependencies."""
orig_bpp = spack.store.layout.build_packages_path
@ -538,7 +504,7 @@ def _repoerr(repo, name):
# The call to install_tree will raise the exception since not mocking
# creation of dependency package files within *install* directories.
with pytest.raises(IOError, match=path):
with pytest.raises(IOError, match=path if not is_windows else ''):
inst.dump_packages(spec, path)
# Now try the error path, which requires the mock directory structure
@ -631,8 +597,6 @@ def test_combine_phase_logs(tmpdir):
assert "Output from %s\n" % log_file in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_check_deps_status_install_failure(install_mockery, monkeypatch):
const_arg = installer_args(['a'], {})
installer = create_installer(const_arg)
@ -645,8 +609,6 @@ def test_check_deps_status_install_failure(install_mockery, monkeypatch):
installer._check_deps_status(request)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_check_deps_status_write_locked(install_mockery, monkeypatch):
const_arg = installer_args(['a'], {})
installer = create_installer(const_arg)
@ -659,8 +621,6 @@ def test_check_deps_status_write_locked(install_mockery, monkeypatch):
installer._check_deps_status(request)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_check_deps_status_external(install_mockery, monkeypatch):
const_arg = installer_args(['a'], {})
installer = create_installer(const_arg)
@ -672,8 +632,6 @@ def test_check_deps_status_external(install_mockery, monkeypatch):
assert list(installer.installed)[0].startswith('b')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_check_deps_status_upstream(install_mockery, monkeypatch):
const_arg = installer_args(['a'], {})
installer = create_installer(const_arg)
@ -685,8 +643,6 @@ def test_check_deps_status_upstream(install_mockery, monkeypatch):
assert list(installer.installed)[0].startswith('b')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_add_bootstrap_compilers(install_mockery, monkeypatch):
from collections import defaultdict
@ -709,8 +665,6 @@ def _pkgs(compiler, architecture, pkgs):
assert task.compiler
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_prepare_for_install_on_installed(install_mockery, monkeypatch):
"""Test of _prepare_for_install's early return for installed task path."""
const_arg = installer_args(['dependent-install'], {})
@ -725,8 +679,6 @@ def test_prepare_for_install_on_installed(install_mockery, monkeypatch):
installer._prepare_for_install(task)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_installer_init_requests(install_mockery):
"""Test of installer initial requests."""
spec_name = 'dependent-install'
@ -740,8 +692,6 @@ def test_installer_init_requests(install_mockery):
assert request.pkg.name == spec_name
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_task_use_cache(install_mockery, monkeypatch):
const_arg = installer_args(['trivial-install-test-package'], {})
installer = create_installer(const_arg)
@ -753,8 +703,6 @@ def test_install_task_use_cache(install_mockery, monkeypatch):
assert request.pkg_id in installer.installed
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_task_add_compiler(install_mockery, monkeypatch, capfd):
config_msg = 'mock add_compilers_to_config'
@ -779,8 +727,6 @@ def _add(_compilers):
assert config_msg in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_release_lock_write_n_exception(install_mockery, tmpdir, capsys):
"""Test _release_lock for supposed write lock with exception."""
const_arg = installer_args(['trivial-install-test-package'], {})
@ -798,8 +744,6 @@ def test_release_lock_write_n_exception(install_mockery, tmpdir, capsys):
assert msg in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('installed', [True, False])
def test_push_task_skip_processed(install_mockery, installed):
"""Test to ensure skip re-queueing a processed package."""
@ -819,8 +763,6 @@ def test_push_task_skip_processed(install_mockery, installed):
assert len(list(installer.build_tasks)) == 0
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_requeue_task(install_mockery, capfd):
"""Test to ensure cover _requeue_task."""
const_arg = installer_args(['a'], {})
@ -845,8 +787,6 @@ def test_requeue_task(install_mockery, capfd):
assert ' in progress by another process' in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_cleanup_all_tasks(install_mockery, monkeypatch):
"""Test to ensure cover _cleanup_all_tasks."""
def _mktask(pkg):
@ -871,8 +811,6 @@ def _rmtask(installer, pkg_id):
assert len(installer.build_tasks) == 1
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_setup_install_dir_grp(install_mockery, monkeypatch, capfd):
"""Test _setup_install_dir's group change."""
mock_group = 'mockgroup'
@ -893,6 +831,10 @@ def _chgrp(path, group):
fs.touchp(spec.prefix)
metadatadir = spack.store.layout.metadata_path(spec)
# Regex matching with Windows style paths typically fails
# so we skip the match check here
if is_windows:
metadatadir = None
# Should fail with a "not a directory" error
with pytest.raises(OSError, match=metadatadir):
installer._setup_install_dir(spec.package)
@ -903,8 +845,6 @@ def _chgrp(path, group):
assert expected_msg in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_cleanup_failed_err(install_mockery, tmpdir, monkeypatch, capsys):
"""Test _cleanup_failed exception path."""
msg = 'Fake release_write exception'
@ -927,8 +867,6 @@ def _raise_except(lock):
assert msg in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_update_failed_no_dependent_task(install_mockery):
"""Test _update_failed with missing dependent build tasks."""
const_arg = installer_args(['dependent-install'], {})
@ -941,8 +879,6 @@ def test_update_failed_no_dependent_task(install_mockery):
assert installer.failed[task.pkg_id] is None
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_uninstalled_deps(install_mockery, monkeypatch, capsys):
"""Test install with uninstalled dependencies."""
const_arg = installer_args(['dependent-install'], {})
@ -961,8 +897,6 @@ def test_install_uninstalled_deps(install_mockery, monkeypatch, capsys):
assert 'Detected uninstalled dependencies for' in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_failed(install_mockery, monkeypatch, capsys):
"""Test install with failed install."""
const_arg = installer_args(['b'], {})
@ -979,8 +913,6 @@ def test_install_failed(install_mockery, monkeypatch, capsys):
assert 'failed to install' in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_failed_not_fast(install_mockery, monkeypatch, capsys):
"""Test install with failed install."""
const_arg = installer_args(['a'], {'fail_fast': False})
@ -997,8 +929,6 @@ def test_install_failed_not_fast(install_mockery, monkeypatch, capsys):
assert 'Skipping build of a' in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_fail_on_interrupt(install_mockery, monkeypatch):
"""Test ctrl-c interrupted install."""
spec_name = 'a'
@ -1023,8 +953,6 @@ def _interrupt(installer, task, **kwargs):
assert spec_name not in installer.installed
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_fail_single(install_mockery, monkeypatch):
"""Test expected results for failure of single package."""
spec_name = 'a'
@ -1052,8 +980,6 @@ def _install(installer, task, **kwargs):
assert spec_name not in installer.installed
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_fail_multi(install_mockery, monkeypatch):
"""Test expected results for failure of multiple packages."""
spec_name = 'c'
@ -1081,8 +1007,6 @@ def _install(installer, task, **kwargs):
assert spec_name not in installer.installed
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_fail_fast_on_detect(install_mockery, monkeypatch, capsys):
"""Test fail_fast install when an install failure is detected."""
const_arg = installer_args(['b'], {'fail_fast': False})
@ -1114,8 +1038,6 @@ def _test_install_fail_fast_on_except_patch(installer, **kwargs):
raise RuntimeError('mock patch failure')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_fail_fast_on_except(install_mockery, monkeypatch, capsys):
"""Test fail_fast install when an install failure results from an error."""
const_arg = installer_args(['a'], {'fail_fast': True})
@ -1138,8 +1060,6 @@ def test_install_fail_fast_on_except(install_mockery, monkeypatch, capsys):
assert 'Skipping build of a' in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_lock_failures(install_mockery, monkeypatch, capfd):
"""Cover basic install lock failure handling in a single pass."""
def _requeued(installer, task):
@ -1163,8 +1083,6 @@ def _requeued(installer, task):
assert exp in ln
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_lock_installed_requeue(install_mockery, monkeypatch, capfd):
"""Cover basic install handling for installed package."""
const_arg = installer_args(['b'], {})
@ -1200,8 +1118,6 @@ def _requeued(installer, task):
assert exp in ln
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_read_locked_requeue(install_mockery, monkeypatch, capfd):
"""Cover basic read lock handling for uninstalled package with requeue."""
orig_fn = inst.PackageInstaller._ensure_locked
@ -1240,8 +1156,6 @@ def _requeued(installer, task):
assert exp in ln
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_install_skip_patch(install_mockery, mock_fetch):
"""Test the path skip_patch install path."""
spec_name = 'b'

View file

@ -3,6 +3,7 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import re
import sys
import pytest
@ -11,6 +12,9 @@
from spack.compiler import _parse_non_system_link_dirs
is_windows = sys.platform == 'win32'
if is_windows:
drive_m = re.search(r'[A-Za-z]:', spack.paths.test_path)
drive = drive_m.group() if drive_m else None
#: directory with sample compiler data
datadir = os.path.join(spack.paths.test_path, 'data',
'compiler_verbose_output')
@ -27,7 +31,6 @@ def check_link_paths(filename, paths):
with open(os.path.join(datadir, filename)) as file:
output = file.read()
detected_paths = _parse_non_system_link_dirs(output)
print(detected_paths)
actual = detected_paths
expected = paths
@ -44,9 +47,9 @@ def check_link_paths(filename, paths):
def test_icc16_link_paths():
if is_windows:
check_link_paths('icc-16.0.3.txt', [
r'C:\usr\tce\packages\intel\intel-16.0.3\compilers_and_libraries_2016.3.210\linux\compiler\lib\intel64_lin', # noqa
r'C:\usr\tce\packages\gcc\gcc-4.9.3\lib64\gcc\x86_64-unknown-linux-gnu\4.9.3', # noqa
r'C:\usr\tce\packages\gcc\gcc-4.9.3\lib64'])
drive + r'\usr\tce\packages\intel\intel-16.0.3\compilers_and_libraries_2016.3.210\linux\compiler\lib\intel64_lin', # noqa
drive + r'\usr\tce\packages\gcc\gcc-4.9.3\lib64\gcc\x86_64-unknown-linux-gnu\4.9.3', # noqa
drive + r'\usr\tce\packages\gcc\gcc-4.9.3\lib64'])
else:
check_link_paths('icc-16.0.3.txt', [
'/usr/tce/packages/intel/intel-16.0.3/compilers_and_libraries_2016.3.210/linux/compiler/lib/intel64_lin', # noqa
@ -57,32 +60,26 @@ def test_icc16_link_paths():
def test_pgi_link_paths():
if is_windows:
check_link_paths('pgcc-16.3.txt', [
r'C:\usr\tce\packages\pgi\pgi-16.3\linux86-64\16.3\lib'])
drive + r'\usr\tce\packages\pgi\pgi-16.3\linux86-64\16.3\lib'])
else:
check_link_paths('pgcc-16.3.txt', [
'/usr/tce/packages/pgi/pgi-16.3/linux86-64/16.3/lib'])
def test_gcc7_link_paths():
if is_windows:
check_link_paths('gcc-7.3.1.txt', [])
else:
check_link_paths('gcc-7.3.1.txt', [])
check_link_paths('gcc-7.3.1.txt', [])
def test_clang4_link_paths():
if is_windows:
check_link_paths('clang-4.0.1.txt', [])
else:
check_link_paths('clang-4.0.1.txt', [])
check_link_paths('clang-4.0.1.txt', [])
def test_xl_link_paths():
if is_windows:
check_link_paths('xl-13.1.5.txt', [
r'C:\opt\ibm\xlsmp\4.1.5\lib',
r'C:\opt\ibm\xlmass\8.1.5\lib',
r'C:\opt\ibm\xlC\13.1.5\lib'])
drive + r'\opt\ibm\xlsmp\4.1.5\lib',
drive + r'\opt\ibm\xlmass\8.1.5\lib',
drive + r'\opt\ibm\xlC\13.1.5\lib'])
else:
check_link_paths('xl-13.1.5.txt', [
'/opt/ibm/xlsmp/4.1.5/lib',
@ -93,22 +90,23 @@ def test_xl_link_paths():
def test_cce_link_paths():
if is_windows:
check_link_paths('cce-8.6.5.txt', [
r'C:\opt\gcc\6.1.0\snos\lib64',
r'C:\opt\cray\dmapp\default\lib64',
r'C:\opt\cray\pe\mpt\7.7.0\gni\mpich-cray\8.6\lib',
r'C:\opt\cray\pe\libsci\17.12.1\CRAY\8.6\x86_64\lib',
r'C:\opt\cray\rca\2.2.16-6.0.5.0_15.34__g5e09e6d.ari\lib64',
r'C:\opt\cray\pe\pmi\5.0.13\lib64',
r'C:\opt\cray\xpmem\2.2.4-6.0.5.0_4.8__g35d5e73.ari\lib64',
r'C:\opt\cray\dmapp\7.1.1-6.0.5.0_49.8__g1125556.ari\lib64',
r'C:\opt\cray\ugni\6.0.14-6.0.5.0_16.9__g19583bb.ari\lib64',
r'C:\opt\cray\udreg\2.3.2-6.0.5.0_13.12__ga14955a.ari\lib64',
r'C:\opt\cray\alps\6.5.28-6.0.5.0_18.6__g13a91b6.ari\lib64',
r'C:\opt\cray\pe\atp\2.1.1\libApp',
r'C:\opt\cray\pe\cce\8.6.5\cce\x86_64\lib',
r'C:\opt\cray\wlm_detect\1.3.2-6.0.5.0_3.1__g388ccd5.ari\lib64',
r'C:\opt\gcc\6.1.0\snos\lib\gcc\x86_64-suse-linux\6.1.0',
r'C:\opt\cray\pe\cce\8.6.5\binutils\x86_64\x86_64-unknown-linux-gnu\lib'])
drive + r'\opt\gcc\6.1.0\snos\lib64',
drive + r'\opt\cray\dmapp\default\lib64',
drive + r'\opt\cray\pe\mpt\7.7.0\gni\mpich-cray\8.6\lib',
drive + r'\opt\cray\pe\libsci\17.12.1\CRAY\8.6\x86_64\lib',
drive + r'\opt\cray\rca\2.2.16-6.0.5.0_15.34__g5e09e6d.ari\lib64',
drive + r'\opt\cray\pe\pmi\5.0.13\lib64',
drive + r'\opt\cray\xpmem\2.2.4-6.0.5.0_4.8__g35d5e73.ari\lib64',
drive + r'\opt\cray\dmapp\7.1.1-6.0.5.0_49.8__g1125556.ari\lib64',
drive + r'\opt\cray\ugni\6.0.14-6.0.5.0_16.9__g19583bb.ari\lib64',
drive + r'\opt\cray\udreg\2.3.2-6.0.5.0_13.12__ga14955a.ari\lib64',
drive + r'\opt\cray\alps\6.5.28-6.0.5.0_18.6__g13a91b6.ari\lib64',
drive + r'\opt\cray\pe\atp\2.1.1\libApp',
drive + r'\opt\cray\pe\cce\8.6.5\cce\x86_64\lib',
drive + r'\opt\cray\wlm_detect\1.3.2-6.0.5.0_3.1__g388ccd5.ari\lib64',
drive + r'\opt\gcc\6.1.0\snos\lib\gcc\x86_64-suse-linux\6.1.0',
drive +
r'\opt\cray\pe\cce\8.6.5\binutils\x86_64\x86_64-unknown-linux-gnu\lib'])
else:
check_link_paths('cce-8.6.5.txt', [
'/opt/gcc/6.1.0/snos/lib64',
@ -132,7 +130,7 @@ def test_cce_link_paths():
def test_clang_apple_ld_link_paths():
if is_windows:
check_link_paths('clang-9.0.0-apple-ld.txt', [
r'C:\Applications\Xcode.app\Contents\Developer\Platforms\MacOSX.platform\Developer\SDKs\MacOSX10.13.sdk\usr\lib']) # noqa
drive + r'\Applications\Xcode.app\Contents\Developer\Platforms\MacOSX.platform\Developer\SDKs\MacOSX10.13.sdk\usr\lib']) # noqa
else:
check_link_paths('clang-9.0.0-apple-ld.txt', [
'/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/lib']) # noqa
@ -145,9 +143,9 @@ def test_nag_mixed_gcc_gnu_ld_link_paths():
# '/path/to/gcc/bin/g++ -Wl,-v ./main.c'.
if is_windows:
check_link_paths('collect2-6.3.0-gnu-ld.txt', [
r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib\gcc\x86_64-pc-linux-gnu\6.5.0', # noqa
r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib64', # noqa
r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib']) # noqa
drive + r'\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib\gcc\x86_64-pc-linux-gnu\6.5.0', # noqa
drive + r'\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib64', # noqa
drive + r'\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib']) # noqa
else:
check_link_paths('collect2-6.3.0-gnu-ld.txt', [
'/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib/gcc/x86_64-pc-linux-gnu/6.5.0', # noqa
@ -162,9 +160,9 @@ def test_nag_link_paths():
# 'nagfor -Wc=/path/to/gcc/bin/gcc -Wl,-v ./main.c'.
if is_windows:
check_link_paths('nag-6.2-gcc-6.5.0.txt', [
r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib\gcc\x86_64-pc-linux-gnu\6.5.0', # noqa
r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib64', # noqa
r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib']) # noqa
drive + r'\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib\gcc\x86_64-pc-linux-gnu\6.5.0', # noqa
drive + r'\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib64', # noqa
drive + r'\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib']) # noqa
else:
check_link_paths('nag-6.2-gcc-6.5.0.txt', [
'/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib/gcc/x86_64-pc-linux-gnu/6.5.0', # noqa
@ -175,8 +173,8 @@ def test_nag_link_paths():
def test_obscure_parsing_rules():
if is_windows:
check_link_paths('obscure-parsing-rules.txt', [
r'C:\first\path',
r'C:\third\path'])
drive + r'\first\path',
drive + r'\third\path'])
else:
check_link_paths('obscure-parsing-rules.txt', [
'/first/path',

View file

@ -176,21 +176,15 @@ def test_symlinks_true(self, stage):
fs.copy_tree('source', 'dest', symlinks=True)
assert os.path.exists('dest/2')
if sys.platform != "win32":
# TODO: islink will return false for junctions
assert islink('dest/2')
assert islink('dest/2')
assert os.path.exists('dest/a/b2')
if sys.platform != "win32":
# TODO: Not supported for junctions ?
with fs.working_dir('dest/a'):
assert os.path.exists(os.readlink('b2'))
with fs.working_dir('dest/a'):
assert os.path.exists(os.readlink('b2'))
if sys.platform != "win32":
# TODO: Not supported on Windows ?
assert (os.path.realpath('dest/f/2') ==
os.path.abspath('dest/a/b/2'))
assert os.path.realpath('dest/2') == os.path.abspath('dest/1')
assert (os.path.realpath('dest/f/2') ==
os.path.abspath('dest/a/b/2'))
assert os.path.realpath('dest/2') == os.path.abspath('dest/1')
def test_symlinks_true_ignore(self, stage):
"""Test copying when specifying relative paths that should be ignored
@ -387,7 +381,6 @@ def test_recursive_search_of_headers_from_prefix(
if sys.platform == "win32":
# TODO: Test \\s
dir_list = [
(['C:/pfx/include/foo.h', 'C:/pfx/include/subdir/foo.h'], ['C:/pfx/include']),
(['C:/pfx/include/foo.h', 'C:/pfx/subdir/foo.h'],

View file

@ -628,6 +628,7 @@ def test_read_lock_read_only_dir_writable_lockfile(lock_dir, lock_path):
pass
@pytest.mark.skipif(False if is_windows else getuid() == 0, reason='user is root')
def test_read_lock_no_lockfile(lock_dir, lock_path):
"""read-only directory, no lockfile (so can't create)."""
with read_only(lock_dir):
@ -689,13 +690,11 @@ def test_upgrade_read_to_write_fails_with_readonly_file(private_lock_path):
lock = lk.Lock(private_lock_path)
assert lock._reads == 0
assert lock._writes == 0
assert lock._current_lock is None
lock.acquire_read()
assert lock._reads == 1
assert lock._writes == 0
assert lock._file.mode == 'r'
assert lock._current_lock == lock.LOCK_SH
# upgrade to write here
with pytest.raises(lk.LockROFileError):
@ -1358,6 +1357,7 @@ def _lockf(fd, cmd, len, start, whence):
lock = lk.Lock(lockfile)
touch(lockfile)
monkeypatch.setattr(fcntl, 'lockf', _lockf)
if err_num in [errno.EAGAIN, errno.EACCES]:

View file

@ -18,8 +18,8 @@
import pytest
import llnl.util.tty.log as log
import llnl.util.lang as lang
import llnl.util.tty.log as log
import llnl.util.tty.pty as pty
from spack.util.executable import which

View file

@ -15,7 +15,7 @@
pytestmark = pytest.mark.skipif(
sys.platform == 'win32',
reason="Test functionality support but failing on Win")
reason="Test functionality supported but tests are failing on Win")
def test_get_version_no_match_git(tmpdir, working_env):

View file

@ -20,7 +20,8 @@
from spack.util.environment import path_put_first
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
reason="MakeExecutable \
not supported on Windows")
class MakeExecutableTest(unittest.TestCase):

View file

@ -17,6 +17,9 @@
path_from_modules,
)
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="Tests fail on Windows")
test_module_lines = ['prepend-path LD_LIBRARY_PATH /path/to/lib',
'setenv MOD_DIR /path/to',
'setenv LDFLAGS -Wl,-rpath/path/to/lib',
@ -24,8 +27,6 @@
'prepend-path PATH /path/to/bin']
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_module_function_change_env(tmpdir, working_env):
src_file = str(tmpdir.join('src_me'))
with open(src_file, 'w') as f:
@ -38,8 +39,6 @@ def test_module_function_change_env(tmpdir, working_env):
assert os.environ['NOT_AFFECTED'] == "NOT_AFFECTED"
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_module_function_no_change(tmpdir):
src_file = str(tmpdir.join('src_me'))
with open(src_file, 'w') as f:
@ -128,6 +127,7 @@ def test_get_argument_from_module_line():
get_path_args_from_module_line(bl)
# lmod is entirely unsupported on Windows
def test_lmod_quote_parsing():
lines = ['setenv("SOME_PARTICULAR_DIR","-L/opt/cray/pe/mpich/8.1.4/gtl/lib")']
result = get_path_from_module_contents(lines, 'some-module')

View file

@ -3,8 +3,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
import pytest
from spack.spec import Spec
@ -98,8 +96,6 @@ def test_normalize(spec_and_expected, config, mock_packages):
assert spec.eq_dag(expected, deptypes=False)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_default_variant(config, mock_packages):
spec = Spec('optional-dep-test-3')
spec.concretize()

View file

@ -4,7 +4,6 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import sys
import pytest
@ -64,8 +63,6 @@ def test_import_package_as(self):
import spack.pkg.builtin.mock.mpich as mp # noqa
from spack.pkg.builtin import mock # noqa
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_inheritance_of_diretives(self):
p = spack.repo.get('simple-inheritance')
@ -91,16 +88,12 @@ def test_inheritance_of_diretives(self):
assert '~openblas' in s
assert 'mpi' in s
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.regression('11844')
def test_inheritance_of_patches(self):
s = Spec('patch-inheritance')
# Will error if inheritor package cannot find inherited patch files
s.concretize()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_dependency_extensions(self):
s = Spec('extension2')
s.concretize()
@ -125,8 +118,6 @@ def test_import_namespace_container_modules(self):
from spack.pkg.builtin import mock # noqa
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.regression('2737')
def test_urls_for_versions(mock_packages, config):
"""Version directive without a 'url' argument should use default url."""
@ -151,8 +142,6 @@ def test_url_for_version_with_no_urls(mock_packages, config):
pkg.url_for_version('1.1')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_url_for_version_with_only_overrides(mock_packages, config):
spec = Spec('url-only-override')
spec.concretize()
@ -171,8 +160,6 @@ def test_url_for_version_with_only_overrides(mock_packages, config):
assert pkg.url_for_version('0.7.0') == 'http://c.example.com/url_override-0.7.0.tar.gz'
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_url_for_version_with_only_overrides_with_gaps(mock_packages, config):
spec = Spec('url-only-override-with-gaps')
spec.concretize()
@ -340,8 +327,6 @@ def test_git_url_top_level_conflicts(mock_packages, config):
spack.fetch_strategy.for_package_version(pkg, '1.3')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_rpath_args(mutable_database):
"""Test a package's rpath_args property."""

View file

@ -40,6 +40,9 @@
)
from spack.spec import Spec
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
def fake_fetchify(url, pkg):
"""Fake the URL for a package so it downloads from a file."""
@ -48,8 +51,6 @@ def fake_fetchify(url, pkg):
pkg.fetcher = fetcher
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('install_mockery', 'mock_gnupghome')
def test_buildcache(mock_archive, tmpdir):
# tweak patchelf to only do a download
@ -192,8 +193,6 @@ def test_buildcache(mock_archive, tmpdir):
bindist._cached_specs = set()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('install_mockery')
def test_relocate_text(tmpdir):
spec = Spec('trivial-install-test-package')
@ -217,8 +216,6 @@ def test_relocate_text(tmpdir):
bindist._cached_specs = set()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_relocate_links(tmpdir):
with tmpdir.as_cwd():
old_layout_root = os.path.join(
@ -260,8 +257,6 @@ def test_needs_relocation():
assert needs_binary_relocation('application', 'x-mach-binary')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_replace_paths(tmpdir):
with tmpdir.as_cwd():
suffix = 'dylib' if platform.system().lower() == 'darwin' else 'so'
@ -471,8 +466,6 @@ def test_replace_paths(tmpdir):
}
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_macho_make_paths():
out = macho_make_paths_relative('/Users/Shared/spack/pkgC/lib/libC.dylib',
'/Users/Shared/spack',

View file

@ -19,20 +19,26 @@
from spack.spec import Spec
from spack.stage import Stage
from spack.util.executable import Executable
from spack.util.path import is_windows
# various sha256 sums (using variables for legibility)
# many file based shas will differ between Windows and other platforms
# due to the use of carriage returns ('\r\n') in Windows line endings
# files with contents 'foo', 'bar', and 'baz'
foo_sha256 = 'b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
bar_sha256 = '7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730'
baz_sha256 = 'bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c'
biz_sha256 = 'a69b288d7393261e613c276c6d38a01461028291f6e381623acc58139d01f54d'
foo_sha256 = 'b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c' if not is_windows else 'bf874c7dd3a83cf370fdc17e496e341de06cd596b5c66dbf3c9bb7f6c139e3ee'
bar_sha256 = '7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730' if not is_windows else '556ddc69a75d0be0ecafc82cd4657666c8063f13d762282059c39ff5dbf18116'
baz_sha256 = 'bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c' if not is_windows else 'd30392e66c636a063769cbb1db08cd3455a424650d4494db6379d73ea799582b'
biz_sha256 = 'a69b288d7393261e613c276c6d38a01461028291f6e381623acc58139d01f54d' if not is_windows else '2f2b087a8f84834fd03d4d1d5b43584011e869e4657504ef3f8b0a672a5c222e'
# url patches
# url shas are the same on Windows
url1_sha256 = 'abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'
url2_sha256 = '1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd'
url2_archive_sha256 = 'abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd'
platform_url_sha = '252c0af58be3d90e5dc5e0d16658434c9efa5d20a5df6c10bf72c2d77f780866' if not is_windows else 'ecf44a8244a486e9ef5f72c6cb622f99718dcd790707ac91af0b8c9a4ab7a2bb'
@pytest.fixture()
def mock_patch_stage(tmpdir_factory, monkeypatch):
@ -46,7 +52,7 @@ def mock_patch_stage(tmpdir_factory, monkeypatch):
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
reason="Line ending conflict on Windows")
@pytest.mark.parametrize('filename, sha256, archive_sha256', [
# compressed patch -- needs sha256 and archive_256
(os.path.join(data_path, 'foo.tgz'),
@ -54,7 +60,7 @@ def mock_patch_stage(tmpdir_factory, monkeypatch):
'4e8092a161ec6c3a1b5253176fcf33ce7ba23ee2ff27c75dbced589dabacd06e'),
# uncompressed patch -- needs only sha256
(os.path.join(data_path, 'foo.patch'),
'252c0af58be3d90e5dc5e0d16658434c9efa5d20a5df6c10bf72c2d77f780866',
platform_url_sha,
None)
])
def test_url_patch(mock_patch_stage, filename, sha256, archive_sha256):
@ -92,8 +98,6 @@ def test_url_patch(mock_patch_stage, filename, sha256, archive_sha256):
assert filecmp.cmp('foo.txt', 'foo-expected.txt')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_patch_in_spec(mock_packages, config):
"""Test whether patches in a package appear in the spec."""
spec = Spec('patch')
@ -112,8 +116,6 @@ def test_patch_in_spec(mock_packages, config):
tuple(spec.variants['patches']._patches_in_order_of_appearance))
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_patch_mixed_versions_subset_constraint(mock_packages, config):
"""If we have a package with mixed x.y and x.y.z versions, make sure that
a patch applied to a version range of x.y.z versions is not applied to
@ -128,15 +130,17 @@ def test_patch_mixed_versions_subset_constraint(mock_packages, config):
assert biz_sha256 not in spec2.variants['patches'].value
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_patch_order(mock_packages, config):
spec = Spec('dep-diamond-patch-top')
spec.concretize()
mid2_sha256 = 'mid21234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'
mid1_sha256 = '0b62284961dab49887e31319843431ee5b037382ac02c4fe436955abef11f094'
top_sha256 = 'f7de2947c64cb6435e15fb2bef359d1ed5f6356b2aebb7b20535e3772904e6db'
mid2_sha256 = 'mid21234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234' \
if not is_windows \
else 'mid21234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'
mid1_sha256 = '0b62284961dab49887e31319843431ee5b037382ac02c4fe436955abef11f094' \
if not is_windows else 'aeb16c4dec1087e39f2330542d59d9b456dd26d791338ae6d80b6ffd10c89dfa'
top_sha256 = 'f7de2947c64cb6435e15fb2bef359d1ed5f6356b2aebb7b20535e3772904e6db' \
if not is_windows else 'ff34cb21271d16dbf928374f610bb5dd593d293d311036ddae86c4846ff79070'
dep = spec['patch']
patch_order = dep.variants['patches']._patches_in_order_of_appearance
@ -178,7 +182,7 @@ def test_nested_directives(mock_packages):
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
reason="Test requires Autotools")
def test_patched_dependency(
mock_packages, config, install_mockery, mock_fetch):
"""Test whether patched dependencies work."""
@ -187,7 +191,9 @@ def test_patched_dependency(
assert 'patches' in list(spec['libelf'].variants.keys())
# make sure the patch makes it into the dependency spec
assert (('c45c1564f70def3fc1a6e22139f62cb21cd190cc3a7dbe6f4120fa59ce33dcb8',) ==
t_sha = 'c45c1564f70def3fc1a6e22139f62cb21cd190cc3a7dbe6f4120fa59ce33dcb8' \
if not is_windows else '3c5b65abcd6a3b2c714dbf7c31ff65fe3748a1adc371f030c283007ca5534f11'
assert ((t_sha,) ==
spec['libelf'].variants['patches'].value)
# make sure the patch in the dependent's directory is applied to the
@ -206,8 +212,6 @@ def test_patched_dependency(
assert 'Patched!' in mf.read()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_multiple_patched_dependencies(mock_packages, config):
"""Test whether multiple patched dependencies work."""
spec = Spec('patch-several-dependencies')
@ -226,8 +230,6 @@ def test_multiple_patched_dependencies(mock_packages, config):
(url2_sha256, url1_sha256) == spec['fake'].variants['patches'].value)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_conditional_patched_dependencies(mock_packages, config):
"""Test whether conditional patched dependencies work."""
spec = Spec('patch-several-dependencies @1.0')
@ -309,8 +311,6 @@ def get_patch(spec, ending):
assert url2_patch.archive_sha256 == url2_archive_sha256
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_conditional_patched_deps_with_conditions(mock_packages, config):
"""Test whether conditional patched dependencies with conditions work."""
spec = Spec('patch-several-dependencies @1.0 ^libdwarf@20111030')
@ -326,8 +326,6 @@ def test_conditional_patched_deps_with_conditions(mock_packages, config):
spec.package.package_dir)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_write_and_read_sub_dags_with_patched_deps(mock_packages, config):
"""Test whether patched dependencies are still correct after writing and
reading a sub-DAG of a concretized Spec.

View file

@ -13,9 +13,10 @@
from spack.util.file_permissions import InvalidPermissionsError, set_permissions
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="chmod unsupported on Windows")
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_chmod_real_entries_ignores_suid_sgid(tmpdir):
path = str(tmpdir.join('file').ensure())
mode = stat.S_ISUID | stat.S_ISGID | stat.S_ISVTX
@ -28,8 +29,6 @@ def test_chmod_real_entries_ignores_suid_sgid(tmpdir):
assert os.stat(path).st_mode == mode | perms & ~stat.S_IXUSR
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_chmod_rejects_group_writable_suid(tmpdir):
path = str(tmpdir.join('file').ensure())
mode = stat.S_ISUID
@ -40,8 +39,6 @@ def test_chmod_rejects_group_writable_suid(tmpdir):
set_permissions(path, perms)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_chmod_rejects_world_writable_suid(tmpdir):
path = str(tmpdir.join('file').ensure())
mode = stat.S_ISUID
@ -52,8 +49,6 @@ def test_chmod_rejects_world_writable_suid(tmpdir):
set_permissions(path, perms)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_chmod_rejects_world_writable_sgid(tmpdir):
path = str(tmpdir.join('file').ensure())
mode = stat.S_ISGID

View file

@ -21,6 +21,9 @@
import spack.tengine
import spack.util.executable
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="Tests fail on Windows")
def skip_unless_linux(f):
return pytest.mark.skipif(
@ -225,8 +228,6 @@ def test_file_is_relocatable_errors(tmpdir):
assert 'is not an absolute path' in str(exc_info.value)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('patchelf_behavior,expected', [
('echo ', []),
('echo /opt/foo/lib:/opt/foo/lib64', ['/opt/foo/lib', '/opt/foo/lib64']),
@ -269,8 +270,6 @@ def test_normalize_relative_paths(start_path, relative_paths, expected):
assert normalized == expected
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_set_elf_rpaths(mock_patchelf):
# Try to relocate a mock version of patchelf and check
# the call made to patchelf itself

View file

@ -60,7 +60,7 @@
@pytest.fixture # type: ignore[no-redef]
def sbang_line():
yield '#!/bin/sh {0}{1}bin{1}sbang\n'.format(spack.store.layout.root, os.sep)
yield '#!/bin/sh %s/bin/sbang\n' % spack.store.layout.root
class ScriptDirectory(object):

View file

@ -5,8 +5,6 @@
"""
These tests check Spec DAG operations using dummy packages.
"""
import sys
import pytest
import spack.error
@ -16,9 +14,6 @@
from spack.spec import Spec
from spack.util.mock_package import MockPackageMultiRepo
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
def check_links(spec_to_check):
for spec in spec_to_check.traverse():

View file

@ -314,8 +314,6 @@ def test_satisfies_multi_value_variant(self):
check_satisfies('multivalue-variant foo="bar,baz"',
'foo="bar"')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_satisfies_single_valued_variant(self):
"""Tests that the case reported in
https://github.com/spack/spack/pull/2386#issuecomment-282147639
@ -339,8 +337,6 @@ def test_satisfies_single_valued_variant(self):
# Check that conditional dependencies are treated correctly
assert '^b' in a
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_unsatisfied_single_valued_variant(self):
a = Spec('a foobar=baz')
a.concretize()
@ -350,15 +346,11 @@ def test_unsatisfied_single_valued_variant(self):
mv.concretize()
assert 'a@1.0' not in mv
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_indirect_unsatisfied_single_valued_variant(self):
spec = Spec('singlevalue-variant-dependent')
spec.concretize()
assert 'a@1.0' not in spec
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_unsatisfiable_multi_value_variant(self):
# Semantics for a multi-valued variant is different
@ -491,8 +483,6 @@ def test_unsatisfiable_compiler_flag(self):
# 'mpich' is concrete:
check_unsatisfiable('mpich', 'mpich cppflags="-O3"', True)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_copy_satisfies_transitive(self):
spec = Spec('dttop')
spec.concretize()
@ -506,8 +496,6 @@ def test_unsatisfiable_compiler_flag_mismatch(self):
check_unsatisfiable(
'mpich cppflags="-O3"', 'mpich cppflags="-O2"')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_satisfies_virtual(self):
# Don't use check_satisfies: it checks constrain() too, and
# you can't constrain a non-virtual by a virtual.
@ -515,8 +503,6 @@ def test_satisfies_virtual(self):
assert Spec('mpich2').satisfies(Spec('mpi'))
assert Spec('zmpi').satisfies(Spec('mpi'))
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_satisfies_virtual_dep_with_virtual_constraint(self):
"""Ensure we can satisfy virtual constraints when there are multiple
vdep providers in the specs."""
@ -533,8 +519,6 @@ def test_satisfies_virtual_dep_with_virtual_constraint(self):
'netlib-lapack ^netlib-blas'
)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_satisfies_same_spec_with_different_hash(self):
"""Ensure that concrete specs are matched *exactly* by hash."""
s1 = Spec('mpileaks').concretized()
@ -580,8 +564,6 @@ def test_spec_contains_deps(self):
assert 'libelf' in s
assert 'mpi' in s
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('config')
def test_virtual_index(self):
s = Spec('callpath')
@ -776,8 +758,6 @@ def test_exceptional_paths_for_constructor(self):
with pytest.raises(ValueError):
Spec('libelf foo')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_spec_formatting(self):
spec = Spec("multivalue-variant cflags=-O2")
spec.concretize()
@ -850,8 +830,6 @@ def test_spec_formatting(self):
actual = spec.format(named_str)
assert expected == actual
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_spec_formatting_escapes(self):
spec = Spec('multivalue-variant cflags=-O2')
spec.concretize()
@ -884,8 +862,6 @@ def test_spec_formatting_escapes(self):
with pytest.raises(SpecFormatStringError):
spec.format(fmt_str)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_spec_deprecated_formatting(self):
spec = Spec("libelf cflags=-O2")
spec.concretize()
@ -929,8 +905,6 @@ def test_spec_deprecated_formatting(self):
actual = spec.format(named_str)
assert str(expected) == actual
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.regression('9908')
def test_spec_flags_maintain_order(self):
# Spack was assembling flags in a manner that could result in
@ -997,8 +971,6 @@ def test_abstract_spec_prefix_error(self):
with pytest.raises(SpecError):
spec.prefix
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_forwarding_of_architecture_attributes(self):
spec = Spec('libelf target=x86_64').concretized()
@ -1019,8 +991,6 @@ def test_forwarding_of_architecture_attributes(self):
assert 'avx512' not in spec.target
assert spec.target < 'broadwell'
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('transitive', [True, False])
def test_splice(self, transitive):
# Tests the new splice function in Spec using a somewhat simple case
@ -1056,8 +1026,6 @@ def test_splice(self, transitive):
# Finally, the spec should know it's been spliced:
assert out.spliced
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('transitive', [True, False])
def test_splice_with_cached_hashes(self, transitive):
spec = Spec('splice-t')
@ -1088,8 +1056,6 @@ def test_splice_with_cached_hashes(self, transitive):
assert (out['splice-h'].build_hash() == dep.build_hash()) == transitive
assert out['splice-z'].build_hash() == out_z_expected.build_hash()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('transitive', [True, False])
def test_splice_input_unchanged(self, transitive):
spec = Spec('splice-t').concretized()
@ -1102,8 +1068,6 @@ def test_splice_input_unchanged(self, transitive):
assert spec.full_hash() == orig_spec_hash
assert dep.full_hash() == orig_dep_hash
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('transitive', [True, False])
def test_splice_subsequent(self, transitive):
spec = Spec('splice-t')
@ -1208,8 +1172,6 @@ def test_satisfies_dependencies_ordered(self):
assert s.satisfies('mpileaks ^zmpi ^fake', strict=True)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.regression('3887')
@pytest.mark.parametrize('spec_str', [
'git', 'hdf5', 'py-flake8'

View file

@ -5,7 +5,6 @@
import itertools
import os
import shlex
import sys
import pytest

View file

@ -11,7 +11,6 @@
import ast
import inspect
import os
import sys
import pytest

View file

@ -20,6 +20,10 @@
from spack.filesystem_view import YamlFilesystemView
from spack.repo import RepoPath
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="Python activation not \
currently supported on Windows")
def create_ext_pkg(name, prefix, extendee_spec, monkeypatch):
ext_spec = spack.spec.Spec(name)
@ -178,8 +182,6 @@ def test_python_activation_with_files(tmpdir, python_and_extension_dirs,
assert 'setuptools.egg' not in easy_install_contents
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_python_activation_view(tmpdir, python_and_extension_dirs,
builtin_and_mock_packages, monkeypatch):
python_prefix, ext_prefix = python_and_extension_dirs
@ -203,8 +205,6 @@ def test_python_activation_view(tmpdir, python_and_extension_dirs,
assert os.path.exists(os.path.join(view_dir, 'bin/py-ext-tool'))
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_python_ignore_namespace_init_conflict(
tmpdir, namespace_extensions, builtin_and_mock_packages, monkeypatch):
"""Test the view update logic in PythonPackage ignores conflicting
@ -239,8 +239,6 @@ def test_python_ignore_namespace_init_conflict(
assert os.path.exists(os.path.join(view_dir, init_file))
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_python_keep_namespace_init(
tmpdir, namespace_extensions, builtin_and_mock_packages, monkeypatch):
"""Test the view update logic in PythonPackage keeps the namespace
@ -283,8 +281,6 @@ def test_python_keep_namespace_init(
assert not os.path.exists(os.path.join(view_dir, init_file))
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_python_namespace_conflict(tmpdir, namespace_extensions,
monkeypatch, builtin_and_mock_packages):
"""Test the view update logic in PythonPackage reports an error when two

View file

@ -12,9 +12,10 @@
import spack.install_test
import spack.spec
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="Tests fail on Windows")
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_test_log_pathname(mock_packages, config):
"""Ensure test log path is reasonable."""
spec = spack.spec.Spec('libdwarf').concretized()
@ -28,8 +29,6 @@ def test_test_log_pathname(mock_packages, config):
assert test_suite.test_log_name(spec) in logfile
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_test_ensure_stage(mock_test_stage):
"""Make sure test stage directory is properly set up."""
spec = spack.spec.Spec('libdwarf').concretized()
@ -43,8 +42,6 @@ def test_test_ensure_stage(mock_test_stage):
assert mock_test_stage in test_suite.stage
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_write_test_result(mock_packages, mock_test_stage):
"""Ensure test results written to a results file."""
spec = spack.spec.Spec('libdwarf').concretized()
@ -65,7 +62,6 @@ def test_write_test_result(mock_packages, mock_test_stage):
assert spec.name in msg
@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows")
def test_do_test(mock_packages, install_mockery, mock_test_stage):
"""Perform a stand-alone test with files to copy."""
spec = spack.spec.Spec('trivial-smoke-test').concretized()

View file

@ -163,6 +163,7 @@ def test_fetch(
assert 'echo Building...' in contents
# TODO-27021
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('spec,url,digest', [

View file

@ -12,7 +12,9 @@
import spack.util.editor as ed
pytestmark = pytest.mark.usefixtures('working_env')
pytestmark = [pytest.mark.usefixtures('working_env'),
pytest.mark.skipif(sys.platform == 'win32',
reason="editor not implemented on windows")]
def _make_exe(tmpdir_factory, name, contents=None):
@ -23,8 +25,6 @@ def _make_exe(tmpdir_factory, name, contents=None):
with open(path, 'w') as f:
f.write('#!/bin/sh\n%s\n' % contents)
set_executable(path)
if sys.platform == "win32":
path = path.replace('\\', '/')
return path
@ -48,13 +48,11 @@ def vim_exe(tmpdir_factory):
return _make_exe(tmpdir_factory, 'vim', 'exit 0')
@pytest.mark.skipif(sys.platform == 'win32', reason="editor not implemented on windows")
def test_find_exe_from_env_var(good_exe):
os.environ['EDITOR'] = good_exe
assert ed._find_exe_from_env_var('EDITOR') == (good_exe, [good_exe])
@pytest.mark.skipif(sys.platform == 'win32', reason="editor not implemented on windows")
def test_find_exe_from_env_var_with_args(good_exe):
os.environ['EDITOR'] = good_exe + ' a b c'
assert ed._find_exe_from_env_var('EDITOR') == (
@ -72,7 +70,6 @@ def test_find_exe_from_env_var_no_editor():
assert ed._find_exe_from_env_var('FOO') == (None, [])
@pytest.mark.skipif(sys.platform == 'win32', reason="editor not implemented on windows")
def test_editor_visual(good_exe):
os.environ['VISUAL'] = good_exe
@ -83,7 +80,6 @@ def assert_exec(exe, args):
ed.editor('/path/to/file', _exec_func=assert_exec)
@pytest.mark.skipif(sys.platform == 'win32', reason="editor not implemented on windows")
def test_editor_visual_bad(good_exe, bad_exe):
os.environ['VISUAL'] = bad_exe
os.environ['EDITOR'] = good_exe
@ -98,7 +94,6 @@ def assert_exec(exe, args):
ed.editor('/path/to/file', _exec_func=assert_exec)
@pytest.mark.skipif(sys.platform == 'win32', reason="editor not implemented on windows")
def test_editor_no_visual(good_exe):
if 'VISUAL' in os.environ:
del os.environ['VISUAL']
@ -111,7 +106,6 @@ def assert_exec(exe, args):
ed.editor('/path/to/file', _exec_func=assert_exec)
@pytest.mark.skipif(sys.platform == 'win32', reason="editor not implemented on windows")
def test_editor_no_visual_with_args(good_exe):
if 'VISUAL' in os.environ:
del os.environ['VISUAL']
@ -126,7 +120,6 @@ def assert_exec(exe, args):
ed.editor('/path/to/file', _exec_func=assert_exec)
@pytest.mark.skipif(sys.platform == 'win32', reason="editor not implemented on windows")
def test_editor_both_bad(nosuch_exe, vim_exe):
os.environ['VISUAL'] = nosuch_exe
os.environ['EDITOR'] = nosuch_exe

View file

@ -11,6 +11,8 @@
import spack.util.environment as envutil
is_windows = sys.platform == 'win32'
@pytest.fixture()
def prepare_environment_for_tests():
@ -20,25 +22,34 @@ def prepare_environment_for_tests():
del os.environ['TEST_ENV_VAR']
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_is_system_path():
assert(envutil.is_system_path('/usr/bin'))
sys_path = 'C:\\Users' if is_windows else '/usr/bin'
assert(envutil.is_system_path(sys_path))
assert(not envutil.is_system_path('/nonsense_path/bin'))
assert(not envutil.is_system_path(''))
assert(not envutil.is_system_path(None))
test_paths = ['/usr/bin',
'/nonsense_path/lib',
'/usr/local/lib',
'/bin',
'/nonsense_path/extra/bin',
'/usr/lib64']
if is_windows:
test_paths = [
'C:\\Users',
'C:\\',
'C:\\ProgramData',
'C:\\nonsense_path',
'C:\\Program Files',
'C:\\nonsense_path\\extra\\bin']
else:
test_paths = ['/usr/bin',
'/nonsense_path/lib',
'/usr/local/lib',
'/bin',
'/nonsense_path/extra/bin',
'/usr/lib64']
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_filter_system_paths():
expected = [p for p in test_paths if p.startswith('/nonsense_path')]
nonsense_prefix = 'C:\\nonsense_path' if is_windows else '/nonsense_path'
expected = [p for p in test_paths if p.startswith(nonsense_prefix)]
filtered = envutil.filter_system_paths(test_paths)
assert(expected == filtered)
@ -57,9 +68,8 @@ def test_prune_duplicate_paths():
assert(expected == envutil.prune_duplicate_paths(test_paths))
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_get_path(prepare_environment_for_tests):
os.environ['TEST_ENV_VAR'] = '/a:/b:/c/d'
os.environ['TEST_ENV_VAR'] = os.pathsep.join(['/a', '/b', '/c/d'])
expected = ['/a', '/b', '/c/d']
assert(envutil.get_path('TEST_ENV_VAR') == expected)

View file

@ -14,10 +14,16 @@
import spack.util.executable as ex
from spack.hooks.sbang import filter_shebangs_in_directory
is_windows = sys.platform == 'win32'
def test_read_unicode(tmpdir, working_env):
script_name = 'print_unicode.py'
# read the unicode back in and see whether things work
if is_windows:
script = ex.Executable('%s %s' % (sys.executable, script_name))
else:
script = ex.Executable('./%s' % script_name)
with tmpdir.as_cwd():
os.environ['LD_LIBRARY_PATH'] = spack.main.spack_ld_library_path
# make a script that prints some unicode
@ -35,12 +41,6 @@ def test_read_unicode(tmpdir, working_env):
fs.set_executable(script_name)
filter_shebangs_in_directory('.', [script_name])
# read the unicode back in and see whether things work
if sys.platform == 'win32':
script = ex.Executable('%s %s' % (sys.executable, script_name))
else:
script = ex.Executable('./%s' % script_name)
assert u'\xc3' == script(output=str).strip()
@ -54,9 +54,10 @@ def test_which_relative_path_with_slash(tmpdir, working_env):
no_exe = ex.which('.{0}exe'.format(os.path.sep))
assert no_exe is None
if sys.platform == "win32":
# For Windows, need to create files with .exe after any assert is none tests
tmpdir.ensure("exe.exe")
# These checks are for 'executable' files, Windows
# determines this by file extension.
path += ".exe"
tmpdir.ensure('exe.exe')
else:
fs.set_executable(path)

View file

@ -5,7 +5,6 @@
"""Test Spack's FileCache."""
import os
import sys
import pytest
@ -30,8 +29,6 @@ def test_write_and_read_cache_file(file_cache):
assert text == "foobar\n"
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_write_and_remove_cache_file(file_cache):
"""Test two write transactions on a cached file. Then try to remove an
entry from it.

View file

@ -12,6 +12,12 @@
import spack.config
import spack.util.path as sup
# This module pertains to path string padding manipulation specifically
# which is used for binary caching. This functionality is not supported
# on Windows as of yet.
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="Tests fail on Windows")
#: Some lines with lots of placeholders
padded_lines = [
"==> [2021-06-23-15:59:05.020387] './configure' '--prefix=/Users/gamblin2/padding-log-test/opt/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_pla/darwin-bigsur-skylake/apple-clang-12.0.5/zlib-1.2.11-74mwnxgn6nujehpyyalhwizwojwn5zga", # noqa: E501
@ -28,24 +34,18 @@
]
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize("padded,fixed", zip(padded_lines, fixed_lines))
def test_padding_substitution(padded, fixed):
"""Ensure that all padded lines are unpadded correctly."""
assert fixed == sup.padding_filter(padded)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_no_substitution():
"""Ensure that a line not containing one full path placeholder is not modified."""
partial = "--prefix=/Users/gamblin2/padding-log-test/opt/__spack_path_pla/darwin-bigsur-skylake/apple-clang-12.0.5/zlib-1.2.11-74mwnxgn6nujehpyyalhwizwojwn5zga'" # noqa: E501
assert sup.padding_filter(partial) == partial
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_short_substitution():
"""Ensure that a single placeholder path component is replaced"""
short = "--prefix=/Users/gamblin2/padding-log-test/opt/__spack_path_placeholder__/darwin-bigsur-skylake/apple-clang-12.0.5/zlib-1.2.11-74mwnxgn6nujehpyyalhwizwojwn5zga'" # noqa: E501
@ -53,8 +53,6 @@ def test_short_substitution():
assert short_subst == sup.padding_filter(short)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_partial_substitution():
"""Ensure that a single placeholder path component is replaced"""
short = "--prefix=/Users/gamblin2/padding-log-test/opt/__spack_path_placeholder__/__spack_p/darwin-bigsur-skylake/apple-clang-12.0.5/zlib-1.2.11-74mwnxgn6nujehpyyalhwizwojwn5zga'" # noqa: E501
@ -72,8 +70,6 @@ def test_longest_prefix_re():
)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_output_filtering(capfd, install_mockery, mutable_config):
"""Test filtering padding out of tty messages."""
long_path = "/" + "/".join([sup.SPACK_PATH_PADDING_CHARS] * 200)

View file

@ -7,19 +7,22 @@
import os
import os.path
import posixpath
import re
import sys
import pytest
import spack.paths
import spack.util.url as url_util
from spack.util.path import convert_to_posix_path
is_windows = sys.platform == 'win32'
if is_windows:
drive_m = re.search(r'[A-Za-z]:', spack.paths.test_path)
drive = drive_m.group() if drive_m else None
def test_url_parse():
parsed = url_util.parse('/path/to/resource')
assert(parsed.scheme == 'file')
assert(parsed.netloc == '')
assert(parsed.path == '/path/to/resource')
parsed = url_util.parse('/path/to/resource', scheme='fake')
assert(parsed.scheme == 'fake')
@ -36,11 +39,20 @@ def test_url_parse():
assert(parsed.netloc == '')
assert(parsed.path == '/path/to/resource')
if sys.platform != 'win32':
parsed = url_util.parse('file://path/to/resource')
parsed = url_util.parse('file://path/to/resource')
assert(parsed.scheme == 'file')
expected = convert_to_posix_path(
os.path.abspath(
posixpath.join('path', 'to', 'resource')))
if is_windows:
expected = expected.lstrip(drive)
assert(parsed.path == expected)
if is_windows:
parsed = url_util.parse('file://%s\\path\\to\\resource' % drive)
assert(parsed.scheme == 'file')
expected = os.path.abspath(posixpath.join('path', 'to', 'resource'))
assert(parsed.path == expected)
expected = '/' + posixpath.join('path', 'to', 'resource')
assert parsed.path == expected
parsed = url_util.parse('https://path/to/resource')
assert(parsed.scheme == 'https')
@ -48,46 +60,34 @@ def test_url_parse():
assert(parsed.path == '/to/resource')
spack_root = spack.paths.spack_root
parsed = url_util.parse('$spack')
parsed = url_util.parse('file://$spack')
assert(parsed.scheme == 'file')
if sys.platform != 'win32':
assert(parsed.netloc == '')
if sys.platform == "win32":
spack_root = spack_root.replace('\\', '/')
if is_windows:
spack_root = '/' + convert_to_posix_path(spack_root)
assert(parsed.netloc + parsed.path == spack_root)
# Test that sticking the spack root at the end of a posix path resolves
# correctly.
if sys.platform != "win32":
parsed = url_util.parse('/a/b/c/$spack')
assert(parsed.scheme == 'file')
assert(parsed.netloc == '')
expected = os.path.abspath(os.path.join(
'/', 'a', 'b', 'c', './' + spack_root))
assert(parsed.path == expected)
def test_url_local_file_path():
spack_root = spack.paths.spack_root
sep = os.path.sep
lfp = url_util.local_file_path('/a/b/c.txt')
assert(lfp == '/a/b/c.txt')
assert(lfp == sep + os.path.join('a', 'b', 'c.txt'))
lfp = url_util.local_file_path('file:///a/b/c.txt')
assert(lfp == '/a/b/c.txt')
assert(lfp == sep + os.path.join('a', 'b', 'c.txt'))
if sys.platform != "win32":
if is_windows:
lfp = url_util.local_file_path('file://a/b/c.txt')
expected = os.path.abspath(os.path.join('a', 'b', 'c.txt'))
assert(lfp == expected)
lfp = url_util.local_file_path('$spack/a/b/c.txt')
lfp = url_util.local_file_path('file://$spack/a/b/c.txt')
expected = os.path.abspath(os.path.join(spack_root, 'a', 'b', 'c.txt'))
assert(lfp == expected)
if sys.platform != "win32":
if is_windows:
lfp = url_util.local_file_path('file:///$spack/a/b/c.txt')
expected = os.path.abspath(os.path.join(spack_root, 'a', 'b', 'c.txt'))
assert(lfp == expected)
@ -285,7 +285,7 @@ def test_url_join_absolute_paths():
# ...to work out what resource it points to)
if sys.platform == "win32":
cwd.replace('\\', '/')
convert_to_posix_path(cwd)
cwd = '/' + cwd
# So, even though parse() assumes "file://" URL, the scheme is still

View file

@ -18,9 +18,10 @@
import spack.util.spack_json as sjson
import spack.verify
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason='Tests fail on Win')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_link_manifest_entry(tmpdir):
# Test that symlinks are properly checked against the manifest.
# Test that the appropriate errors are generated when the check fails.
@ -120,8 +121,6 @@ def test_file_manifest_entry(tmpdir):
assert sorted(results.errors[file]) == sorted(expected)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_check_chmod_manifest_entry(tmpdir):
# Check that the verification properly identifies errors for files whose
# permissions have been modified.
@ -195,8 +194,6 @@ def test_check_prefix_manifest(tmpdir):
assert results.errors[spec.prefix] == ['manifest corrupted']
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_single_file_verification(tmpdir):
# Test the API to verify a single file, including finding the package
# to which it belongs

View file

@ -28,8 +28,13 @@
import spack.util.spack_json as sjson
from spack.util.path import path_to_os_path, system_path_filter
system_paths = ['/', '/usr', '/usr/local']
suffixes = ['bin', 'bin64', 'include', 'lib', 'lib64']
is_windows = sys.platform == 'win32'
system_paths = ['/', '/usr', '/usr/local'] if \
not is_windows else ['C:\\', 'C:\\Program Files',
'C:\\Program Files (x86)', 'C:\\Users',
'C:\\ProgramData']
suffixes = ['bin', 'bin64', 'include', 'lib', 'lib64'] if not is_windows else []
system_dirs = [os.path.join(p, s) for s in suffixes for p in system_paths] + \
system_paths

View file

@ -14,7 +14,7 @@
import llnl.util.tty as tty
import spack.error
from spack.util.path import Path, marshall_path, path_to_os_path, system_path_filter
from spack.util.path import Path, format_os_path, path_to_os_path, system_path_filter
__all__ = ['Executable', 'which', 'ProcessError']
@ -24,7 +24,7 @@ class Executable(object):
def __init__(self, name):
# necesary here for the shlex call to succeed
name = marshall_path(name, mode=Path.unix)
name = format_os_path(name, mode=Path.unix)
self.exe = shlex.split(str(name))
# filter back to platform dependent path
self.exe = path_to_os_path(*self.exe)
@ -82,7 +82,6 @@ def path(self):
"""
return self.exe[0]
# needs a small fixup to better handle URLS and the like
def __call__(self, *args, **kwargs):
"""Run this executable in a subprocess.

View file

@ -170,7 +170,7 @@ def remove(self, key):
os.unlink(self.cache_path(key))
finally:
lock.release_write()
os.unlink(self._lock_path(key))
lock.cleanup()
class CacheError(SpackError):

View file

@ -45,6 +45,10 @@ def _debug(self, *args):
if self._enable:
super(Lock, self)._debug(*args)
def cleanup(self, *args):
if self._enable:
super(Lock, self).cleanup(*args)
def check_lock_safety(path):
"""Do some extra checks to ensure disabling locks is safe.

View file

@ -127,7 +127,7 @@ def parallel_map(func, arguments, max_processes=None, debug=False):
RuntimeError: if any error occurred in the worker processes
"""
task_wrapper = Task(func)
if sys.platform != 'darwin':
if sys.platform != 'darwin' and sys.platform != 'win32':
with pool(processes=num_processes(max_processes=max_processes)) as p:
results = p.map(task_wrapper, arguments)
else:

View file

@ -68,9 +68,13 @@ def is_path_url(path):
return bool(url_tuple.scheme) and len(url_tuple.scheme) > 1
def win_exe_ext():
return '.exe'
def path_to_os_path(*pths):
"""
Takes an arbitrary number of postional parameters
Takes an arbitrary number of positional parameters
converts each arguemnt of type string to use a normalized
filepath separator, and returns a list of all values
"""
@ -78,7 +82,7 @@ def path_to_os_path(*pths):
for pth in pths:
if type(pth) is str and\
not is_path_url(pth):
pth = marshall_path(pth, mode=Path.platform_path)
pth = convert_to_platform_path(pth)
ret_pths.append(pth)
return ret_pths
@ -89,7 +93,7 @@ def system_path_filter(_func=None, arg_slice=None):
Optional slicing range can be specified to select specific arguments
This decorator takes all (or a slice) of a method's positional arguments
and normalizes useage of filepath separators on a per platform basis.
and normalizes usage of filepath separators on a per platform basis.
Note: **kwargs, urls, and any type that is not a string are ignored
so in such cases where path normalization is required, that should be
@ -121,15 +125,18 @@ def path_filter_caller(*args, **kwargs):
def get_system_path_max():
# Choose a conservative default
sys_max_path_length = 256
try:
path_max_proc = subprocess.Popen(['getconf', 'PATH_MAX', '/'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
proc_output = str(path_max_proc.communicate()[0].decode())
sys_max_path_length = int(proc_output)
except (ValueError, subprocess.CalledProcessError, OSError):
tty.msg('Unable to find system max path length, using: {0}'.format(
sys_max_path_length))
if is_windows:
sys_max_path_length = 260
else:
try:
path_max_proc = subprocess.Popen(['getconf', 'PATH_MAX', '/'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
proc_output = str(path_max_proc.communicate()[0].decode())
sys_max_path_length = int(proc_output)
except (ValueError, subprocess.CalledProcessError, OSError):
tty.msg('Unable to find system max path length, using: {0}'.format(
sys_max_path_length))
return sys_max_path_length
@ -148,18 +155,21 @@ class Path:
else unix
def marshall_path(path, mode=Path.unix):
def format_os_path(path, mode=Path.unix):
"""
Format path to use consistent, platform specific
separators.
separators. Absolute paths are converted between
drive letters and a prepended '/' as per platform
requirement.
Parameters:
path (str): the path to be normalized, must be a string
or expose the replace method.
mode (Path): the path filesperator style to normalize the
passed path to. Default is unix style, i.e. '/'
"""
if not path:
return path
if mode == Path.windows:
path = path.replace('/', '\\')
else:
@ -168,11 +178,15 @@ def marshall_path(path, mode=Path.unix):
def convert_to_posix_path(path):
return path.replace('\\', '/')
return format_os_path(path, mode=Path.unix)
def convert_to_windows_path(path):
return path.replace('/', '\\')
return format_os_path(path, mode=Path.windows)
def convert_to_platform_path(path):
return format_os_path(path, mode=Path.platform_path)
def substitute_config_variables(path):

View file

@ -8,7 +8,6 @@
"""
import itertools
import ntpath
import posixpath
import re
import sys
@ -16,7 +15,13 @@
import six.moves.urllib.parse as urllib_parse
from six import string_types
import spack.util.path
from spack.util.path import (
canonicalize_path,
convert_to_platform_path,
convert_to_posix_path,
)
is_windows = sys.platform == 'win32'
def _split_all(path):
@ -49,13 +54,11 @@ def local_file_path(url):
url = parse(url)
if url.scheme == 'file':
is_windows_path = (len(url.netloc) == 2 and
url.netloc[1] == ':' and
'A' <= url.netloc[0] and
url.netloc[0] <= 'Z')
if is_windows_path:
return ntpath.abspath(ntpath.join(url.netloc, '\\', url.path))
if is_windows:
pth = convert_to_platform_path(url.netloc + url.path)
if re.search(r'^\\[A-Za-z]:', pth):
pth = pth.lstrip('\\')
return pth
return url.path
return None
@ -70,7 +73,11 @@ def parse(url, scheme='file'):
Otherwise, the returned value is the same as urllib's urlparse() with
allow_fragments=False.
"""
# guarantee a value passed in is of proper url format. Guarantee
# allows for easier string manipulation accross platforms
if isinstance(url, string_types):
require_url_format(url)
url = escape_file_url(url)
url_obj = (
urllib_parse.urlparse(url, scheme=scheme, allow_fragments=False)
if isinstance(url, string_types) else url)
@ -79,51 +86,25 @@ def parse(url, scheme='file'):
scheme = (scheme or 'file').lower()
# This is the first way that a windows path can be parsed.
# (The user leaves out the file:// scheme.)
# examples:
# C:\\a\\b\\c
# X:/a/b/c
is_windows_path = (len(scheme) == 1 and 'a' <= scheme and scheme <= 'z')
if is_windows_path:
netloc = scheme.upper() + ':'
scheme = 'file'
if scheme == 'file':
# If the above windows path case did not hold, check the second case.
if not is_windows_path:
# This is the other way that a windows path can be parsed.
# (The user explicitly provides the file:// scheme.)
# examples:
# file://C:\\a\\b\\c
# file://X:/a/b/c
is_windows_path = (len(netloc) == 2 and
netloc[1] == ':' and
(('A' <= netloc[0] and netloc[0] <= 'Z') or
('a' <= netloc[0] and netloc[0] <= 'z')))
if is_windows_path:
netloc = netloc[0].upper() + ':'
path = spack.util.path.canonicalize_path(netloc + path)
path = re.sub(r'\\', '/', path)
# (The user explicitly provides the file:// scheme.)
# examples:
# file://C:\\a\\b\\c
# file://X:/a/b/c
path = canonicalize_path(netloc + path)
path = re.sub(r'^/+', '/', path)
netloc = ''
if not is_windows_path:
netloc = ''
# If canonicalize_path() returns a path with a drive letter (e.g.: on
# windows), we need to pop that part off from the head of the string.
# We also need to set netloc == that part to handle the case of a local
# file path being passed. (e.g.: file://../a/b/c)
update_netloc = (len(path) >= 2 and
path[1] == ':' and
(('A' <= path[0] and path[0] <= 'Z') or
('a' <= path[0] and path[0] <= 'z')))
if update_netloc:
netloc, path = path[:2], path[2:]
drive_ltr_lst = re.findall(r'[A-Za-z]:\\', path)
is_win_path = bool(drive_ltr_lst)
if is_windows and is_win_path:
drive_ltr = drive_ltr_lst[0].strip('\\')
path = re.sub(r'[\\]*' + drive_ltr, '', path)
netloc = '/' + drive_ltr.strip('\\')
if sys.platform == "win32":
path = path.replace('\\', '/')
path = convert_to_posix_path(path)
return urllib_parse.ParseResult(scheme=scheme,
netloc=netloc,
@ -199,9 +180,11 @@ def join(base_url, path, *extra, **kwargs):
'file:///opt/spack'
"""
paths = [
(x.replace('\\', '/') if isinstance(x, string_types)
else x.geturl().replace('\\', '/'))
(x) if isinstance(x, string_types)
else x.geturl()
for x in itertools.chain((base_url, path), extra)]
paths = [convert_to_posix_path(x) for x in paths]
n = len(paths)
last_abs_component = None
scheme = ''
@ -296,7 +279,7 @@ def _join(base_url, path, *extra, **kwargs):
base_path = posixpath.join('', *path_tokens)
if sys.platform == "win32":
base_path = base_path.replace('\\', '/')
base_path = convert_to_posix_path(base_path)
return format(urllib_parse.ParseResult(scheme=scheme,
netloc=netloc,
@ -357,3 +340,16 @@ def parse_git_url(url):
raise ValueError("bad port in git url: %s" % url)
return (scheme, user, hostname, port, path)
def require_url_format(url):
ut = re.search(r'^(file://|http://|https://|ftp://|s3://|/)', url)
assert ut is not None
def escape_file_url(url):
drive_ltr = re.findall(r'[A-Za-z]:\\', url)
if is_windows and drive_ltr:
url = url.replace(drive_ltr[0], '/' + drive_ltr[0])
return url

View file

@ -32,6 +32,7 @@
import spack.util.s3 as s3_util
import spack.util.url as url_util
from spack.util.compression import ALLOWED_ARCHIVE_TYPES
from spack.util.path import convert_to_posix_path
if sys.version_info < (3, 0):
# Python 2 had these in the HTMLParser package.
@ -114,7 +115,7 @@ def read_from_url(url, accept_content_type=None):
url_scheme = url.scheme
url = url_util.format(url)
if sys.platform == "win32" and url_scheme == "file":
url = url.replace("\\", "/")
url = convert_to_posix_path(url)
req = Request(url)
content_type = None
@ -652,7 +653,7 @@ def find_versions_of_archive(
versions = {}
matched = set()
for url in archive_urls + sorted(links):
url = url.replace("\\", "/")
url = convert_to_posix_path(url)
if any(re.search(r, url) for r in regexes):
try:
ver = spack.url.parse_version(url)

View file

@ -94,6 +94,8 @@ def install(self, spec, prefix):
# check that which('cmake') returns the right one.
cmake = which('cmake')
print(cmake)
print(cmake.exe)
check(cmake.exe[0].startswith(spec['cmake'].prefix.bin),
"Wrong cmake was in environment: %s" % cmake)

View file

@ -4,9 +4,12 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import sys
from spack import *
is_windows = sys.platform == 'win32'
def check(condition, msg):
"""Raise an install error if condition is False."""
@ -43,7 +46,7 @@ def install(self, spec, prefix):
check(os.environ['for_install'] == 'for_install',
"Couldn't read env var set in compile envieonmnt")
cmake_exe = join_path(prefix.bin, 'cmake')
cmake_exe_ext = ".exe" if is_windows else ''
cmake_exe = join_path(prefix.bin, 'cmake{}'.format(cmake_exe_ext))
touch(cmake_exe)
set_executable(cmake_exe)

View file

@ -20,11 +20,11 @@ def determine_spec_details(cls, prefix, exes_in_prefix):
exe_to_path = dict(
(os.path.basename(p), p) for p in exes_in_prefix
)
if 'find-externals1-exe' not in exe_to_path:
return None
exes = [x for x in exe_to_path.keys() if 'find-externals1-exe' in x]
if not exes:
return
exe = spack.util.executable.Executable(
exe_to_path['find-externals1-exe'])
exe_to_path[exes[0]])
output = exe('--version', output=str)
if output:
match = re.search(r'find-externals1.*version\s+(\S+)', output)

View file

@ -2,7 +2,6 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack import *
@ -15,6 +14,4 @@ class TrivialInstallTestPackage(Package):
version('1.0', '0123456789abcdef0123456789abcdef')
def install(self, spec, prefix):
configure('--prefix=%s' % prefix)
make()
make('install')
touch(join_path(prefix, 'an_installation_file'))

View file

@ -5,7 +5,6 @@
import os
import re
import sys
import llnl.util.tty as tty
@ -98,8 +97,6 @@ class Openssl(Package): # Uses Fake Autotools, should subclass Package
depends_on('perl@5.14.0:', type=('build', 'test'))
depends_on('ca-certificates-mozilla', type=('build', 'run'), when='certs=mozilla')
conflicts('+dynamic', when=sys.platform != 'win32')
@classmethod
def determine_version(cls, exe):
output = Executable(exe)('version', output=str, error=str)
@ -141,39 +138,32 @@ def install(self, spec, prefix):
options.append('-D__STDC_NO_ATOMICS__')
# Make a flag for shared library builds
shared_flag = ''
if spec.satisfies('~shared'):
shared_flag = 'no-shared'
def configure_args():
base_args = ['--prefix=%s' % prefix,
'--openssldir=%s'
% join_path(prefix, 'etc', 'openssl')]
if spec.satisfies('platform=windows'):
base_args.extend([
'CC=%s' % os.environ.get('CC'),
'CXX=%s' % os.environ.get('CXX'),
'%s' % shared_flag,
'VC-WIN64A',
])
base_args.insert(0, 'Configure')
else:
base_args.extend(
[
'-I{0}'.format(self.spec['zlib'].prefix.include),
'-L{0}'.format(self.spec['zlib'].prefix.lib)
]
)
base_args.extend(options)
return base_args
base_args = ['--prefix=%s' % prefix,
'--openssldir=%s'
% join_path(prefix, 'etc', 'openssl')]
if spec.satisfies('platform=windows'):
base_args.extend([
'CC=%s' % os.environ.get('CC'),
'CXX=%s' % os.environ.get('CXX'),
'VC-WIN64A',
])
if spec.satisfies('~shared'):
base_args.append('no-shared')
else:
base_args.extend(
[
'-I{0}'.format(self.spec['zlib'].prefix.include),
'-L{0}'.format(self.spec['zlib'].prefix.lib)
]
)
base_args.extend(options)
# On Windows, we use perl for configuration and build through MSVC
# nmake.
if spec.satisfies('platform=windows'):
config = Executable('perl')
Executable('perl')('Configure', *base_args)
else:
config = Executable('./config')
Executable('./config')(*base_args)
config(*configure_args())
# Remove non-standard compiler options if present. These options are
# present e.g. on Darwin. They are non-standard, i.e. most compilers
# (e.g. gcc) will not accept them.
@ -183,10 +173,6 @@ def configure_args():
# This variant only makes sense for Windows
if spec.satisfies('platform=windows'):
filter_file(r'MT', 'MD', 'makefile')
else:
tty.warn("Dynamic runtime builds are only available for "
"Windows operating systems. Please disable "
"+dynamic to suppress this warning.")
if spec.satisfies('platform=windows'):
host_make = nmake

View file

@ -4,17 +4,16 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import glob
import inspect
import json
import os
import platform
import re
import subprocess
import sys
from distutils.dir_util import copy_tree
from shutil import copy
import llnl.util.tty as tty
from llnl.util.filesystem import get_filetype, path_contains_subdirectory
from llnl.util.filesystem import copy_tree, get_filetype, path_contains_subdirectory
from llnl.util.lang import match_predicate
from spack import *
@ -46,7 +45,6 @@ class Python(Package):
version('3.10.0', sha256='c4e0cbad57c90690cb813fb4663ef670b4d0f587d8171e2c42bd4c9245bd2758')
version('3.9.10', sha256='1aa9c0702edbae8f6a2c95f70a49da8420aaa76b7889d3419c186bfc8c0e571e', preferred=True)
version('3.9.9', sha256='2cc7b67c1f3f66c571acc42479cdf691d8ed6b47bee12c9b68430413a17a44ea')
version('3.9.9', sha256='2cc7b67c1f3f66c571acc42479cdf691d8ed6b47bee12c9b68430413a17a44ea')
version('3.9.8', sha256='7447fb8bb270942d620dd24faa7814b1383b61fa99029a240025fd81c1db8283')
version('3.9.7', sha256='a838d3f9360d157040142b715db34f0218e535333696a5569dc6f854604eb9d1')
version('3.9.6', sha256='d0a35182e19e416fc8eae25a3dcd4d02d4997333e4ad1f2eee6010aadc3fe866')
@ -226,7 +224,6 @@ class Python(Package):
patch('python-3.7.4+-distutils-C++.patch', when='@3.7.4:')
patch('python-3.7.4+-distutils-C++-testsuite.patch', when='@3.7.4:')
patch('cpython-windows-externals.patch', when='@:3.9.6 platform=windows')
patch('tkinter.patch', when='@:2.8,3.3:3.7 platform=darwin')
# Patch the setup script to deny that tcl/x11 exists rather than allowing
# autodetection of (possibly broken) system components
@ -680,7 +677,7 @@ def build(self, spec, prefix):
# See https://autotools.io/automake/silent.html
params = ['V=1']
params += self.build_targets
inspect.getmodule(self).make(*params)
make(*params)
def install(self, spec, prefix):
"""Makes the install targets specified by
@ -690,7 +687,7 @@ def install(self, spec, prefix):
if is_windows:
self.win_installer(prefix)
else:
inspect.getmodule(self).make(*self.install_targets)
make(*self.install_targets)
@run_after('install')
def filter_compilers(self):
@ -909,7 +906,6 @@ def config_vars(self):
Returns:
dict: variable definitions
"""
cmd = """
import json
from sysconfig import (

Some files were not shown because too many files have changed in this diff Show more