summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Parent <john.parent@kitware.com>2022-03-16 16:41:34 -0400
committerPeter Scheibel <scheibel1@llnl.gov>2022-03-17 09:01:01 -0700
commit4aee27816e7101753aeb392e868096236a26d84d (patch)
tree2a6099f9b5305997e71e397aa2fae7f624786b90
parente63b4f752a73a67d24802a21bdf4c8a931216d2e (diff)
downloadspack-4aee27816e7101753aeb392e868096236a26d84d.tar.gz
spack-4aee27816e7101753aeb392e868096236a26d84d.tar.bz2
spack-4aee27816e7101753aeb392e868096236a26d84d.tar.xz
spack-4aee27816e7101753aeb392e868096236a26d84d.zip
Windows Support: Testing Suite integration
Broaden support for execution of the test suite on Windows. General bug and review fixups
-rw-r--r--.github/workflows/windows_python.yml11
-rw-r--r--.gitignore5
-rw-r--r--bin/spack_cmd.bat1
-rw-r--r--lib/spack/docs/getting_started.rst40
-rw-r--r--lib/spack/external/ctest_log_parser.py9
-rw-r--r--lib/spack/external/macholib/util.py4
-rw-r--r--lib/spack/external/pytest-fallback/py/_path/local.py8
-rw-r--r--lib/spack/llnl/util/filesystem.py18
-rw-r--r--lib/spack/llnl/util/lock.py7
-rw-r--r--lib/spack/llnl/util/tty/__init__.py4
-rw-r--r--lib/spack/llnl/util/tty/log.py45
-rw-r--r--lib/spack/spack/build_systems/cmake.py3
-rw-r--r--lib/spack/spack/cmd/create.py10
-rw-r--r--lib/spack/spack/cmd/make_installer.py5
-rw-r--r--lib/spack/spack/compilers/msvc.py14
-rw-r--r--lib/spack/spack/detection/path.py9
-rw-r--r--lib/spack/spack/environment/environment.py7
-rw-r--r--lib/spack/spack/fetch_strategy.py1
-rw-r--r--lib/spack/spack/hooks/sbang.py2
-rwxr-xr-xlib/spack/spack/operating_systems/windows_os.py5
-rw-r--r--lib/spack/spack/package.py42
-rw-r--r--lib/spack/spack/parse.py1
-rw-r--r--lib/spack/spack/paths.py9
-rwxr-xr-xlib/spack/spack/platforms/windows.py2
-rw-r--r--lib/spack/spack/repo.py3
-rw-r--r--lib/spack/spack/spec.py12
-rw-r--r--lib/spack/spack/test/architecture.py5
-rw-r--r--lib/spack/spack/test/build_distribution.py9
-rw-r--r--lib/spack/spack/test/build_environment.py61
-rw-r--r--lib/spack/spack/test/buildrequest.py7
-rw-r--r--lib/spack/spack/test/cache_fetch.py13
-rw-r--r--lib/spack/spack/test/cmd/common/arguments.py7
-rw-r--r--lib/spack/spack/test/cmd/compiler.py3
-rw-r--r--lib/spack/spack/test/cmd/concretize.py4
-rw-r--r--lib/spack/spack/test/cmd/config.py6
-rw-r--r--lib/spack/spack/test/cmd/env.py160
-rw-r--r--lib/spack/spack/test/cmd/external.py75
-rw-r--r--lib/spack/spack/test/cmd/fetch.py9
-rw-r--r--lib/spack/spack/test/cmd/info.py6
-rw-r--r--lib/spack/spack/test/cmd/is_git_repo.py4
-rw-r--r--lib/spack/spack/test/cmd/list.py10
-rw-r--r--lib/spack/spack/test/cmd/mirror.py9
-rw-r--r--lib/spack/spack/test/cmd/pkg.py13
-rw-r--r--lib/spack/spack/test/cmd/providers.py5
-rw-r--r--lib/spack/spack/test/cmd/resource.py35
-rw-r--r--lib/spack/spack/test/cmd/test.py2
-rw-r--r--lib/spack/spack/test/cmd/uninstall.py3
-rw-r--r--lib/spack/spack/test/cmd_extensions.py8
-rw-r--r--lib/spack/spack/test/concretize.py21
-rw-r--r--lib/spack/spack/test/concretize_preferences.py1
-rw-r--r--lib/spack/spack/test/config.py153
-rw-r--r--lib/spack/spack/test/conftest.py27
-rw-r--r--lib/spack/spack/test/database.py12
-rw-r--r--lib/spack/spack/test/directory_layout.py12
-rw-r--r--lib/spack/spack/test/environment_modifications.py9
-rw-r--r--lib/spack/spack/test/git_fetch.py5
-rw-r--r--lib/spack/spack/test/install.py49
-rw-r--r--lib/spack/spack/test/installer.py100
-rw-r--r--lib/spack/spack/test/link_paths.py80
-rw-r--r--lib/spack/spack/test/llnl/util/filesystem.py19
-rw-r--r--lib/spack/spack/test/llnl/util/lock.py4
-rw-r--r--lib/spack/spack/test/llnl/util/tty/log.py2
-rw-r--r--lib/spack/spack/test/main.py2
-rw-r--r--lib/spack/spack/test/make_executable.py3
-rw-r--r--lib/spack/spack/test/module_parsing.py8
-rw-r--r--lib/spack/spack/test/optional_deps.py4
-rw-r--r--lib/spack/spack/test/packages.py15
-rw-r--r--lib/spack/spack/test/packaging.py13
-rw-r--r--lib/spack/spack/test/patch.py48
-rw-r--r--lib/spack/spack/test/permissions.py11
-rw-r--r--lib/spack/spack/test/relocate.py7
-rw-r--r--lib/spack/spack/test/sbang.py2
-rw-r--r--lib/spack/spack/test/spec_dag.py5
-rw-r--r--lib/spack/spack/test/spec_semantics.py38
-rw-r--r--lib/spack/spack/test/spec_syntax.py1
-rw-r--r--lib/spack/spack/test/spec_yaml.py1
-rw-r--r--lib/spack/spack/test/test_activations.py12
-rw-r--r--lib/spack/spack/test/test_suite.py10
-rw-r--r--lib/spack/spack/test/url_fetch.py1
-rw-r--r--lib/spack/spack/test/util/editor.py13
-rw-r--r--lib/spack/spack/test/util/environment.py34
-rw-r--r--lib/spack/spack/test/util/executable.py19
-rw-r--r--lib/spack/spack/test/util/file_cache.py3
-rw-r--r--lib/spack/spack/test/util/path.py16
-rw-r--r--lib/spack/spack/test/util/util_url.py60
-rw-r--r--lib/spack/spack/test/verification.py9
-rw-r--r--lib/spack/spack/util/environment.py9
-rw-r--r--lib/spack/spack/util/executable.py5
-rw-r--r--lib/spack/spack/util/file_cache.py2
-rw-r--r--lib/spack/spack/util/lock.py4
-rw-r--r--lib/spack/spack/util/parallel.py2
-rw-r--r--lib/spack/spack/util/path.py48
-rw-r--r--lib/spack/spack/util/url.py102
-rw-r--r--lib/spack/spack/util/web.py5
-rw-r--r--share/spack/qa/windows_test_setup.ps12
-rw-r--r--var/spack/repos/builtin.mock/packages/cmake-client/package.py2
-rw-r--r--var/spack/repos/builtin.mock/packages/cmake/package.py7
-rw-r--r--var/spack/repos/builtin.mock/packages/find-externals1/package.py8
-rw-r--r--var/spack/repos/builtin.mock/packages/trivial-install-test-package/package.py5
-rw-r--r--var/spack/repos/builtin/packages/openssl/package.py56
-rw-r--r--var/spack/repos/builtin/packages/python/package.py12
-rw-r--r--var/spack/repos/builtin/packages/wrf/package.py6
102 files changed, 770 insertions, 1065 deletions
diff --git a/.github/workflows/windows_python.yml b/.github/workflows/windows_python.yml
index 0c517eef5f..b45cd716bb 100644
--- a/.github/workflows/windows_python.yml
+++ b/.github/workflows/windows_python.yml
@@ -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:
diff --git a/.gitignore b/.gitignore
index 6a816e5531..68f83ea38d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -269,11 +269,6 @@ local.properties
# CDT-specific (C/C++ Development Tooling)
.cproject
-# VSCode files
-.vs
-.vscode
-.devcontainer
-
# CDT- autotools
.autotools
diff --git a/bin/spack_cmd.bat b/bin/spack_cmd.bat
index 839f1828da..6edc6da2c2 100644
--- a/bin/spack_cmd.bat
+++ b/bin/spack_cmd.bat
@@ -68,4 +68,5 @@ set
GOTO:EOF
:continue
+set PROMPT=[spack] %PROMPT%
%comspec% /k
diff --git a/lib/spack/docs/getting_started.rst b/lib/spack/docs/getting_started.rst
index d4121750db..32007332d5 100644
--- a/lib/spack/docs/getting_started.rst
+++ b/lib/spack/docs/getting_started.rst
@@ -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
^^^^^^^^^^^^^^^^^
diff --git a/lib/spack/external/ctest_log_parser.py b/lib/spack/external/ctest_log_parser.py
index d1c8db16c8..2b2746003a 100644
--- a/lib/spack/external/ctest_log_parser.py
+++ b/lib/spack/external/ctest_log_parser.py
@@ -71,8 +71,6 @@ from __future__ import division
import re
import math
import multiprocessing
-import sys
-import threading
import time
from contextlib import contextmanager
@@ -411,12 +409,7 @@ class CTestLogParser(object):
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()
diff --git a/lib/spack/external/macholib/util.py b/lib/spack/external/macholib/util.py
index 4eb4bd60e7..d5ab33544a 100644
--- a/lib/spack/external/macholib/util.py
+++ b/lib/spack/external/macholib/util.py
@@ -6,8 +6,6 @@ import sys
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,
diff --git a/lib/spack/external/pytest-fallback/py/_path/local.py b/lib/spack/external/pytest-fallback/py/_path/local.py
index 72ffb9f6cb..d2f16b993e 100644
--- a/lib/spack/external/pytest-fallback/py/_path/local.py
+++ b/lib/spack/external/pytest-fallback/py/_path/local.py
@@ -12,8 +12,6 @@ from stat import S_ISLNK, S_ISDIR, S_ISREG
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 @@ class PosixPath(common.PathBase):
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 @@ class PosixPath(common.PathBase):
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 @@ class LocalPath(FSBase):
except OSError:
pass
try:
- symlink(src, dest)
+ os.symlink(src, dest)
except (OSError, AttributeError, NotImplementedError):
pass
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py
index 9f46b275b2..22ca97c347 100644
--- a/lib/spack/llnl/util/filesystem.py
+++ b/lib/spack/llnl/util/filesystem.py
@@ -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):
diff --git a/lib/spack/llnl/util/lock.py b/lib/spack/llnl/util/lock.py
index 37989bac35..1ff7ceec64 100644
--- a/lib/spack/llnl/util/lock.py
+++ b/lib/spack/llnl/util/lock.py
@@ -191,6 +191,7 @@ class LockType(object):
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 @@ class Lock(object):
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 ''
diff --git a/lib/spack/llnl/util/tty/__init__.py b/lib/spack/llnl/util/tty/__init__.py
index ae7634afea..de49f3f77f 100644
--- a/lib/spack/llnl/util/tty/__init__.py
+++ b/lib/spack/llnl/util/tty/__init__.py
@@ -395,7 +395,7 @@ def terminal_size():
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])
diff --git a/lib/spack/llnl/util/tty/log.py b/lib/spack/llnl/util/tty/log.py
index 0df3cf7829..544a9a6c48 100644
--- a/lib/spack/llnl/util/tty/log.py
+++ b/lib/spack/llnl/util/tty/log.py
@@ -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 @@ class StreamWrapper:
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 @@ class StreamWrapper:
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
diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py
index 9fd2267d51..6e6b5e20b0 100644
--- a/lib/spack/spack/build_systems/cmake.py
+++ b/lib/spack/spack/build_systems/cmake.py
@@ -19,6 +19,7 @@ from llnl.util.filesystem import working_dir
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 @@ class CMakePackage(PackageBase):
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),
]
diff --git a/lib/spack/spack/cmd/create.py b/lib/spack/spack/cmd/create.py
index 1a496a9842..1281c6d9ef 100644
--- a/lib/spack/spack/cmd/create.py
+++ b/lib/spack/spack/cmd/create.py
@@ -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)
diff --git a/lib/spack/spack/cmd/make_installer.py b/lib/spack/spack/cmd/make_installer.py
index c1bced479f..761401ea37 100644
--- a/lib/spack/spack/cmd/make_installer.py
+++ b/lib/spack/spack/cmd/make_installer.py
@@ -9,6 +9,7 @@ import sys
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")
diff --git a/lib/spack/spack/compilers/msvc.py b/lib/spack/spack/compilers/msvc.py
index fe5014128e..a3c5a7c752 100644
--- a/lib/spack/spack/compilers/msvc.py
+++ b/lib/spack/spack/compilers/msvc.py
@@ -83,13 +83,13 @@ class Msvc(Compiler):
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(
diff --git a/lib/spack/spack/detection/path.py b/lib/spack/spack/detection/path.py
index 32e5f57af7..ef0bffad67 100644
--- a/lib/spack/spack/detection/path.py
+++ b/lib/spack/spack/detection/path.py
@@ -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))
diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py
index 9d6c5ba8c8..a3e35a234a 100644
--- a/lib/spack/spack/environment/environment.py
+++ b/lib/spack/spack/environment/environment.py
@@ -16,8 +16,9 @@ import six
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 @@ class ViewDescriptor(object):
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):
diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py
index 7abcea7383..94b5fab042 100644
--- a/lib/spack/spack/fetch_strategy.py
+++ b/lib/spack/spack/fetch_strategy.py
@@ -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.
diff --git a/lib/spack/spack/hooks/sbang.py b/lib/spack/spack/hooks/sbang.py
index 2793906ebd..bef30d2b76 100644
--- a/lib/spack/spack/hooks/sbang.py
+++ b/lib/spack/spack/hooks/sbang.py
@@ -30,7 +30,7 @@ else:
#: 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
diff --git a/lib/spack/spack/operating_systems/windows_os.py b/lib/spack/spack/operating_systems/windows_os.py
index 879a2b77c7..61525df887 100755
--- a/lib/spack/spack/operating_systems/windows_os.py
+++ b/lib/spack/spack/operating_systems/windows_os.py
@@ -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
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index d91c5109ae..5888416b10 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -59,6 +59,7 @@ from spack.installer import InstallError, PackageInstaller
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 @@ class DetectablePackageMeta(object):
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 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
" 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.
diff --git a/lib/spack/spack/parse.py b/lib/spack/spack/parse.py
index 2d4dce3a75..603848a3a0 100644
--- a/lib/spack/spack/parse.py
+++ b/lib/spack/spack/parse.py
@@ -13,6 +13,7 @@ from six import string_types
import spack.error
import spack.util.path as sp
+
class Token(object):
"""Represents tokens; generated from input by lexer and fed to parse()."""
diff --git a/lib/spack/spack/paths.py b/lib/spack/spack/paths.py
index 4d8747d741..b423e9e6c5 100644
--- a/lib/spack/spack/paths.py
+++ b/lib/spack/spack/paths.py
@@ -81,7 +81,8 @@ gpg_path = os.path.join(opt_path, "spack", "gpg")
# 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 @@ default_misc_cache_path = os.path.join(user_cache_path, 'cache')
# 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
diff --git a/lib/spack/spack/platforms/windows.py b/lib/spack/spack/platforms/windows.py
index 552e520193..9626b29cc8 100755
--- a/lib/spack/spack/platforms/windows.py
+++ b/lib/spack/spack/platforms/windows.py
@@ -16,8 +16,6 @@ from ._platform import Platform
class Windows(Platform):
priority = 101
- # binary_formats = ['macho']
-
def __init__(self):
super(Windows, self).__init__('windows')
diff --git a/lib/spack/spack/repo.py b/lib/spack/spack/repo.py
index e1403bd44f..904c22d9ba 100644
--- a/lib/spack/spack/repo.py
+++ b/lib/spack/spack/repo.py
@@ -330,7 +330,8 @@ class RepoIndex(object):
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 = {}
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 7feebdd4e2..b4c778ee76 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -111,6 +111,7 @@ import spack.util.crypto
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 @@ class Spec(object):
@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 @@ class SpecLexer(spack.parse.Lexer):
# 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
diff --git a/lib/spack/spack/test/architecture.py b/lib/spack/spack/test/architecture.py
index a9b168f863..18a8dbe1b6 100644
--- a/lib/spack/spack/test/architecture.py
+++ b/lib/spack/spack/test/architecture.py
@@ -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.
diff --git a/lib/spack/spack/test/build_distribution.py b/lib/spack/spack/test/build_distribution.py
index c2008ffa63..c5132a9558 100644
--- a/lib/spack/spack/test/build_distribution.py
+++ b/lib/spack/spack/test/build_distribution.py
@@ -18,6 +18,15 @@ pytestmark = pytest.mark.skipif(sys.platform == "win32",
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):
diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py
index 50241e6c9e..a816ac4ba9 100644
--- a/lib/spack/spack/test/build_environment.py
+++ b/lib/spack/spack/test/build_environment.py
@@ -24,6 +24,18 @@ from spack.build_environment import (
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_variables(config, mock_packages, monkeypatch, working_env):
@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 test_cc_not_changed_by_modules(monkeypatch, working_env):
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 test_cc_not_changed_by_modules(monkeypatch, working_env):
{'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
diff --git a/lib/spack/spack/test/buildrequest.py b/lib/spack/spack/test/buildrequest.py
index 86c4a37d0f..a4ae76086a 100644
--- a/lib/spack/spack/test/buildrequest.py
+++ b/lib/spack/spack/test/buildrequest.py
@@ -11,9 +11,10 @@ import spack.installer as inst
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")
diff --git a/lib/spack/spack/test/cache_fetch.py b/lib/spack/spack/test/cache_fetch.py
index 44a5275868..828dd81791 100644
--- a/lib/spack/spack/test/cache_fetch.py
+++ b/lib/spack/spack/test/cache_fetch.py
@@ -4,6 +4,7 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
+import sys
import pytest
@@ -13,13 +14,17 @@ import spack.config
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:
diff --git a/lib/spack/spack/test/cmd/common/arguments.py b/lib/spack/spack/test/cmd/common/arguments.py
index 763c6880c0..5f1299a94a 100644
--- a/lib/spack/spack/test/cmd/common/arguments.py
+++ b/lib/spack/spack/test/cmd/common/arguments.py
@@ -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')
diff --git a/lib/spack/spack/test/cmd/compiler.py b/lib/spack/spack/test/cmd/compiler.py
index 26dcb7ff59..f799d96b0f 100644
--- a/lib/spack/spack/test/cmd/compiler.py
+++ b/lib/spack/spack/test/cmd/compiler.py
@@ -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
):
diff --git a/lib/spack/spack/test/cmd/concretize.py b/lib/spack/spack/test/cmd/concretize.py
index c630ebeb68..d357ccc9dc 100644
--- a/lib/spack/spack/test/cmd/concretize.py
+++ b/lib/spack/spack/test/cmd/concretize.py
@@ -3,7 +3,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import sys
import pytest
@@ -19,7 +18,6 @@ add = SpackCommand('add')
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."""
diff --git a/lib/spack/spack/test/cmd/config.py b/lib/spack/spack/test/cmd/config.py
index a76ec07ca5..e8dc80c6da 100644
--- a/lib/spack/spack/test/cmd/config.py
+++ b/lib/spack/spack/test/cmd/config.py
@@ -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')
diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py
index ae47aada02..868eb8ec45 100644
--- a/lib/spack/spack/test/cmd/env.py
+++ b/lib/spack/spack/test/cmd/env.py
@@ -27,10 +27,12 @@ from spack.stage import stage_prefix
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 @@ stage = SpackCommand('stage')
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 test_env_modifications_error_on_activate(
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ spack:
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 @@ packages:
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 @@ packages:
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 @@ packages:
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 @@ packages:
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 @@ env:
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 test_indirect_build_dep():
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 test_store_different_build_deps():
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ env:
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 @@ env:
(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 @@ env:
(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 @@ env:
(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 @@ env:
(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 @@ env:
(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 @@ spack:
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 @@ env:
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 @@ env:
(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 @@ env:
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 @@ env:
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 @@ env:
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 @@ spack:
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 @@ spack:
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 @@ spack:
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:
diff --git a/lib/spack/spack/test/cmd/external.py b/lib/spack/spack/test/cmd/external.py
index 3d7554c2eb..3a3c4face3 100644
--- a/lib/spack/spack/test/cmd/external.py
+++ b/lib/spack/spack/test/cmd/external.py
@@ -14,6 +14,8 @@ import spack.detection.path
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 executables_found(monkeypatch):
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 test_overriding_prefix(mock_executable, mutable_config, monkeypatch):
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'),
diff --git a/lib/spack/spack/test/cmd/fetch.py b/lib/spack/spack/test/cmd/fetch.py
index 323fd06cd2..da56fbd528 100644
--- a/lib/spack/spack/test/cmd/fetch.py
+++ b/lib/spack/spack/test/cmd/fetch.py
@@ -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
diff --git a/lib/spack/spack/test/cmd/info.py b/lib/spack/spack/test/cmd/info.py
index dada99d1dd..9d240628b4 100644
--- a/lib/spack/spack/test/cmd/info.py
+++ b/lib/spack/spack/test/cmd/info.py
@@ -13,6 +13,9 @@ from spack.main import SpackCommand
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 mock_print(monkeypatch, info_lines):
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',
diff --git a/lib/spack/spack/test/cmd/is_git_repo.py b/lib/spack/spack/test/cmd/is_git_repo.py
index 7cb0dc2694..025d04fff0 100644
--- a/lib/spack/spack/test/cmd/is_git_repo.py
+++ b/lib/spack/spack/test/cmd/is_git_repo.py
@@ -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])
diff --git a/lib/spack/spack/test/cmd/list.py b/lib/spack/spack/test/cmd/list.py
index 42253eb354..fe86a7f3b7 100644
--- a/lib/spack/spack/test/cmd/list.py
+++ b/lib/spack/spack/test/cmd/list.py
@@ -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
diff --git a/lib/spack/spack/test/cmd/mirror.py b/lib/spack/spack/test/cmd/mirror.py
index 317febdd7b..0027b4ae2b 100644
--- a/lib/spack/spack/test/cmd/mirror.py
+++ b/lib/spack/spack/test/cmd/mirror.py
@@ -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):
diff --git a/lib/spack/spack/test/cmd/pkg.py b/lib/spack/spack/test/cmd/pkg.py
index 1924fbccb8..7f681ad9b9 100644
--- a/lib/spack/spack/test/cmd/pkg.py
+++ b/lib/spack/spack/test/cmd/pkg.py
@@ -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 == []
diff --git a/lib/spack/spack/test/cmd/providers.py b/lib/spack/spack/test/cmd/providers.py
index cc6b3068ed..44d56ca1a1 100644
--- a/lib/spack/spack/test/cmd/providers.py
+++ b/lib/spack/spack/test/cmd/providers.py
@@ -12,8 +12,10 @@ from spack.main import SpackCommand
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',
diff --git a/lib/spack/spack/test/cmd/resource.py b/lib/spack/spack/test/cmd/resource.py
index 04e7e0e325..64a79fd601 100644
--- a/lib/spack/spack/test/cmd/resource.py
+++ b/lib/spack/spack/test/cmd/resource.py
@@ -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 @@ mock_hashes = [
'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')
-
- assert out.startswith('c45c1564f70def3fc1a6e22139f62cb21cd190cc3a7dbe6f4120fa59ce33dcb8')
- assert 'repos/builtin.mock/packages/patch-a-dependency/libelf.patch' in out
+ out = resource('show', test_hash)
+
+ 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
diff --git a/lib/spack/spack/test/cmd/test.py b/lib/spack/spack/test/cmd/test.py
index ad631db899..0f8e707376 100644
--- a/lib/spack/spack/test/cmd/test.py
+++ b/lib/spack/spack/test/cmd/test.py
@@ -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
diff --git a/lib/spack/spack/test/cmd/uninstall.py b/lib/spack/spack/test/cmd/uninstall.py
index 0ce3a260e6..857f1ae35d 100644
--- a/lib/spack/spack/test/cmd/uninstall.py
+++ b/lib/spack/spack/test/cmd/uninstall.py
@@ -13,9 +13,6 @@ from spack.main import SpackCommand, SpackCommandError
uninstall = SpackCommand('uninstall')
install = SpackCommand('install')
-# pytestmark = pytest.mark.skipif(sys.platform == "win32",
-# reason="does not run on windows")
-
class MockArgs(object):
diff --git a/lib/spack/spack/test/cmd_extensions.py b/lib/spack/spack/test/cmd_extensions.py
index d7e0538ce1..dbe79e603a 100644
--- a/lib/spack/spack/test/cmd_extensions.py
+++ b/lib/spack/spack/test/cmd_extensions.py
@@ -14,6 +14,8 @@ import spack.config
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
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 73da1ccbab..f47dc58073 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -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.spec import Spec
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 @@ class TestConcretize(object):
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 @@ class TestConcretize(object):
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 @@ class TestConcretize(object):
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 @@ class TestConcretize(object):
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 @@ class TestConcretize(object):
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()
diff --git a/lib/spack/spack/test/concretize_preferences.py b/lib/spack/spack/test/concretize_preferences.py
index 75aa3e813c..525bd0701f 100644
--- a/lib/spack/spack/test/concretize_preferences.py
+++ b/lib/spack/spack/test/concretize_preferences.py
@@ -5,7 +5,6 @@
import os
import stat
-import sys
import pytest
diff --git a/lib/spack/spack/test/config.py b/lib/spack/spack/test/config.py
index 1ab9c48eaa..a765582a2b 100644
--- a/lib/spack/spack/test/config.py
+++ b/lib/spack/spack/test/config.py
@@ -92,6 +92,13 @@ env:
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 @@ class MockEnv(object):
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'
- )
-
-
-@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'
+ 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_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,36 +477,57 @@ MAX_PATH_LEN = spack.util.path.get_system_path_max()
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'],
+])
+def test_parse_install_tree(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
+
+
+@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('/path', PAD_STRING[:5]), '/path', None]),
+ [os.path.join(os.sep + 'path', PAD_STRING[:5]), os.sep + 'path', None]),
([['config:install_tree:root', '/path/$padding:11']],
- [os.path.join('/path', PAD_STRING[:5]), '/path', None]),
+ [os.path.join(os.sep + 'path', PAD_STRING[:5]), os.sep + 'path', None]),
([['config:install_tree', '/path/${padding:11}']],
- [os.path.join('/path', PAD_STRING[:5]), '/path', None]),
+ [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', '/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]),
+ ['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(config_settings, expected, mutable_config):
+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
@@ -524,7 +541,6 @@ 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
@@ -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()
diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py
index 3d9acf4594..c946898076 100644
--- a/lib/spack/spack/test/conftest.py
+++ b/lib/spack/spack/test/conftest.py
@@ -13,6 +13,7 @@ import os
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 @@ class MockLayout(object):
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)
diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py
index a695b8d852..4278aeb4f0 100644
--- a/lib/spack/spack/test/database.py
+++ b/lib/spack/spack/test/database.py
@@ -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 test_110_no_write_with_exception_on_install(database):
# reload DB and make sure cmake was not written.
with database.read_transaction():
- # import pdb; pdb.set_trace()
-
assert database.query('cmake', installed=any) == []
diff --git a/lib/spack/spack/test/directory_layout.py b/lib/spack/spack/test/directory_layout.py
index 11bf7ed34a..7aa6a565fc 100644
--- a/lib/spack/spack/test/directory_layout.py
+++ b/lib/spack/spack/test/directory_layout.py
@@ -8,7 +8,6 @@ This test verifies that the Spack directory layout works properly.
"""
import os
import os.path
-import sys
import pytest
@@ -19,13 +18,12 @@ from spack.directory_layout import (
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')
diff --git a/lib/spack/spack/test/environment_modifications.py b/lib/spack/spack/test/environment_modifications.py
index 93e904a378..c76b08fd95 100644
--- a/lib/spack/spack/test/environment_modifications.py
+++ b/lib/spack/spack/test/environment_modifications.py
@@ -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
diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py
index af00651592..6e8993978c 100644
--- a/lib/spack/spack/test/git_fetch.py
+++ b/lib/spack/spack/test/git_fetch.py
@@ -19,6 +19,10 @@ from spack.stage import Stage
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 mock_bad_git(monkeypatch):
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')
diff --git a/lib/spack/spack/test/install.py b/lib/spack/spack/test/install.py
index 9465b5ec0e..00276b379c 100644
--- a/lib/spack/spack/test/install.py
+++ b/lib/spack/spack/test/install.py
@@ -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 @@ class MockStage(object):
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(tmpdir_factory, gen_mock_layout, install_mockery):
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'
diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py
index 053578f156..a7b0b1edd9 100644
--- a/lib/spack/spack/test/installer.py
+++ b/lib/spack/spack/test/installer.py
@@ -23,6 +23,8 @@ import spack.spec
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 test_process_binary_cache_tarball_tar(install_mockery, monkeypatch, capfd):
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 test_ensure_locked_err(install_mockery, monkeypatch, tmpdir, capsys):
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 test_packages_needed_to_bootstrap_compiler_packages(install_mockery,
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 test_dump_packages_deps_errs(install_mockery, tmpdir, monkeypatch, capsys):
# 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 test_add_bootstrap_compilers(install_mockery, monkeypatch):
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 test_install_task_add_compiler(install_mockery, monkeypatch, capfd):
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 test_cleanup_all_tasks(install_mockery, monkeypatch):
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 test_setup_install_dir_grp(install_mockery, monkeypatch, capfd):
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 test_setup_install_dir_grp(install_mockery, monkeypatch, capfd):
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 test_cleanup_failed_err(install_mockery, tmpdir, monkeypatch, capsys):
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 test_install_fail_on_interrupt(install_mockery, monkeypatch):
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 test_install_fail_single(install_mockery, monkeypatch):
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 test_install_fail_multi(install_mockery, monkeypatch):
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 test_install_lock_failures(install_mockery, monkeypatch, capfd):
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 test_install_lock_installed_requeue(install_mockery, monkeypatch, capfd):
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 test_install_read_locked_requeue(install_mockery, monkeypatch, capfd):
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'
diff --git a/lib/spack/spack/test/link_paths.py b/lib/spack/spack/test/link_paths.py
index c02d124a8c..cafb646322 100644
--- a/lib/spack/spack/test/link_paths.py
+++ b/lib/spack/spack/test/link_paths.py
@@ -3,6 +3,7 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
+import re
import sys
import pytest
@@ -11,6 +12,9 @@ import spack.paths
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',
diff --git a/lib/spack/spack/test/llnl/util/filesystem.py b/lib/spack/spack/test/llnl/util/filesystem.py
index 463ca1da5a..2bd6994754 100644
--- a/lib/spack/spack/test/llnl/util/filesystem.py
+++ b/lib/spack/spack/test/llnl/util/filesystem.py
@@ -176,21 +176,15 @@ class TestCopyTree:
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'],
diff --git a/lib/spack/spack/test/llnl/util/lock.py b/lib/spack/spack/test/llnl/util/lock.py
index 211d822a61..da8f77b2c3 100644
--- a/lib/spack/spack/test/llnl/util/lock.py
+++ b/lib/spack/spack/test/llnl/util/lock.py
@@ -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 test_poll_lock_exception(tmpdir, monkeypatch, err_num, err_msg):
lock = lk.Lock(lockfile)
touch(lockfile)
+
monkeypatch.setattr(fcntl, 'lockf', _lockf)
if err_num in [errno.EAGAIN, errno.EACCES]:
diff --git a/lib/spack/spack/test/llnl/util/tty/log.py b/lib/spack/spack/test/llnl/util/tty/log.py
index fd8c7d30da..2491a5dbe3 100644
--- a/lib/spack/spack/test/llnl/util/tty/log.py
+++ b/lib/spack/spack/test/llnl/util/tty/log.py
@@ -18,8 +18,8 @@ if TYPE_CHECKING:
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
diff --git a/lib/spack/spack/test/main.py b/lib/spack/spack/test/main.py
index 1bbe594666..9917fac6f5 100644
--- a/lib/spack/spack/test/main.py
+++ b/lib/spack/spack/test/main.py
@@ -15,7 +15,7 @@ from spack.main import get_version, main
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):
diff --git a/lib/spack/spack/test/make_executable.py b/lib/spack/spack/test/make_executable.py
index a814601176..9fcf4cc8c4 100644
--- a/lib/spack/spack/test/make_executable.py
+++ b/lib/spack/spack/test/make_executable.py
@@ -20,7 +20,8 @@ from spack.build_environment import MakeExecutable
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):
diff --git a/lib/spack/spack/test/module_parsing.py b/lib/spack/spack/test/module_parsing.py
index d20f6a2b95..2a19d39033 100644
--- a/lib/spack/spack/test/module_parsing.py
+++ b/lib/spack/spack/test/module_parsing.py
@@ -17,6 +17,9 @@ from spack.util.module_cmd import (
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 @@ test_module_lines = ['prepend-path LD_LIBRARY_PATH /path/to/lib',
'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')
diff --git a/lib/spack/spack/test/optional_deps.py b/lib/spack/spack/test/optional_deps.py
index 313903d272..84c3f2df43 100644
--- a/lib/spack/spack/test/optional_deps.py
+++ b/lib/spack/spack/test/optional_deps.py
@@ -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()
diff --git a/lib/spack/spack/test/packages.py b/lib/spack/spack/test/packages.py
index be8243fd6f..e403d85899 100644
--- a/lib/spack/spack/test/packages.py
+++ b/lib/spack/spack/test/packages.py
@@ -4,7 +4,6 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
-import sys
import pytest
@@ -64,8 +63,6 @@ class TestPackage(object):
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 @@ class TestPackage(object):
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 @@ class TestPackage(object):
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."""
diff --git a/lib/spack/spack/test/packaging.py b/lib/spack/spack/test/packaging.py
index b23df6e30d..ff68418ac4 100644
--- a/lib/spack/spack/test/packaging.py
+++ b/lib/spack/spack/test/packaging.py
@@ -40,6 +40,9 @@ from spack.relocate import (
)
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 @@ echo $PATH"""
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',
diff --git a/lib/spack/spack/test/patch.py b/lib/spack/spack/test/patch.py
index 1eaec4e7b9..0d88b93c23 100644
--- a/lib/spack/spack/test/patch.py
+++ b/lib/spack/spack/test/patch.py
@@ -19,20 +19,26 @@ import spack.util.compression
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 @@ data_path = os.path.join(spack.paths.test_path, 'data', 'patch')
@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 @@ data_path = os.path.join(spack.paths.test_path, 'data', 'patch')
'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 @@ third line
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 check_multi_dependency_patch_specs(
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.
diff --git a/lib/spack/spack/test/permissions.py b/lib/spack/spack/test/permissions.py
index 01787922ae..e2667b9b56 100644
--- a/lib/spack/spack/test/permissions.py
+++ b/lib/spack/spack/test/permissions.py
@@ -13,9 +13,10 @@ import llnl.util.filesystem as fs
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
diff --git a/lib/spack/spack/test/relocate.py b/lib/spack/spack/test/relocate.py
index ac490b5fb2..b5c0151420 100644
--- a/lib/spack/spack/test/relocate.py
+++ b/lib/spack/spack/test/relocate.py
@@ -21,6 +21,9 @@ import spack.store
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
diff --git a/lib/spack/spack/test/sbang.py b/lib/spack/spack/test/sbang.py
index ce64d0669b..2a4189e7f8 100644
--- a/lib/spack/spack/test/sbang.py
+++ b/lib/spack/spack/test/sbang.py
@@ -60,7 +60,7 @@ last_line = "last!\n"
@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):
diff --git a/lib/spack/spack/test/spec_dag.py b/lib/spack/spack/test/spec_dag.py
index 991adc5fc3..046ff7aad2 100644
--- a/lib/spack/spack/test/spec_dag.py
+++ b/lib/spack/spack/test/spec_dag.py
@@ -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.dependency import Dependency, all_deptypes, canonical_deptype
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():
diff --git a/lib/spack/spack/test/spec_semantics.py b/lib/spack/spack/test/spec_semantics.py
index 0c948c046c..fe8e07a54f 100644
--- a/lib/spack/spack/test/spec_semantics.py
+++ b/lib/spack/spack/test/spec_semantics.py
@@ -314,8 +314,6 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
# 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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
# '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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
'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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
# 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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
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 @@ class TestSpecSematics(object):
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'
diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py
index 681bf42659..48e55254f4 100644
--- a/lib/spack/spack/test/spec_syntax.py
+++ b/lib/spack/spack/test/spec_syntax.py
@@ -5,7 +5,6 @@
import itertools
import os
import shlex
-import sys
import pytest
diff --git a/lib/spack/spack/test/spec_yaml.py b/lib/spack/spack/test/spec_yaml.py
index b676653849..8aa14b9230 100644
--- a/lib/spack/spack/test/spec_yaml.py
+++ b/lib/spack/spack/test/spec_yaml.py
@@ -11,7 +11,6 @@ YAML format preserves DAG information in the spec.
import ast
import inspect
import os
-import sys
import pytest
diff --git a/lib/spack/spack/test/test_activations.py b/lib/spack/spack/test/test_activations.py
index 915b4d2081..8eadfa837b 100644
--- a/lib/spack/spack/test/test_activations.py
+++ b/lib/spack/spack/test/test_activations.py
@@ -20,6 +20,10 @@ from spack.directory_layout import DirectoryLayout
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
diff --git a/lib/spack/spack/test/test_suite.py b/lib/spack/spack/test/test_suite.py
index 419e633e9c..20d7172eea 100644
--- a/lib/spack/spack/test/test_suite.py
+++ b/lib/spack/spack/test/test_suite.py
@@ -12,9 +12,10 @@ import llnl.util.filesystem as fs
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()
diff --git a/lib/spack/spack/test/url_fetch.py b/lib/spack/spack/test/url_fetch.py
index d3155a45f0..8497fbebd7 100644
--- a/lib/spack/spack/test/url_fetch.py
+++ b/lib/spack/spack/test/url_fetch.py
@@ -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', [
diff --git a/lib/spack/spack/test/util/editor.py b/lib/spack/spack/test/util/editor.py
index f197682a97..e7c8bf2364 100644
--- a/lib/spack/spack/test/util/editor.py
+++ b/lib/spack/spack/test/util/editor.py
@@ -12,7 +12,9 @@ from llnl.util.filesystem import set_executable
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 test_editor_visual(good_exe):
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 test_editor_visual_bad(good_exe, bad_exe):
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 test_editor_no_visual(good_exe):
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 test_editor_no_visual_with_args(good_exe):
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
diff --git a/lib/spack/spack/test/util/environment.py b/lib/spack/spack/test/util/environment.py
index 3604b7871b..1e28590e80 100644
--- a/lib/spack/spack/test/util/environment.py
+++ b/lib/spack/spack/test/util/environment.py
@@ -11,6 +11,8 @@ import pytest
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)
diff --git a/lib/spack/spack/test/util/executable.py b/lib/spack/spack/test/util/executable.py
index 6a313e751f..ea9213f063 100644
--- a/lib/spack/spack/test/util/executable.py
+++ b/lib/spack/spack/test/util/executable.py
@@ -14,10 +14,16 @@ import spack
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 @@ print(u'\\xc3')
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)
diff --git a/lib/spack/spack/test/util/file_cache.py b/lib/spack/spack/test/util/file_cache.py
index 02056fd444..988e243835 100644
--- a/lib/spack/spack/test/util/file_cache.py
+++ b/lib/spack/spack/test/util/file_cache.py
@@ -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.
diff --git a/lib/spack/spack/test/util/path.py b/lib/spack/spack/test/util/path.py
index 13633195db..7d2b81e8b3 100644
--- a/lib/spack/spack/test/util/path.py
+++ b/lib/spack/spack/test/util/path.py
@@ -12,6 +12,12 @@ import llnl.util.tty as tty
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 @@ fixed_lines = [
]
-@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)
diff --git a/lib/spack/spack/test/util/util_url.py b/lib/spack/spack/test/util/util_url.py
index b0316aaf3f..8e22c99164 100644
--- a/lib/spack/spack/test/util/util_url.py
+++ b/lib/spack/spack/test/util/util_url.py
@@ -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
diff --git a/lib/spack/spack/test/verification.py b/lib/spack/spack/test/verification.py
index fbfefab1c8..ad7373a439 100644
--- a/lib/spack/spack/test/verification.py
+++ b/lib/spack/spack/test/verification.py
@@ -18,9 +18,10 @@ import spack.store
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
diff --git a/lib/spack/spack/util/environment.py b/lib/spack/spack/util/environment.py
index da91414af0..207a904073 100644
--- a/lib/spack/spack/util/environment.py
+++ b/lib/spack/spack/util/environment.py
@@ -28,8 +28,13 @@ import spack.util.executable as executable
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
diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py
index 9d8fe5f626..a278fd1f5d 100644
--- a/lib/spack/spack/util/executable.py
+++ b/lib/spack/spack/util/executable.py
@@ -14,7 +14,7 @@ from six import string_types, text_type
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 @@ class Executable(object):
"""
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.
diff --git a/lib/spack/spack/util/file_cache.py b/lib/spack/spack/util/file_cache.py
index 5f68911241..f9436ace73 100644
--- a/lib/spack/spack/util/file_cache.py
+++ b/lib/spack/spack/util/file_cache.py
@@ -170,7 +170,7 @@ class FileCache(object):
os.unlink(self.cache_path(key))
finally:
lock.release_write()
- os.unlink(self._lock_path(key))
+ lock.cleanup()
class CacheError(SpackError):
diff --git a/lib/spack/spack/util/lock.py b/lib/spack/spack/util/lock.py
index ff3e0dd14b..75d5c653b6 100644
--- a/lib/spack/spack/util/lock.py
+++ b/lib/spack/spack/util/lock.py
@@ -45,6 +45,10 @@ class Lock(llnl.util.lock.Lock): # type: ignore[no-redef]
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.
diff --git a/lib/spack/spack/util/parallel.py b/lib/spack/spack/util/parallel.py
index c64d0431f9..a931bba0c6 100644
--- a/lib/spack/spack/util/parallel.py
+++ b/lib/spack/spack/util/parallel.py
@@ -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:
diff --git a/lib/spack/spack/util/path.py b/lib/spack/spack/util/path.py
index b56ec11ede..fd51acbce7 100644
--- a/lib/spack/spack/util/path.py
+++ b/lib/spack/spack/util/path.py
@@ -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 system_path_filter(_func=None, arg_slice=None):
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):
diff --git a/lib/spack/spack/util/url.py b/lib/spack/spack/util/url.py
index 7f7554e838..d63498674b 100644
--- a/lib/spack/spack/util/url.py
+++ b/lib/spack/spack/util/url.py
@@ -8,7 +8,6 @@ Utility functions for parsing, formatting, and manipulating URLs.
"""
import itertools
-import ntpath
import posixpath
import re
import sys
@@ -16,7 +15,13 @@ import sys
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)
- path = re.sub(r'^/+', '/', path)
- if not is_windows_path:
- netloc = ''
+ # (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 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
diff --git a/lib/spack/spack/util/web.py b/lib/spack/spack/util/web.py
index b13bde2e98..d3a9d57607 100644
--- a/lib/spack/spack/util/web.py
+++ b/lib/spack/spack/util/web.py
@@ -32,6 +32,7 @@ import spack.util.gcs as gcs_util
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)
diff --git a/share/spack/qa/windows_test_setup.ps1 b/share/spack/qa/windows_test_setup.ps1
index eebd0b7480..a7e3c66ea3 100644
--- a/share/spack/qa/windows_test_setup.ps1
+++ b/share/spack/qa/windows_test_setup.ps1
@@ -8,4 +8,4 @@ foreach {
$v = $_.split("=")
[Environment]::SetEnvironmentVariable($v[0], $v[1])
}
-} \ No newline at end of file
+}
diff --git a/var/spack/repos/builtin.mock/packages/cmake-client/package.py b/var/spack/repos/builtin.mock/packages/cmake-client/package.py
index 09b445fd49..0e8d1a3d9b 100644
--- a/var/spack/repos/builtin.mock/packages/cmake-client/package.py
+++ b/var/spack/repos/builtin.mock/packages/cmake-client/package.py
@@ -94,6 +94,8 @@ class CmakeClient(CMakePackage):
# 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)
diff --git a/var/spack/repos/builtin.mock/packages/cmake/package.py b/var/spack/repos/builtin.mock/packages/cmake/package.py
index e5dd7057d1..8c19ca8a6e 100644
--- a/var/spack/repos/builtin.mock/packages/cmake/package.py
+++ b/var/spack/repos/builtin.mock/packages/cmake/package.py
@@ -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 @@ class Cmake(Package):
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)
diff --git a/var/spack/repos/builtin.mock/packages/find-externals1/package.py b/var/spack/repos/builtin.mock/packages/find-externals1/package.py
index 9200668d7c..c85598e891 100644
--- a/var/spack/repos/builtin.mock/packages/find-externals1/package.py
+++ b/var/spack/repos/builtin.mock/packages/find-externals1/package.py
@@ -20,11 +20,11 @@ class FindExternals1(AutotoolsPackage):
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)
diff --git a/var/spack/repos/builtin.mock/packages/trivial-install-test-package/package.py b/var/spack/repos/builtin.mock/packages/trivial-install-test-package/package.py
index 748034baca..467a1631fa 100644
--- a/var/spack/repos/builtin.mock/packages/trivial-install-test-package/package.py
+++ b/var/spack/repos/builtin.mock/packages/trivial-install-test-package/package.py
@@ -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'))
diff --git a/var/spack/repos/builtin/packages/openssl/package.py b/var/spack/repos/builtin/packages/openssl/package.py
index 94c1dccf4c..55b949ea9a 100644
--- a/var/spack/repos/builtin/packages/openssl/package.py
+++ b/var/spack/repos/builtin/packages/openssl/package.py
@@ -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 @@ class Openssl(Package): # Uses Fake Autotools, should subclass Package
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 @@ class Openssl(Package): # Uses Fake Autotools, should subclass Package
# 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
diff --git a/var/spack/repos/builtin/packages/python/package.py b/var/spack/repos/builtin/packages/python/package.py
index d0499b7c49..85e9d8ec44 100644
--- a/var/spack/repos/builtin/packages/python/package.py
+++ b/var/spack/repos/builtin/packages/python/package.py
@@ -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 @@ class Python(Package):
# 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 @@ class Python(Package):
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 @@ class Python(Package):
Returns:
dict: variable definitions
"""
-
cmd = """
import json
from sysconfig import (
diff --git a/var/spack/repos/builtin/packages/wrf/package.py b/var/spack/repos/builtin/packages/wrf/package.py
index 84c8f9dafa..2c8c2f552a 100644
--- a/var/spack/repos/builtin/packages/wrf/package.py
+++ b/var/spack/repos/builtin/packages/wrf/package.py
@@ -6,8 +6,6 @@
import glob
import re
import time
-from fcntl import F_GETFL, F_SETFL, fcntl
-from os import O_NONBLOCK
from os.path import basename
from subprocess import PIPE, Popen
from sys import platform, stdout
@@ -20,9 +18,7 @@ is_windows = platform == 'win32'
if not is_windows:
from fcntl import F_GETFL, F_SETFL, fcntl
- from os import O_NONBLOCK, rename
-else:
- from os import rename
+ from os import O_NONBLOCK
re_optline = re.compile(r'\s+[0-9]+\..*\((serial|smpar|dmpar|dm\+sm)\)\s+')
re_paroptname = re.compile(r'\((serial|smpar|dmpar|dm\+sm)\)')