Expand external find for Windows (#27588)

* Incorporate new search location

* Add external user option

* proper doc string

* Explicit commands in getting started

* raise during chgrp on Win

recover installer changes

Notate admin privleges

Windows phase install hooks

Find external python and install ninja (#23496)

Allow external find python to find windows python and spack install ninja

Co-authored-by: Adam J. Stewart <ajstewart426@gmail.com>
Co-authored-by: Betsy McPhail <betsy.mcphail@kitware.com>
This commit is contained in:
John Parent 2022-03-15 15:11:56 -04:00 committed by Peter Scheibel
parent 06aef626cb
commit df4129d395
56 changed files with 535 additions and 457 deletions

View file

@ -2,4 +2,4 @@ config:
locks: false
concretizer: original
build_stage::
- '~/.spack'
- '$spack/.staging'

View file

@ -1533,13 +1533,16 @@ Step 1: Install prerequisites
To use Spack on Windows, you will need the following packages:
Required:
* Microsoft Visual Studio
* Intel Fortran (needed for some packages)
* Python
* Git
* Perl (needed for some packages)
* NASM (needed for some packages)
* CMake
Optional:
* Intel Fortran (needed for some packages)
Note:
Currently MSVC is the only compiler tested for C/C++ projects. Intel OneAPI provides Fortran support.
"""""""""""""""""""""""
Microsoft Visual Studio
@ -1587,21 +1590,6 @@ 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.
""""
NASM
""""
The Netwide Assembler (NASM) is a x86-64 assembler that some Windows packages
will use to create binaries and can be found at https://www.nasm.us.
"""""
CMake
"""""
While the CMake provided by your Microsoft Visual Studio installation should
suffice for most packages, we still recommend downloading and installing the
most recent version of the software at https://cmake.org/download/ in case
of version restrictions.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Step 2: Install and setup Spack
@ -1611,23 +1599,40 @@ 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``.
The files and scripts used for Windows installation are on the
``features/windows-support`` branch; ``cd`` into the repo and use
``git checkout`` to switch to it.
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
Note:
If you chose to install spack into a directory on Windows that is set up to require Administrative
Privleges (either by default like `C:\Program Files`, or by administrative settings), or have administrative
restrictions on a directory spack install files to such as `C:\Users\`, Spack will require elevated privleges
to run.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Step 3: Run and configure Spack
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To use Spack, run ``bin\spack_cmd.bat`` (you may need to Run as Administrator)
from the spack source tree root. This will provide a Windows command prompt
with an environment properly set up with Spack and its prerequisites.
If you receive a warning message that Python is not in your ``PATH``
(which may happen if you installed Python from the website and not
the Windows Store), add the location of the Python executable to your
``PATH`` now.
To use Spack, run ``bin\spack_cmd.bat`` (you may need to Run as Administrator) from the top-level spack
directory. This will provide a Windows command prompt with an environment properly set up with Spack
and its prerequisites. If you receive a warning message that Python is not in your ``PATH``
(which may happen if you installed Python from the website and not the Windows Store) add the location
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.
To configure Spack, first run the following command inside the Spack console:
@ -1635,7 +1640,7 @@ To configure Spack, first run the following command inside the Spack console:
spack compiler find
This creates a ``.spack`` directory in our home directory, along with a ``windows`` subdirectory
This creates a ``.staging`` directory in our Spack prefix, along with a ``windows`` subdirectory
containing a ``compilers.yaml`` file. On a fresh Windows install with the above packages
installed, this command should only detect Microsoft Visual Studio and the Intel Fortran
compiler will be integrated within the first version of MSVC present in the ``compilers.yaml``
@ -1649,8 +1654,11 @@ as this specifies the directory that will temporarily hold the source code for t
be installed. This path name must be sufficiently short for compliance with cmd, otherwise you
will see build errors during installation (particularly with CMake) tied to long path names.
For the ``packages.yaml`` file, there are two options. The first
and easiest choice is to use Spack to find installation on your system. In
To allow Spack use of external tools and dependencies already on your system, the
external pieces of software must be described in the ``packages.yaml`` file.
There are two methods to populate this file:
The first and easiest choice is to use Spack to find installation on your system. In
the Spack terminal, run the following commands:
.. code-block:: console
@ -1660,10 +1668,10 @@ the Spack terminal, run the following commands:
The ``spack external find <name>`` will find executables on your system
with the same name given. The command will store the items found in
``packages.yaml`` in the ``.spack\`` directory.
``packages.yaml`` in the ``.staging\`` directory.
Assuming that the command found CMake and Ninja executables in the previous
step, continue to Step 4. If no executables were found, we need to manually direct spack towards the CMake
step, continue to Step 4. If no executables were found, we may need to manually direct spack towards the CMake
and Ninja installations we set up with Visual Studio. Therefore, your ``packages.yaml`` file will look something
like this, with possibly slight variants in the paths to CMake and Ninja:
@ -1698,6 +1706,8 @@ Spack console via:
spack install cpuinfo
If in the previous step, you did not have CMake or Ninja installed, running the command above should boostrap both packages
"""""""""""""""""""""""""""
Windows Compatible Packages
"""""""""""""""""""""""""""
@ -1712,6 +1722,15 @@ packages known to work on Windows:
* netlib-lapack (requires Intel Fortran)
* openssl
* zlib
* perl
* ruby
* python
* cmake
* ninja
* nasm
* clingo
Note: this is not a comprehensive list
^^^^^^^^^^^^^^
For developers
@ -1721,3 +1740,5 @@ The intent is to provide a Windows installer that will automatically set up
Python, Git, and Spack, instead of requiring the user to do so manually.
Instructions for creating the installer are at
https://github.com/spack/spack/blob/features/windows-support/lib/spack/spack/cmd/installer/README.md.
Alternatively a pre-built copy of the Windows installer is available as an artifact of Spack's Windows CI

View file

@ -321,6 +321,9 @@ def group_ids(uid=None):
def chgrp(path, group):
"""Implement the bash chgrp function on a single path"""
if is_windows:
raise OSError("Function 'chgrp' is not supported on Windows")
if isinstance(group, six.string_types):
gid = grp.getgrnam(group).gr_gid
else:

View file

@ -403,7 +403,52 @@ def replace_environment(env):
os.environ[name] = val
class log_output(object):
def log_output(*args, **kwargs):
"""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
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.
This method is actually a factory serving a per platform
(nix vs windows) log_output class
"""
if sys.platform == 'win32':
return winlog(*args, **kwargs)
else:
return nixlog(*args, **kwargs)
class nixlog(object):
"""Context manager that logs its output to a file.
In the simplest case, the usage looks like this::
@ -747,12 +792,13 @@ def close(self):
os.close(self.saved_stream)
class winlog:
def __init__(self, logfile, echo=False, debug=0, env=None):
class winlog(object):
def __init__(self, file_like=None, echo=False, debug=0, buffer=False,
env=None, filter_fn=None):
self.env = env
self.debug = debug
self.echo = echo
self.logfile = logfile
self.logfile = file_like
self.stdout = StreamWrapper('stdout')
self.stderr = StreamWrapper('stderr')
self._active = False
@ -807,6 +853,7 @@ def background_reader(reader, echo_writer, _kill):
self._thread = Thread(target=background_reader,
args=(self.reader, self.echo_writer, self._kill))
self._thread.start()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if self._ioflag:
@ -831,18 +878,10 @@ def force_echo(self):
if not self._active:
raise RuntimeError(
"Can't call force_echo() outside log_output region!")
# This uses the xon/xoff to highlight regions to be echoed in the
# output. We use these control characters rather than, say, a
# separate pipe, because they're in-band and assured to appear
# exactly before and after the text we want to echo.
sys.stdout.write(xon)
sys.stdout.flush()
try:
yield
yield self
finally:
sys.stdout.write(xoff)
sys.stdout.flush()
pass
def _writer_daemon(stdin_multiprocess_fd, read_multiprocess_fd, write_fd, echo,

View file

@ -9,7 +9,7 @@
import platform
import re
import sys
from typing import List # novm
from typing import List
import six
@ -18,7 +18,7 @@
import spack.build_environment
from spack.directives import conflicts, depends_on, variant
from spack.package import PackageBase, run_after
from spack.package import InstallError, PackageBase, run_after
# Regex to extract the primary generator from the CMake generator
# string.
@ -146,10 +146,19 @@ def _std_args(pkg):
"""Computes the standard cmake arguments for a generic package"""
try:
if not pkg.generator:
raise AttributeError
generator = pkg.generator
except AttributeError:
pkg.generator = CMakePackage.generator
generator = CMakePackage.generator
# Make sure a valid generator was chosen
valid_primary_generators = ['Unix Makefiles', 'Ninja']
primary_generator = _extract_primary_generator(generator)
if primary_generator not in valid_primary_generators:
msg = "Invalid CMake generator: '{0}'\n".format(generator)
msg += "CMakePackage currently supports the following "
msg += "primary generators: '{0}'".\
format("', '".join(valid_primary_generators))
raise InstallError(msg)
try:
build_type = pkg.spec.variants['build_type'].value
@ -163,7 +172,7 @@ def _std_args(pkg):
define = CMakePackage.define
args = [
'-G', pkg.generator,
'-G', generator,
define('CMAKE_INSTALL_PREFIX', pkg.prefix.replace('\\', '/')),
define('CMAKE_BUILD_TYPE', build_type),
]
@ -172,7 +181,7 @@ def _std_args(pkg):
if pkg.spec.satisfies('^cmake@3.9:'):
args.append(define('CMAKE_INTERPROCEDURAL_OPTIMIZATION', ipo))
if pkg.generator == 'Unix Makefiles':
if generator == 'Unix Makefiles':
args.append(define('CMAKE_VERBOSE_MAKEFILE', True))
if platform.mac_ver()[0]:

View file

@ -4,7 +4,6 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import posixpath
import subprocess
import sys
import spack.paths
@ -38,10 +37,10 @@ def line_to_rtf(str):
def setup_parser(subparser):
spack_source_group = subparser.add_mutually_exclusive_group(required=True)
spack_source_group.add_argument(
'-v', '--spack_version', default="",
'-v', '--spack-version', default="",
help='download given spack version e.g. 0.16.0')
spack_source_group.add_argument(
'-s', '--spack_source', default="",
'-s', '--spack-source', default="",
help='full path to spack source')
subparser.add_argument(
@ -97,41 +96,50 @@ def make_installer(parser, args):
"share/spack/logo/favicon.ico")
try:
subprocess.check_call(
('"%s" -S "%s" -B "%s" -DSPACK_VERSION=%s '
'-DSPACK_SOURCE="%s" -DSPACK_LICENSE="%s" '
'-DSPACK_LOGO="%s" -DSPACK_GIT_VERBOSITY="%s"')
% (cmake_path, source_dir, output_dir, spack_version, spack_source,
spack_license, spack_logo, git_verbosity),
shell=True)
except subprocess.CalledProcessError:
spack.util.executable.Executable(cmake_path)(
'-S', source_dir, '-B', output_dir,
'-DSPACK_VERSION=%s' % spack_version,
'-DSPACK_SOURCE=%s' % spack_source,
'-DSPACK_LICENSE=%s' % spack_license,
'-DSPACK_LOGO=%s' % spack_logo,
'-DSPACK_GIT_VERBOSITY=%s' % git_verbosity
)
except spack.util.executable.ProcessError:
print("Failed to generate installer")
return subprocess.CalledProcessError.returncode
return spack.util.executable.ProcessError.returncode
try:
subprocess.check_call(
'"%s" --config "%s/CPackConfig.cmake" -B "%s/"'
% (cpack_path, output_dir, output_dir),
shell=True)
except subprocess.CalledProcessError:
spack.util.executable.Executable(cpack_path)(
"--config",
"%s/CPackConfig.cmake" % output_dir,
"-B",
"%s/" % output_dir)
except spack.util.executable.ProcessError:
print("Failed to generate installer")
return subprocess.CalledProcessError.returncode
return spack.util.executable.ProcessError.returncode
try:
subprocess.check_call(
'"%s/bin/candle.exe" -ext WixBalExtension "%s/bundle.wxs"'
' -out "%s/bundle.wixobj"'
% (os.environ.get('WIX'), output_dir, output_dir), shell=True)
except subprocess.CalledProcessError:
spack.util.executable.Executable(os.environ.get('WIX') + '/bin/candle.exe')(
'-ext',
'WixBalExtension',
'%s/bundle.wxs' % output_dir,
'-out',
'%s/bundle.wixobj' % output_dir
)
except spack.util.executable.ProcessError:
print("Failed to generate installer chain")
return subprocess.CalledProcessError.returncode
return spack.util.executable.ProcessError.returncode
try:
subprocess.check_call(
'"%s/bin/light.exe" -sw1134 -ext WixBalExtension "%s/bundle.wixobj"'
' -out "%s/Spack.exe"'
% (os.environ.get('WIX'), output_dir, output_dir), shell=True)
except subprocess.CalledProcessError:
spack.util.executable.Executable(os.environ.get('WIX') + "/bin/light.exe")(
"-sw1134",
"-ext",
"WixBalExtension",
"%s/bundle.wixobj" % output_dir,
'-out',
'%s/Spack.exe' % output_dir
)
except spack.util.executable.ProcessError:
print("Failed to generate installer chain")
return subprocess.CalledProcessError.returncode
return spack.util.executable.ProcessError.returncode
print("Successfully generated Spack.exe in %s" % (output_dir))
else:
print('The make-installer command is currently only supported on Windows.')

View file

@ -211,6 +211,7 @@ def find_compilers(path_hints=None):
for o in all_os_classes():
search_paths = getattr(o, 'compiler_search_paths', default_paths)
arguments.extend(arguments_to_detect_version_fn(o, search_paths))
# Here we map the function arguments to the corresponding calls
tp = multiprocessing.pool.ThreadPool()
try:

View file

@ -51,6 +51,11 @@ class Msvc(Compiler):
fc_names = ['ifx.exe'] # type: List[str]
# Named wrapper links within build_env_path
# Due to the challenges of supporting compiler wrappers
# in Windows, we leave these blank, and dynamically compute
# based on proper versions of MSVC from there
# pending acceptance of #28117 for full support using
# compiler wrappers
link_paths = {'cc': '',
'cxx': '',
'f77': '',

View file

@ -14,8 +14,10 @@
detection mechanisms.
"""
import collections
import itertools
import os
import os.path
import re
import six
@ -175,3 +177,49 @@ def update_configuration(detected_packages, scope=None, buildable=True):
spack.config.set('packages', pkgs_cfg, scope=scope)
return all_new_specs
def find_win32_additional_install_paths():
"""Not all programs on Windows live on the PATH
Return a list of other potential install locations.
"""
windows_search_ext = []
cuda_re = r'CUDA_PATH[a-zA-Z1-9_]*'
# The list below should be expanded with other
# common Windows install locations as neccesary
path_ext_keys = ['I_MPI_ONEAPI_ROOT',
'MSMPI_BIN',
'MLAB_ROOT',
'NUGET_PACKAGES']
user = os.environ["USERPROFILE"]
add_path = lambda key: re.search(cuda_re, key) or key in path_ext_keys
windows_search_ext.extend([os.environ[key] for key
in os.environ.keys() if
add_path(key)])
# note windows paths are fine here as this method should only ever be invoked
# to interact with Windows
# Add search path for default Chocolatey (https://github.com/chocolatey/choco)
# install directory
windows_search_ext.append("C:\\ProgramData\\chocolatey\\bin")
# Add search path for NuGet package manager default install location
windows_search_ext.append(os.path.join(user, ".nuget", "packages"))
windows_search_ext.extend(
spack.config.get("config:additional_external_search_paths", default=[])
)
return windows_search_ext
def compute_windows_program_path_for_package(pkg):
"""Given a package, attempt to compute its Windows
program files location, return list of best guesses
Args:
pkg (spack.package.Package): package for which
Program Files location is to be computed
"""
program_files = 'C:\\Program Files {}\\{}'
return[program_files.format(arch, name) for
arch, name in itertools.product(("", "(x86)"),
(pkg.name, pkg.name.capitalize()))]

View file

@ -6,6 +6,7 @@
and running executables.
"""
import collections
from distutils.spawn import find_executable
import os
import os.path
import re
@ -21,11 +22,40 @@
from .common import (
DetectedPackage,
_convert_to_iterable,
compute_windows_program_path_for_package,
executable_prefix,
find_win32_additional_install_paths,
is_executable,
)
def find_executables(path_hints):
"""Get the paths of all executables available from provided hints
For convenience, this is constructed as a dictionary where the keys are
the executable paths and the values are the names of the executables
(i.e. the basename of the executable path).
There may be multiple paths with the same basename. In this case it is
assumed there are two different instances of the executable.
Args:
path_hints (list): list of paths to be searched. If None the list will be
constructed based on the PATH environment variable.
"""
search_paths = llnl.util.filesystem.search_paths_for_executables(*path_hints)
path_to_exe = {}
# Reverse order of search directories so that an exe in the first PATH
# entry overrides later entries
for search_path in reversed(search_paths):
for exe in os.listdir(search_path):
exe_path = os.path.join(search_path, exe)
if is_executable(exe_path):
path_to_exe[exe_path] = exe
return path_to_exe
def executables_in_path(path_hints=None):
"""Get the paths of all executables available from the current PATH.
@ -56,18 +86,8 @@ def executables_in_path(path_hints=None):
"CMake", "Ninja")
for path in msvc_paths]
path_hints = msvc_ninja_paths + path_hints
search_paths = llnl.util.filesystem.search_paths_for_executables(*path_hints)
path_to_exe = {}
# Reverse order of search directories so that an exe in the first PATH
# entry overrides later entries
for search_path in reversed(search_paths):
for exe in os.listdir(search_path):
exe_path = os.path.join(search_path, exe)
if is_executable(exe_path):
path_to_exe[exe_path] = exe
return path_to_exe
path_hints.extend(find_win32_additional_install_paths())
return find_executables(path_hints)
def _group_by_prefix(paths):
@ -95,6 +115,12 @@ def by_executable(packages_to_check, path_hints=None):
exe = exe.replace('$', r'\.exe$')
exe_pattern_to_pkgs[exe].append(pkg)
path_to_exe_name.update(
find_executables(
compute_windows_program_path_for_package(pkg)
)
)
pkg_to_found_exes = collections.defaultdict(set)
for exe_pattern, pkgs in exe_pattern_to_pkgs.items():
compiled_re = re.compile(exe_pattern)

View file

@ -165,11 +165,12 @@ def _do_fake_install(pkg):
library = 'lib' + library
dso_suffix = '.dylib' if sys.platform == 'darwin' else '.so'
chmod = which('chmod')
# Install fake command
fs.mkdirp(pkg.prefix.bin)
fs.touch(os.path.join(pkg.prefix.bin, command))
if sys.platform != 'win32':
chmod = which('chmod')
chmod('+x', os.path.join(pkg.prefix.bin, command))
# Install fake header file
@ -1936,7 +1937,7 @@ def _real_install(self):
# Spawn a daemon that reads from a pipe and redirects
# everything to log_path, and provide the phase for logging
if sys.platform != 'win32':
# if sys.platform != 'win32':
for i, (phase_name, phase_attr) in enumerate(zip(
pkg.phases, pkg._InstallPhase_phases)):
@ -1957,7 +1958,6 @@ def _real_install(self):
env=self.unmodified_env,
filter_fn=self.filter_fn
)
with log_contextmanager as logger:
with logger.force_echo():
inner_debug_level = tty.debug_level()
@ -1988,23 +1988,23 @@ def _real_install(self):
# We assume loggers share echo True/False
self.echo = logger.echo
else:
with winlog(pkg.log_path, True, True,
env=self.unmodified_env) as logger:
# if True:
# with winlog(pkg.log_path, True, True,
# env=self.unmodified_env) as logger:
for phase_name, phase_attr in zip(
pkg.phases, pkg._InstallPhase_phases):
# for phase_name, phase_attr in zip(
# pkg.phases, pkg._InstallPhase_phases):
# with logger.force_echo():
# inner_debug_level = tty.debug_level()
# tty.set_debug(debug_level)
# tty.msg("{0} Executing phase: '{1}'"
# .format(pre, phase_name))
# tty.set_debug(inner_debug_level)
# # with logger.force_echo():
# # inner_debug_level = tty.debug_level()
# # tty.set_debug(debug_level)
# # tty.msg("{0} Executing phase: '{1}'"
# # .format(pre, phase_name))
# # tty.set_debug(inner_debug_level)
# Redirect stdout and stderr to daemon pipe
phase = getattr(pkg, phase_attr)
phase(pkg.spec, pkg.prefix)
# # Redirect stdout and stderr to daemon pipe
# phase = getattr(pkg, phase_attr)
# phase(pkg.spec, pkg.prefix)
if sys.platform != 'win32':
# After log, we can get all output/error files from the package stage

View file

@ -5,9 +5,11 @@
import glob
import os
import platform
import subprocess
import sys
from spack.error import SpackError
from spack.version import Version
from ._operating_system import OperatingSystem
@ -65,6 +67,8 @@ class WindowsOs(OperatingSystem):
compiler_search_paths = comp_search_paths
def __init__(self):
if Version(platform.release()) < Version('10'):
raise SpackError("Spack is not supported on Windows versions older than 10")
super(WindowsOs, self).__init__('Windows10', '10')
def __str__(self):

View file

@ -103,6 +103,10 @@
'type': 'string',
'enum': ['urllib', 'curl']
},
'additional_external_search_paths': {
'type': 'array',
'items': {'type': 'string'}
}
},
},
}

View file

@ -14,7 +14,6 @@
import stat
import sys
import tempfile
from sys import platform as _platform
from typing import Dict # novm
from six import iteritems, string_types
@ -23,6 +22,7 @@
import llnl.util.tty as tty
from llnl.util.filesystem import (
can_access,
getuid,
install,
install_tree,
mkdirp,
@ -42,10 +42,6 @@
import spack.util.url as url_util
from spack.util.crypto import bit_length, prefix_bits
if _platform == "win32":
import win32api
import win32security
# The well-known stage source subdirectory name.
_source_path_subdir = 'spack-src'
@ -61,10 +57,7 @@ def create_stage_root(path):
err_msg = 'Cannot create stage root {0}: Access to {1} is denied'
if _platform != "win32":
user_uid = os.getuid() # type: ignore[attr-defined]
else:
user_uid = win32api.GetUserName()
user_uid = getuid()
# Obtain lists of ancestor and descendant paths of the $user node, if any.
group_paths, user_node, user_paths = partition_path(path,
@ -97,26 +90,7 @@ def create_stage_root(path):
for p in user_paths:
# Ensure access controls of subdirs from `$user` on down are
# restricted to the user.
if not os.path.exists(p):
mkdirp(p, mode=stat.S_IRWXU)
p_stat = os.stat(p)
if p_stat.st_mode & stat.S_IRWXU != stat.S_IRWXU:
tty.error("Expected {0} to support mode {1}, but it is {2}"
.format(p, stat.S_IRWXU, p_stat.st_mode))
raise OSError(errno.EACCES, err_msg.format(path, p))
else:
p_stat = os.stat(p)
if _platform != "win32":
owner_uid = p_stat.st_uid
else:
sid = win32security.GetFileSecurity(
p, win32security.OWNER_SECURITY_INFORMATION) \
.GetSecurityDescriptorOwner()
owner_uid = win32security.LookupAccountSid(None, sid)[0]
owner_uid = sup.get_owner_uid(p)
if user_uid != owner_uid:
tty.warn("Expected user {0} to own {1}, but it is owned by {2}"
.format(user_uid, p, owner_uid))

View file

@ -27,6 +27,9 @@
from spack.paths import test_path
from spack.spec import Spec
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
mirror_cmd = spack.main.SpackCommand('mirror')
install_cmd = spack.main.SpackCommand('install')
uninstall_cmd = spack.main.SpackCommand('uninstall')

View file

@ -3,6 +3,7 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import sys
import pytest
@ -150,6 +151,8 @@ def test_nested_use_of_context_manager(mutable_config):
assert spack.config.config == user_config
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('expected_missing', [False, True])
def test_status_function_find_files(
mutable_config, mock_executable, tmpdir, monkeypatch, expected_missing

View file

@ -14,9 +14,10 @@
install = spack.main.SpackCommand('install')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_build_tarball_overwrite(
install_mockery, mock_fetch, monkeypatch, tmpdir):

View file

@ -21,9 +21,10 @@
DATA_PATH = os.path.join(spack.paths.test_path, 'data')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize(
'directory',
glob.iglob(os.path.join(DATA_PATH, 'make', 'affirmative', '*'))
@ -43,8 +44,6 @@ def test_affirmative_make_check(directory, config, mock_packages, working_env):
pkg._if_make_target_execute('check')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize(
'directory',
glob.iglob(os.path.join(DATA_PATH, 'make', 'negative', '*'))
@ -111,8 +110,6 @@ def test_negative_ninja_check(directory, config, mock_packages, working_env):
pkg._if_ninja_target_execute('check')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_cmake_std_args(config, mock_packages):
# Call the function on a CMakePackage instance
s = Spec('cmake-client')
@ -127,16 +124,12 @@ def test_cmake_std_args(config, mock_packages):
assert get_std_cmake_args(pkg)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_cmake_bad_generator(config, mock_packages):
with pytest.raises(serr.SpackError):
s = Spec('cmake-client generator="Yellow Sticky Note"')
s.concretize()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_cmake_secondary_generator(config, mock_packages):
s = Spec('cmake-client')
s.concretize()
@ -327,8 +320,6 @@ def test_broken_external_gnuconfig(self, mutable_database, tmpdir):
e.install_all()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('config', 'mock_packages')
class TestCMakePackage(object):
@ -370,8 +361,6 @@ def test_define_from_variant(self):
pkg.define_from_variant('NONEXISTENT')
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('config', 'mock_packages')
class TestGNUMirrorPackage(object):
@ -395,8 +384,6 @@ def test_define(self):
'make/make-4.2.1.tar.gz'
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('config', 'mock_packages')
class TestSourceforgePackage(object):
@ -420,8 +407,6 @@ def test_define(self):
'tcl/tcl8.6.5-src.tar.gz'
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('config', 'mock_packages')
class TestSourcewarePackage(object):
@ -445,8 +430,6 @@ def test_define(self):
'bzip2/bzip2-1.0.8.tar.gz'
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('config', 'mock_packages')
class TestXorgPackage(object):

View file

@ -60,6 +60,8 @@ class MyAnalyzer(AnalyzerBase):
MyAnalyzer(spec)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_analyze_output(tmpdir, mock_fetch, install_mockery_mutable_config):
"""
Test that an analyzer errors if requested name does not exist.
@ -152,6 +154,8 @@ def test_environment_analyzer(tmpdir, mock_fetch, install_mockery_mutable_config
assert not result['environment_variables']
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_list_analyzers():
"""
test that listing analyzers shows all the possible analyzers.
@ -167,6 +171,8 @@ def test_list_analyzers():
assert analyzer_type in out
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_configargs_analyzer(tmpdir, mock_fetch, install_mockery_mutable_config):
"""
test the config args analyzer.

View file

@ -40,8 +40,9 @@
uninstall_cmd = spack.main.SpackCommand('uninstall')
buildcache_cmd = spack.main.SpackCommand('buildcache')
pytestmark = pytest.mark.maybeslow
pytestmark = [pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows"),
pytest.mark.maybeslow]
@pytest.fixture()

View file

@ -14,6 +14,9 @@
clean = spack.main.SpackCommand('clean')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.fixture()
def mock_calls_for_clean(monkeypatch):
@ -57,7 +60,6 @@ def __call__(self, *args, **kwargs):
('-a', all_effects),
('', []),
])
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
def test_function_calls(command_line, effects, mock_calls_for_clean):
# Call the command with the supplied command line

View file

@ -17,8 +17,10 @@
debug = SpackCommand('debug')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.db
def test_create_db_tarball(tmpdir, database):
with tmpdir.as_cwd():
@ -48,7 +50,6 @@ def test_create_db_tarball(tmpdir, database):
assert spec_suffix in contents
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
def test_report():
out = debug('report')
host_platform = spack.platforms.host()

View file

@ -20,8 +20,10 @@
]
mpi_deps = ['fake']
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
def test_direct_dependencies(mock_packages):
out = dependencies('mpileaks')
actual = set(re.split(r'\s+', out.strip()))
@ -29,7 +31,6 @@ def test_direct_dependencies(mock_packages):
assert expected == actual
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
def test_transitive_dependencies(mock_packages):
out = dependencies('--transitive', 'mpileaks')
actual = set(re.split(r'\s+', out.strip()))
@ -38,7 +39,6 @@ def test_transitive_dependencies(mock_packages):
assert expected == actual
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
def test_transitive_dependencies_with_deptypes(mock_packages):
out = dependencies('--transitive', '--deptype=link,run', 'dtbuild1')
deps = set(re.split(r'\s+', out.strip()))
@ -53,7 +53,6 @@ def test_transitive_dependencies_with_deptypes(mock_packages):
assert set(['dtlink2']) == deps
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.db
def test_direct_installed_dependencies(mock_packages, database):
with color_when(False):
@ -71,7 +70,6 @@ def test_direct_installed_dependencies(mock_packages, database):
assert expected == hashes
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.db
def test_transitive_installed_dependencies(mock_packages, database):
with color_when(False):

View file

@ -15,8 +15,10 @@
dependents = SpackCommand('dependents')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
def test_immediate_dependents(mock_packages):
out = dependents('libelf')
actual = set(re.split(r'\s+', out.strip()))
@ -30,7 +32,6 @@ def test_immediate_dependents(mock_packages):
])
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
def test_transitive_dependents(mock_packages):
out = dependents('--transitive', 'libelf')
actual = set(re.split(r'\s+', out.strip()))
@ -47,7 +48,6 @@ def test_transitive_dependents(mock_packages):
])
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.db
def test_immediate_installed_dependents(mock_packages, database):
with color_when(False):
@ -65,7 +65,6 @@ def test_immediate_installed_dependents(mock_packages, database):
assert expected == hashes
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.db
def test_transitive_installed_dependents(mock_packages, database):
with color_when(False):

View file

@ -24,6 +24,9 @@
base32_alphabet = 'abcdefghijklmnopqrstuvwxyz234567'
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.fixture(scope='module')
def parser():
@ -49,7 +52,6 @@ def display(x, *args, **kwargs):
monkeypatch.setattr(spack.cmd, 'display_specs', display)
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
def test_query_arguments():
query_arguments = spack.cmd.find.query_arguments
@ -87,7 +89,6 @@ def test_query_arguments():
assert q_args['explicit'] is False
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
@pytest.mark.usefixtures('database', 'mock_display')
def test_tag1(parser, specs):
@ -100,7 +101,6 @@ def test_tag1(parser, specs):
assert 'mpich2' in [x.name for x in specs]
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
@pytest.mark.usefixtures('database', 'mock_display')
def test_tag2(parser, specs):
@ -111,7 +111,6 @@ def test_tag2(parser, specs):
assert 'mpich' in [x.name for x in specs]
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
@pytest.mark.usefixtures('database', 'mock_display')
def test_tag2_tag3(parser, specs):
@ -121,7 +120,6 @@ def test_tag2_tag3(parser, specs):
assert len(specs) == 0
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_namespaces_shown_correctly(database):
out = find()
@ -157,7 +155,6 @@ def _check_json_output_deps(spec_list):
assert names.count("libelf") == 1
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_find_json(database):
output = find('--json', 'mpileaks')
@ -165,7 +162,6 @@ def test_find_json(database):
_check_json_output(spec_list)
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_find_json_deps(database):
output = find('-d', '--json', 'mpileaks')
@ -173,7 +169,6 @@ def test_find_json_deps(database):
_check_json_output_deps(spec_list)
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_display_json(database, capsys):
specs = [Spec(s).concretized() for s in [
@ -191,7 +186,6 @@ def test_display_json(database, capsys):
_check_json_output(spec_list)
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_display_json_deps(database, capsys):
specs = [Spec(s).concretized() for s in [
@ -209,7 +203,6 @@ def test_display_json_deps(database, capsys):
_check_json_output_deps(spec_list)
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_find_format(database, config):
output = find('--format', '{name}-{^mpi.name}', 'mpileaks')
@ -243,7 +236,6 @@ def test_find_format(database, config):
assert c in base32_alphabet
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_find_format_deps(database, config):
output = find('-d', '--format', '{name}-{version}', 'mpileaks', '^zmpi')
@ -259,7 +251,6 @@ def test_find_format_deps(database, config):
"""
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_find_format_deps_paths(database, config):
output = find('-dp', '--format', '{name}-{version}', 'mpileaks', '^zmpi')
@ -279,7 +270,6 @@ def test_find_format_deps_paths(database, config):
""".format(*prefixes)
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_find_very_long(database, config):
output = find('-L', '--no-groups', "mpileaks")
@ -295,14 +285,12 @@ def test_find_very_long(database, config):
])
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_find_show_compiler(database, config):
output = find('--no-groups', '--show-full-compiler', "mpileaks")
assert "mpileaks@2.3%gcc@4.5.0" in output
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_find_not_found(database, config, capsys):
with capsys.disabled():
@ -311,7 +299,6 @@ def test_find_not_found(database, config, capsys):
assert find.returncode == 1
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_find_no_sections(database, config):
output = find()
@ -322,14 +309,12 @@ def test_find_no_sections(database, config):
assert "==>" not in output
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.db
def test_find_command_basic_usage(database):
output = find()
assert 'mpileaks' in output
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.regression('9875')
def test_find_prefix_in_env(mutable_mock_env_path, install_mockery, mock_fetch,
mock_packages, mock_archive, config):
@ -343,7 +328,6 @@ def test_find_prefix_in_env(mutable_mock_env_path, install_mockery, mock_fetch,
# Would throw error on regression
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
def test_find_loaded(database, working_env):
output = find('--loaded', '--group')
assert output == ''

View file

@ -13,8 +13,10 @@
gc = spack.main.SpackCommand('gc')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.db
def test_no_packages_to_remove(config, mutable_database, capsys):
with capsys.disabled():
@ -22,7 +24,6 @@ def test_no_packages_to_remove(config, mutable_database, capsys):
assert 'There are no unused specs.' in output
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.db
def test_packages_are_removed(config, mutable_database, capsys):
s = spack.spec.Spec('simple-inheritance')
@ -33,7 +34,6 @@ def test_packages_are_removed(config, mutable_database, capsys):
assert 'Successfully uninstalled cmake' in output
@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows")
@pytest.mark.db
def test_gc_with_environment(
config, mutable_database, mutable_mock_env_path, capsys

View file

@ -21,8 +21,10 @@
gpg = SpackCommand('gpg')
bootstrap = SpackCommand('bootstrap')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
# test gpg command detection
@pytest.mark.parametrize('cmd_name,version', [
('gpg', 'undetectable'), # undetectable version
@ -50,6 +52,8 @@ def test_find_gpg(cmd_name, version, tmpdir, mock_gnupghome, monkeypatch):
assert spack.util.gpg.GPGCONF is not None
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_no_gpg_in_path(tmpdir, mock_gnupghome, monkeypatch, mutable_config):
monkeypatch.setitem(os.environ, "PATH", str(tmpdir))
bootstrap('disable')
@ -57,7 +61,6 @@ def test_no_gpg_in_path(tmpdir, mock_gnupghome, monkeypatch, mutable_config):
spack.util.gpg.init(force=True)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.maybeslow
def test_gpg(tmpdir, mock_gnupghome):
# Verify a file with an empty keyring.

View file

@ -11,8 +11,10 @@
graph = SpackCommand('graph')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.usefixtures('mock_packages', 'database')
def test_graph_ascii():
@ -20,7 +22,6 @@ def test_graph_ascii():
graph('--ascii', 'dt-diamond')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.usefixtures('mock_packages', 'database')
def test_graph_dot():
@ -28,7 +29,6 @@ def test_graph_dot():
graph('--dot', 'dt-diamond')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.usefixtures('mock_packages', 'database')
def test_graph_static():
@ -36,7 +36,6 @@ def test_graph_static():
graph('--static', 'dt-diamond')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.usefixtures('mock_packages', 'database')
def test_graph_installed():
@ -48,7 +47,6 @@ def test_graph_installed():
graph('--installed', 'dt-diamond')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.usefixtures('mock_packages', 'database')
def test_graph_deptype():
@ -56,7 +54,6 @@ def test_graph_deptype():
graph('--deptype', 'all', 'dt-diamond')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_graph_no_specs():
"""Tests spack graph with no arguments"""

View file

@ -35,6 +35,9 @@
buildcache = SpackCommand('buildcache')
find = SpackCommand('find')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.fixture()
def noop_install(monkeypatch):
@ -43,7 +46,6 @@ def noop(*args, **kwargs):
monkeypatch.setattr(spack.installer.PackageInstaller, 'install', noop)
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_install_package_and_dependency(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -61,7 +63,6 @@ def test_install_package_and_dependency(
assert 'errors="0"' in content
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.disable_clean_stage_check
def test_install_runtests_notests(monkeypatch, mock_packages, install_mockery):
def check(pkg):
@ -70,7 +71,6 @@ def check(pkg):
install('-v', 'dttop')
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.disable_clean_stage_check
def test_install_runtests_root(monkeypatch, mock_packages, install_mockery):
def check(pkg):
@ -80,7 +80,6 @@ def check(pkg):
install('--test=root', 'dttop')
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.disable_clean_stage_check
def test_install_runtests_all(monkeypatch, mock_packages, install_mockery):
def check(pkg):
@ -91,7 +90,6 @@ def check(pkg):
install('--run-tests', 'a')
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_install_package_already_installed(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -113,7 +111,6 @@ def test_install_package_already_installed(
assert len(skipped) == 2
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
@pytest.mark.parametrize('arguments,expected', [
([], spack.config.get('config:dirty')), # default from config file
(['--clean'], False),
@ -126,7 +123,6 @@ def test_install_dirty_flag(arguments, expected):
assert args.dirty == expected
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_package_output(tmpdir, capsys, install_mockery, mock_fetch):
"""
Ensure output printed from pkgs is captured by output redirection.
@ -148,7 +144,6 @@ def test_package_output(tmpdir, capsys, install_mockery, mock_fetch):
assert "AFTER INSTALL" in out
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_install_output_on_build_error(mock_packages, mock_archive, mock_fetch,
config, install_mockery, capfd):
@ -163,7 +158,6 @@ def test_install_output_on_build_error(mock_packages, mock_archive, mock_fetch,
assert 'Installing build-error' in out
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_install_output_on_python_error(
mock_packages, mock_archive, mock_fetch, config, install_mockery):
@ -173,7 +167,6 @@ def test_install_output_on_python_error(
assert 'raise InstallError("Expected failure.")' in out
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_install_with_source(
mock_packages, mock_archive, mock_fetch, config, install_mockery):
@ -186,7 +179,6 @@ def test_install_with_source(
os.path.join(src, 'configure'))
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_env_variables(
mock_packages, mock_archive, mock_fetch, config, install_mockery
):
@ -196,7 +188,6 @@ def test_install_env_variables(
assert os.path.isfile(spec.package.install_env_path)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_show_log_on_error(mock_packages, mock_archive, mock_fetch,
config, install_mockery, capfd):
@ -213,7 +204,6 @@ def test_show_log_on_error(mock_packages, mock_archive, mock_fetch,
assert 'See build log for details:' in out
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_overwrite(
mock_packages, mock_archive, mock_fetch, config, install_mockery
):
@ -247,7 +237,6 @@ def test_install_overwrite(
assert fs.hash_directory(spec.prefix, ignore=ignores) != bad_md5
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_overwrite_not_installed(
mock_packages, mock_archive, mock_fetch, config, install_mockery,
):
@ -261,7 +250,6 @@ def test_install_overwrite_not_installed(
assert os.path.exists(spec.prefix)
@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows")
def test_install_commit(
mock_git_version_info, install_mockery, mock_packages, monkeypatch):
"""Test installing a git package from a commit.
@ -289,7 +277,6 @@ def test_install_commit(
assert content == '[]' # contents are weird for another test
@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows")
def test_install_overwrite_multiple(
mock_packages, mock_archive, mock_fetch, config, install_mockery
):
@ -347,7 +334,6 @@ def test_install_overwrite_multiple(
assert cm_hash != bad_cmake_md5
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.usefixtures(
'mock_packages', 'mock_archive', 'mock_fetch', 'config', 'install_mockery',
)
@ -357,7 +343,6 @@ def test_install_conflicts(conflict_spec):
install(conflict_spec)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.usefixtures(
'mock_packages', 'mock_archive', 'mock_fetch', 'config', 'install_mockery',
)
@ -367,7 +352,6 @@ def test_install_invalid_spec(invalid_spec):
install(invalid_spec)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.usefixtures('noop_install', 'mock_packages', 'config')
@pytest.mark.parametrize('spec,concretize,error_code', [
(Spec('mpi'), False, 1),
@ -400,7 +384,6 @@ def test_install_from_file(spec, concretize, error_code, tmpdir):
assert err_msg in out
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
@pytest.mark.usefixtures(
'mock_packages', 'mock_archive', 'mock_fetch', 'config', 'install_mockery'
@ -443,7 +426,6 @@ def test_junit_output_with_failures(tmpdir, exc_typename, msg):
assert msg in content
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
@pytest.mark.parametrize('exc_typename,expected_exc,msg', [
('RuntimeError', spack.installer.InstallError, 'something weird happened'),
@ -487,7 +469,6 @@ def just_throw(*args, **kwargs):
assert 'error message="{0}"'.format(msg) in content
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.usefixtures('noop_install', 'mock_packages', 'config')
@pytest.mark.parametrize('clispecs,filespecs', [
[[], ['mpi']],
@ -512,7 +493,6 @@ def test_install_mix_cli_and_files(clispecs, filespecs, tmpdir):
assert install.returncode == 0
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_extra_files_are_archived(mock_packages, mock_archive, mock_fetch,
config, install_mockery):
s = Spec('archive-files')
@ -532,7 +512,6 @@ def test_extra_files_are_archived(mock_packages, mock_archive, mock_fetch,
assert os.path.exists(errors_txt)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_cdash_report_concretization_error(tmpdir, mock_fetch, install_mockery,
capfd, conflict_spec):
@ -559,7 +538,6 @@ def test_cdash_report_concretization_error(tmpdir, mock_fetch, install_mockery,
assert any(x in content for x in expected_messages)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_cdash_upload_build_error(tmpdir, mock_fetch, install_mockery,
capfd):
@ -580,7 +558,6 @@ def test_cdash_upload_build_error(tmpdir, mock_fetch, install_mockery,
assert '<Text>configure: error: in /path/to/some/file:</Text>' in content
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_cdash_upload_clean_build(tmpdir, mock_fetch, install_mockery, capfd):
# capfd interferes with Spack's capturing of e.g., Build.xml output
@ -599,7 +576,6 @@ def test_cdash_upload_clean_build(tmpdir, mock_fetch, install_mockery, capfd):
assert '<Text>' not in content
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_cdash_upload_extra_params(tmpdir, mock_fetch, install_mockery, capfd):
# capfd interferes with Spack's capture of e.g., Build.xml output
@ -622,7 +598,6 @@ def test_cdash_upload_extra_params(tmpdir, mock_fetch, install_mockery, capfd):
assert '-my_custom_track' in content
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_cdash_buildstamp_param(tmpdir, mock_fetch, install_mockery, capfd):
# capfd interferes with Spack's capture of e.g., Build.xml output
@ -645,7 +620,6 @@ def test_cdash_buildstamp_param(tmpdir, mock_fetch, install_mockery, capfd):
assert buildstamp in content
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_cdash_install_from_spec_yaml(tmpdir, mock_fetch, install_mockery,
capfd, mock_packages, mock_archive,
@ -684,7 +658,6 @@ def test_cdash_install_from_spec_yaml(tmpdir, mock_fetch, install_mockery,
assert 'a@' in install_command
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_build_error_output(tmpdir, mock_fetch, install_mockery, capfd):
with capfd.disabled():
@ -699,7 +672,6 @@ def test_build_error_output(tmpdir, mock_fetch, install_mockery, capfd):
assert 'configure: error: cannot run C compiled programs.' in msg
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_build_warning_output(tmpdir, mock_fetch, install_mockery, capfd):
with capfd.disabled():
@ -714,7 +686,6 @@ def test_build_warning_output(tmpdir, mock_fetch, install_mockery, capfd):
assert 'foo.c:89: warning: some weird warning!' in msg
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_cache_only_fails(tmpdir, mock_fetch, install_mockery, capfd):
# libelf from cache fails to install, which automatically removes the
# the libdwarf build task
@ -731,7 +702,6 @@ def test_cache_only_fails(tmpdir, mock_fetch, install_mockery, capfd):
assert 'libdwarf' in failure_lock_prefixes
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_only_dependencies(tmpdir, mock_fetch, install_mockery):
dep = Spec('dependency-install').concretized()
root = Spec('dependent-install').concretized()
@ -742,7 +712,6 @@ def test_install_only_dependencies(tmpdir, mock_fetch, install_mockery):
assert not os.path.exists(root.prefix)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_only_package(tmpdir, mock_fetch, install_mockery, capfd):
msg = ''
with capfd.disabled():
@ -755,7 +724,6 @@ def test_install_only_package(tmpdir, mock_fetch, install_mockery, capfd):
assert '1 uninstalled dependency' in msg
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_deps_then_package(tmpdir, mock_fetch, install_mockery):
dep = Spec('dependency-install').concretized()
root = Spec('dependent-install').concretized()
@ -768,7 +736,6 @@ def test_install_deps_then_package(tmpdir, mock_fetch, install_mockery):
assert os.path.exists(root.prefix)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.regression('12002')
def test_install_only_dependencies_in_env(tmpdir, mock_fetch, install_mockery,
mutable_mock_env_path):
@ -784,7 +751,6 @@ def test_install_only_dependencies_in_env(tmpdir, mock_fetch, install_mockery,
assert not os.path.exists(root.prefix)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.regression('12002')
def test_install_only_dependencies_of_all_in_env(
tmpdir, mock_fetch, install_mockery, mutable_mock_env_path
@ -805,7 +771,6 @@ def test_install_only_dependencies_of_all_in_env(
assert os.path.exists(dep.prefix)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_no_add_in_env(tmpdir, mock_fetch, install_mockery,
mutable_mock_env_path):
# To test behavior of --no-add option, we create the following environment:
@ -912,7 +877,6 @@ def test_install_no_add_in_env(tmpdir, mock_fetch, install_mockery,
assert(not any([s.name == 'bowtie' for s in e.uninstalled_specs()]))
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_help_does_not_show_cdash_options(capsys):
"""
Make sure `spack install --help` does not describe CDash arguments
@ -923,7 +887,6 @@ def test_install_help_does_not_show_cdash_options(capsys):
assert 'CDash URL' not in captured.out
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_help_cdash(capsys):
"""Make sure `spack install --help-cdash` describes CDash arguments"""
install_cmd = SpackCommand('install')
@ -931,7 +894,6 @@ def test_install_help_cdash(capsys):
assert 'CDash URL' in out
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_cdash_auth_token(tmpdir, mock_fetch, install_mockery, capfd):
# capfd interferes with Spack's capturing
@ -946,7 +908,6 @@ def test_cdash_auth_token(tmpdir, mock_fetch, install_mockery, capfd):
assert 'Using CDash auth token from environment' in out
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.disable_clean_stage_check
def test_cdash_configure_warning(tmpdir, mock_fetch, install_mockery, capfd):
# capfd interferes with Spack's capturing of e.g., Build.xml output
@ -966,7 +927,6 @@ def test_cdash_configure_warning(tmpdir, mock_fetch, install_mockery, capfd):
assert 'foo: No such file or directory' in content
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_compiler_bootstrap(
install_mockery_mutable_config, mock_packages, mock_fetch,
mock_archive, mutable_config, monkeypatch):
@ -979,7 +939,6 @@ def test_compiler_bootstrap(
install('a%gcc@2.0')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_compiler_bootstrap_from_binary_mirror(
install_mockery_mutable_config, mock_packages, mock_fetch,
mock_archive, mutable_config, monkeypatch, tmpdir):
@ -1018,7 +977,6 @@ def test_compiler_bootstrap_from_binary_mirror(
install('--no-cache', '--only', 'package', 'b%gcc@10.2.0')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.regression('16221')
def test_compiler_bootstrap_already_installed(
install_mockery_mutable_config, mock_packages, mock_fetch,
@ -1034,7 +992,6 @@ def test_compiler_bootstrap_already_installed(
install('a%gcc@2.0')
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_install_fails_no_args(tmpdir):
# ensure no spack.yaml in directory
with tmpdir.as_cwd():
@ -1046,7 +1003,6 @@ def test_install_fails_no_args(tmpdir):
assert 'using the `spack.yaml` in this directory' not in output
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_install_fails_no_args_suggests_env_activation(tmpdir):
# ensure spack.yaml in directory
tmpdir.ensure('spack.yaml')
@ -1072,7 +1028,6 @@ def fake_full_hash(spec):
return default_full_hash(spec)
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_cache_install_full_hash_match(
install_mockery_mutable_config, mock_packages, mock_fetch,
mock_archive, mutable_config, monkeypatch, tmpdir):
@ -1131,7 +1086,6 @@ def test_cache_install_full_hash_match(
shutil.rmtree(mirror_dir.strpath)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_env_with_tests_all(tmpdir, mock_packages, mock_fetch,
install_mockery, mutable_mock_env_path):
env('create', 'test')
@ -1142,7 +1096,6 @@ def test_install_env_with_tests_all(tmpdir, mock_packages, mock_fetch,
assert os.path.exists(test_dep.prefix)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_install_env_with_tests_root(tmpdir, mock_packages, mock_fetch,
install_mockery, mutable_mock_env_path):
env('create', 'test')

View file

@ -17,8 +17,10 @@
license = SpackCommand('license')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_list_files():
files = license('list-files').strip().split('\n')
assert all(f.startswith(spack.paths.prefix) for f in files)
@ -26,7 +28,6 @@ def test_list_files():
assert os.path.abspath(__file__) in files
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_verify(tmpdir):
source_dir = tmpdir.join('lib', 'spack', 'spack')
mkdirp(str(source_dir))
@ -74,7 +75,6 @@ def test_verify(tmpdir):
assert license.returncode == 1
@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed")
def test_update_copyright_year(tmpdir):
source_dir = tmpdir.join('lib', 'spack', 'spack')
mkdirp(str(source_dir))

View file

@ -17,8 +17,9 @@
from spack.main import SpackCommand, SpackCommandError
# Everything here uses (or can use) the mock config and database.
pytestmark = pytest.mark.usefixtures('config', 'database')
pytestmark = [pytest.mark.usefixtures('config', 'database'),
pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")]
# location prints out "locations of packages and spack directories"
location = SpackCommand('location')
env = SpackCommand('env')
@ -38,14 +39,12 @@ def mock_spec():
shutil.rmtree(pkg.stage.path)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_location_build_dir(mock_spec):
"""Tests spack location --build-dir."""
spec, pkg = mock_spec
assert location('--build-dir', spec.name).strip() == pkg.stage.source_path
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.regression('22738')
def test_location_source_dir(mock_spec):
"""Tests spack location --source-dir."""
@ -54,7 +53,6 @@ def test_location_source_dir(mock_spec):
assert location(spec.name).strip() == pkg.stage.source_path
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_location_source_dir_missing():
"""Tests spack location --source-dir with a missing source directory."""
spec = 'mpileaks'
@ -65,7 +63,6 @@ def test_location_source_dir_missing():
assert out == expected
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.parametrize('options', [([]),
(['--source-dir', 'mpileaks']),
(['--env', 'missing-env']),
@ -76,7 +73,6 @@ def test_location_cmd_error(options):
location(*options)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_location_env_exists(mutable_mock_env_path):
"""Tests spack location --env <name> for an existing environment."""
e = ev.create("example")
@ -84,7 +80,6 @@ def test_location_env_exists(mutable_mock_env_path):
assert location('--env', "example").strip() == e.path
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_location_with_active_env(mutable_mock_env_path):
"""Tests spack location --env with active env"""
e = ev.create("example")
@ -93,7 +88,6 @@ def test_location_with_active_env(mutable_mock_env_path):
assert location('--env').strip() == e.path
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_location_env_flag_interference(mutable_mock_env_path, tmpdir):
"""
Tests that specifying an active environment using `spack -e x location ...`
@ -115,7 +109,6 @@ def test_location_env_flag_interference(mutable_mock_env_path, tmpdir):
assert 'first_env' not in location('--packages', global_args=global_args)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_location_env_missing():
"""Tests spack location --env."""
missing_env_name = 'missing-env'
@ -124,7 +117,6 @@ def test_location_env_missing():
assert out == error
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_location_install_dir(mock_spec):
"""Tests spack location --install-dir."""
@ -132,7 +124,6 @@ def test_location_install_dir(mock_spec):
assert location('--install-dir', spec.name).strip() == spec.prefix
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_location_package_dir(mock_spec):
"""Tests spack location --package-dir."""
@ -140,7 +131,6 @@ def test_location_package_dir(mock_spec):
assert location('--package-dir', spec.name).strip() == pkg.package_dir
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.parametrize('option,expected', [
('--module-dir', spack.paths.module_path),
@ -151,7 +141,6 @@ def test_location_paths_options(option, expected):
assert location(option).strip() == expected
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.parametrize('specs,expected', [
([], "You must supply a spec."),
(['spec1', 'spec2'], "Too many specs. Supply only one.")])
@ -161,7 +150,6 @@ def test_location_spec_errors(specs, expected):
assert location(*specs, fail_on_error=False).strip() == error
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_location_stage_dir(mock_spec):
"""Tests spack location --stage-dir."""
@ -169,7 +157,6 @@ def test_location_stage_dir(mock_spec):
assert location('--stage-dir', spec.name).strip() == pkg.stage.path
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_location_stages(mock_spec):
"""Tests spack location --stages."""

View file

@ -15,22 +15,22 @@
install = SpackCommand('install')
uninstall = SpackCommand('uninstall')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_mark_mode_required(mutable_database):
with pytest.raises(SystemExit):
mark('-a')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_mark_spec_required(mutable_database):
with pytest.raises(SpackCommandError):
mark('-i')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_mark_all_explicit(mutable_database):
mark('-e', '-a')
@ -39,7 +39,6 @@ def test_mark_all_explicit(mutable_database):
assert len(all_specs) == 15
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_mark_all_implicit(mutable_database):
mark('-i', '-a')
@ -48,7 +47,6 @@ def test_mark_all_implicit(mutable_database):
assert len(all_specs) == 0
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_mark_one_explicit(mutable_database):
mark('-e', 'libelf')
@ -58,7 +56,6 @@ def test_mark_one_explicit(mutable_database):
assert len(all_specs) == 3
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_mark_one_implicit(mutable_database):
mark('-i', 'externaltest')
@ -67,7 +64,6 @@ def test_mark_one_implicit(mutable_database):
assert len(all_specs) == 14
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_mark_all_implicit_then_explicit(mutable_database):
mark('-i', '-a')

View file

@ -20,6 +20,9 @@
buildcache = SpackCommand('buildcache')
uninstall = SpackCommand('uninstall')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.fixture
def tmp_scope():
@ -42,8 +45,6 @@ def tmp_scope():
@pytest.mark.disable_clean_stage_check
@pytest.mark.regression('8083')
@pytest.mark.skipif(sys.platform == 'win32',
reason="MirrorCaches only work with file:// URLs")
def test_regression_8083(tmpdir, capfd, mock_packages, mock_fetch, config):
with capfd.disabled():
output = mirror('create', '-d', str(tmpdir), 'externaltool')
@ -51,8 +52,6 @@ def test_regression_8083(tmpdir, capfd, mock_packages, mock_fetch, config):
assert 'as it is an external spec' in output
@pytest.mark.skipif(sys.platform == 'win32',
reason="MirrorCaches only work with file:// URLs")
@pytest.mark.regression('12345')
def test_mirror_from_env(tmpdir, mock_packages, mock_fetch, config,
mutable_mock_env_path):
@ -86,8 +85,6 @@ def source_for_pkg_with_hash(mock_packages, tmpdir):
pkg.versions[spack.version.Version('1.0')]['url'] = local_url
@pytest.mark.skipif(sys.platform == 'win32',
reason="MirrorCaches only work with file:// URLs")
def test_mirror_skip_unstable(tmpdir_factory, mock_packages, config,
source_for_pkg_with_hash):
mirror_dir = str(tmpdir_factory.mktemp('mirror-dir'))
@ -152,7 +149,6 @@ def test_exclude_file(mock_packages, tmpdir, config):
assert (not expected_exclude & set(mirror_specs))
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_mirror_crud(tmp_scope, capsys):
with capsys.disabled():
mirror('add', '--scope', tmp_scope, 'mirror', 'http://spack.io')
@ -208,7 +204,6 @@ def test_mirror_crud(tmp_scope, capsys):
assert 'No mirrors configured' in output
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_mirror_nonexisting(tmp_scope):
with pytest.raises(SpackCommandError):
mirror('remove', '--scope', tmp_scope, 'not-a-mirror')
@ -218,7 +213,6 @@ def test_mirror_nonexisting(tmp_scope):
'not-a-mirror', 'http://spack.io')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_mirror_name_collision(tmp_scope):
mirror('add', '--scope', tmp_scope, 'first', '1')
@ -226,7 +220,6 @@ def test_mirror_name_collision(tmp_scope):
mirror('add', '--scope', tmp_scope, 'first', '1')
@pytest.mark.skipif(sys.platform == 'win32', reason="hangs on windows")
def test_mirror_destroy(install_mockery_mutable_config,
mock_packages, mock_fetch, mock_archive,
mutable_config, monkeypatch, tmpdir):

View file

@ -16,6 +16,9 @@
module = spack.main.SpackCommand('module')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
#: make sure module files are generated for all the tests here
@pytest.fixture(scope='module', autouse=True)
@ -60,14 +63,12 @@ def module_type(request):
# TODO : this requires having a separate directory for test modules
# TODO : add tests for loads and find to check the prompt format
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_exit_with_failure(database, module_type, failure_args):
with pytest.raises(spack.main.SpackCommandError):
module(module_type, *failure_args)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_remove_and_add(database, module_type):
"""Tests adding and removing a tcl module file."""
@ -91,7 +92,6 @@ def test_remove_and_add(database, module_type):
assert os.path.exists(item)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.parametrize('cli_args', [
['libelf'],
@ -106,7 +106,6 @@ def test_find(database, cli_args, module_type):
module(module_type, *(['find'] + cli_args))
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.usefixtures('database')
@pytest.mark.regression('2215')
@ -126,7 +125,6 @@ def test_find_fails_on_multiple_matches():
assert 'matches multiple packages' in out
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.usefixtures('database')
@pytest.mark.regression('2570')
@ -137,7 +135,6 @@ def test_find_fails_on_non_existing_packages():
assert 'matches no package' in out
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.usefixtures('database')
def test_find_recursive():
@ -151,7 +148,6 @@ def test_find_recursive():
assert len(out.split()) > 1
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_find_recursive_blacklisted(database, module_configuration):
module_configuration('blacklist')
@ -160,7 +156,6 @@ def test_find_recursive_blacklisted(database, module_configuration):
module('lmod', 'find', '-r', 'mpileaks ^mpich')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_loads_recursive_blacklisted(database, module_configuration):
module_configuration('blacklist')
@ -185,7 +180,6 @@ def test_loads_recursive_blacklisted(database, module_configuration):
writer_cls = spack.modules.lmod.LmodModulefileWriter
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_setdefault_command(
mutable_database, mutable_config

View file

@ -15,9 +15,10 @@
env = SpackCommand('env')
concretize = SpackCommand('concretize')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_undevelop(tmpdir, config, mock_packages, mutable_mock_env_path):
# setup environment
envdir = tmpdir.mkdir('env')
@ -45,8 +46,6 @@ def test_undevelop(tmpdir, config, mock_packages, mutable_mock_env_path):
assert not after.satisfies('dev_path=*')
@pytest.mark.skipif(sys.platform == "win32",
reason='Not supported on Windows (yet)')
def test_undevelop_nonexistent(tmpdir, config, mock_packages, mutable_mock_env_path):
# setup environment
envdir = tmpdir.mkdir('env')

View file

@ -15,6 +15,9 @@
uninstall = SpackCommand('uninstall')
install = SpackCommand('install')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
class MockArgs(object):
@ -26,7 +29,6 @@ def __init__(self, packages, all=False, force=False, dependents=False):
self.yes_to_all = True
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_multiple_matches(mutable_database):
"""Test unable to uninstall when multiple matches."""
@ -34,7 +36,6 @@ def test_multiple_matches(mutable_database):
uninstall('-y', 'mpileaks')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_installed_dependents(mutable_database):
"""Test can't uninstall when there are installed dependents."""
@ -42,7 +43,6 @@ def test_installed_dependents(mutable_database):
uninstall('-y', 'libelf')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_recursive_uninstall(mutable_database):
"""Test recursive uninstall."""
@ -60,7 +60,6 @@ def test_recursive_uninstall(mutable_database):
assert len(mpi_specs) == 3
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.regression('3690')
@pytest.mark.parametrize('constraint,expected_number_of_specs', [
@ -75,7 +74,6 @@ def test_uninstall_spec_with_multiple_roots(
assert len(all_specs) == expected_number_of_specs
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.parametrize('constraint,expected_number_of_specs', [
('dyninst', 14), ('libelf', 14)
@ -89,7 +87,6 @@ def test_force_uninstall_spec_with_ref_count_not_zero(
assert len(all_specs) == expected_number_of_specs
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
def test_force_uninstall_and_reinstall_by_hash(mutable_database):
"""Test forced uninstall and reinstall of old specs."""
@ -169,7 +166,6 @@ def db_specs():
assert len(mpi_specs) == 3
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.db
@pytest.mark.regression('15773')
def test_in_memory_consistency_when_uninstalling(

View file

@ -20,8 +20,10 @@
verify = SpackCommand('verify')
install = SpackCommand('install')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_single_file_verify_cmd(tmpdir):
# Test the verify command interface to verifying a single file.
filedir = os.path.join(str(tmpdir), 'a', 'b', 'c', 'd')
@ -68,7 +70,6 @@ def test_single_file_verify_cmd(tmpdir):
assert sorted(errors) == sorted(expected)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_single_spec_verify_cmd(tmpdir, mock_packages, mock_archive,
mock_fetch, config, install_mockery):
# Test the verify command interface to verify a single spec

View file

@ -12,8 +12,10 @@
versions = SpackCommand('versions')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_safe_only_versions():
"""Only test the safe versions of a package.
(Using the deprecated command line argument)
@ -21,14 +23,12 @@ def test_safe_only_versions():
versions('--safe-only', 'zlib')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_safe_versions():
"""Only test the safe versions of a package."""
versions('--safe', 'zlib')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.maybeslow
def test_remote_versions():
"""Test a package for which remote versions should be available."""
@ -36,7 +36,6 @@ def test_remote_versions():
versions('zlib')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.maybeslow
def test_remote_versions_only():
"""Test a package for which remote versions should be available."""
@ -44,7 +43,6 @@ def test_remote_versions_only():
versions('--remote', 'zlib')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.usefixtures('mock_packages')
def test_new_versions_only(monkeypatch):
"""Test a package for which new versions should be available."""
@ -73,7 +71,6 @@ def mock_fetch_remote_versions(*args, **kwargs):
assert(v.strip(' \n\t') == "99.99.99\n 3.2.1")
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.maybeslow
def test_no_versions():
"""Test a package for which no remote versions are available."""
@ -81,7 +78,6 @@ def test_no_versions():
versions('converge')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.maybeslow
def test_no_unchecksummed_versions():
"""Test a package for which no unchecksummed versions are available."""
@ -89,7 +85,6 @@ def test_no_unchecksummed_versions():
versions('bzip2')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.maybeslow
def test_versions_no_url():
"""Test a package with versions but without a ``url`` attribute."""
@ -97,7 +92,6 @@ def test_versions_no_url():
versions('graphviz')
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.maybeslow
def test_no_versions_no_url():
"""Test a package without versions or a ``url`` attribute."""

View file

@ -16,6 +16,9 @@
install = SpackCommand('install')
view = SpackCommand('view')
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
def create_projection_file(tmpdir, projection):
if 'projections' not in projection:
@ -26,7 +29,6 @@ def create_projection_file(tmpdir, projection):
return projection_file
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.parametrize('cmd', ['hardlink', 'symlink', 'hard', 'add',
'copy', 'relocate'])
def test_view_link_type(
@ -43,7 +45,6 @@ def test_view_link_type(
assert os.path.islink(package_prefix) == is_link_cmd
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.parametrize('add_cmd', ['hardlink', 'symlink', 'hard', 'add',
'copy', 'relocate'])
def test_view_link_type_remove(
@ -59,7 +60,6 @@ def test_view_link_type_remove(
assert not os.path.exists(bindir)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
@pytest.mark.parametrize('cmd', ['hardlink', 'symlink', 'hard', 'add',
'copy', 'relocate'])
def test_view_projections(
@ -85,7 +85,6 @@ def test_view_projections(
assert os.path.islink(package_prefix) == is_symlink_cmd
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_multiple_projections(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -108,7 +107,6 @@ def test_view_multiple_projections(
assert os.path.exists(extendee_prefix)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_multiple_projections_all_first(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -131,7 +129,6 @@ def test_view_multiple_projections_all_first(
assert os.path.exists(extendee_prefix)
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_external(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -141,7 +138,6 @@ def test_view_external(
assert 'Skipping external package: externaltool' in output
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_extension(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -168,7 +164,6 @@ def test_view_extension(
assert os.path.exists(os.path.join(viewpath, 'bin', 'extension1'))
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_extension_projection(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -202,7 +197,6 @@ def test_view_extension_projection(
'bin', 'extension1'))
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_extension_remove(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -222,7 +216,6 @@ def test_view_extension_remove(
assert not os.path.exists(os.path.join(viewpath, 'bin', 'extension1'))
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_extension_conflict(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -235,7 +228,6 @@ def test_view_extension_conflict(
assert 'Package conflict detected' in output
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_extension_conflict_ignored(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -249,7 +241,6 @@ def test_view_extension_conflict_ignored(
assert fin.read() == '1.0'
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_extension_global_activation(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -279,7 +270,6 @@ def test_view_extension_global_activation(
assert not os.path.exists(os.path.join(viewpath, 'bin', 'extension2'))
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_extendee_with_global_activations(
tmpdir, mock_packages, mock_archive, mock_fetch, config,
install_mockery):
@ -293,7 +283,6 @@ def test_view_extendee_with_global_activations(
assert 'Error: Globally activated extensions cannot be used' in output
@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win")
def test_view_fails_with_missing_projections_file(tmpdir):
viewpath = str(tmpdir.mkdir('view'))
projection_file = os.path.join(str(tmpdir), 'nonexistent')

View file

@ -22,6 +22,9 @@
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")
def check_spec(abstract, concrete):
if abstract.versions.concrete:
@ -166,8 +169,6 @@ def change(self, context):
return _changing_pkg
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
# This must use the mutable_config fixture because the test
# adjusting_default_target_based_on_compiler uses the current_host fixture,
# which changes the config.

View file

@ -17,6 +17,9 @@
from spack.spec import Spec
from spack.version import Version
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@pytest.fixture()
def concretize_scope(mutable_config, tmpdir):
@ -72,8 +75,6 @@ def assert_variant_values(spec, **variants):
assert concrete.variants[variant].value == value
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.usefixtures('concretize_scope', 'mock_packages')
class TestConcretizePreferences(object):
@pytest.mark.parametrize('package_name,variant_value,expected_results', [

View file

@ -989,6 +989,8 @@ def test_database_works_with_empty_dir(tmpdir):
assert not os.path.exists(db._index_path)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize('query_arg,exc_type,msg_str', [
(['callpath'], spack.store.MatchError, 'matches multiple packages'),
(['tensorflow'], spack.store.MatchError, 'does not match any')
@ -999,6 +1001,8 @@ def test_store_find_failures(database, query_arg, exc_type, msg_str):
assert msg_str in str(exc_info.value)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_store_find_accept_string(database):
result = spack.store.find('callpath', multiple=True)
assert len(result) == 3

View file

@ -50,11 +50,11 @@
import shutil
import socket
import stat
import sys
import tempfile
import traceback
from contextlib import contextmanager
from multiprocessing import Process, Queue
from sys import platform as _platform
import pytest
@ -62,6 +62,7 @@
import llnl.util.multiproc as mp
from llnl.util.filesystem import getuid, touch
_platform = sys.platform
if _platform == "win32":
import pywintypes
import win32con
@ -373,6 +374,8 @@ def __call__(self, barrier):
# Test that exclusive locks on other processes time out when an
# exclusive lock is held.
#
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_write_lock_timeout_on_write(lock_path):
multiproc_test(
AcquireWrite(lock_path),
@ -617,6 +620,8 @@ def test_write_lock_timeout_with_multiple_readers_3_2_ranges(lock_path):
TimeoutWrite(lock_path, 5, 1))
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.skipif(getuid() == 0, reason='user is root')
def test_read_lock_on_read_only_lockfile(lock_dir, lock_path):
"""read-only directory, read-only lockfile."""
@ -632,6 +637,8 @@ def test_read_lock_on_read_only_lockfile(lock_dir, lock_path):
pass
@pytest.mark.skipif(_platform == 'win32',
reason="Not supported on Windows (yet)")
def test_read_lock_read_only_dir_writable_lockfile(lock_dir, lock_path):
"""read-only directory, writable lockfile."""
touch(lock_path)
@ -699,6 +706,8 @@ def test_upgrade_read_to_write(private_lock_path):
assert lock._file is None
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_upgrade_read_to_write_fails_with_readonly_file(private_lock_path):
"""Test that read-only file can be read-locked but not write-locked."""
# ensure lock file exists the first time
@ -853,6 +862,8 @@ def p3(self, barrier):
# Longer test case that ensures locks are reusable. Ordering is
# enforced by barriers throughout -- steps are shown with numbers.
#
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_complex_acquire_and_release_chain(lock_path):
test_chain = ComplexAcquireAndRelease(lock_path)
multiproc_test(test_chain.p1,
@ -897,6 +908,8 @@ def release_write(self, release_fn=None):
return result
@pytest.mark.skipif(_platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize(
"transaction,type",
[(lk.ReadTransaction, "read"), (lk.WriteTransaction, "write")]
@ -944,6 +957,8 @@ def exit_fn(t, v, tb):
assert not vals['exception']
@pytest.mark.skipif(_platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize(
"transaction,type",
[(lk.ReadTransaction, "read"), (lk.WriteTransaction, "write")]
@ -1001,6 +1016,8 @@ def exit_fn(t, v, tb):
assert vals['exception']
@pytest.mark.skipif(_platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize(
"transaction,type",
[(lk.ReadTransaction, "read"), (lk.WriteTransaction, "write")]
@ -1119,6 +1136,8 @@ def assert_only_ctx_exception(raises=True):
assert_only_ctx_exception(raises=False)
@pytest.mark.skipif(_platform == 'win32',
reason="Not supported on Windows (yet)")
def test_nested_write_transaction(lock_path):
"""Ensure that the outermost write transaction writes."""
@ -1170,6 +1189,8 @@ def write(t, v, tb):
assert vals['wrote']
@pytest.mark.skipif(_platform == 'win32',
reason="Not supported on Windows (yet)")
def test_nested_reads(lock_path):
"""Ensure that write transactions won't re-read data."""

View file

@ -32,12 +32,15 @@
pass
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
@contextlib.contextmanager
def nullcontext():
yield
@pytest.mark.skipif(sys.platform == 'win32', reason="echo not implemented on windows")
def test_log_python_output_with_echo(capfd, tmpdir):
with tmpdir.as_cwd():
with log.log_output('foo.txt', echo=True):
@ -51,7 +54,6 @@ def test_log_python_output_with_echo(capfd, tmpdir):
assert capfd.readouterr()[0] == 'logged\n'
@pytest.mark.skipif(sys.platform == 'win32', reason="echo not implemented on windows")
def test_log_python_output_without_echo(capfd, tmpdir):
with tmpdir.as_cwd():
with log.log_output('foo.txt'):
@ -65,7 +67,6 @@ def test_log_python_output_without_echo(capfd, tmpdir):
assert capfd.readouterr()[0] == ''
@pytest.mark.skipif(sys.platform == 'win32', reason="echo not implemented on windows")
def test_log_python_output_with_invalid_utf8(capfd, tmpdir):
with tmpdir.as_cwd():
with log.log_output('foo.txt'):
@ -84,7 +85,6 @@ def test_log_python_output_with_invalid_utf8(capfd, tmpdir):
assert capfd.readouterr()[0] == ''
@pytest.mark.skipif(sys.platform == 'win32', reason="echo not implemented on windows")
def test_log_python_output_and_echo_output(capfd, tmpdir):
with tmpdir.as_cwd():
# echo two lines
@ -105,8 +105,6 @@ def _log_filter_fn(string):
return string.replace("foo", "bar")
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_log_output_with_filter(capfd, tmpdir):
with tmpdir.as_cwd():
with log.log_output('foo.txt', filter_fn=_log_filter_fn):
@ -136,7 +134,7 @@ def test_log_output_with_filter(capfd, tmpdir):
assert capfd.readouterr()[0] == 'bar blah\nblah bar\nbar bar\n'
@pytest.mark.skipif(not which('echo') or os.name == 'nt', reason="needs echo command")
@pytest.mark.skipif(not which('echo'), reason="needs echo command")
def test_log_subproc_and_echo_output_no_capfd(capfd, tmpdir):
echo = which('echo')
@ -154,7 +152,7 @@ def test_log_subproc_and_echo_output_no_capfd(capfd, tmpdir):
assert f.read() == 'echo\nlogged\n'
@pytest.mark.skipif(not which('echo') or os.name == 'nt', reason="needs echo command")
@pytest.mark.skipif(not which('echo'), reason="needs echo command")
def test_log_subproc_and_echo_output_capfd(capfd, tmpdir):
echo = which('echo')

View file

@ -19,9 +19,10 @@
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")
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
class MakeExecutableTest(unittest.TestCase):
def setUp(self):

View file

@ -20,7 +20,9 @@
from spack.util.executable import which
from spack.util.spack_yaml import SpackYAMLError
pytestmark = pytest.mark.usefixtures('mutable_config', 'mutable_mock_repo')
pytestmark = [pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows"),
pytest.mark.usefixtures('mutable_config', 'mutable_mock_repo')]
# paths in repos that shouldn't be in the mirror tarballs.
exclude = ['.hg', '.git', '.svn']
@ -104,16 +106,12 @@ def check_mirror():
assert all(left in exclude for left in dcmp.left_only)
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_url_mirror(mock_archive):
set_up_package('trivial-install-test-package', mock_archive, 'url')
check_mirror()
repos.clear()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.skipif(
not which('git'), reason='requires git to be installed')
def test_git_mirror(mock_git_repository):
@ -122,8 +120,6 @@ def test_git_mirror(mock_git_repository):
repos.clear()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.skipif(
not which('svn') or not which('svnadmin'),
reason='requires subversion to be installed')
@ -133,8 +129,6 @@ def test_svn_mirror(mock_svn_repository):
repos.clear()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.skipif(
not which('hg'), reason='requires mercurial to be installed')
def test_hg_mirror(mock_hg_repository):
@ -143,8 +137,6 @@ def test_hg_mirror(mock_hg_repository):
repos.clear()
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.skipif(
not all([which('svn'), which('hg'), which('git')]),
reason='requires subversion, git, and mercurial to be installed')
@ -330,8 +322,6 @@ def archive(dst):
pass
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.regression('14067')
def test_mirror_cache_symlinks(tmpdir):
"""Confirm that the cosmetic symlink created in the mirror cache (which may

View file

@ -26,6 +26,11 @@
if sys.platform != 'win32':
import grp
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
too_long = sbang.system_shebang_limit + 1

View file

@ -16,6 +16,9 @@
from spack.spec import Spec
from spack.util.mock_package import MockPackageMultiRepo
pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
def check_links(spec_to_check):
for spec in spec_to_check.traverse():

View file

@ -18,13 +18,13 @@
from spack.util.executable import which
from spack.version import ver
pytestmark = pytest.mark.skipif(
pytestmark = [pytest.mark.skipif(
not which('svn') or not which('svnadmin'),
reason='requires subversion to be installed')
reason='requires subversion to be installed'),
pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")]
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
@pytest.mark.parametrize("type_of_test", ['default', 'rev0'])
@pytest.mark.parametrize("secure", [True, False])
def test_fetch(
@ -81,8 +81,6 @@ def test_fetch(
assert h() == t.revision
@pytest.mark.skipif(sys.platform == 'win32',
reason="Not supported on Windows (yet)")
def test_svn_extra_fetch(tmpdir):
"""Ensure a fetch after downloading is effectively a no-op."""
testpath = str(tmpdir)

View file

@ -17,6 +17,9 @@
import spack.util.unparse
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="Test module unsupported on Windows")
def read_pyfile(filename):
"""Read and return the contents of a Python source file (as a

View file

@ -8,18 +8,25 @@
TODO: this is really part of spack.config. Consolidate it.
"""
import contextlib
import errno
import getpass
import os
import re
import stat
import subprocess
import tempfile
from sys import platform as _platform
import llnl.util.tty as tty
from llnl.util.filesystem import mkdirp
from llnl.util.lang import memoized
import spack.paths
import spack.util.spack_yaml as syaml
if _platform == "win32":
import win32security
__all__ = [
'substitute_config_variables',
'substitute_path_variables',
@ -70,6 +77,30 @@ def get_system_path_max():
return sys_max_path_length
def get_owner_uid(path, err_msg=None):
if not os.path.exists(path):
mkdirp(path, mode=stat.S_IRWXU)
p_stat = os.stat(path)
if p_stat.st_mode & stat.S_IRWXU != stat.S_IRWXU:
tty.error("Expected {0} to support mode {1}, but it is {2}"
.format(path, stat.S_IRWXU, p_stat.st_mode))
raise OSError(errno.EACCES,
err_msg.format(path, path) if err_msg else "")
else:
p_stat = os.stat(path)
if _platform != "win32":
owner_uid = p_stat.st_uid
else:
sid = win32security.GetFileSecurity(
path, win32security.OWNER_SECURITY_INFORMATION) \
.GetSecurityDescriptorOwner()
owner_uid = win32security.LookupAccountSid(None, sid)[0]
return owner_uid
def substitute_config_variables(path):
"""Substitute placeholders into paths.

View file

@ -45,7 +45,7 @@ def patch(self):
def configure(self, spec, prefix):
with working_dir(self.stage.source_path, create=True):
if not is_windows:
configure(['--prefix={0}'.format(self.prefix)])
configure(*['--prefix={0}'.format(self.prefix)])
def build(self, spec, prefix):
with working_dir(self.stage.source_path):
@ -53,11 +53,11 @@ def build(self, spec, prefix):
touch('asm\\warnings.time')
nmake('/f', 'Mkfiles\\msvc.mak')
else:
make(['V=1'])
make(*['V=1'])
def install(self, spec, prefix):
with working_dir(self.stage.source_path):
if is_windows:
pass
else:
make(['install'])
make(*['install'])

View file

@ -2,6 +2,7 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import sys
class Ninja(Package):
@ -53,9 +54,14 @@ def setup_run_environment(self, env):
def install(self, spec, prefix):
mkdir(prefix.bin)
install('ninja', prefix.bin)
name = 'ninja'
if sys.platform == 'win32':
name = name + '.exe'
install(name, prefix.bin)
install_tree('misc', prefix.misc)
if sys.platform == "win32":
return
# Some distros like Fedora install a 'ninja-build' executable
# instead of 'ninja'. Install both for uniformity.
with working_dir(prefix.bin):

View file

@ -194,7 +194,7 @@ def nmake_arguments(self):
args.append('CCTYPE=%s' % self.compiler.msvc_version)
else:
raise RuntimeError("Perl unsupported for non MSVC compilers on Windows")
args.append('INST_TOP="%s"' % self.prefix.replace('/', '\\'))
args.append('INST_TOP=%s' % self.prefix.replace('/', '\\'))
args.append("INST_ARCH=\\$(ARCHNAME)")
if self.spec.satisfies('~shared'):
args.append("ALL_STATIC=%s" % "define")

View file

@ -846,9 +846,13 @@ def command(self):
# in that order if using python@3.6.5, for example.
version = self.spec.version
for ver in [version.up_to(2), version.up_to(1), '']:
if sys.platform != "win32":
path = os.path.join(self.prefix.bin, 'python{0}'.format(ver))
else:
path = os.path.join(self.prefix, 'python{0}.exe'.format(ver))
if os.path.exists(path):
return Executable(path)
else:
msg = 'Unable to locate {0} command in {1}'
raise RuntimeError(msg.format(self.name, self.prefix.bin))
@ -892,21 +896,6 @@ def config_vars(self):
Returns:
dict: variable definitions
"""
# Some values set by sysconfig may not always exist on Windows, so
# compute Windows alternatives
def repair_win_sysconf(conf):
if is_windows:
conf["LIBDIR"] = os.path.join(conf["LIBDEST"], "..", "libs")
conf["LIBPL"] = conf["LIBDIR"]
conf["PYTHONFRAMEWORKPREFIX"] = ""
conf["LDLIBRARY"] = "python" + conf["VERSION"] + ".dll"
conf["LIBRARY"] = "python" + conf["VERSION"] + ".lib"
conf["CC"] = ""
conf["CXX"] = ""
conf["LDSHARED"] = ""
conf["LDCXXSHARED"] = ""
return conf
# TODO: distutils is deprecated in Python 3.10 and will be removed in
# Python 3.12, find a different way to access this information.
@ -976,7 +965,7 @@ def repair_win_sysconf(conf):
config.update(json.loads(self.command('-c', cmd, output=str)))
except (ProcessError, RuntimeError):
pass
self._config_vars[dag_hash] = repair_win_sysconf(config)
self._config_vars[dag_hash] = config
return self._config_vars[dag_hash]
def get_sysconfigdata_name(self):

View file

@ -46,7 +46,9 @@ class Ruby(Package):
depends_on('openssl@:1.0', when='@:2.3')
extendable = True
phases = ['autoreconf', 'configure', 'build', 'install']
phases = ['configure', 'build', 'install']
build_targets = []
install_targets = ['install']
# Known build issues when Avira antivirus software is running:
# https://github.com/rvm/rvm/issues/4313#issuecomment-374020379
# TODO: add check for this and warn user
@ -120,17 +122,17 @@ def setup_dependent_package(self, module, dependent_spec):
module.rake = Executable(self.prefix.bin.rake)
def configure(self, spec, prefix):
with working_dir(self.build_directory, create=True):
if is_windows:
Executable("win32\\configure.bat", "--prefix=%s" % self.prefix)
else:
options = getattr(self, 'configure_flag_args', [])
options += ['--prefix={0}'.format(prefix)]
options += self.configure_args()
configure(*options)
with working_dir(self.stage.source_path, create=True):
# if is_windows:
Executable("win32\\configure.bat")("--prefix=%s" % self.prefix)
# else:
# options = getattr(self, 'configure_flag_args', [])
# options += ['--prefix={0}'.format(prefix)]
# options += self.configure_args()
# configure(*options)
def build(self, spec, prefix):
with working_dir(self.build_directory):
with working_dir(self.stage.source_path):
if is_windows:
nmake()
else:
@ -139,7 +141,7 @@ def build(self, spec, prefix):
make(*params)
def install(self, spec, prefix):
with working_dir(self.build_directory):
with working_dir(self.stage.source_path):
if is_windows:
nmake('install')
else: