diff --git a/lib/spack/docs/getting_started.rst b/lib/spack/docs/getting_started.rst index 2d44af9a5d..d4121750db 100644 --- a/lib/spack/docs/getting_started.rst +++ b/lib/spack/docs/getting_started.rst @@ -1541,14 +1541,15 @@ Required: Optional: * Intel Fortran (needed for some packages) -Note: -Currently MSVC is the only compiler tested for C/C++ projects. Intel OneAPI provides Fortran support. +.. note:: + + Currently MSVC is the only compiler tested for C/C++ projects. Intel OneAPI provides Fortran support. """"""""""""""""""""""" Microsoft Visual Studio """"""""""""""""""""""" -Microsoft Visual Studio provides the Windows C/C++ compiler that is currently supported by Spack. +Microsoft Visual Studio provides the only Windows C/C++ compiler that is currently supported by Spack. We require several specific components to be included in the Visual Studio installation. One is the C/C++ toolset, which can be selected as "Desktop development with C++" or "C++ build tools," @@ -1578,6 +1579,9 @@ As Spack is a Python-based package, an installation of Python will be needed to Python 3 can be downloaded and installed from the Windows Store, and will be automatically added to your ``PATH`` in this case. +.. note:: + + Spack currently supports Python versions later than 3.2 inclusive. """ Git """ @@ -1590,6 +1594,12 @@ When given the option of adjusting your ``PATH``, choose the ``Git from the command line and also from 3rd-party software`` option. This will automatically update your ``PATH`` variable to include the ``git`` command. +.. note:: + + Spack support on Windows is currently dependent on installing the Git for Windows project + as the project providing Git support on Windows. This is additionally the recommended method + for installing Git on Windows, a link to which can be found above. Spack requires the + utilities vendored by this project. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Step 2: Install and setup Spack @@ -1617,12 +1627,14 @@ with git checkout -b features/windows-support --track /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. +.. note:: + If you chose to install Spack into a directory on Windows that is set up to require Administrative + Privleges*, Spack will require elevated privleges to run. + + *Administrative Privleges can be denoted either by default such as + `C:\Program Files`, or aministrator applied administrative restrictions + on a directory that spack installs files to such as `C:\Users\` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Step 3: Run and configure Spack ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1695,6 +1707,11 @@ obtain it by running the Visual Studio Installer and following the instructions at the start of this section. Also note that .yaml files use spaces for indentation and not tabs, so ensure that this is the case when editing one directly. + +.. note:: Cygwin + The use of Cygwin is not officially supported by Spack and is not tested. + However Spack will not throw an error, so use if choosing to use Spack + with Cygwin, know that no functionality is garunteed. ^^^^^^^^^^^^^^^^^ Step 4: Use Spack ^^^^^^^^^^^^^^^^^ @@ -1717,20 +1734,22 @@ dependencies or incompatible build tools like autoconf. Here are several packages known to work on Windows: * abseil-cpp -* cpuinfo -* glm -* netlib-lapack (requires Intel Fortran) -* openssl -* zlib -* perl -* ruby -* python -* cmake -* ninja -* nasm * clingo +* cpuinfo +* cmake +* glm +* nasm +* netlib-lapack (requires Intel Fortran) +* ninja +* openssl +* perl +* python +* ruby +* wrf +* zlib -Note: this is not a comprehensive list +.. note:: + This is by no means a comprehensive list ^^^^^^^^^^^^^^ For developers diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py index 6fd6c140c8..9f46b275b2 100644 --- a/lib/spack/llnl/util/filesystem.py +++ b/lib/spack/llnl/util/filesystem.py @@ -36,17 +36,6 @@ import win32security -is_windows = _platform == 'win32' - -if not is_windows: - import grp - import pwd - -if sys.version_info >= (3, 3): - from collections.abc import Sequence # novm -else: - from collections import Sequence - __all__ = [ 'FileFilter', 'FileList', @@ -908,7 +897,7 @@ def ancestor(dir, n=1): parent = os.path.abspath(dir) for i in range(n): parent = os.path.dirname(parent) - return parent.replace("\\", "/") + return parent @system_path_filter diff --git a/lib/spack/llnl/util/lock.py b/lib/spack/llnl/util/lock.py index 3b93303297..37989bac35 100644 --- a/lib/spack/llnl/util/lock.py +++ b/lib/spack/llnl/util/lock.py @@ -4,9 +4,9 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) import errno -import fcntl import os import socket +import sys import time from datetime import datetime from typing import Dict, Tuple # novm @@ -15,6 +15,10 @@ import spack.util.string +if sys.platform != 'win32': + import fcntl + + __all__ = [ 'Lock', 'LockDowngradeError', @@ -29,8 +33,6 @@ 'CantCreateLockError' ] -#: Mapping of supported locks to description -lock_type = {fcntl.LOCK_SH: 'read', fcntl.LOCK_EX: 'write'} #: A useful replacement for functions that should return True when not provided #: for example. @@ -166,6 +168,29 @@ def _attempts_str(wait_time, nattempts): return ' after {0:0.2f}s and {1}'.format(wait_time, attempts) +class LockType(object): + READ = 0 + WRITE = 1 + + @staticmethod + def to_str(tid): + ret = "READ" + if tid == LockType.WRITE: + ret = "WRITE" + return ret + + @staticmethod + def to_module(tid): + lock = fcntl.LOCK_SH + if tid == LockType.WRITE: + lock = fcntl.LOCK_EX + return lock + + @staticmethod + def is_valid(op): + return op == LockType.READ \ + or op == LockType.WRITE + class Lock(object): """This is an implementation of a filesystem lock using Python's lockf. @@ -276,9 +301,10 @@ def _lock(self, op, timeout=None): successfully acquired, the total wait time and the number of attempts is returned. """ - assert op in lock_type + assert LockType.is_valid(op) + op_str = LockType.to_str(op) - self._log_acquiring('{0} LOCK'.format(lock_type[op].upper())) + self._log_acquiring('{0} LOCK'.format(op_str)) timeout = timeout or self.default_timeout # Create file and parent directories if they don't exist. @@ -286,13 +312,13 @@ def _lock(self, op, timeout=None): self._ensure_parent_directory() self._file = file_tracker.get_fh(self.path) - if op == fcntl.LOCK_EX and self._file.mode == 'r': + if LockType.to_module(op) == fcntl.LOCK_EX and self._file.mode == 'r': # Attempt to upgrade to write lock w/a read-only file. # If the file were writable, we'd have opened it 'r+' raise LockROFileError(self.path) self._log_debug("{0} locking [{1}:{2}]: timeout {3} sec" - .format(lock_type[op], self._start, self._length, + .format(op_str.lower(), self._start, self._length, timeout)) poll_intervals = iter(Lock._poll_interval_generator()) @@ -313,17 +339,16 @@ def _lock(self, op, timeout=None): return total_wait_time, num_attempts raise LockTimeoutError("Timed out waiting for a {0} lock." - .format(lock_type[op])) + .format(op_str.lower())) def _poll_lock(self, op): """Attempt to acquire the lock in a non-blocking manner. Return whether the locking attempt succeeds """ - assert op in lock_type - + module_op = LockType.to_module(op) try: # Try to get the lock (will raise if not available.) - fcntl.lockf(self._file, op | fcntl.LOCK_NB, + fcntl.lockf(self._file, module_op | fcntl.LOCK_NB, self._length, self._start, os.SEEK_SET) # help for debugging distributed locking @@ -331,11 +356,11 @@ def _poll_lock(self, op): # All locks read the owner PID and host self._read_log_debug_data() self._log_debug('{0} locked {1} [{2}:{3}] (owner={4})' - .format(lock_type[op], self.path, + .format(LockType.to_str(op), self.path, self._start, self._length, self.pid)) # Exclusive locks write their PID/host - if op == fcntl.LOCK_EX: + if module_op == fcntl.LOCK_EX: self._write_log_debug_data() return True @@ -420,7 +445,7 @@ def acquire_read(self, timeout=None): if self._reads == 0 and self._writes == 0: # can raise LockError. - wait_time, nattempts = self._lock(fcntl.LOCK_SH, timeout=timeout) + wait_time, nattempts = self._lock(LockType.READ, timeout=timeout) self._reads += 1 # Log if acquired, which includes counts when verbose self._log_acquired('READ LOCK', wait_time, nattempts) @@ -445,7 +470,7 @@ def acquire_write(self, timeout=None): if self._writes == 0: # can raise LockError. - wait_time, nattempts = self._lock(fcntl.LOCK_EX, timeout=timeout) + wait_time, nattempts = self._lock(LockType.WRITE, timeout=timeout) self._writes += 1 # Log if acquired, which includes counts when verbose self._log_acquired('WRITE LOCK', wait_time, nattempts) @@ -489,7 +514,7 @@ def downgrade_write_to_read(self, timeout=None): if self._writes == 1 and self._reads == 0: self._log_downgrading() # can raise LockError. - wait_time, nattempts = self._lock(fcntl.LOCK_SH, timeout=timeout) + wait_time, nattempts = self._lock(LockType.READ, timeout=timeout) self._reads = 1 self._writes = 0 self._log_downgraded(wait_time, nattempts) @@ -508,7 +533,7 @@ def upgrade_read_to_write(self, timeout=None): if self._reads == 1 and self._writes == 0: self._log_upgrading() # can raise LockError. - wait_time, nattempts = self._lock(fcntl.LOCK_EX, timeout=timeout) + wait_time, nattempts = self._lock(LockType.WRITE, timeout=timeout) self._reads = 0 self._writes = 1 self._log_upgraded(wait_time, nattempts) diff --git a/lib/spack/llnl/util/symlink.py b/lib/spack/llnl/util/symlink.py index 3e5f0d4868..d6e4651557 100644 --- a/lib/spack/llnl/util/symlink.py +++ b/lib/spack/llnl/util/symlink.py @@ -9,9 +9,11 @@ from os.path import exists, join from sys import platform as _platform -is_windows = _platform == 'win32' +from llnl.util import lang -__win32_can_symlink__ = None +from spack.util.executable import Executable + +is_windows = _platform == 'win32' def symlink(real_path, link_path): @@ -51,21 +53,20 @@ def _win32_junction(path, link): path = os.path.join(parent, path) path = os.path.abspath(path) + command = "mklink" + default_args = [link, path] if os.path.isdir(path): # try using a junction - command = 'mklink /J "%s" "%s"' % (link, path) + default_args.insert(0, '/J') else: # try using a hard link - command = 'mklink /H "%s" "%s"' % (link, path) + default_args.insert(0, '/H') - _cmd(command) + Executable(command)(*default_args) +@lang.memoized def _win32_can_symlink(): - global __win32_can_symlink__ - if __win32_can_symlink__ is not None: - return __win32_can_symlink__ - tempdir = tempfile.mkdtemp() dpath = join(tempdir, 'dpath') @@ -92,9 +93,7 @@ def _win32_can_symlink(): # Cleanup the test directory shutil.rmtree(tempdir) - __win32_can_symlink__ = can_symlink_directories and can_symlink_files - - return __win32_can_symlink__ + return can_symlink_directories and can_symlink_files def _win32_is_junction(path): @@ -119,21 +118,3 @@ def _win32_is_junction(path): bool(res & FILE_ATTRIBUTE_REPARSE_POINT) return False - - -# Based on https://github.com/Erotemic/ubelt/blob/master/ubelt/util_cmd.py -def _cmd(command): - import subprocess - - # Create a new process to execute the command - def make_proc(): - # delay the creation of the process until we validate all args - proc = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, shell=True, - universal_newlines=True, cwd=None, env=None) - return proc - - proc = make_proc() - (out, err) = proc.communicate() - if proc.wait() != 0: - raise OSError(str(err)) diff --git a/lib/spack/llnl/util/tty/__init__.py b/lib/spack/llnl/util/tty/__init__.py index 5b8729d7ec..ae7634afea 100644 --- a/lib/spack/llnl/util/tty/__init__.py +++ b/lib/spack/llnl/util/tty/__init__.py @@ -394,7 +394,8 @@ def ioctl_gwinsz(fd): return int(rc[0]), int(rc[1]) else: - # return shutil.get_terminal_size() - # TODO: find python 2 compatible module to get terminal size + if sys.version_info[0] < 3: + raise RuntimeError("""Terminal size not obtainable on Windows with a + Python version older than 3""") rc = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) return int(rc[0]), int(rc[1]) diff --git a/lib/spack/llnl/util/tty/log.py b/lib/spack/llnl/util/tty/log.py index c16982241e..0df3cf7829 100644 --- a/lib/spack/llnl/util/tty/log.py +++ b/lib/spack/llnl/util/tty/log.py @@ -938,8 +938,7 @@ def _writer_daemon(stdin_multiprocess_fd, read_multiprocess_fd, write_fd, echo, # write_fd to terminate the reading loop, so we close the file descriptor # here. Forking is the process spawning method everywhere except Mac OS # for Python >= 3.8 and on Windows - if sys.version_info < (3, 8) \ - or sys.platform not in ['darwin', 'cygwin']: + if sys.version_info < (3, 8) or sys.platform != 'darwin': os.close(write_fd) # Use line buffering (3rd param = 1) since Python 3 has a bug diff --git a/lib/spack/llnl/util/tty/pty.py b/lib/spack/llnl/util/tty/pty.py index 0475667825..1a5731a5c7 100644 --- a/lib/spack/llnl/util/tty/pty.py +++ b/lib/spack/llnl/util/tty/pty.py @@ -11,6 +11,7 @@ things like timeouts in ``ProcessController.wait()``, which are set to get tests done quickly, not to avoid high CPU usage. +Note: The functionality in this module is unsupported on Windows """ from __future__ import print_function diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py index bf0797a278..5f9e1d8100 100644 --- a/lib/spack/spack/build_environment.py +++ b/lib/spack/spack/build_environment.py @@ -265,16 +265,16 @@ def set_compiler_environment_variables(pkg, env): # Set SPACK compiler variables so that our wrapper knows what to call if compiler.cc: env.set('SPACK_CC', compiler.cc) - env.set('CC', os.path.join(link_dir, os.path.join(compiler.link_paths['cc']))) + env.set('CC', os.path.join(link_dir, compiler.link_paths['cc'])) if compiler.cxx: env.set('SPACK_CXX', compiler.cxx) - env.set('CXX', os.path.join(link_dir, os.path.join(compiler.link_paths['cxx']))) + env.set('CXX', os.path.join(link_dir, compiler.link_paths['cxx'])) if compiler.f77: env.set('SPACK_F77', compiler.f77) - env.set('F77', os.path.join(link_dir, os.path.join(compiler.link_paths['f77']))) + env.set('F77', os.path.join(link_dir, compiler.link_paths['f77'])) if compiler.fc: env.set('SPACK_FC', compiler.fc) - env.set('FC', os.path.join(link_dir, os.path.join(compiler.link_paths['fc']))) + env.set('FC', os.path.join(link_dir, compiler.link_paths['fc'])) # Set SPACK compiler rpath flags so that our wrapper knows what to use env.set('SPACK_CC_RPATH_ARG', compiler.cc_rpath_arg) @@ -375,7 +375,7 @@ def set_wrapper_variables(pkg, env): env_paths = [] compiler_specific = os.path.join( spack.paths.build_env_path, - os.path.dirname(os.path.join(pkg.compiler.link_paths['cc']))) + os.path.dirname(pkg.compiler.link_paths['cc'])) for item in [spack.paths.build_env_path, compiler_specific]: env_paths.append(item) ci = os.path.join(item, 'case-insensitive') @@ -525,11 +525,10 @@ def _set_variables_for_single_module(pkg, module): m.configure = Executable('./configure') m.meson = Executable('meson') - # m.cmake = Executable('cmake') m.cmake = Executable('cmake') m.ctest = MakeExecutable('ctest', jobs) - if os.name == 'nt': + if sys.platform == 'win32': m.nmake = Executable('nmake') # Standard CMake arguments m.std_cmake_args = spack.build_systems.cmake.CMakePackage._std_args(pkg) @@ -538,10 +537,10 @@ def _set_variables_for_single_module(pkg, module): # Put spack compiler paths in module scope. link_dir = spack.paths.build_env_path - m.spack_cc = os.path.join(link_dir, os.path.join(pkg.compiler.link_paths['cc'])) - m.spack_cxx = os.path.join(link_dir, os.path.join(pkg.compiler.link_paths['cxx'])) - m.spack_f77 = os.path.join(link_dir, os.path.join(pkg.compiler.link_paths['f77'])) - m.spack_fc = os.path.join(link_dir, os.path.join(pkg.compiler.link_paths['fc'])) + m.spack_cc = os.path.join(link_dir, pkg.compiler.link_paths['cc']) + m.spack_cxx = os.path.join(link_dir, pkg.compiler.link_paths['cxx']) + m.spack_f77 = os.path.join(link_dir, pkg.compiler.link_paths['f77']) + m.spack_fc = os.path.join(link_dir, pkg.compiler.link_paths['fc']) # Emulate some shell commands for convenience m.pwd = os.getcwd diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py index 7a53adc250..9fd2267d51 100644 --- a/lib/spack/spack/build_systems/cmake.py +++ b/lib/spack/spack/build_systems/cmake.py @@ -181,7 +181,7 @@ def _std_args(pkg): if pkg.spec.satisfies('^cmake@3.9:'): args.append(define('CMAKE_INTERPROCEDURAL_OPTIMIZATION', ipo)) - if generator == 'Unix Makefiles': + if primary_generator == 'Unix Makefiles': args.append(define('CMAKE_VERBOSE_MAKEFILE', True)) if platform.mac_ver()[0]: diff --git a/lib/spack/spack/cmd/make_installer.py b/lib/spack/spack/cmd/make_installer.py index 71d0aa3ada..c1bced479f 100644 --- a/lib/spack/spack/cmd/make_installer.py +++ b/lib/spack/spack/cmd/make_installer.py @@ -16,11 +16,11 @@ def txt_to_rtf(file_path): - rtf_header = """{{\\rtf1\\ansi\\deff0\\nouicompat - {{\\fonttbl{{\\f0\\fnil\\fcharset0 Courier New;}}}} - {{\\colortbl ;\\red0\\green0\\blue255;}} - {{\\*\\generator Riched20 10.0.19041}}\\viewkind4\\uc1 - \\f0\\fs22\\lang1033 + rtf_header = r"""{{\rtf1\ansi\deff0\nouicompat + {{\fonttbl{{\f0\\fnil\fcharset0 Courier New;}}}} + {{\colortbl ;\red0\green0\blue255;}} + {{\*\generator Riched20 10.0.19041}}\viewkind4\uc1 + \f0\fs22\lang1033 {} }} """ diff --git a/lib/spack/spack/cmd/modules/lmod.py b/lib/spack/spack/cmd/modules/lmod.py index fec663e53e..8555822826 100644 --- a/lib/spack/spack/cmd/modules/lmod.py +++ b/lib/spack/spack/cmd/modules/lmod.py @@ -4,10 +4,6 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) import functools -import os - -import llnl.util.filesystem -from llnl.util.symlink import symlink import spack.cmd.common.arguments import spack.cmd.modules @@ -60,10 +56,3 @@ def setdefault(module_type, specs, args): with spack.config.override(scope): writer = spack.modules.module_types['lmod'](spec, args.module_set_name) writer.update_module_defaults() - - module_folder = os.path.dirname(writer.layout.filename) - module_basename = os.path.basename(writer.layout.filename) - with llnl.util.filesystem.working_dir(module_folder): - if os.path.exists('default') and os.path.islink('default'): - os.remove('default') - symlink(module_basename, 'default') diff --git a/lib/spack/spack/cmd/unit_test.py b/lib/spack/spack/cmd/unit_test.py index 05c308b84c..eb78ad893b 100644 --- a/lib/spack/spack/cmd/unit_test.py +++ b/lib/spack/spack/cmd/unit_test.py @@ -28,6 +28,7 @@ description = "run spack's unit tests (wrapper around pytest)" section = "developer" level = "long" +is_windows = sys.platform == 'win32' def setup_parser(subparser): @@ -179,8 +180,11 @@ def unit_test(parser, args, unknown_args): # Ensure clingo is available before switching to the # mock configuration used by unit tests - with spack.bootstrap.ensure_bootstrap_configuration(): - spack.bootstrap.ensure_clingo_importable_or_raise() + # Note: skip on windows here because for the moment, + # clingo is wholly unsupported from bootstrap + if not is_windows: + with spack.bootstrap.ensure_bootstrap_configuration(): + spack.bootstrap.ensure_clingo_importable_or_raise() if pytest is None: vendored_pytest_dir = os.path.join( diff --git a/lib/spack/spack/compilers/clang.py b/lib/spack/spack/compilers/clang.py index 2802aad840..c9982d1440 100644 --- a/lib/spack/spack/compilers/clang.py +++ b/lib/spack/spack/compilers/clang.py @@ -14,20 +14,20 @@ #: compiler symlink mappings for mixed f77 compilers f77_mapping = [ - ('gfortran', ('clang', 'gfortran')), - ('xlf_r', ('xl_r', 'xlf_r')), - ('xlf', ('xl', 'xlf')), - ('pgfortran', ('pgi', 'pgfortran')), - ('ifort', ('intel', 'ifort')) + ('gfortran', os.path.join('clang', 'gfortran')), + ('xlf_r', os.path.join('xl_r', 'xlf_r')), + ('xlf', os.path.join('xl', 'xlf')), + ('pgfortran', os.path.join('pgi', 'pgfortran')), + ('ifort', os.path.join('intel', 'ifort')) ] #: compiler symlink mappings for mixed f90/fc compilers fc_mapping = [ - ('gfortran', ('clang', 'gfortran')), - ('xlf90_r', ('xl_r', 'xlf90_r')), - ('xlf90', ('xl', 'xlf90')), - ('pgfortran', ('pgi', 'pgfortran')), - ('ifort', ('intel', 'ifort')) + ('gfortran', os.path.join('clang', 'gfortran')), + ('xlf90_r', os.path.join('xl_r', 'xlf90_r')), + ('xlf90', os.path.join('xl', 'xlf90')), + ('pgfortran', os.path.join('pgi', 'pgfortran')), + ('ifort', os.path.join('intel', 'ifort')) ] diff --git a/lib/spack/spack/compilers/msvc.py b/lib/spack/spack/compilers/msvc.py index 32a9620c3d..fe5014128e 100644 --- a/lib/spack/spack/compilers/msvc.py +++ b/lib/spack/spack/compilers/msvc.py @@ -1,4 +1,4 @@ -# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other +# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) @@ -83,19 +83,18 @@ def __init__(self, *args, **kwargs): self.setvarsfile = os.path.join( os.getenv("ONEAPI_ROOT"), "setvars.bat") else: + # The long relative path below points six directories up + # to the root of the MSVC tree associated with this (self) + # vesion of MSVC, so that we can then find the relevant + # VCVARS file. Note: This is done in the opposite order + # that this procedure typically goes on Windows + # However it is done this way here with great intent to conform + # with how Spack discovers compilers. self.setvarsfile = os.path.abspath( os.path.join(self.cc, '../../../../../../..')) self.setvarsfile = os.path.join( self.setvarsfile, 'Auxiliary', 'Build', 'vcvars64.bat') - @property - def verbose_flag(self): - return "" - - @property - def pic_flag(self): - return "" - @property def msvc_version(self): ver = re.search(Msvc.version_regex, self.cc).group(1) diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py index fa6846e207..822d674807 100644 --- a/lib/spack/spack/config.py +++ b/lib/spack/spack/config.py @@ -137,7 +137,7 @@ def __init__(self, name, path): @property def is_platform_dependent(self): - return '/' in self.name + return os.sep in self.name def get_section_filename(self, section): _validate_section_name(section) @@ -755,7 +755,7 @@ def override(path_or_scope, value=None): def _add_platform_scope(cfg, scope_type, name, path): """Add a platform-specific subdirectory for the current platform.""" platform = spack.platforms.host().name - plat_name = '%s/%s' % (name, platform) + plat_name = os.path.join(name, platform) plat_path = os.path.join(path, platform) cfg.push_scope(scope_type(plat_name, plat_path)) @@ -934,6 +934,12 @@ def set(path, value, scope=None): return config.set(path, value, scope) +def add_default_platform_scope(platform): + plat_name = os.path.join('defaults', platform) + plat_path = os.path.join(configuration_defaults_path[1], platform) + config.push_scope(ConfigScope(plat_name, plat_path)) + + def scopes(): """Convenience function to get list of configuration scopes.""" return config.scopes diff --git a/lib/spack/spack/detection/common.py b/lib/spack/spack/detection/common.py index 62de85a652..4f56a526aa 100644 --- a/lib/spack/spack/detection/common.py +++ b/lib/spack/spack/detection/common.py @@ -18,6 +18,7 @@ import os import os.path import re +import sys import six @@ -27,6 +28,7 @@ import spack.spec import spack.util.spack_yaml +is_windows = sys.platform == 'win32' #: Information on a package that has been detected DetectedPackage = collections.namedtuple( 'DetectedPackage', ['spec', 'prefix'] @@ -206,7 +208,7 @@ def find_win32_additional_install_paths(): windows_search_ext.extend( spack.config.get("config:additional_external_search_paths", default=[]) ) - + windows_search_ext.extend(spack.util.environment.get_path('PATH')) return windows_search_ext @@ -218,10 +220,12 @@ def compute_windows_program_path_for_package(pkg): pkg (spack.package.Package): package for which Program Files location is to be computed """ + if not is_windows: + return [] # note windows paths are fine here as this method should only ever be invoked # to interact with Windows - program_files = 'C:\\Program Files {}\\{}' + program_files = 'C:\\Program Files{}\\{}' return[program_files.format(arch, name) for - arch, name in itertools.product(("", "(x86)"), + arch, name in itertools.product(("", " (x86)"), (pkg.name, pkg.name.capitalize()))] diff --git a/lib/spack/spack/detection/path.py b/lib/spack/spack/detection/path.py index 835a8a0c5a..32e5f57af7 100644 --- a/lib/spack/spack/detection/path.py +++ b/lib/spack/spack/detection/path.py @@ -6,7 +6,6 @@ and running executables. """ import collections -from distutils.spawn import find_executable import os import os.path import re @@ -29,33 +28,6 @@ ) -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. @@ -87,7 +59,17 @@ def executables_in_path(path_hints=None): for path in msvc_paths] path_hints = msvc_ninja_paths + path_hints path_hints.extend(find_win32_additional_install_paths()) - return find_executables(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 def _group_by_prefix(paths): @@ -106,21 +88,15 @@ def by_executable(packages_to_check, path_hints=None): path_hints (list): list of paths to be searched. If None the list will be constructed based on the PATH environment variable. """ - path_to_exe_name = executables_in_path(path_hints=path_hints) + path_hints = [] if path_hints is None else path_hints exe_pattern_to_pkgs = collections.defaultdict(list) for pkg in packages_to_check: - if hasattr(pkg, 'executables'): - for exe in pkg.executables: - if sys.platform == 'win32': - 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) - ) - ) + for exe in pkg.platform_executables: + exe_pattern_to_pkgs[exe].append(pkg) + # Add Windows specific, package related paths to the search paths + path_hints.extend(compute_windows_program_path_for_package(pkg)) + path_to_exe_name = executables_in_path(path_hints=path_hints) pkg_to_found_exes = collections.defaultdict(set) for exe_pattern, pkgs in exe_pattern_to_pkgs.items(): compiled_re = re.compile(exe_pattern) diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py index d7884423ce..a33eff045a 100644 --- a/lib/spack/spack/directory_layout.py +++ b/lib/spack/spack/directory_layout.py @@ -24,6 +24,9 @@ import spack.util.spack_json as sjson from spack.error import SpackError +# Note: Posixpath is used here as opposed to +# os.path.join due to spack.spec.Spec.format +# requiring forward slash path seperators at this stage default_projections = {'all': posixpath.join( '{architecture}', '{compiler.name}-{compiler.version}', '{name}-{version}-{hash}')} @@ -284,7 +287,7 @@ def all_specs(self): specs = [] for _, path_scheme in self.projections.items(): - path_elems = ["*"] * len(path_scheme.split(os.sep)) + path_elems = ["*"] * len(path_scheme.split(posixpath.sep)) # NOTE: Does not validate filename extension; should happen later path_elems += [self.metadata_dir, 'spec.json'] pattern = os.path.join(self.root, *path_elems) @@ -302,7 +305,7 @@ def all_deprecated_specs(self): deprecated_specs = set() for _, path_scheme in self.projections.items(): - path_elems = ["*"] * len(path_scheme.split(os.sep)) + path_elems = ["*"] * len(path_scheme.split(posixpath.sep)) # NOTE: Does not validate filename extension; should happen later path_elems += [self.metadata_dir, self.deprecated_dir, '*_spec.*'] # + self.spec_file_name] diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py index 0d2041b736..7abcea7383 100644 --- a/lib/spack/spack/fetch_strategy.py +++ b/lib/spack/spack/fetch_strategy.py @@ -34,11 +34,11 @@ import six import six.moves.urllib.parse as urllib_parse +import llnl.util import llnl.util.tty as tty from llnl.util.filesystem import ( get_single_file, mkdirp, - rename, temp_cwd, temp_rename, working_dir, @@ -58,6 +58,7 @@ #: List of all fetch strategies, created by FetchStrategy metaclass. all_strategies = [] +is_windows = sys.platform == 'win32' CONTENT_TYPE_MISMATCH_WARNING_TEMPLATE = ( "The contents of {subject} look like {content_type}. Either the URL" @@ -304,13 +305,10 @@ def candidate_urls(self): urls = [] for url in [self.url] + (self.mirrors or []): - if sys.platform == "win32": - url = url.replace("\\", "/") + # This must be skipped on Windows due to URL encoding + # of ':' characters on filepaths on Windows if sys.platform != "win32" and url.startswith('file://'): path = urllib_parse.quote(url[len('file://'):]) - if sys.platform == "win32": - if not path.startswith("/"): - path = "/" + path url = 'file://' + path urls.append(url) @@ -331,7 +329,7 @@ def fetch(self): try: partial_file, save_file = self._fetch_from_url(url) if save_file and (partial_file is not None): - rename(partial_file, save_file) + llnl.util.filesystem.rename(partial_file, save_file) break except FailedDownloadError as e: errors.append(str(e)) @@ -635,7 +633,9 @@ class CacheURLFetchStrategy(URLFetchStrategy): @_needs_stage def fetch(self): - path = re.sub('^file://', '', self.url) + reg_str = r'^file://' + reg_str += '/' if is_windows else '' + path = re.sub(reg_str, '', self.url) # check whether the cache file exists. if not os.path.isfile(path): @@ -684,9 +684,6 @@ def __init__(self, **kwargs): raise ValueError( "%s requires %s argument." % (self.__class__, self.url_attr)) - if sys.platform == "win32": - self.url = self.url.replace('\\', '/') - for attr in self.optional_attrs: setattr(self, attr, kwargs.get(attr, None)) @@ -1410,7 +1407,7 @@ def fetch(self): warn_content_type_mismatch(self.archive_file or "the archive") if self.stage.save_filename: - rename( + llnl.util.filesystem.rename( os.path.join(self.stage.path, basename), self.stage.save_filename) diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py index c6da212340..4cc1eedbe6 100644 --- a/lib/spack/spack/installer.py +++ b/lib/spack/spack/installer.py @@ -43,7 +43,7 @@ import llnl.util.lock as lk import llnl.util.tty as tty from llnl.util.tty.color import colorize -from llnl.util.tty.log import log_output, winlog +from llnl.util.tty.log import log_output import spack.binary_distribution as binary_distribution import spack.compilers @@ -1937,7 +1937,6 @@ 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': for i, (phase_name, phase_attr) in enumerate(zip( pkg.phases, pkg._InstallPhase_phases)): @@ -1958,6 +1957,7 @@ 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,28 +1988,10 @@ def _real_install(self): # We assume loggers share echo True/False self.echo = logger.echo - # 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): - - # # 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) - - if sys.platform != 'win32': - # After log, we can get all output/error files from the package stage - combine_phase_logs(pkg.phase_log_files, pkg.log_path) - log(pkg) + # After log, we can get all output/error files from the package stage + combine_phase_logs(pkg.phase_log_files, pkg.log_path) + log(pkg) def build_process(pkg, install_args): diff --git a/lib/spack/spack/main.py b/lib/spack/spack/main.py index 1f3cf5e723..15c970a357 100644 --- a/lib/spack/spack/main.py +++ b/lib/spack/spack/main.py @@ -494,7 +494,7 @@ def setup_main_options(args): # debug must be set first so that it can even affect behavior of # errors raised by spack.config. - tty.debug(spack.config.config) + if args.debug: spack.error.debug = True spack.util.debug.register_interrupt_handler() diff --git a/lib/spack/spack/modules/lmod.py b/lib/spack/spack/modules/lmod.py index e83f005854..97f79cfd28 100644 --- a/lib/spack/spack/modules/lmod.py +++ b/lib/spack/spack/modules/lmod.py @@ -100,6 +100,9 @@ def guess_core_compilers(name, store=False): class LmodConfiguration(BaseConfiguration): """Configuration class for lmod module files.""" + # Note: Posixpath is used here as well as below as opposed to + # os.path.join due to spack.spec.Spec.format + # requiring forward slash path seperators at this stage default_projections = {'all': posixpath.join('{name}', '{version}')} @property diff --git a/lib/spack/spack/modules/tcl.py b/lib/spack/spack/modules/tcl.py index 2a9e6ac047..6762616337 100644 --- a/lib/spack/spack/modules/tcl.py +++ b/lib/spack/spack/modules/tcl.py @@ -106,4 +106,7 @@ def conflicts(self): class TclModulefileWriter(BaseModuleFileWriter): """Writer class for tcl module files.""" + # Note: Posixpath is used here as opposed to + # os.path.join due to spack.spec.Spec.format + # requiring forward slash path seperators at this stage default_template = posixpath.join('modules', 'modulefile.tcl') diff --git a/lib/spack/spack/operating_systems/windows_os.py b/lib/spack/spack/operating_systems/windows_os.py index b32768f709..879a2b77c7 100755 --- a/lib/spack/spack/operating_systems/windows_os.py +++ b/lib/spack/spack/operating_systems/windows_os.py @@ -15,12 +15,10 @@ from ._operating_system import OperatingSystem -# FIXME: To get the actual Windows version, we need a python that runs -# natively on Windows, not Cygwin. def windows_version(): """temporary workaround to return a Windows version as a Version object """ - return Version('10') + return Version(platform.release()) class WindowsOs(OperatingSystem): diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index addbdf4e84..d91c5109ae 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -898,6 +898,16 @@ def version(self): " does not have a concrete version.") return self.spec.versions[0] + @property + def platform_executables(self): + plat_exe = [] + if hasattr(self, 'executables'): + for exe in self.executables: + if sys.platform == 'win32': + exe = exe.replace('$', r'\.exe$') + plat_exe.append(exe) + return plat_exe + @memoized def version_urls(self): """OrderedDict of explicitly defined URLs for versions of this package. diff --git a/lib/spack/spack/parse.py b/lib/spack/spack/parse.py index 52dec5a5fe..2d4dce3a75 100644 --- a/lib/spack/spack/parse.py +++ b/lib/spack/spack/parse.py @@ -11,7 +11,7 @@ from six import string_types import spack.error - +import spack.util.path as sp class Token(object): """Represents tokens; generated from input by lexer and fed to parse().""" @@ -144,6 +144,9 @@ def expect(self, id): def setup(self, text): if isinstance(text, string_types): + # shlex does not handle Windows path + # separators, so we must normalize to posix + text = sp.convert_to_posix_path(text) text = shlex.split(str(text)) self.text = text self.push_tokens(self.lexer.lex(text)) diff --git a/lib/spack/spack/patch.py b/lib/spack/spack/patch.py index 64f3919029..4485313053 100644 --- a/lib/spack/spack/patch.py +++ b/lib/spack/spack/patch.py @@ -7,6 +7,7 @@ import inspect import os import os.path +import sys import llnl.util.filesystem import llnl.util.lang @@ -33,12 +34,18 @@ def apply_patch(stage, patch_path, level=1, working_dir='.'): (default '.') """ git_utils_path = os.environ.get('PATH', '') - if os.name == 'nt': + if sys.platform == 'win32': git = which_string('git', required=True) - git_root = os.path.dirname(git).split('/')[:-1] + git_root = git.split('\\')[:-2] git_root.extend(['usr', 'bin']) git_utils_path = os.sep.join(git_root) + # TODO: Decouple Spack's patch support on Windows from Git + # for Windows, and instead have Spack directly fetch, install, and + # utilize that patch. + # Note for future developers: The GNU port of patch to windows + # has issues handling CRLF line endings unless the --binary + # flag is passed. patch = which("patch", required=True, path=git_utils_path) with llnl.util.filesystem.working_dir(stage.source_path): patch('-s', diff --git a/lib/spack/spack/paths.py b/lib/spack/spack/paths.py index 5e0c89f25c..4d8747d741 100644 --- a/lib/spack/spack/paths.py +++ b/lib/spack/spack/paths.py @@ -10,7 +10,6 @@ dependencies. """ import os -import posixpath import llnl.util.filesystem @@ -21,41 +20,41 @@ spack_root = prefix #: bin directory in the spack prefix -bin_path = posixpath.join(prefix, "bin") +bin_path = os.path.join(prefix, "bin") #: The spack script itself -spack_script = posixpath.join(bin_path, "spack") +spack_script = os.path.join(bin_path, "spack") #: The sbang script in the spack installation -sbang_script = posixpath.join(bin_path, "sbang") +sbang_script = os.path.join(bin_path, "sbang") # spack directory hierarchy -lib_path = posixpath.join(prefix, "lib", "spack") -external_path = posixpath.join(lib_path, "external") -build_env_path = posixpath.join(lib_path, "env") -module_path = posixpath.join(lib_path, "spack") -command_path = posixpath.join(module_path, "cmd") -analyzers_path = posixpath.join(module_path, "analyzers") -platform_path = posixpath.join(module_path, 'platforms') -compilers_path = posixpath.join(module_path, "compilers") -build_systems_path = posixpath.join(module_path, 'build_systems') -operating_system_path = posixpath.join(module_path, 'operating_systems') -test_path = posixpath.join(module_path, "test") -hooks_path = posixpath.join(module_path, "hooks") -opt_path = posixpath.join(prefix, "opt") -share_path = posixpath.join(prefix, "share", "spack") -etc_path = posixpath.join(prefix, "etc") +lib_path = os.path.join(prefix, "lib", "spack") +external_path = os.path.join(lib_path, "external") +build_env_path = os.path.join(lib_path, "env") +module_path = os.path.join(lib_path, "spack") +command_path = os.path.join(module_path, "cmd") +analyzers_path = os.path.join(module_path, "analyzers") +platform_path = os.path.join(module_path, 'platforms') +compilers_path = os.path.join(module_path, "compilers") +build_systems_path = os.path.join(module_path, 'build_systems') +operating_system_path = os.path.join(module_path, 'operating_systems') +test_path = os.path.join(module_path, "test") +hooks_path = os.path.join(module_path, "hooks") +opt_path = os.path.join(prefix, "opt") +share_path = os.path.join(prefix, "share", "spack") +etc_path = os.path.join(prefix, "etc") # # Things in $spack/var/spack # -var_path = posixpath.join(prefix, "var", "spack") +var_path = os.path.join(prefix, "var", "spack") # read-only things in $spack/var/spack -repos_path = posixpath.join(var_path, "repos") -packages_path = posixpath.join(repos_path, "builtin") -mock_packages_path = posixpath.join(repos_path, "builtin.mock") +repos_path = os.path.join(var_path, "repos") +packages_path = os.path.join(repos_path, "builtin") +mock_packages_path = os.path.join(repos_path, "builtin.mock") # # Writable things in $spack/var/spack @@ -63,13 +62,13 @@ # TODO: These should probably move to user cache, or some other location. # # fetch cache for downloaded files -default_fetch_cache_path = posixpath.join(var_path, "cache") +default_fetch_cache_path = os.path.join(var_path, "cache") # GPG paths. -gpg_keys_path = posixpath.join(var_path, "gpg") -mock_gpg_data_path = posixpath.join(var_path, "gpg.mock", "data") -mock_gpg_keys_path = posixpath.join(var_path, "gpg.mock", "keys") -gpg_path = posixpath.join(opt_path, "spack", "gpg") +gpg_keys_path = os.path.join(var_path, "gpg") +mock_gpg_data_path = os.path.join(var_path, "gpg.mock", "data") +mock_gpg_keys_path = os.path.join(var_path, "gpg.mock", "keys") +gpg_path = os.path.join(opt_path, "spack", "gpg") # Below paths are where Spack can write information for the user. @@ -88,22 +87,22 @@ def _get_user_cache_path(): user_cache_path = _get_user_cache_path() #: junit, cdash, etc. reports about builds -reports_path = posixpath.join(user_cache_path, "reports") +reports_path = os.path.join(user_cache_path, "reports") #: installation test (spack test) output -default_test_path = posixpath.join(user_cache_path, "test") +default_test_path = os.path.join(user_cache_path, "test") #: spack monitor analysis directories -default_monitor_path = posixpath.join(reports_path, "monitor") +default_monitor_path = os.path.join(reports_path, "monitor") #: git repositories fetched to compare commits to versions -user_repos_cache_path = posixpath.join(user_cache_path, 'git_repos') +user_repos_cache_path = os.path.join(user_cache_path, 'git_repos') #: bootstrap store for bootstrapping clingo and other tools -default_user_bootstrap_path = posixpath.join(user_cache_path, 'bootstrap') +default_user_bootstrap_path = os.path.join(user_cache_path, 'bootstrap') #: transient caches for Spack data (virtual cache, patch sha256 lookup, etc.) -default_misc_cache_path = posixpath.join(user_cache_path, 'cache') +default_misc_cache_path = os.path.join(user_cache_path, 'cache') # Below paths pull configuration from the host environment. diff --git a/lib/spack/spack/platforms/_platform.py b/lib/spack/spack/platforms/_platform.py index a19381b8d4..b68b7f1299 100644 --- a/lib/spack/spack/platforms/_platform.py +++ b/lib/spack/spack/platforms/_platform.py @@ -2,8 +2,6 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) -import platform - import llnl.util.lang import spack.error @@ -145,6 +143,3 @@ def oses(): for o in sorted(self.operating_sys.values()): yield o._cmp_iter yield oses - - def is_64bit(self): - return platform.machine().endswith('64') diff --git a/lib/spack/spack/repo.py b/lib/spack/spack/repo.py index 9bcca297f4..e1403bd44f 100644 --- a/lib/spack/spack/repo.py +++ b/lib/spack/spack/repo.py @@ -11,7 +11,7 @@ import inspect import itertools import os -import posixpath +import os.path import re import shutil import stat @@ -138,8 +138,6 @@ class FastPackageChecker(Mapping): def __init__(self, packages_path): # The path of the repository managed by this instance self.packages_path = packages_path - if sys.platform == 'win32': - self.packages_path = self.packages_path.replace("\\", "/") # If the cache we need is not there yet, then build it appropriately if packages_path not in self._paths_cache: @@ -166,7 +164,7 @@ def _create_new_cache(self): # type: () -> Dict[str, os.stat_result] cache = {} # type: Dict[str, os.stat_result] for pkg_name in os.listdir(self.packages_path): # Skip non-directories in the package root. - pkg_dir = posixpath.join(self.packages_path, pkg_name) + pkg_dir = os.path.join(self.packages_path, pkg_name) # Warn about invalid names that look like packages. if not nm.valid_module_name(pkg_name): @@ -177,7 +175,7 @@ def _create_new_cache(self): # type: () -> Dict[str, os.stat_result] continue # Construct the file name from the directory - pkg_file = posixpath.join( + pkg_file = os.path.join( self.packages_path, pkg_name, package_file_name ) @@ -710,8 +708,6 @@ def __init__(self, root): # Root directory, containing _repo.yaml and package dirs # Allow roots to by spack-relative by starting with '$spack' self.root = spack.util.path.canonicalize_path(root) - if sys.platform == 'win32': - self.root = self.root.replace("\\", "/") # check and raise BadRepoError on fail. def check(condition, msg): @@ -719,18 +715,18 @@ def check(condition, msg): raise BadRepoError(msg) # Validate repository layout. - self.config_file = posixpath.join(self.root, repo_config_name) + self.config_file = os.path.join(self.root, repo_config_name) check(os.path.isfile(self.config_file), "No %s found in '%s'" % (repo_config_name, root)) - self.packages_path = posixpath.join(self.root, packages_dir_name) + self.packages_path = os.path.join(self.root, packages_dir_name) check(os.path.isdir(self.packages_path), "No directory '%s' found in '%s'" % (packages_dir_name, root)) # Read configuration and validate namespace config = self._read_config() check('namespace' in config, '%s must define a namespace.' - % posixpath.join(root, repo_config_name)) + % os.path.join(root, repo_config_name)) self.namespace = config['namespace'] check(re.match(r'[a-zA-Z][a-zA-Z0-9_.]+', self.namespace), @@ -979,7 +975,7 @@ def extensions_for(self, extendee_spec): def dirname_for_package_name(self, pkg_name): """Get the directory name for a particular package. This is the directory that contains its package.py file.""" - return posixpath.join(self.packages_path, pkg_name) + return os.path.join(self.packages_path, pkg_name) def filename_for_package_name(self, pkg_name): """Get the filename for the module we should load for a particular @@ -991,7 +987,7 @@ def filename_for_package_name(self, pkg_name): the package exists before importing. """ pkg_dir = self.dirname_for_package_name(pkg_name) - return posixpath.join(pkg_dir, package_file_name) + return os.path.join(pkg_dir, package_file_name) @property def _pkg_checker(self): @@ -1167,8 +1163,8 @@ def create_repo(root, namespace=None): "Cannot create repository in %s: can't access parent!" % root) try: - config_path = posixpath.join(root, repo_config_name) - packages_path = posixpath.join(root, packages_dir_name) + config_path = os.path.join(root, repo_config_name) + packages_path = os.path.join(root, packages_dir_name) fs.mkdirp(packages_path) with open(config_path, 'w') as config: diff --git a/lib/spack/spack/reporters/cdash.py b/lib/spack/spack/reporters/cdash.py index 06f4479b14..d947becde8 100644 --- a/lib/spack/spack/reporters/cdash.py +++ b/lib/spack/spack/reporters/cdash.py @@ -62,6 +62,8 @@ class CDash(Reporter): def __init__(self, args): Reporter.__init__(self, args) self.success = True + # Posixpath is used here to support the underlying template enginge + # Jinja2, which expects `/` path separators self.template_dir = posixpath.join('reports', 'cdash') self.cdash_upload_url = args.cdash_upload_url diff --git a/lib/spack/spack/reporters/junit.py b/lib/spack/spack/reporters/junit.py index bcd777e532..8ed299fe23 100644 --- a/lib/spack/spack/reporters/junit.py +++ b/lib/spack/spack/reporters/junit.py @@ -18,6 +18,8 @@ class JUnit(Reporter): def __init__(self, args): Reporter.__init__(self, args) + # Posixpath is used here to support the underlying template enginge + # Jinja2, which expects `/` path separators self.template_file = posixpath.join('reports', 'junit.xml') def build_report(self, filename, report_data): diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index 5fc8b69f07..7feebdd4e2 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -81,6 +81,7 @@ import operator import os import re +import sys import warnings import ruamel.yaml as yaml @@ -145,6 +146,7 @@ 'SpecDeprecatedError', ] +is_windows = sys.platform == 'win32' #: Valid pattern for an identifier in Spack identifier_re = r'\w[\w-]*' @@ -4887,7 +4889,10 @@ def __init__(self): # Filenames match before identifiers, so no initial filename # component is parsed as a spec (e.g., in subdir/spec.yaml/json) - (r'[/\w.-]*/[/\w/-]+\.(yaml|json)[^\b]*', + # posixpath on Windows here because this string will be fed through + # shlex + (r'[/\w.-]*/[/\w/-]+\.(yaml|json)[^\b]*' if not is_windows\ + else r'([A-Za-z]:)*?[/\w.-]*/[/\w/-]+\.(yaml|json)[^\b]*', lambda scanner, v: self.token(FILE, v)), # Hash match after filename. No valid filename can be a hash diff --git a/lib/spack/spack/test/bindist.py b/lib/spack/spack/test/bindist.py index c3c7e0e7b2..b7d970c02a 100644 --- a/lib/spack/spack/test/bindist.py +++ b/lib/spack/spack/test/bindist.py @@ -341,8 +341,6 @@ def test_relative_rpaths_install_nondefault(mirror_dir): buildcache_cmd('install', '-auf', cspec.name) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_push_and_fetch_keys(mock_gnupghome): testpath = str(mock_gnupghome) @@ -431,8 +429,6 @@ def fake_full_hash(spec): 'install_mockery_mutable_config', 'mock_packages', 'mock_fetch', 'test_mirror' ) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_spec_needs_rebuild(monkeypatch, tmpdir): """Make sure needs_rebuild properly compares remote full_hash against locally computed one, avoiding unnecessary rebuilds""" @@ -461,8 +457,6 @@ def test_spec_needs_rebuild(monkeypatch, tmpdir): assert rebuild -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures( 'install_mockery_mutable_config', 'mock_packages', 'mock_fetch', ) @@ -502,8 +496,6 @@ def test_generate_index_missing(monkeypatch, tmpdir, mutable_config): assert 'libelf' not in cache_list -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_generate_indices_key_error(monkeypatch, capfd): def mock_list_url(url, recursive=False): @@ -552,8 +544,6 @@ def mock_list_url(url, recursive=False): assert expect in err -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('mock_fetch', 'install_mockery') def test_update_sbang(tmpdir, test_mirror): """Test the creation and installation of buildcaches with default rpaths @@ -625,8 +615,6 @@ def test_update_sbang(tmpdir, test_mirror): uninstall_cmd('-y', '/%s' % new_spec.dag_hash()) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") # Need one where the platform has been changed to the test platform. def test_install_legacy_yaml(test_legacy_mirror, install_mockery_mutable_config, mock_packages): @@ -636,8 +624,6 @@ def test_install_legacy_yaml(test_legacy_mirror, install_mockery_mutable_config, uninstall_cmd('-y', '/t5mczux3tfqpxwmg7egp7axy2jvyulqk') -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures( 'install_mockery_mutable_config', 'mock_packages', 'mock_fetch', ) diff --git a/lib/spack/spack/test/bootstrap.py b/lib/spack/spack/test/bootstrap.py index b0825a521c..8c56cd1cf5 100644 --- a/lib/spack/spack/test/bootstrap.py +++ b/lib/spack/spack/test/bootstrap.py @@ -128,17 +128,13 @@ def test_custom_store_in_environment(mutable_config, tmpdir): install_tree: root: /tmp/store """) - if os.name == 'nt': - sep = '\\' - else: - sep = '/' with spack.environment.Environment(str(tmpdir)): assert spack.environment.active_environment() assert spack.config.get('config:install_tree:root') == '/tmp/store' # Don't trigger evaluation here with spack.bootstrap.ensure_bootstrap_configuration(): pass - assert str(spack.store.root) == sep + os.path.join('tmp', 'store') + assert str(spack.store.root) == os.sep + os.path.join('tmp', 'store') def test_nested_use_of_context_manager(mutable_config): diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index b98b00da7b..50241e6c9e 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -190,10 +190,7 @@ def test_compiler_config_modifications( # Check they were applied for name, value in expected.items(): if value is not None: - eviron_value = os.environ[name] - if sys.platform == "win32": - eviron_value = eviron_value.replace("\\", "/") - assert eviron_value == value + assert os.environ[name] == value continue assert name not in os.environ diff --git a/lib/spack/spack/test/build_system_guess.py b/lib/spack/spack/test/build_system_guess.py index f5b329b9e5..9e97dfbfb2 100644 --- a/lib/spack/spack/test/build_system_guess.py +++ b/lib/spack/spack/test/build_system_guess.py @@ -11,6 +11,9 @@ import spack.stage import spack.util.executable +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + @pytest.fixture( scope='function', @@ -52,8 +55,6 @@ def url_and_build_system(request, tmpdir): orig_dir.chdir() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_build_systems(url_and_build_system): url, build_system = url_and_build_system with spack.stage.Stage(url) as stage: diff --git a/lib/spack/spack/test/build_systems.py b/lib/spack/spack/test/build_systems.py index 337b7c21a1..5c1f3c293c 100644 --- a/lib/spack/spack/test/build_systems.py +++ b/lib/spack/spack/test/build_systems.py @@ -12,7 +12,6 @@ import llnl.util.filesystem as fs import spack.environment -import spack.error as serr import spack.platforms import spack.repo from spack.build_environment import ChildError, get_std_cmake_args, setup_package @@ -125,9 +124,12 @@ def test_cmake_std_args(config, mock_packages): def test_cmake_bad_generator(config, mock_packages): - with pytest.raises(serr.SpackError): - s = Spec('cmake-client generator="Yellow Sticky Note"') - s.concretize() + s = Spec('cmake-client') + s.concretize() + pkg = spack.repo.get(s) + pkg.generator = 'Yellow Sticky Notes' + with pytest.raises(spack.package.InstallError): + get_std_cmake_args(pkg) def test_cmake_secondary_generator(config, mock_packages): @@ -141,8 +143,6 @@ def test_cmake_secondary_generator(config, mock_packages): @pytest.mark.usefixtures('config', 'mock_packages') class TestAutotoolsPackage(object): - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_with_or_without(self): s = Spec('a') s.concretize() @@ -178,8 +178,6 @@ def activate(value): options = pkg.with_or_without('lorem-ipsum', variant='lorem_ipsum') assert '--without-lorem-ipsum' in options - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_none_is_allowed(self): s = Spec('a foo=none') s.concretize() @@ -194,8 +192,6 @@ def test_none_is_allowed(self): assert '--without-baz' in options assert '--no-fee' in options - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_libtool_archive_files_are_deleted_by_default( self, mutable_database ): @@ -213,8 +209,6 @@ def test_libtool_archive_files_are_deleted_by_default( ) assert libtool_deletion_log - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_libtool_archive_files_might_be_installed_on_demand( self, mutable_database, monkeypatch ): @@ -228,8 +222,6 @@ def test_libtool_archive_files_might_be_installed_on_demand( # Assert libtool archives are installed assert os.path.exists(s.package.libtool_archive_file) - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_autotools_gnuconfig_replacement(self, mutable_database): """ Tests whether only broken config.sub and config.guess are replaced with @@ -251,8 +243,6 @@ def test_autotools_gnuconfig_replacement(self, mutable_database): with open(os.path.join(s.prefix.working, 'config.guess')) as f: assert "gnuconfig version of config.guess" not in f.read() - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_autotools_gnuconfig_replacement_disabled(self, mutable_database): """ Tests whether disabling patch_config_files @@ -273,8 +263,6 @@ def test_autotools_gnuconfig_replacement_disabled(self, mutable_database): with open(os.path.join(s.prefix.working, 'config.guess')) as f: assert "gnuconfig version of config.guess" not in f.read() - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.disable_clean_stage_check def test_autotools_gnuconfig_replacement_no_gnuconfig(self, mutable_database): """ @@ -288,8 +276,6 @@ def test_autotools_gnuconfig_replacement_no_gnuconfig(self, mutable_database): with pytest.raises(ChildError, match=msg): s.package.do_install() - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.disable_clean_stage_check def test_broken_external_gnuconfig(self, mutable_database, tmpdir): """ diff --git a/lib/spack/spack/test/buildrequest.py b/lib/spack/spack/test/buildrequest.py index e76e0f4768..86c4a37d0f 100644 --- a/lib/spack/spack/test/buildrequest.py +++ b/lib/spack/spack/test/buildrequest.py @@ -11,6 +11,12 @@ import spack.repo import spack.spec +# Functionality supported on windows however tests are currently failing +# due to compatibility issues, or due to dependent components currently +# being unsupported on Windows +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + def test_build_request_errors(install_mockery): with pytest.raises(ValueError, match='must be a package'): @@ -21,8 +27,6 @@ def test_build_request_errors(install_mockery): inst.BuildRequest(pkg, {}) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_build_request_basics(install_mockery): spec = spack.spec.Spec('dependent-install') spec.concretize() @@ -39,8 +43,6 @@ def test_build_request_basics(install_mockery): assert 'install_deps' in request.install_args -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_build_request_strings(install_mockery): """Tests of BuildRequest repr and str for coverage purposes.""" # Using a package with one dependency diff --git a/lib/spack/spack/test/cache_fetch.py b/lib/spack/spack/test/cache_fetch.py index c809ebb871..44a5275868 100644 --- a/lib/spack/spack/test/cache_fetch.py +++ b/lib/spack/spack/test/cache_fetch.py @@ -4,7 +4,6 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) import os -import sys import pytest @@ -26,8 +25,6 @@ def test_fetch_missing_cache(tmpdir, _fetch_method): fetcher.fetch() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize('_fetch_method', ['curl', 'urllib']) def test_fetch(tmpdir, _fetch_method): """Ensure a fetch after expanding is effectively a no-op.""" diff --git a/lib/spack/spack/test/cc.py b/lib/spack/spack/test/cc.py index 9bed592ed8..36890c2eb2 100644 --- a/lib/spack/spack/test/cc.py +++ b/lib/spack/spack/test/cc.py @@ -102,6 +102,9 @@ test_args_without_paths ) +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + @pytest.fixture(scope='function') def wrapper_environment(): @@ -171,14 +174,12 @@ def dump_mode(cc, args): return cc(*args, output=str).strip() -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_no_wrapper_environment(): with pytest.raises(ProcessError): output = cc(output=str) assert "Spack compiler must be run from Spack" in output -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_vcheck_mode(wrapper_environment): assert dump_mode(cc, ['-I/include', '--version']) == 'vcheck' assert dump_mode(cc, ['-I/include', '-V']) == 'vcheck' @@ -188,19 +189,16 @@ def test_vcheck_mode(wrapper_environment): assert dump_mode(cc, ['-I/include', '-V', '-o', 'output']) == 'vcheck' -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_cpp_mode(wrapper_environment): assert dump_mode(cc, ['-E']) == 'cpp' assert dump_mode(cxx, ['-E']) == 'cpp' assert dump_mode(cpp, []) == 'cpp' -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_as_mode(wrapper_environment): assert dump_mode(cc, ['-S']) == 'as' -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ccld_mode(wrapper_environment): assert dump_mode(cc, []) == 'ccld' assert dump_mode(cc, ['foo.c', '-o', 'foo']) == 'ccld' @@ -209,14 +207,12 @@ def test_ccld_mode(wrapper_environment): 'foo.o', 'bar.o', 'baz.o', '-o', 'foo', '-Wl,-rpath,foo']) == 'ccld' -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ld_mode(wrapper_environment): assert dump_mode(ld, []) == 'ld' assert dump_mode(ld, [ 'foo.o', 'bar.o', 'baz.o', '-o', 'foo', '-Wl,-rpath,foo']) == 'ld' -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ld_flags(wrapper_environment, wrapper_flags): check_args( ld, test_args, @@ -230,7 +226,6 @@ def test_ld_flags(wrapper_environment, wrapper_flags): spack_ldlibs) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_cpp_flags(wrapper_environment, wrapper_flags): check_args( cpp, test_args, @@ -241,7 +236,6 @@ def test_cpp_flags(wrapper_environment, wrapper_flags): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_cc_flags(wrapper_environment, wrapper_flags): check_args( cc, test_args, @@ -254,7 +248,6 @@ def test_cc_flags(wrapper_environment, wrapper_flags): spack_ldlibs) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_cxx_flags(wrapper_environment, wrapper_flags): check_args( cxx, test_args, @@ -267,7 +260,6 @@ def test_cxx_flags(wrapper_environment, wrapper_flags): spack_ldlibs) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_fc_flags(wrapper_environment, wrapper_flags): check_args( fc, test_args, @@ -280,7 +272,6 @@ def test_fc_flags(wrapper_environment, wrapper_flags): spack_ldlibs) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_dep_rpath(wrapper_environment): """Ensure RPATHs for root package are added.""" check_args( @@ -290,7 +281,6 @@ def test_dep_rpath(wrapper_environment): common_compile_args) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_dep_include(wrapper_environment): """Ensure a single dependency include directory is added.""" with set_env(SPACK_INCLUDE_DIRS='x'): @@ -306,7 +296,6 @@ def test_dep_include(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_system_path_cleanup(wrapper_environment): """Ensure SPACK_ENV_PATH is removed from PATH, even with trailing / @@ -327,7 +316,6 @@ def test_system_path_cleanup(wrapper_environment): check_env_var(cc, 'PATH', system_path) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_dep_lib(wrapper_environment): """Ensure a single dependency RPATH is added.""" with set_env(SPACK_LINK_DIRS='x', @@ -345,7 +333,6 @@ def test_dep_lib(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_dep_lib_no_rpath(wrapper_environment): """Ensure a single dependency link flag is added with no dep RPATH.""" with set_env(SPACK_LINK_DIRS='x'): @@ -361,7 +348,6 @@ def test_dep_lib_no_rpath(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_dep_lib_no_lib(wrapper_environment): """Ensure a single dependency RPATH is added with no -L.""" with set_env(SPACK_RPATH_DIRS='x'): @@ -377,7 +363,6 @@ def test_dep_lib_no_lib(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ccld_deps(wrapper_environment): """Ensure all flags are added in ccld mode.""" with set_env(SPACK_INCLUDE_DIRS='xinc:yinc:zinc', @@ -403,7 +388,6 @@ def test_ccld_deps(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ccld_deps_isystem(wrapper_environment): """Ensure all flags are added in ccld mode. When a build uses -isystem, Spack should inject it's @@ -435,7 +419,6 @@ def test_ccld_deps_isystem(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_cc_deps(wrapper_environment): """Ensure -L and RPATHs are not added in cc mode.""" with set_env(SPACK_INCLUDE_DIRS='xinc:yinc:zinc', @@ -454,7 +437,6 @@ def test_cc_deps(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ccld_with_system_dirs(wrapper_environment): """Ensure all flags are added in ccld mode.""" with set_env(SPACK_INCLUDE_DIRS='xinc:yinc:zinc', @@ -491,7 +473,6 @@ def test_ccld_with_system_dirs(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ccld_with_system_dirs_isystem(wrapper_environment): """Ensure all flags are added in ccld mode. Ensure that includes are in the proper @@ -531,7 +512,6 @@ def test_ccld_with_system_dirs_isystem(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ld_deps(wrapper_environment): """Ensure no (extra) -I args or -Wl, are passed in ld mode.""" with set_env(SPACK_INCLUDE_DIRS='xinc:yinc:zinc', @@ -553,7 +533,6 @@ def test_ld_deps(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ld_deps_no_rpath(wrapper_environment): """Ensure SPACK_LINK_DEPS controls -L for ld.""" with set_env(SPACK_INCLUDE_DIRS='xinc:yinc:zinc', @@ -571,7 +550,6 @@ def test_ld_deps_no_rpath(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ld_deps_no_link(wrapper_environment): """Ensure SPACK_RPATH_DEPS controls -rpath for ld.""" with set_env(SPACK_INCLUDE_DIRS='xinc:yinc:zinc', @@ -589,7 +567,6 @@ def test_ld_deps_no_link(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ld_deps_partial(wrapper_environment): """Make sure ld -r (partial link) is handled correctly on OS's where it doesn't accept rpaths. @@ -628,7 +605,6 @@ def test_ld_deps_partial(wrapper_environment): test_args_without_paths) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ccache_prepend_for_cc(wrapper_environment): with set_env(SPACK_CCACHE_BINARY='ccache'): os.environ['SPACK_SHORT_SPEC'] = "foo@1.2=linux-x86_64" @@ -648,7 +624,6 @@ def test_ccache_prepend_for_cc(wrapper_environment): common_compile_args) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_no_ccache_prepend_for_fc(wrapper_environment): os.environ['SPACK_SHORT_SPEC'] = "foo@1.2=linux-x86_64" check_args( @@ -667,8 +642,6 @@ def test_no_ccache_prepend_for_fc(wrapper_environment): common_compile_args) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.regression('9160') def test_disable_new_dtags(wrapper_environment, wrapper_flags): with set_env(SPACK_TEST_COMMAND='dump-args'): @@ -678,8 +651,6 @@ def test_disable_new_dtags(wrapper_environment, wrapper_flags): assert '-Wl,--disable-new-dtags' in result -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.regression('9160') def test_filter_enable_new_dtags(wrapper_environment, wrapper_flags): with set_env(SPACK_TEST_COMMAND='dump-args'): @@ -692,8 +663,6 @@ def test_filter_enable_new_dtags(wrapper_environment, wrapper_flags): assert '-Wl,--enable-new-dtags' not in result -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.regression('22643') def test_linker_strips_loopopt(wrapper_environment, wrapper_flags): with set_env(SPACK_TEST_COMMAND='dump-args'): diff --git a/lib/spack/spack/test/cmd/activate.py b/lib/spack/spack/test/cmd/activate.py index bc15aa7613..edb126be83 100644 --- a/lib/spack/spack/test/cmd/activate.py +++ b/lib/spack/spack/test/cmd/activate.py @@ -13,8 +13,10 @@ install = SpackCommand('install') extensions = SpackCommand('extensions') +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_activate( mock_packages, mock_archive, mock_fetch, config, install_mockery): @@ -24,7 +26,6 @@ def test_activate( assert 'extension1' in output -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_deactivate( mock_packages, mock_archive, mock_fetch, config, install_mockery): @@ -35,7 +36,6 @@ def test_deactivate( assert 'extension1' not in output -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_deactivate_all( mock_packages, mock_archive, mock_fetch, config, install_mockery): diff --git a/lib/spack/spack/test/cmd/analyze.py b/lib/spack/spack/test/cmd/analyze.py index 5084113b3c..77f26ccb23 100644 --- a/lib/spack/spack/test/cmd/analyze.py +++ b/lib/spack/spack/test/cmd/analyze.py @@ -18,6 +18,9 @@ install = SpackCommand('install') analyze = SpackCommand('analyze') +pytestmark = pytest.mark.skipif(sys.platform == 'win32', + reason="Test is unsupported on Windows") + def test_test_package_not_installed(mock_fetch, install_mockery_mutable_config): # We cannot run an analysis for a package not installed @@ -60,8 +63,6 @@ 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. @@ -107,7 +108,6 @@ def _run_analyzer(name, package, tmpdir): return output_file -@pytest.mark.skipif(sys.platform == 'win32', reason="Install hangs on windows") def test_installfiles_analyzer(tmpdir, mock_fetch, install_mockery_mutable_config): """ test the install files analyzer @@ -128,7 +128,6 @@ def test_installfiles_analyzer(tmpdir, mock_fetch, install_mockery_mutable_confi assert key in basenames -@pytest.mark.skipif(sys.platform == 'win32', reason="Install hangs on windows") def test_environment_analyzer(tmpdir, mock_fetch, install_mockery_mutable_config): """ test the environment variables analyzer. @@ -154,8 +153,6 @@ 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. @@ -171,8 +168,6 @@ 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. diff --git a/lib/spack/spack/test/cmd/bootstrap.py b/lib/spack/spack/test/cmd/bootstrap.py index 660b1a5314..6419829f69 100644 --- a/lib/spack/spack/test/cmd/bootstrap.py +++ b/lib/spack/spack/test/cmd/bootstrap.py @@ -10,6 +10,7 @@ import spack.config import spack.environment as ev import spack.main +from spack.util.path import convert_to_posix_path _bootstrap = spack.main.SpackCommand('bootstrap') @@ -40,7 +41,7 @@ def test_root_get_and_set(mutable_config, scope): _bootstrap('root', path, *scope_args) out = _bootstrap('root', *scope_args, output=str) if sys.platform == 'win32': - out = out.replace("\\", "/") + out = convert_to_posix_path(out) assert out.strip() == path diff --git a/lib/spack/spack/test/cmd/buildcache.py b/lib/spack/spack/test/cmd/buildcache.py index f1b51447fa..958f5c3777 100644 --- a/lib/spack/spack/test/cmd/buildcache.py +++ b/lib/spack/spack/test/cmd/buildcache.py @@ -25,6 +25,9 @@ mirror = spack.main.SpackCommand('mirror') uninstall = spack.main.SpackCommand('uninstall') +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + @pytest.fixture() def mock_get_specs(database, monkeypatch): @@ -58,7 +61,6 @@ def test_buildcache_preview_just_runs(database): buildcache('preview', 'mpileaks') -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") @pytest.mark.db @pytest.mark.regression('13757') def test_buildcache_list_duplicates(mock_get_specs, capsys): @@ -68,7 +70,6 @@ def test_buildcache_list_duplicates(mock_get_specs, capsys): assert output.count('mpileaks') == 3 -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") @pytest.mark.db @pytest.mark.regression('17827') def test_buildcache_list_allarch(database, mock_get_specs_multiarch, capsys): @@ -83,7 +84,6 @@ def test_buildcache_list_allarch(database, mock_get_specs_multiarch, capsys): assert output.count('mpileaks') == 2 -@pytest.mark.skipif(sys.platform == 'win32', reason="Install hangs on windows") def tests_buildcache_create( install_mockery, mock_fetch, monkeypatch, tmpdir): """"Ensure that buildcache create creates output files""" @@ -101,7 +101,6 @@ def tests_buildcache_create( os.path.join(str(tmpdir), 'build_cache', tarball)) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def tests_buildcache_create_env( install_mockery, mock_fetch, monkeypatch, tmpdir, mutable_mock_env_path): @@ -124,7 +123,6 @@ def tests_buildcache_create_env( os.path.join(str(tmpdir), 'build_cache', tarball)) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_buildcache_create_fails_on_noargs(tmpdir): """Ensure that buildcache create fails when given no args or environment.""" @@ -132,7 +130,6 @@ def test_buildcache_create_fails_on_noargs(tmpdir): buildcache('create', '-d', str(tmpdir), '--unsigned') -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_buildcache_create_fail_on_perm_denied( install_mockery, mock_fetch, monkeypatch, tmpdir): """Ensure that buildcache create fails on permission denied error.""" @@ -146,7 +143,6 @@ def test_buildcache_create_fail_on_perm_denied( tmpdir.chmod(0o700) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_update_key_index(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, mock_fetch, mock_stage, mock_gnupghome): @@ -183,7 +179,6 @@ def test_update_key_index(tmpdir, mutable_mock_env_path, assert 'index.json' in key_dir_list -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_buildcache_sync(mutable_mock_env_path, install_mockery_mutable_config, mock_packages, mock_fetch, mock_stage, tmpdir): """ @@ -260,7 +255,6 @@ def verify_mirror_contents(): verify_mirror_contents() -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_buildcache_create_install(mutable_mock_env_path, install_mockery_mutable_config, mock_packages, mock_fetch, mock_stage, diff --git a/lib/spack/spack/test/cmd/ci.py b/lib/spack/spack/test/cmd/ci.py index a668e69528..9e257539bb 100644 --- a/lib/spack/spack/test/cmd/ci.py +++ b/lib/spack/spack/test/cmd/ci.py @@ -60,7 +60,6 @@ def set_env_var(key, val): os.environ[key] = val -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_specs_staging(config): """Make sure we achieve the best possible staging for the following spec DAG:: @@ -120,7 +119,6 @@ def test_specs_staging(config): assert (spec_a_label in stages[3]) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ci_generate_with_env(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, project_dir_env, mock_binary_index): @@ -217,7 +215,6 @@ def _validate_needs_graph(yaml_contents, needs_graph, artifacts): break -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_bootstrap_gcc(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, project_dir_env): @@ -280,7 +277,6 @@ def test_ci_generate_bootstrap_gcc(tmpdir, mutable_mock_env_path, _validate_needs_graph(yaml_contents, needs_graph, False) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_bootstrap_artifacts_buildcache(tmpdir, mutable_mock_env_path, install_mockery, @@ -348,7 +344,6 @@ def test_ci_generate_bootstrap_artifacts_buildcache(tmpdir, _validate_needs_graph(yaml_contents, needs_graph, True) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_with_env_missing_section(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, project_dir_env, @@ -375,7 +370,6 @@ def test_ci_generate_with_env_missing_section(tmpdir, mutable_mock_env_path, assert(expect_out in output) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_with_cdash_token(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, project_dir_env, @@ -432,7 +426,6 @@ def test_ci_generate_with_cdash_token(tmpdir, mutable_mock_env_path, assert(filecmp.cmp(orig_file, copy_to_file) is True) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_with_custom_scripts(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, monkeypatch, @@ -524,7 +517,6 @@ def test_ci_generate_with_custom_scripts(tmpdir, mutable_mock_env_path, assert(found_it) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_pkg_with_deps(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, project_dir_env): @@ -579,7 +571,6 @@ def test_ci_generate_pkg_with_deps(tmpdir, mutable_mock_env_path, assert('dependency-install' in found) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_for_pr_pipeline(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, monkeypatch, @@ -644,7 +635,6 @@ def test_ci_generate_for_pr_pipeline(tmpdir, mutable_mock_env_path, assert(pipeline_vars['SPACK_PIPELINE_TYPE'] == 'spack_pull_request') -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_with_external_pkg(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, monkeypatch, @@ -690,7 +680,6 @@ def test_ci_generate_with_external_pkg(tmpdir, mutable_mock_env_path, @pytest.mark.xfail(reason='fails intermittently and covered by gitlab ci') -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ci_rebuild(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, monkeypatch, mock_gnupghome, mock_fetch, project_dir_env, @@ -850,7 +839,6 @@ def mystrip(s): env_cmd('deactivate') -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ci_nothing_to_rebuild(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, monkeypatch, mock_fetch, project_dir_env, mock_binary_index): @@ -925,7 +913,6 @@ def fake_dl_method(spec, *args, **kwargs): env_cmd('deactivate') -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") @pytest.mark.disable_clean_stage_check def test_push_mirror_contents(tmpdir, mutable_mock_env_path, install_mockery_mutable_config, mock_packages, @@ -1076,7 +1063,6 @@ def test_push_mirror_contents(tmpdir, mutable_mock_env_path, assert(len(dl_dir_list) == 3) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_push_mirror_contents_exceptions(monkeypatch, capsys): def failing_access(*args, **kwargs): raise Exception('Error: Access Denied') @@ -1094,7 +1080,6 @@ def failing_access(*args, **kwargs): assert expect_msg in std_out -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_override_runner_attrs(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, monkeypatch, @@ -1240,7 +1225,6 @@ def test_ci_generate_override_runner_attrs(tmpdir, mutable_mock_env_path, assert(the_elt['after_script'][0] == 'post step one') -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_with_workarounds(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, monkeypatch, @@ -1292,7 +1276,6 @@ def test_ci_generate_with_workarounds(tmpdir, mutable_mock_env_path, assert(found_one is True) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") @pytest.mark.disable_clean_stage_check def test_ci_rebuild_index(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, mock_fetch, @@ -1345,7 +1328,6 @@ def test_ci_rebuild_index(tmpdir, mutable_mock_env_path, validate(index_object, db_idx_schema) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ci_generate_bootstrap_prune_dag( install_mockery_mutable_config, mock_packages, mock_fetch, mock_archive, mutable_config, monkeypatch, tmpdir, @@ -1480,7 +1462,6 @@ def fake_get_mirrors_for_spec(spec=None, full_hash_match=False, _validate_needs_graph(new_yaml_contents, needs_graph, False) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_subcommands_without_mirror(tmpdir, mutable_mock_env_path, mock_packages, install_mockery, project_dir_env, @@ -1520,7 +1501,6 @@ def test_ci_subcommands_without_mirror(tmpdir, mutable_mock_env_path, assert(ex in output) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ensure_only_one_temporary_storage(): """Make sure 'gitlab-ci' section of env does not allow specification of both 'enable-artifacts-buildcache' and 'temporary-storage-url-prefix'.""" @@ -1561,7 +1541,6 @@ def test_ensure_only_one_temporary_storage(): validate(yaml_obj, gitlab_ci_schema) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_ci_generate_temp_storage_url(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, monkeypatch, @@ -1618,7 +1597,6 @@ def test_ci_generate_temp_storage_url(tmpdir, mutable_mock_env_path, assert(cleanup_job['stage'] == stages[-2]) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ci_generate_read_broken_specs_url(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, monkeypatch, @@ -1678,7 +1656,6 @@ def test_ci_generate_read_broken_specs_url(tmpdir, mutable_mock_env_path, assert(ex not in output) -@pytest.mark.skipif(sys.platform == 'win32', reason="Not yet implemented on windows") def test_ci_reproduce(tmpdir, mutable_mock_env_path, install_mockery, mock_packages, monkeypatch, last_two_git_commits, project_dir_env, mock_binary_index): diff --git a/lib/spack/spack/test/cmd/commands.py b/lib/spack/spack/test/cmd/commands.py index d3abf5cf6c..bec6cba729 100644 --- a/lib/spack/spack/test/cmd/commands.py +++ b/lib/spack/spack/test/cmd/commands.py @@ -216,7 +216,9 @@ def test_update_completion_arg(tmpdir, monkeypatch): assert "--update-completion" in mock_bashfile.read() -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") +# Note: this test is never expected to be supported on Windows +@pytest.mark.skipif(sys.platform == 'win32', + reason="bash completion script generator fails on windows") def test_updated_completion_scripts(tmpdir): """Make sure our shell tab completion scripts remain up-to-date.""" diff --git a/lib/spack/spack/test/cmd/compiler.py b/lib/spack/spack/test/cmd/compiler.py index 0685ed1437..26dcb7ff59 100644 --- a/lib/spack/spack/test/cmd/compiler.py +++ b/lib/spack/spack/test/cmd/compiler.py @@ -51,7 +51,8 @@ def mock_compiler_dir(tmpdir, mock_compiler_version): return str(tmpdir) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") +@pytest.mark.skipif(sys.platform == 'win32', reason="Cannot execute bash \ + script on Windows") @pytest.mark.regression('11678,13138') def test_compiler_find_without_paths(no_compilers_yaml, working_env, tmpdir): with tmpdir.as_cwd(): @@ -184,7 +185,8 @@ def clangdir(tmpdir): yield tmpdir -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") +@pytest.mark.skipif(sys.platform == 'win32', reason="Cannot execute bash \ + script on Windows") @pytest.mark.regression('17590') def test_compiler_find_mixed_suffixes( no_compilers_yaml, working_env, clangdir): @@ -220,7 +222,8 @@ def test_compiler_find_mixed_suffixes( } -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") +@pytest.mark.skipif(sys.platform == 'win32', reason="Cannot execute bash \ + script on Windows") @pytest.mark.regression('17590') def test_compiler_find_prefer_no_suffix( no_compilers_yaml, working_env, clangdir): @@ -246,7 +249,8 @@ def test_compiler_find_prefer_no_suffix( assert clang['paths']['cxx'] == str(clangdir.join('clang++')) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") +@pytest.mark.skipif(sys.platform == 'win32', reason="Cannot execute bash \ + script on Windows") def test_compiler_find_path_order( no_compilers_yaml, working_env, clangdir): """Ensure that we find compilers that come first in the PATH first diff --git a/lib/spack/spack/test/cmd/config.py b/lib/spack/spack/test/cmd/config.py index afed72df19..a76ec07ca5 100644 --- a/lib/spack/spack/test/cmd/config.py +++ b/lib/spack/spack/test/cmd/config.py @@ -240,7 +240,6 @@ def test_config_add_ordered_dict(mutable_empty_config): """ -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_add_invalid_fails(mutable_empty_config): config('add', 'packages:all:variants:+debug') with pytest.raises( @@ -249,7 +248,6 @@ def test_config_add_invalid_fails(mutable_empty_config): config('add', 'packages:all:True') -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_add_from_file(mutable_empty_config, tmpdir): contents = """spack: config: @@ -267,7 +265,6 @@ def test_config_add_from_file(mutable_empty_config, tmpdir): """ -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_add_from_file_multiple(mutable_empty_config, tmpdir): contents = """spack: config: @@ -323,7 +320,6 @@ def test_config_add_override_leaf_from_file(mutable_empty_config, tmpdir): """ -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_add_update_dict_from_file(mutable_empty_config, tmpdir): config('add', 'packages:all:compiler:[gcc]') @@ -375,7 +371,6 @@ def test_config_add_invalid_file_fails(tmpdir): config('add', '-f', file) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_remove_value(mutable_empty_config): config('add', 'config:dirty:true') config('remove', 'config:dirty:true') @@ -385,7 +380,6 @@ def test_config_remove_value(mutable_empty_config): """ -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_remove_alias_rm(mutable_empty_config): config('add', 'config:dirty:true') config('rm', 'config:dirty:true') @@ -395,7 +389,6 @@ def test_config_remove_alias_rm(mutable_empty_config): """ -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_remove_dict(mutable_empty_config): config('add', 'config:dirty:true') config('rm', 'config:dirty') @@ -405,7 +398,6 @@ def test_config_remove_dict(mutable_empty_config): """ -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_remove_from_list(mutable_empty_config): config('add', 'config:template_dirs:test1') config('add', 'config:template_dirs:[test2]') @@ -420,7 +412,6 @@ def test_remove_from_list(mutable_empty_config): """ -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_remove_list(mutable_empty_config): config('add', 'config:template_dirs:test1') config('add', 'config:template_dirs:[test2]') @@ -435,7 +426,9 @@ def test_remove_list(mutable_empty_config): """ -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") + +@pytest.mark.skipif(sys.platform == 'win32', + reason="Lockfiles not support on Windows (yet)") def test_config_add_to_env(mutable_empty_config, mutable_mock_env_path): ev.create('test') with ev.read('test'): @@ -449,7 +442,6 @@ def test_config_add_to_env(mutable_empty_config, mutable_mock_env_path): assert expected in output -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_add_to_env_preserve_comments(mutable_empty_config, mutable_mock_env_path, tmpdir): @@ -482,7 +474,6 @@ def test_config_add_to_env_preserve_comments(mutable_empty_config, assert output == expected -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_remove_from_env(mutable_empty_config, mutable_mock_env_path): env('create', 'test') @@ -500,7 +491,6 @@ def test_config_remove_from_env(mutable_empty_config, mutable_mock_env_path): assert output == expected -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_update_packages(packages_yaml_v015): """Test Spack updating old packages.yaml format for externals to new format. Ensure that data is preserved and converted @@ -514,7 +504,6 @@ def test_config_update_packages(packages_yaml_v015): check_packages_updated(data) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_update_config(config_yaml_v015): config_yaml_v015() config('update', '-y', 'config') @@ -524,7 +513,6 @@ def test_config_update_config(config_yaml_v015): check_config_updated(data) -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_update_not_needed(mutable_config): data_before = spack.config.get('repos') config('update', '-y', 'repos') @@ -532,7 +520,6 @@ def test_config_update_not_needed(mutable_config): assert data_before == data_after -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_update_fail_on_permission_issue( packages_yaml_v015, monkeypatch ): @@ -546,7 +533,6 @@ def test_config_update_fail_on_permission_issue( config('update', '-y', 'packages') -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_config_revert(packages_yaml_v015): cfg_file = packages_yaml_v015() bkp_file = cfg_file + '.bkp' diff --git a/lib/spack/spack/test/cmd/deprecate.py b/lib/spack/spack/test/cmd/deprecate.py index 17db777acf..0abe0024d7 100644 --- a/lib/spack/spack/test/cmd/deprecate.py +++ b/lib/spack/spack/test/cmd/deprecate.py @@ -17,8 +17,10 @@ find = SpackCommand('find') activate = SpackCommand('activate') +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_deprecate(mock_packages, mock_archive, mock_fetch, install_mockery): install('libelf@0.8.13') install('libelf@0.8.10') @@ -34,7 +36,6 @@ def test_deprecate(mock_packages, mock_archive, mock_fetch, install_mockery): assert non_deprecated == spack.store.db.query('libelf@0.8.13') -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_deprecate_fails_no_such_package(mock_packages, mock_archive, mock_fetch, install_mockery): """Tests that deprecating a spec that is not installed fails. @@ -52,7 +53,6 @@ def test_deprecate_fails_no_such_package(mock_packages, mock_archive, assert "Spec 'libelf@0.8.13' matches no installed packages" in output -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_deprecate_install(mock_packages, mock_archive, mock_fetch, install_mockery): """Tests that the ```-i`` option allows us to deprecate in favor of a spec @@ -71,7 +71,6 @@ def test_deprecate_install(mock_packages, mock_archive, mock_fetch, assert non_deprecated[0].satisfies('libelf@0.8.13') -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_deprecate_deps(mock_packages, mock_archive, mock_fetch, install_mockery): """Test that the deprecate command deprecates all dependencies properly.""" @@ -96,7 +95,6 @@ def test_deprecate_deps(mock_packages, mock_archive, mock_fetch, assert sorted(deprecated) == sorted(list(old_spec.traverse())) -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_deprecate_fails_active_extensions(mock_packages, mock_archive, mock_fetch, install_mockery): """Tests that active extensions and their extendees cannot be @@ -116,7 +114,6 @@ def test_deprecate_fails_active_extensions(mock_packages, mock_archive, assert 'is an active extension of' in output -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_uninstall_deprecated(mock_packages, mock_archive, mock_fetch, install_mockery): """Tests that we can still uninstall deprecated packages.""" @@ -133,7 +130,6 @@ def test_uninstall_deprecated(mock_packages, mock_archive, mock_fetch, assert spack.store.db.query() == non_deprecated -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_deprecate_already_deprecated(mock_packages, mock_archive, mock_fetch, install_mockery): """Tests that we can re-deprecate a spec to change its deprecator.""" @@ -159,7 +155,6 @@ def test_deprecate_already_deprecated(mock_packages, mock_archive, mock_fetch, assert deprecator == spack.spec.Spec('libelf@0.8.13').concretized() -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_deprecate_deprecator(mock_packages, mock_archive, mock_fetch, install_mockery): """Tests that when a deprecator spec is deprecated, its deprecatee specs @@ -190,7 +185,6 @@ def test_deprecate_deprecator(mock_packages, mock_archive, mock_fetch, assert second_deprecator == final_deprecator -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_concretize_deprecated(mock_packages, mock_archive, mock_fetch, install_mockery): """Tests that the concretizer throws an error if we concretize to a diff --git a/lib/spack/spack/test/cmd/dev_build.py b/lib/spack/spack/test/cmd/dev_build.py index 6ce1aca34f..7aa3b58d65 100644 --- a/lib/spack/spack/test/cmd/dev_build.py +++ b/lib/spack/spack/test/cmd/dev_build.py @@ -18,8 +18,10 @@ install = SpackCommand('install') env = SpackCommand('env') +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_dev_build_basics(tmpdir, mock_packages, install_mockery): spec = spack.spec.Spec('dev-build-test-install@0.0.0 dev_path=%s' % tmpdir) spec.concretize() @@ -39,7 +41,6 @@ def test_dev_build_basics(tmpdir, mock_packages, install_mockery): assert os.path.exists(str(tmpdir)) -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_dev_build_before(tmpdir, mock_packages, install_mockery): spec = spack.spec.Spec('dev-build-test-install@0.0.0 dev_path=%s' % tmpdir) spec.concretize() @@ -57,7 +58,6 @@ def test_dev_build_before(tmpdir, mock_packages, install_mockery): assert not os.path.exists(spec.prefix) -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_dev_build_until(tmpdir, mock_packages, install_mockery): spec = spack.spec.Spec('dev-build-test-install@0.0.0 dev_path=%s' % tmpdir) spec.concretize() @@ -76,7 +76,6 @@ def test_dev_build_until(tmpdir, mock_packages, install_mockery): assert not spack.store.db.query(spec, installed=True) -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_dev_build_until_last_phase(tmpdir, mock_packages, install_mockery): # Test that we ignore the last_phase argument if it is already last spec = spack.spec.Spec('dev-build-test-install@0.0.0 dev_path=%s' % tmpdir) @@ -97,7 +96,6 @@ def test_dev_build_until_last_phase(tmpdir, mock_packages, install_mockery): assert os.path.exists(str(tmpdir)) -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_dev_build_before_until(tmpdir, mock_packages, install_mockery, capsys): spec = spack.spec.Spec('dev-build-test-install@0.0.0 dev_path=%s' % tmpdir) spec.concretize() @@ -139,7 +137,6 @@ def mock_module_noop(*args): pass -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_dev_build_drop_in(tmpdir, mock_packages, monkeypatch, install_mockery, working_env): monkeypatch.setattr(os, 'execvp', print_spack_cc) @@ -152,7 +149,6 @@ def test_dev_build_drop_in(tmpdir, mock_packages, monkeypatch, assert "lib/spack/env" in output -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_dev_build_fails_already_installed(tmpdir, mock_packages, install_mockery): spec = spack.spec.Spec('dev-build-test-install@0.0.0 dev_path=%s' % tmpdir) @@ -187,7 +183,6 @@ def test_dev_build_fails_no_version(mock_packages): assert 'dev-build spec must have a single, concrete version' in output -@pytest.mark.skipif(sys.platform == 'win32', reason="Filename/extension is too long") def test_dev_build_env(tmpdir, mock_packages, install_mockery, mutable_mock_env_path): """Test Spack does dev builds for packages in develop section of env.""" @@ -225,7 +220,6 @@ def test_dev_build_env(tmpdir, mock_packages, install_mockery, assert f.read() == spec.package.replacement_string -@pytest.mark.skipif(sys.platform == 'win32', reason="Error on Win") def test_dev_build_env_version_mismatch(tmpdir, mock_packages, install_mockery, mutable_mock_env_path): """Test Spack constraints concretization by develop specs.""" @@ -259,7 +253,6 @@ def test_dev_build_env_version_mismatch(tmpdir, mock_packages, install_mockery, install() -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs") def test_dev_build_multiple(tmpdir, mock_packages, install_mockery, mutable_mock_env_path, mock_fetch): """Test spack install with multiple developer builds""" @@ -315,7 +308,6 @@ def test_dev_build_multiple(tmpdir, mock_packages, install_mockery, assert f.read() == spec.package.replacement_string -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") def test_dev_build_env_dependency(tmpdir, mock_packages, install_mockery, mock_fetch, mutable_mock_env_path): """ @@ -364,7 +356,6 @@ def test_dev_build_env_dependency(tmpdir, mock_packages, install_mockery, assert spec.satisfies('^dev_path=*') -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") @pytest.mark.parametrize('test_spec', ['dev-build-test-install', 'dependent-of-dev-build']) def test_dev_build_rebuild_on_source_changes( diff --git a/lib/spack/spack/test/cmd/develop.py b/lib/spack/spack/test/cmd/develop.py index fcbb490cff..5d101e53f8 100644 --- a/lib/spack/spack/test/cmd/develop.py +++ b/lib/spack/spack/test/cmd/develop.py @@ -17,6 +17,9 @@ develop = SpackCommand('develop') env = SpackCommand('env') +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + @pytest.mark.usefixtures( 'mutable_mock_env_path', 'mock_packages', 'mock_fetch') @@ -41,7 +44,6 @@ def check_develop(self, env, spec, path=None): else: assert yaml_entry['path'] == path - @pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_develop_no_path_no_clone(self): env('create', 'test') with ev.read('test') as e: @@ -50,21 +52,18 @@ def test_develop_no_path_no_clone(self): develop('--no-clone', 'mpich@1.0') self.check_develop(e, spack.spec.Spec('mpich@1.0')) - @pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_develop_no_clone(self, tmpdir): env('create', 'test') with ev.read('test') as e: develop('--no-clone', '-p', str(tmpdir), 'mpich@1.0') self.check_develop(e, spack.spec.Spec('mpich@1.0'), str(tmpdir)) - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_develop(self): env('create', 'test') with ev.read('test') as e: develop('mpich@1.0') self.check_develop(e, spack.spec.Spec('mpich@1.0')) - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_develop_no_args(self): env('create', 'test') with ev.read('test') as e: @@ -76,7 +75,6 @@ def test_develop_no_args(self): develop() self.check_develop(e, spack.spec.Spec('mpich@1.0')) - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_develop_twice(self): env('create', 'test') with ev.read('test') as e: @@ -91,7 +89,6 @@ def test_develop_twice(self): self.check_develop(e, spack.spec.Spec('mpich@1.0')) assert len(e.dev_specs) == 1 - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_develop_update_path(self, tmpdir): env('create', 'test') with ev.read('test') as e: @@ -100,7 +97,6 @@ def test_develop_update_path(self, tmpdir): self.check_develop(e, spack.spec.Spec('mpich@1.0'), str(tmpdir)) assert len(e.dev_specs) == 1 - @pytest.mark.skipif(sys.platform == 'win32', reason="not implemented on windows") def test_develop_update_spec(self): env('create', 'test') with ev.read('test') as e: diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py index 8d88cfcfbd..ae47aada02 100644 --- a/lib/spack/spack/test/cmd/env.py +++ b/lib/spack/spack/test/cmd/env.py @@ -2866,7 +2866,7 @@ def test_custom_store_in_environment(mutable_config, tmpdir): install_tree: root: /tmp/store """) - if os.name == 'nt': + if sys.platform == 'win32': sep = '\\' else: sep = '/' diff --git a/lib/spack/spack/test/cmd/fetch.py b/lib/spack/spack/test/cmd/fetch.py index 59eedc795f..323fd06cd2 100644 --- a/lib/spack/spack/test/cmd/fetch.py +++ b/lib/spack/spack/test/cmd/fetch.py @@ -11,12 +11,12 @@ from spack.main import SpackCommand, SpackCommandError # everything here uses the mock_env_path -pytestmark = pytest.mark.usefixtures( - "mutable_mock_env_path", "config", "mutable_mock_repo" -) +pytestmark = [pytest.mark.usefixtures( + "mutable_mock_env_path", "config", "mutable_mock_repo"), + pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows")] -@pytest.mark.skipif(sys.platform == 'win32', reason="Hangs on windows") @pytest.mark.disable_clean_stage_check def test_fetch_in_env( tmpdir, mock_archive, mock_stage, mock_fetch, install_mockery @@ -30,7 +30,6 @@ def test_fetch_in_env( SpackCommand("fetch")() -@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") @pytest.mark.disable_clean_stage_check def test_fetch_single_spec( tmpdir, mock_archive, mock_stage, mock_fetch, install_mockery @@ -38,7 +37,6 @@ def test_fetch_single_spec( SpackCommand("fetch")("mpileaks") -@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") @pytest.mark.disable_clean_stage_check def test_fetch_multiple_specs( tmpdir, mock_archive, mock_stage, mock_fetch, install_mockery diff --git a/lib/spack/spack/test/cmd/gpg.py b/lib/spack/spack/test/cmd/gpg.py index 96f7948b6d..63d68b93d8 100644 --- a/lib/spack/spack/test/cmd/gpg.py +++ b/lib/spack/spack/test/cmd/gpg.py @@ -52,8 +52,6 @@ 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') diff --git a/lib/spack/spack/test/cmd/is_git_repo.py b/lib/spack/spack/test/cmd/is_git_repo.py index 73135141d9..7cb0dc2694 100644 --- a/lib/spack/spack/test/cmd/is_git_repo.py +++ b/lib/spack/spack/test/cmd/is_git_repo.py @@ -6,6 +6,7 @@ from __future__ import print_function import os +import sys import pytest @@ -44,7 +45,7 @@ def git_tmp_worktree(tmpdir): """Create new worktree in a temporary folder and monkeypatch spack.paths.prefix to point to it. """ - if os.name == 'nt': + if sys.platform == 'win32': long_pth = str(tmpdir).split(os.path.sep) tmp_worktree = os.path.sep.join(long_pth[:-1]) else: diff --git a/lib/spack/spack/test/cmd/load.py b/lib/spack/spack/test/cmd/load.py index 18c00d7d88..01902c3143 100644 --- a/lib/spack/spack/test/cmd/load.py +++ b/lib/spack/spack/test/cmd/load.py @@ -17,8 +17,10 @@ install = SpackCommand('install') location = SpackCommand('location') +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_manpath_trailing_colon(install_mockery, mock_fetch, mock_archive, mock_packages, working_env): """Test that the commands generated by load add the MANPATH prefix @@ -37,7 +39,6 @@ def test_manpath_trailing_colon(install_mockery, mock_fetch, mock_archive, assert any(re.match(r'export MANPATH=.*:/tmp/man:;', ln) for ln in lines) -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_load(install_mockery, mock_fetch, mock_archive, mock_packages): """Test that the commands generated by load add the specified prefix inspections. Also test that Spack records loaded specs by hash in the @@ -68,7 +69,6 @@ def test_load(install_mockery, mock_fetch, mock_archive, mock_packages): assert csh_hash_test in csh_out -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_load_recursive(install_mockery, mock_fetch, mock_archive, mock_packages): """Test that the '-r' option to the load command prepends dependency prefix @@ -97,7 +97,6 @@ def test_load_recursive(install_mockery, mock_fetch, mock_archive, assert csh_hash_test in csh_out -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_load_includes_run_env(install_mockery, mock_fetch, mock_archive, mock_packages): """Tests that environment changes from the package's @@ -112,7 +111,6 @@ def test_load_includes_run_env(install_mockery, mock_fetch, mock_archive, assert 'setenv FOOBAR mpileaks' in csh_out -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages): """Test with and without the --first option""" install('libelf@0.8.12') @@ -125,7 +123,6 @@ def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages): load('--sh', '--first', 'libelf') -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_load_fails_no_shell(install_mockery, mock_fetch, mock_archive, mock_packages): """Test that spack load prints an error message without a shell.""" @@ -135,7 +132,6 @@ def test_load_fails_no_shell(install_mockery, mock_fetch, mock_archive, assert "To set up shell support" in out -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_unload(install_mockery, mock_fetch, mock_archive, mock_packages, working_env): """Tests that any variables set in the user environment are undone by the @@ -158,7 +154,6 @@ def test_unload(install_mockery, mock_fetch, mock_archive, mock_packages, assert 'setenv %s garbage' % uenv.spack_loaded_hashes_var in csh_out -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_unload_fails_no_shell(install_mockery, mock_fetch, mock_archive, mock_packages, working_env): """Test that spack unload prints an error message without a shell.""" diff --git a/lib/spack/spack/test/cmd/mirror.py b/lib/spack/spack/test/cmd/mirror.py index ba7177cb41..317febdd7b 100644 --- a/lib/spack/spack/test/cmd/mirror.py +++ b/lib/spack/spack/test/cmd/mirror.py @@ -110,7 +110,6 @@ def __init__(self, specs=None, all=False, file=None, self.exclude_specs = exclude_specs -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_exclude_specs(mock_packages, config): args = MockMirrorArgs( specs=['mpich'], @@ -126,7 +125,6 @@ def test_exclude_specs(mock_packages, config): assert (not expected_exclude & set(mirror_specs)) -@pytest.mark.skipif(sys.platform == "win32", reason="Test unsupported on Windows") def test_exclude_file(mock_packages, tmpdir, config): exclude_path = os.path.join(str(tmpdir), 'test-exclude.txt') with open(exclude_path, 'w') as exclude_file: diff --git a/lib/spack/spack/test/cmd/reindex.py b/lib/spack/spack/test/cmd/reindex.py index e2049b6671..361b6bb152 100644 --- a/lib/spack/spack/test/cmd/reindex.py +++ b/lib/spack/spack/test/cmd/reindex.py @@ -14,8 +14,10 @@ deprecate = SpackCommand('deprecate') reindex = SpackCommand('reindex') +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_reindex_basic(mock_packages, mock_archive, mock_fetch, install_mockery): install('libelf@0.8.13') @@ -28,7 +30,6 @@ def test_reindex_basic(mock_packages, mock_archive, mock_fetch, assert spack.store.db.query() == all_installed -@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_reindex_db_deleted(mock_packages, mock_archive, mock_fetch, install_mockery): install('libelf@0.8.13') @@ -42,7 +43,6 @@ def test_reindex_db_deleted(mock_packages, mock_archive, mock_fetch, assert spack.store.db.query() == all_installed -@pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_reindex_with_deprecated_packages(mock_packages, mock_archive, mock_fetch, install_mockery): install('libelf@0.8.13') diff --git a/lib/spack/spack/test/cmd/resource.py b/lib/spack/spack/test/cmd/resource.py index 87b4ed8a06..04e7e0e325 100644 --- a/lib/spack/spack/test/cmd/resource.py +++ b/lib/spack/spack/test/cmd/resource.py @@ -24,8 +24,10 @@ '7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730', ] +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + -@pytest.mark.skipif(sys.platform == 'win32', reason="Hashes do not match") def test_resource_list(mock_packages, capfd): with capfd.disabled(): out = resource('list') @@ -43,7 +45,6 @@ def test_resource_list(mock_packages, capfd): assert 'patched by: builtin.mock.patch-a-dependency' in out -@pytest.mark.skipif(sys.platform == 'win32', reason="Hashes do not match") def test_resource_list_only_hashes(mock_packages, capfd): with capfd.disabled(): out = resource('list', '--only-hashes') @@ -52,7 +53,6 @@ def test_resource_list_only_hashes(mock_packages, capfd): assert h in out -@pytest.mark.skipif(sys.platform == 'win32', reason="Hashes do not match") def test_resource_show(mock_packages, capfd): with capfd.disabled(): out = resource('show', 'c45c1564f70def3fc1a6e22139f62cb21cd190cc3a7dbe6f4120fa59ce33dcb8') diff --git a/lib/spack/spack/test/cmd/test.py b/lib/spack/spack/test/cmd/test.py index ff0dbad16b..ad631db899 100644 --- a/lib/spack/spack/test/cmd/test.py +++ b/lib/spack/spack/test/cmd/test.py @@ -18,9 +18,10 @@ install = SpackCommand('install') spack_test = SpackCommand('test') +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_test_package_not_installed( tmpdir, mock_packages, mock_archive, mock_fetch, config, install_mockery_mutable_config, mock_test_stage): @@ -42,8 +43,6 @@ def test_test_dirty_flag(arguments, expected): assert args.dirty == expected -@pytest.mark.skipif(sys.platform == "win32", - reason='Not supported on Windows (yet)') def test_test_dup_alias( mock_test_stage, mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config, capfd): @@ -62,8 +61,6 @@ def test_test_dup_alias( assert "already exists" in out -@pytest.mark.skipif(sys.platform == "win32", - reason='Not supported on Windows (yet)') def test_test_output(mock_test_stage, mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config): """Ensure output printed from pkgs is captured by output redirection.""" @@ -89,8 +86,6 @@ def test_test_output(mock_test_stage, mock_packages, mock_archive, mock_fetch, assert "FAILED" not in output -@pytest.mark.skipif(sys.platform == "win32", - reason='FetchError: All fetchers failed') def test_test_output_on_error( mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config, capfd, mock_test_stage @@ -104,8 +99,6 @@ def test_test_output_on_error( assert "Command exited with status 1" in out -@pytest.mark.skipif(sys.platform == "win32", - reason='FetchError: All fetchers failed') def test_test_output_on_failure( mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config, capfd, mock_test_stage @@ -118,8 +111,6 @@ def test_test_output_on_failure( assert "TestFailure" in out -@pytest.mark.skipif(sys.platform == "win32", - reason='FetchError: All fetchers failed') def test_show_log_on_error( mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config, capfd, mock_test_stage @@ -133,8 +124,6 @@ def test_show_log_on_error( assert mock_test_stage in out -@pytest.mark.skipif(sys.platform == "win32", - reason='FetchError: All fetchers failed') @pytest.mark.usefixtures( 'mock_packages', 'mock_archive', 'mock_fetch', 'install_mockery_mutable_config' @@ -168,8 +157,6 @@ def test_junit_output_with_failures(tmpdir, mock_test_stage, pkg_name, msgs): assert msg in content -@pytest.mark.skipif(sys.platform == "win32", - reason='FetchError: All fetchers failed') def test_cdash_output_test_error( tmpdir, mock_fetch, install_mockery_mutable_config, mock_packages, mock_archive, mock_test_stage, capfd): @@ -189,8 +176,6 @@ def test_cdash_output_test_error( assert 'FAILED: Command exited with status 1' in content -@pytest.mark.skipif(sys.platform == "win32", - reason='FetchError: All fetchers failed') def test_cdash_upload_clean_test( tmpdir, mock_fetch, install_mockery_mutable_config, mock_packages, mock_archive, mock_test_stage): @@ -236,8 +221,6 @@ def test_test_list_all(mock_packages): ]) -@pytest.mark.skipif(sys.platform == "win32", - reason='FetchError: All fetchers failed') def test_test_list( mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config ): @@ -257,8 +240,6 @@ def test_has_test_method_fails(capsys): assert 'is not a class' in captured -@pytest.mark.skipif(sys.platform == "win32", - reason='Not supported on Windows (yet)') def test_hash_change(mock_test_stage, mock_packages, mock_archive, mock_fetch, install_mockery_mutable_config): """Ensure output printed from pkgs is captured by output redirection.""" diff --git a/lib/spack/spack/test/cmd/uninstall.py b/lib/spack/spack/test/cmd/uninstall.py index 4f0c0d9c91..0ce3a260e6 100644 --- a/lib/spack/spack/test/cmd/uninstall.py +++ b/lib/spack/spack/test/cmd/uninstall.py @@ -3,8 +3,6 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) -import sys - import pytest import llnl.util.tty as tty @@ -15,8 +13,8 @@ uninstall = SpackCommand('uninstall') install = SpackCommand('install') -pytestmark = pytest.mark.skipif(sys.platform == "win32", - reason="does not run on windows") +# pytestmark = pytest.mark.skipif(sys.platform == "win32", +# reason="does not run on windows") class MockArgs(object): diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py index d17655122c..7610280123 100644 --- a/lib/spack/spack/test/compilers/basics.py +++ b/lib/spack/spack/test/compilers/basics.py @@ -813,7 +813,7 @@ def _call(*args, **kwargs): @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") + reason="Bash scripting unsupported on Windows (for now)") def test_compiler_flags_use_real_version(working_env, monkeypatch, tmpdir): # Create compiler gcc = str(tmpdir.join('gcc')) @@ -850,7 +850,7 @@ def test_compiler_flags_use_real_version(working_env, monkeypatch, tmpdir): @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") + reason="Apple Clang and XCode unsupported on Windows") def test_apple_clang_setup_environment(mock_executable, monkeypatch): """Test a code path that is taken only if the package uses Xcode on MacOS. diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index 61ecbfc4fd..73da1ccbab 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -370,8 +370,6 @@ def test_concretize_two_virtuals_with_dual_provider_and_a_conflict( with pytest.raises(spack.error.SpackError): s.concretize() - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_no_matching_compiler_specs(self, mock_low_high_config): # only relevant when not building compilers as needed with spack.concretize.enable_compiler_existence_check(): @@ -434,8 +432,6 @@ def test_compiler_inheritance(self, compiler_str): assert spec['libdwarf'].compiler.satisfies(compiler_str) assert spec['libelf'].compiler.satisfies(compiler_str) - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_external_package(self): spec = Spec('externaltool%gcc') spec.concretize() @@ -443,8 +439,6 @@ def test_external_package(self): assert 'externalprereq' not in spec assert spec['externaltool'].compiler.satisfies('gcc') - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_external_package_module(self): # No tcl modules on darwin/linux machines # TODO: improved way to check for this. @@ -466,8 +460,6 @@ def test_nobuild_package(self): with pytest.raises(spack.error.SpecError): spec.concretize() - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_external_and_virtual(self): spec = Spec('externaltest') spec.concretize() @@ -715,8 +707,6 @@ def test_noversion_pkg(self, spec): with pytest.raises(spack.error.SpackError): Spec(spec).concretized() - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") # Include targets to prevent regression on 20537 @pytest.mark.parametrize('spec, best_achievable', [ ('mpileaks%gcc@4.4.7 ^dyninst@10.2.1 target=x86_64:', 'core2'), @@ -735,8 +725,6 @@ def test_adjusting_default_target_based_on_compiler( s = Spec(spec).concretized() assert str(s.architecture.target) == str(expected) - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.regression('8735,14730') def test_compiler_version_matches_any_entry_in_compilers_yaml(self): # Ensure that a concrete compiler with different compiler version @@ -1127,8 +1115,6 @@ def test_custom_compiler_version(self): s = Spec('a %gcc@foo os=redhat6').concretized() assert '%gcc@foo' in s - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_all_patches_applied(self): uuidpatch = 'a60a42b73e03f207433c5579de207c6ed61d58e4d12dd3b5142eb525728d89ea' localpatch = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' @@ -1166,8 +1152,6 @@ def test_external_package_versions(self, spec_str, is_external, expected): assert s.external == is_external assert s.satisfies(expected) - @pytest.mark.skipif(sys.platform == "win32", - reason='Not supported on Windows (yet)') @pytest.mark.regression('20292') @pytest.mark.parametrize('context', [ {'add_variant': True, 'delete_variant': False}, diff --git a/lib/spack/spack/test/concretize_preferences.py b/lib/spack/spack/test/concretize_preferences.py index dccaee80a5..75aa3e813c 100644 --- a/lib/spack/spack/test/concretize_preferences.py +++ b/lib/spack/spack/test/concretize_preferences.py @@ -17,9 +17,6 @@ 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): diff --git a/lib/spack/spack/test/config_values.py b/lib/spack/spack/test/config_values.py index e1c736768c..6600545610 100644 --- a/lib/spack/spack/test/config_values.py +++ b/lib/spack/spack/test/config_values.py @@ -9,9 +9,10 @@ import spack.spec import spack.store +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('hash_length', [1, 2, 3, 4, 5, 9]) @pytest.mark.usefixtures('mock_packages') def test_set_install_hash_length(hash_length, mutable_config, tmpdir): @@ -28,8 +29,6 @@ def test_set_install_hash_length(hash_length, mutable_config, tmpdir): assert len(hash_str) == hash_length -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.use_fixtures('mock_packages') def test_set_install_hash_length_upper_case(mutable_config, tmpdir): mutable_config.set('config:install_hash_length', 5) diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py index 97399190b6..3d9acf4594 100644 --- a/lib/spack/spack/test/conftest.py +++ b/lib/spack/spack/test/conftest.py @@ -48,6 +48,8 @@ from spack.fetch_strategy import FetchError, FetchStrategyComposite, URLFetchStrategy from spack.util.pattern import Bunch +is_windows = sys.platform == 'win32' + # # Return list of shas for latest two git commits in local spack repo @@ -532,6 +534,11 @@ def linux_os(): return LinuxOS(name=name, version=version) +@pytest.fixture(autouse=is_windows, scope='session') +def platform_config(): + spack.config.add_default_platform_scope(spack.platforms.real_host().name) + + @pytest.fixture(scope='session') def default_config(): """Isolates the default configuration from the user configs. @@ -539,6 +546,8 @@ def default_config(): This ensures we can test the real default configuration without having tests fail when the user overrides the defaults that we test against.""" defaults_path = os.path.join(spack.paths.etc_path, 'spack', 'defaults') + if is_windows: + defaults_path = os.path.join(defaults_path, "windows") with spack.config.use_configuration(defaults_path) as defaults_config: yield defaults_config @@ -592,17 +601,19 @@ def configuration_dir(tmpdir_factory, linux_os): tmpdir.ensure('user', dir=True) # Slightly modify config.yaml and compilers.yaml - if os.name == 'nt': + if is_windows: solver = 'original' + locks = False else: solver = os.environ.get('SPACK_TEST_SOLVER', 'clingo') + locks = True config_yaml = test_config.join('config.yaml') modules_root = tmpdir_factory.mktemp('share') tcl_root = modules_root.ensure('modules', dir=True) lmod_root = modules_root.ensure('lmod', dir=True) content = ''.join(config_yaml.read()).format( - solver, str(tcl_root), str(lmod_root) + solver, locks, str(tcl_root), str(lmod_root) ) t = tmpdir.join('site', 'config.yaml') t.write(content) diff --git a/lib/spack/spack/test/data/config/config.yaml b/lib/spack/spack/test/data/config/config.yaml index d5c5f914fb..43e8ad1abc 100644 --- a/lib/spack/spack/test/data/config/config.yaml +++ b/lib/spack/spack/test/data/config/config.yaml @@ -14,3 +14,4 @@ config: checksum: true dirty: false concretizer: {0} + locks: {1} diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py index af57fb8c5d..a695b8d852 100644 --- a/lib/spack/spack/test/database.py +++ b/lib/spack/spack/test/database.py @@ -37,6 +37,8 @@ from spack.util.executable import Executable from spack.util.mock_package import MockPackageMultiRepo +is_windows = sys.platform == 'win32' + pytestmark = pytest.mark.db @@ -382,8 +384,6 @@ def _mock_remove(spec): spec.package.do_uninstall(spec) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_default_queries(database): # Testing a package whose name *doesn't* start with 'lib' # to ensure the library has 'lib' prepended to the name @@ -424,22 +424,20 @@ def test_default_queries(database): assert os.path.exists(command.path) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_005_db_exists(database): """Make sure db cache file exists after creating.""" index_file = os.path.join(database.root, '.spack-db', 'index.json') lock_file = os.path.join(database.root, '.spack-db', 'lock') assert os.path.exists(str(index_file)) - assert os.path.exists(str(lock_file)) + # Lockfiles not currently supported on Windows + if not is_windows: + assert os.path.exists(str(lock_file)) with open(index_file) as fd: index_object = json.load(fd) validate(index_object, schema) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_010_all_install_sanity(database): """Ensure that the install layout reflects what we think it does.""" all_specs = spack.store.layout.all_specs() @@ -475,8 +473,6 @@ def test_010_all_install_sanity(database): ) == 1 -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_015_write_and_read(mutable_database): # write and read DB with spack.store.db.write_transaction(): @@ -491,8 +487,6 @@ def test_015_write_and_read(mutable_database): assert new_rec.installed == rec.installed -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_017_write_and_read_without_uuid(mutable_database, monkeypatch): monkeypatch.setattr(spack.database, '_use_uuid', False) # write and read DB @@ -508,23 +502,17 @@ def test_017_write_and_read_without_uuid(mutable_database, monkeypatch): assert new_rec.installed == rec.installed -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_020_db_sanity(database): """Make sure query() returns what's actually in the db.""" _check_db_sanity(database) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_025_reindex(mutable_database): """Make sure reindex works and ref counts are valid.""" spack.store.store.reindex() _check_db_sanity(mutable_database) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_026_reindex_after_deprecate(mutable_database): """Make sure reindex works and ref counts are valid after deprecation.""" mpich = mutable_database.query_one('mpich') @@ -546,8 +534,6 @@ def __call__(self): _mock_remove('mpileaks ^zmpi') -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_030_db_sanity_from_another_process(mutable_database): spack_process = spack.subprocess_context.SpackTestProcess(ReadModify()) p = spack_process.create() @@ -559,15 +545,11 @@ def test_030_db_sanity_from_another_process(mutable_database): assert len(mutable_database.query('mpileaks ^zmpi')) == 0 -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_040_ref_counts(database): """Ensure that we got ref counts right when we read the DB.""" database._check_ref_counts() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_041_ref_counts_deprecate(mutable_database): """Ensure that we have appropriate ref counts after deprecating""" mpich = mutable_database.query_one('mpich') @@ -577,8 +559,6 @@ def test_041_ref_counts_deprecate(mutable_database): mutable_database._check_ref_counts() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_050_basic_query(database): """Ensure querying database is consistent with what is installed.""" # query everything @@ -615,20 +595,14 @@ def test_050_basic_query(database): assert len(database.query(end_date=datetime.datetime.max)) == total_specs -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_060_remove_and_add_root_package(mutable_database): _check_remove_and_add_package(mutable_database, 'mpileaks ^mpich') -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_070_remove_and_add_dependency_package(mutable_database): _check_remove_and_add_package(mutable_database, 'dyninst') -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_080_root_ref_counts(mutable_database): rec = mutable_database.get_record('mpileaks ^mpich') @@ -653,8 +627,6 @@ def test_080_root_ref_counts(mutable_database): assert mutable_database.get_record('mpich').ref_count == 2 -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_090_non_root_ref_counts(mutable_database): mutable_database.get_record('mpileaks ^mpich') mutable_database.get_record('callpath ^mpich') @@ -684,8 +656,6 @@ def test_090_non_root_ref_counts(mutable_database): assert mpich_rec.ref_count == 0 -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_100_no_write_with_exception_on_remove(database): def fail_while_writing(): with database.write_transaction(): @@ -703,8 +673,6 @@ def fail_while_writing(): assert len(database.query('mpileaks ^zmpi', installed=any)) == 1 -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_110_no_write_with_exception_on_install(database): def fail_while_writing(): with database.write_transaction(): @@ -719,11 +687,11 @@ def fail_while_writing(): # reload DB and make sure cmake was not written. with database.read_transaction(): + # import pdb; pdb.set_trace() + assert database.query('cmake', installed=any) == [] -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_115_reindex_with_packages_not_in_repo(mutable_database): # Dont add any package definitions to this repository, the idea is that # packages should not have to be defined in the repository once they @@ -733,27 +701,25 @@ def test_115_reindex_with_packages_not_in_repo(mutable_database): _check_db_sanity(mutable_database) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_external_entries_in_db(mutable_database): rec = mutable_database.get_record('mpileaks ^zmpi') assert rec.spec.external_path is None assert not rec.spec.external_modules rec = mutable_database.get_record('externaltool') - assert rec.spec.external_path == '/path/to/external_tool' + assert rec.spec.external_path == os.sep + \ + os.path.join('path', 'to', 'external_tool') assert not rec.spec.external_modules assert rec.explicit is False rec.spec.package.do_install(fake=True, explicit=True) rec = mutable_database.get_record('externaltool') - assert rec.spec.external_path == '/path/to/external_tool' + assert rec.spec.external_path == os.sep + \ + os.path.join('path', 'to', 'external_tool') assert not rec.spec.external_modules assert rec.explicit is True -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.regression('8036') def test_regression_issue_8036(mutable_database, usr_folder_exists): # The test ensures that the external package prefix is treated as @@ -769,8 +735,6 @@ def test_regression_issue_8036(mutable_database, usr_folder_exists): assert s.package.installed -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.regression('11118') def test_old_external_entries_prefix(mutable_database): with open(spack.store.db._index_path, 'r') as f: @@ -796,8 +760,6 @@ def test_old_external_entries_prefix(mutable_database): assert record.spec.prefix == record.spec.external_path -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_uninstall_by_spec(mutable_database): with mutable_database.write_transaction(): for spec in mutable_database.query(): @@ -808,8 +770,6 @@ def test_uninstall_by_spec(mutable_database): assert len(mutable_database.query()) == 0 -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_query_unused_specs(mutable_database): # This spec installs a fake cmake as a build only dependency s = spack.spec.Spec('simple-inheritance') @@ -821,8 +781,6 @@ def test_query_unused_specs(mutable_database): assert unused[0].name == 'cmake' -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.regression('10019') def test_query_spec_with_conditional_dependency(mutable_database): # The issue is triggered by having dependencies that are @@ -835,8 +793,6 @@ def test_query_spec_with_conditional_dependency(mutable_database): assert not results -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.regression('10019') def test_query_spec_with_non_conditional_virtual_dependency(database): # Ensure the same issue doesn't come up for virtual @@ -845,8 +801,6 @@ def test_query_spec_with_non_conditional_virtual_dependency(database): assert len(results) == 1 -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_failed_spec_path_error(database): """Ensure spec not concrete check is covered.""" s = spack.spec.Spec('a') @@ -854,8 +808,6 @@ def test_failed_spec_path_error(database): spack.store.db._failed_spec_path(s) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_clear_failure_keep(mutable_database, monkeypatch, capfd): """Add test coverage for clear_failure operation when to be retained.""" @@ -871,8 +823,6 @@ def _is(db, spec): assert 'Retaining failure marking' in out -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_clear_failure_forced(mutable_database, monkeypatch, capfd): """Add test coverage for clear_failure operation when force.""" @@ -891,8 +841,6 @@ def _is(db, spec): assert 'Unable to remove failure marking' in out -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_mark_failed(mutable_database, monkeypatch, tmpdir, capsys): """Add coverage to mark_failed.""" @@ -914,8 +862,6 @@ def _raise_exc(lock): del spack.store.db._prefix_failures[s.prefix] -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_prefix_failed(mutable_database, monkeypatch): """Add coverage to prefix_failed operation.""" @@ -940,8 +886,6 @@ def _is(db, spec): assert spack.store.db.prefix_failed(s) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_prefix_read_lock_error(mutable_database, monkeypatch): """Cover the prefix read lock exception.""" def _raise(db, spec): @@ -957,8 +901,6 @@ def _raise(db, spec): assert False -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_prefix_write_lock_error(mutable_database, monkeypatch): """Cover the prefix write lock exception.""" def _raise(db, spec): @@ -989,8 +931,6 @@ 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') @@ -1001,8 +941,6 @@ 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 diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py index 671d2db298..af00651592 100644 --- a/lib/spack/spack/test/git_fetch.py +++ b/lib/spack/spack/test/git_fetch.py @@ -6,7 +6,6 @@ import copy import os import shutil -import sys import pytest @@ -20,10 +19,6 @@ from spack.util.executable import which from spack.version import ver -pytestmark = pytest.mark.skipif( - not which('git'), reason='requires git to be installed') - - _mock_transport_error = 'Mock HTTP transport error' @@ -76,6 +71,7 @@ def bad_git(*args, **kwargs): def test_bad_git(tmpdir, mock_bad_git): """Trigger a SpackError when attempt a fetch with a bad git.""" testpath = str(tmpdir) + print(spack.config.get('config:locks')) with pytest.raises(spack.error.SpackError): fetcher = GitFetchStrategy(git='file:///not-a-real-git-repo') @@ -83,8 +79,6 @@ def test_bad_git(tmpdir, mock_bad_git): fetcher.fetch() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize("type_of_test", ['master', 'branch', 'tag', 'commit']) @pytest.mark.parametrize("secure", [True, False]) def test_fetch(type_of_test, @@ -140,8 +134,6 @@ def test_fetch(type_of_test, assert h('HEAD') == h(t.revision) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize("type_of_test", ['branch', 'commit']) def test_debug_fetch( mock_packages, type_of_test, mock_git_repository, config, monkeypatch @@ -182,8 +174,6 @@ def test_needs_stage(): fetcher.fetch() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize("get_full_repo", [True, False]) def test_get_full_repo(get_full_repo, git_version, mock_git_repository, config, mutable_mock_repo, monkeypatch): @@ -229,8 +219,6 @@ def test_get_full_repo(get_full_repo, git_version, mock_git_repository, assert(ncommits == 1) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.disable_clean_stage_check @pytest.mark.parametrize("submodules", [True, False]) def test_gitsubmodule(submodules, mock_git_repository, config, @@ -260,8 +248,6 @@ def test_gitsubmodule(submodules, mock_git_repository, config, assert not os.path.isfile(file_path) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.disable_clean_stage_check def test_gitsubmodules_delete( mock_git_repository, config, mutable_mock_repo, monkeypatch diff --git a/lib/spack/spack/test/hg_fetch.py b/lib/spack/spack/test/hg_fetch.py index befb30b4d2..a3d84b9973 100644 --- a/lib/spack/spack/test/hg_fetch.py +++ b/lib/spack/spack/test/hg_fetch.py @@ -18,12 +18,14 @@ from spack.util.executable import which from spack.version import ver -pytestmark = pytest.mark.skipif( - not which('hg'), reason='requires mercurial to be installed') +# Test functionality covered is supported on Windows, but currently failing +# and expected to be fixed +pytestmark = [pytest.mark.skipif( + not which('hg'), reason='requires mercurial to be installed'), + pytest.mark.skipif( + sys.platform == 'win32', reason="Failing on Win")] -@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( diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py index 1684aec447..053578f156 100644 --- a/lib/spack/spack/test/installer.py +++ b/lib/spack/spack/test/installer.py @@ -451,8 +451,6 @@ def test_package_id_ok(install_mockery): assert pkg.name in inst.package_id(pkg) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_fake_install(install_mockery): spec = spack.spec.Spec('trivial-install-test-package') spec.concretize() @@ -553,6 +551,8 @@ def _repoerr(repo, name): assert "Couldn't copy in provenance for cmake" in out +@pytest.mark.skipif(sys.platform == 'win32', + reason="Not supported on Windows (yet)") def test_clear_failures_success(install_mockery): """Test the clear_failures happy path.""" diff --git a/lib/spack/spack/test/link_paths.py b/lib/spack/spack/test/link_paths.py index 8167472af5..c02d124a8c 100644 --- a/lib/spack/spack/test/link_paths.py +++ b/lib/spack/spack/test/link_paths.py @@ -10,6 +10,7 @@ import spack.paths from spack.compiler import _parse_non_system_link_dirs +is_windows = sys.platform == 'win32' #: directory with sample compiler data datadir = os.path.join(spack.paths.test_path, 'data', 'compiler_verbose_output') @@ -26,6 +27,7 @@ def check_link_paths(filename, paths): with open(os.path.join(datadir, filename)) as file: output = file.read() detected_paths = _parse_non_system_link_dirs(output) + print(detected_paths) actual = detected_paths expected = paths @@ -39,98 +41,144 @@ def check_link_paths(filename, paths): assert actual == expected -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_icc16_link_paths(): - check_link_paths('icc-16.0.3.txt', [ - '/usr/tce/packages/intel/intel-16.0.3/compilers_and_libraries_2016.3.210/linux/compiler/lib/intel64_lin', # noqa - '/usr/tce/packages/gcc/gcc-4.9.3/lib64/gcc/x86_64-unknown-linux-gnu/4.9.3', # noqa - '/usr/tce/packages/gcc/gcc-4.9.3/lib64']) + if is_windows: + check_link_paths('icc-16.0.3.txt', [ + r'C:\usr\tce\packages\intel\intel-16.0.3\compilers_and_libraries_2016.3.210\linux\compiler\lib\intel64_lin', # noqa + r'C:\usr\tce\packages\gcc\gcc-4.9.3\lib64\gcc\x86_64-unknown-linux-gnu\4.9.3', # noqa + r'C:\usr\tce\packages\gcc\gcc-4.9.3\lib64']) + else: + check_link_paths('icc-16.0.3.txt', [ + '/usr/tce/packages/intel/intel-16.0.3/compilers_and_libraries_2016.3.210/linux/compiler/lib/intel64_lin', # noqa + '/usr/tce/packages/gcc/gcc-4.9.3/lib64/gcc/x86_64-unknown-linux-gnu/4.9.3', # noqa + '/usr/tce/packages/gcc/gcc-4.9.3/lib64']) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_pgi_link_paths(): - check_link_paths('pgcc-16.3.txt', [ - '/usr/tce/packages/pgi/pgi-16.3/linux86-64/16.3/lib']) + if is_windows: + check_link_paths('pgcc-16.3.txt', [ + r'C:\usr\tce\packages\pgi\pgi-16.3\linux86-64\16.3\lib']) + else: + check_link_paths('pgcc-16.3.txt', [ + '/usr/tce/packages/pgi/pgi-16.3/linux86-64/16.3/lib']) def test_gcc7_link_paths(): - check_link_paths('gcc-7.3.1.txt', []) + if is_windows: + check_link_paths('gcc-7.3.1.txt', []) + else: + check_link_paths('gcc-7.3.1.txt', []) def test_clang4_link_paths(): - check_link_paths('clang-4.0.1.txt', []) + if is_windows: + check_link_paths('clang-4.0.1.txt', []) + else: + check_link_paths('clang-4.0.1.txt', []) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_xl_link_paths(): - check_link_paths('xl-13.1.5.txt', [ - '/opt/ibm/xlsmp/4.1.5/lib', - '/opt/ibm/xlmass/8.1.5/lib', - '/opt/ibm/xlC/13.1.5/lib']) + if is_windows: + check_link_paths('xl-13.1.5.txt', [ + r'C:\opt\ibm\xlsmp\4.1.5\lib', + r'C:\opt\ibm\xlmass\8.1.5\lib', + r'C:\opt\ibm\xlC\13.1.5\lib']) + else: + check_link_paths('xl-13.1.5.txt', [ + '/opt/ibm/xlsmp/4.1.5/lib', + '/opt/ibm/xlmass/8.1.5/lib', + '/opt/ibm/xlC/13.1.5/lib']) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_cce_link_paths(): - check_link_paths('cce-8.6.5.txt', [ - '/opt/gcc/6.1.0/snos/lib64', - '/opt/cray/dmapp/default/lib64', - '/opt/cray/pe/mpt/7.7.0/gni/mpich-cray/8.6/lib', - '/opt/cray/pe/libsci/17.12.1/CRAY/8.6/x86_64/lib', - '/opt/cray/rca/2.2.16-6.0.5.0_15.34__g5e09e6d.ari/lib64', - '/opt/cray/pe/pmi/5.0.13/lib64', - '/opt/cray/xpmem/2.2.4-6.0.5.0_4.8__g35d5e73.ari/lib64', - '/opt/cray/dmapp/7.1.1-6.0.5.0_49.8__g1125556.ari/lib64', - '/opt/cray/ugni/6.0.14-6.0.5.0_16.9__g19583bb.ari/lib64', - '/opt/cray/udreg/2.3.2-6.0.5.0_13.12__ga14955a.ari/lib64', - '/opt/cray/alps/6.5.28-6.0.5.0_18.6__g13a91b6.ari/lib64', - '/opt/cray/pe/atp/2.1.1/libApp', - '/opt/cray/pe/cce/8.6.5/cce/x86_64/lib', - '/opt/cray/wlm_detect/1.3.2-6.0.5.0_3.1__g388ccd5.ari/lib64', - '/opt/gcc/6.1.0/snos/lib/gcc/x86_64-suse-linux/6.1.0', - '/opt/cray/pe/cce/8.6.5/binutils/x86_64/x86_64-unknown-linux-gnu/lib']) + if is_windows: + check_link_paths('cce-8.6.5.txt', [ + r'C:\opt\gcc\6.1.0\snos\lib64', + r'C:\opt\cray\dmapp\default\lib64', + r'C:\opt\cray\pe\mpt\7.7.0\gni\mpich-cray\8.6\lib', + r'C:\opt\cray\pe\libsci\17.12.1\CRAY\8.6\x86_64\lib', + r'C:\opt\cray\rca\2.2.16-6.0.5.0_15.34__g5e09e6d.ari\lib64', + r'C:\opt\cray\pe\pmi\5.0.13\lib64', + r'C:\opt\cray\xpmem\2.2.4-6.0.5.0_4.8__g35d5e73.ari\lib64', + r'C:\opt\cray\dmapp\7.1.1-6.0.5.0_49.8__g1125556.ari\lib64', + r'C:\opt\cray\ugni\6.0.14-6.0.5.0_16.9__g19583bb.ari\lib64', + r'C:\opt\cray\udreg\2.3.2-6.0.5.0_13.12__ga14955a.ari\lib64', + r'C:\opt\cray\alps\6.5.28-6.0.5.0_18.6__g13a91b6.ari\lib64', + r'C:\opt\cray\pe\atp\2.1.1\libApp', + r'C:\opt\cray\pe\cce\8.6.5\cce\x86_64\lib', + r'C:\opt\cray\wlm_detect\1.3.2-6.0.5.0_3.1__g388ccd5.ari\lib64', + r'C:\opt\gcc\6.1.0\snos\lib\gcc\x86_64-suse-linux\6.1.0', + r'C:\opt\cray\pe\cce\8.6.5\binutils\x86_64\x86_64-unknown-linux-gnu\lib']) + else: + check_link_paths('cce-8.6.5.txt', [ + '/opt/gcc/6.1.0/snos/lib64', + '/opt/cray/dmapp/default/lib64', + '/opt/cray/pe/mpt/7.7.0/gni/mpich-cray/8.6/lib', + '/opt/cray/pe/libsci/17.12.1/CRAY/8.6/x86_64/lib', + '/opt/cray/rca/2.2.16-6.0.5.0_15.34__g5e09e6d.ari/lib64', + '/opt/cray/pe/pmi/5.0.13/lib64', + '/opt/cray/xpmem/2.2.4-6.0.5.0_4.8__g35d5e73.ari/lib64', + '/opt/cray/dmapp/7.1.1-6.0.5.0_49.8__g1125556.ari/lib64', + '/opt/cray/ugni/6.0.14-6.0.5.0_16.9__g19583bb.ari/lib64', + '/opt/cray/udreg/2.3.2-6.0.5.0_13.12__ga14955a.ari/lib64', + '/opt/cray/alps/6.5.28-6.0.5.0_18.6__g13a91b6.ari/lib64', + '/opt/cray/pe/atp/2.1.1/libApp', + '/opt/cray/pe/cce/8.6.5/cce/x86_64/lib', + '/opt/cray/wlm_detect/1.3.2-6.0.5.0_3.1__g388ccd5.ari/lib64', + '/opt/gcc/6.1.0/snos/lib/gcc/x86_64-suse-linux/6.1.0', + '/opt/cray/pe/cce/8.6.5/binutils/x86_64/x86_64-unknown-linux-gnu/lib']) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_clang_apple_ld_link_paths(): - check_link_paths('clang-9.0.0-apple-ld.txt', [ - '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/lib']) # noqa + if is_windows: + check_link_paths('clang-9.0.0-apple-ld.txt', [ + r'C:\Applications\Xcode.app\Contents\Developer\Platforms\MacOSX.platform\Developer\SDKs\MacOSX10.13.sdk\usr\lib']) # noqa + else: + check_link_paths('clang-9.0.0-apple-ld.txt', [ + '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/lib']) # noqa -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_nag_mixed_gcc_gnu_ld_link_paths(): # This is a test of a mixed NAG/GCC toolchain, i.e. 'cxx' is set to g++ and # is used for the rpath detection. The reference compiler output is a # result of # '/path/to/gcc/bin/g++ -Wl,-v ./main.c'. - check_link_paths('collect2-6.3.0-gnu-ld.txt', [ - '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib/gcc/x86_64-pc-linux-gnu/6.5.0', # noqa - '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib64', # noqa - '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib']) # noqa + if is_windows: + check_link_paths('collect2-6.3.0-gnu-ld.txt', [ + r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib\gcc\x86_64-pc-linux-gnu\6.5.0', # noqa + r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib64', # noqa + r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib']) # noqa + else: + check_link_paths('collect2-6.3.0-gnu-ld.txt', [ + '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib/gcc/x86_64-pc-linux-gnu/6.5.0', # noqa + '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib64', # noqa + '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib']) # noqa -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_nag_link_paths(): # This is a test of a NAG-only toolchain, i.e. 'cc' and 'cxx' are empty, # and therefore 'fc' is used for the rpath detection). The reference # compiler output is a result of # 'nagfor -Wc=/path/to/gcc/bin/gcc -Wl,-v ./main.c'. - check_link_paths('nag-6.2-gcc-6.5.0.txt', [ - '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib/gcc/x86_64-pc-linux-gnu/6.5.0', # noqa - '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib64', # noqa - '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib']) # noqa + if is_windows: + check_link_paths('nag-6.2-gcc-6.5.0.txt', [ + r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib\gcc\x86_64-pc-linux-gnu\6.5.0', # noqa + r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib64', # noqa + r'C:\scratch\local1\spack\opt\spack\gcc-6.3.0-haswell\gcc-6.5.0-4sdjgrs\lib']) # noqa + else: + check_link_paths('nag-6.2-gcc-6.5.0.txt', [ + '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib/gcc/x86_64-pc-linux-gnu/6.5.0', # noqa + '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib64', # noqa + '/scratch/local1/spack/opt/spack/gcc-6.3.0-haswell/gcc-6.5.0-4sdjgrs/lib']) # noqa -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_obscure_parsing_rules(): - check_link_paths('obscure-parsing-rules.txt', [ - '/first/path', - '/second/path', - '/third/path']) + if is_windows: + check_link_paths('obscure-parsing-rules.txt', [ + r'C:\first\path', + r'C:\third\path']) + else: + check_link_paths('obscure-parsing-rules.txt', [ + '/first/path', + '/second/path', + '/third/path']) diff --git a/lib/spack/spack/test/llnl/util/filesystem.py b/lib/spack/spack/test/llnl/util/filesystem.py index bb6914760d..463ca1da5a 100644 --- a/lib/spack/spack/test/llnl/util/filesystem.py +++ b/lib/spack/spack/test/llnl/util/filesystem.py @@ -12,7 +12,7 @@ import pytest import llnl.util.filesystem as fs -from llnl.util.symlink import symlink +from llnl.util.symlink import islink, symlink import spack.paths @@ -149,7 +149,7 @@ def test_multiple_src_file_dest(self, stage): fs.install('source/a/*/*', 'dest/1') -@pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") +@pytest.mark.skipif(sys.platform == 'win32', reason="Skip test on Windows") class TestCopyTree: """Tests for ``filesystem.copy_tree``""" @@ -178,7 +178,7 @@ def test_symlinks_true(self, stage): assert os.path.exists('dest/2') if sys.platform != "win32": # TODO: islink will return false for junctions - assert os.path.islink('dest/2') + assert islink('dest/2') assert os.path.exists('dest/a/b2') if sys.platform != "win32": @@ -238,7 +238,7 @@ def test_parent_dir(self, stage): fs.copy_tree('source', 'source/sub/directory') -@pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") +@pytest.mark.skipif(sys.platform == 'win32', reason="Skip test on Windows") class TestInstallTree: """Tests for ``filesystem.install_tree``""" diff --git a/lib/spack/spack/test/llnl/util/link_tree.py b/lib/spack/spack/test/llnl/util/link_tree.py index e62cc06503..aef9aafc6d 100644 --- a/lib/spack/spack/test/llnl/util/link_tree.py +++ b/lib/spack/spack/test/llnl/util/link_tree.py @@ -14,6 +14,9 @@ from spack.stage import Stage +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + @pytest.fixture() def stage(): @@ -53,8 +56,6 @@ def check_dir(filename): assert os.path.isdir(filename) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_merge_to_new_directory(stage, link_tree): with working_dir(stage.path): link_tree.merge('dest') @@ -80,8 +81,6 @@ def test_merge_to_new_directory(stage, link_tree): assert not os.path.exists('dest') -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_merge_to_new_directory_relative(stage, link_tree): with working_dir(stage.path): link_tree.merge('dest', relative=True) @@ -107,8 +106,6 @@ def test_merge_to_new_directory_relative(stage, link_tree): assert not os.path.exists('dest') -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_merge_to_existing_directory(stage, link_tree): with working_dir(stage.path): @@ -142,8 +139,6 @@ def test_merge_to_existing_directory(stage, link_tree): assert not os.path.isfile('dest/c/d/e/7') -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_merge_with_empty_directories(stage, link_tree): with working_dir(stage.path): mkdirp('dest/f/g') @@ -164,8 +159,6 @@ def test_merge_with_empty_directories(stage, link_tree): assert os.path.isdir('dest/f/g') -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_ignore(stage, link_tree): with working_dir(stage.path): touchp('source/.spec') diff --git a/lib/spack/spack/test/llnl/util/lock.py b/lib/spack/spack/test/llnl/util/lock.py index e7788fa5a1..211d822a61 100644 --- a/lib/spack/spack/test/llnl/util/lock.py +++ b/lib/spack/spack/test/llnl/util/lock.py @@ -62,18 +62,14 @@ import llnl.util.multiproc as mp from llnl.util.filesystem import getuid, touch -_platform = sys.platform -if _platform == "win32": - import pywintypes - import win32con - import win32file - LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK - LOCK_SH = 0 - LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY - __overlapped = pywintypes.OVERLAPPED() -else: +is_windows = sys.platform == "win32" +if not is_windows: import fcntl +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + + # # This test can be run with MPI. MPI is "enabled" if we can import # mpi4py and the number of total MPI processes is greater than 1. @@ -131,7 +127,7 @@ def make_readable(*paths): # stat.S_IREAD constants or a corresponding integer value). All other # bits are ignored." for path in paths: - if (_platform != 'win32'): + if not is_windows: mode = 0o555 if os.path.isdir(path) else 0o444 else: mode = stat.S_IREAD @@ -140,7 +136,7 @@ def make_readable(*paths): def make_writable(*paths): for path in paths: - if (_platform != 'win32'): + if not is_windows: mode = 0o755 if os.path.isdir(path) else 0o744 else: mode = stat.S_IWRITE @@ -374,8 +370,6 @@ 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), @@ -403,8 +397,6 @@ def test_write_lock_timeout_on_write_ranges(lock_path): TimeoutWrite(lock_path, 0, 1)) -@pytest.mark.skipif(_platform == 'win32', - reason='locking ranges not supported on windows') def test_write_lock_timeout_on_write_ranges_2(lock_path): multiproc_test( AcquireWrite(lock_path, 0, 64), @@ -413,8 +405,6 @@ def test_write_lock_timeout_on_write_ranges_2(lock_path): TimeoutWrite(lock_path, 63, 1)) -@pytest.mark.skipif(_platform == 'win32', - reason='locking ranges not supported on windows') def test_write_lock_timeout_on_write_ranges_3(lock_path): multiproc_test( AcquireWrite(lock_path, 0, 1), @@ -424,8 +414,6 @@ def test_write_lock_timeout_on_write_ranges_3(lock_path): TimeoutWrite(lock_path)) -@pytest.mark.skipif(_platform == 'win32', - reason='locking ranges not supported on windows') def test_write_lock_timeout_on_write_ranges_4(lock_path): multiproc_test( AcquireWrite(lock_path, 0, 1), @@ -476,8 +464,6 @@ def test_read_lock_timeout_on_write_ranges_2(lock_path): TimeoutRead(lock_path, 0, 1)) -@pytest.mark.skipif(_platform == 'win32', - reason='locking ranges not supported on windows') def test_read_lock_timeout_on_write_ranges_3(lock_path): """two write locks, overlapping read locks""" multiproc_test( @@ -523,8 +509,6 @@ def test_write_lock_timeout_on_read_ranges_2(lock_path): TimeoutWrite(lock_path, 0, 1)) -@pytest.mark.skipif(_platform == 'win32', - reason='locking ranges not supported on windows') def test_write_lock_timeout_on_read_ranges_3(lock_path): multiproc_test( AcquireRead(lock_path, 0, 1), @@ -583,8 +567,6 @@ def test_write_lock_timeout_with_multiple_readers_3_2(lock_path): TimeoutWrite(lock_path)) -@pytest.mark.skipif(_platform == 'win32', - reason='locking ranges not supported on windows') def test_write_lock_timeout_with_multiple_readers_2_1_ranges(lock_path): multiproc_test( AcquireRead(lock_path, 0, 10), @@ -592,8 +574,6 @@ def test_write_lock_timeout_with_multiple_readers_2_1_ranges(lock_path): TimeoutWrite(lock_path, 5, 5)) -@pytest.mark.skipif(_platform == 'win32', - reason='locking ranges not supported on windows') def test_write_lock_timeout_with_multiple_readers_2_3_ranges(lock_path): multiproc_test( AcquireRead(lock_path, 0, 10), @@ -620,8 +600,6 @@ 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.""" @@ -637,8 +615,6 @@ 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) @@ -652,7 +628,6 @@ def test_read_lock_read_only_dir_writable_lockfile(lock_dir, lock_path): pass -@pytest.mark.skipif(_platform == 'win32' or getuid() == 0, reason='user is root') def test_read_lock_no_lockfile(lock_dir, lock_path): """read-only directory, no lockfile (so can't create).""" with read_only(lock_dir): @@ -667,8 +642,6 @@ def test_read_lock_no_lockfile(lock_dir, lock_path): pass -@pytest.mark.skipif(_platform == 'win32', - reason='not supported on windows') def test_upgrade_read_to_write(private_lock_path): """Test that a read lock can be upgraded to a write lock. @@ -706,8 +679,6 @@ 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 @@ -862,8 +833,6 @@ 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, @@ -908,8 +877,6 @@ 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")] @@ -957,8 +924,6 @@ 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")] @@ -1016,8 +981,6 @@ 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")] @@ -1136,8 +1099,6 @@ 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.""" @@ -1189,8 +1150,6 @@ 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.""" @@ -1317,8 +1276,6 @@ def p2(self, barrier, q1, q2): barrier.wait() # ---------------------------------------- 4 -@pytest.mark.skipif(_platform == 'win32', - reason='debug output not supported on windows') def test_lock_debug_output(lock_path): test_debug = LockDebugOutput(lock_path) q1, q2 = Queue(), Queue() @@ -1391,8 +1348,6 @@ def test_downgrade_write_fails(tmpdir): [(errno.EACCES, "Fake EACCES error"), (errno.EAGAIN, "Fake EAGAIN error"), (errno.ENOENT, "Fake ENOENT error")]) -@pytest.mark.skipif(_platform == 'win32', - reason='not supported on windows') def test_poll_lock_exception(tmpdir, monkeypatch, err_num, err_msg): """Test poll lock exception handling.""" def _lockf(fd, cmd, len, start, whence): @@ -1403,23 +1358,13 @@ def _lockf(fd, cmd, len, start, whence): lock = lk.Lock(lockfile) touch(lockfile) - if _platform == 'win32': - monkeypatch.setattr(win32file, 'LockFileEx', _lockf) - - if err_num in [errno.EAGAIN, errno.EACCES]: - assert not lock._poll_lock(win32con.LOCKFILE_EXCLUSIVE_LOCK) - else: - with pytest.raises(IOError, match=err_msg): - lock._poll_lock(win32con.LOCKFILE_EXCLUSIVE_LOCK) + monkeypatch.setattr(fcntl, 'lockf', _lockf) + if err_num in [errno.EAGAIN, errno.EACCES]: + assert not lock._poll_lock(fcntl.LOCK_EX) else: - monkeypatch.setattr(fcntl, 'lockf', _lockf) - - if err_num in [errno.EAGAIN, errno.EACCES]: - assert not lock._poll_lock(fcntl.LOCK_EX) - else: - with pytest.raises(IOError, match=err_msg): - lock._poll_lock(fcntl.LOCK_EX) + with pytest.raises(IOError, match=err_msg): + lock._poll_lock(fcntl.LOCK_EX) def test_upgrade_read_okay(tmpdir): diff --git a/lib/spack/spack/test/main.py b/lib/spack/spack/test/main.py index 225d862759..1bbe594666 100644 --- a/lib/spack/spack/test/main.py +++ b/lib/spack/spack/test/main.py @@ -13,6 +13,10 @@ import spack.paths from spack.main import get_version, main +pytestmark = pytest.mark.skipif( + sys.platform == 'win32', + reason="Test functionality support but failing on Win") + def test_get_version_no_match_git(tmpdir, working_env): git = str(tmpdir.join("git")) @@ -26,8 +30,6 @@ def test_get_version_no_match_git(tmpdir, working_env): assert spack.spack_version == get_version() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_get_version_match_git(tmpdir, working_env): git = str(tmpdir.join("git")) with open(git, "w") as f: diff --git a/lib/spack/spack/test/mirror.py b/lib/spack/spack/test/mirror.py index 0aeb4f46f9..3f02239b61 100644 --- a/lib/spack/spack/test/mirror.py +++ b/lib/spack/spack/test/mirror.py @@ -154,8 +154,6 @@ def test_all_mirror( repos.clear() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize( "mirror", [ @@ -172,8 +170,6 @@ def test_roundtrip_mirror(mirror): assert spack.mirror.Mirror.from_json(mirror_json) == mirror -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize( "invalid_yaml", [ @@ -188,8 +184,6 @@ def test_invalid_yaml_mirror(invalid_yaml): assert invalid_yaml in exc_msg -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize( "invalid_json, error_message", [ @@ -204,8 +198,6 @@ def test_invalid_json_mirror(invalid_json, error_message): assert error_message in exc_msg -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize( "mirror_collection", [ @@ -228,8 +220,6 @@ def test_roundtrip_mirror_collection(mirror_collection): mirror_collection) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize( "invalid_yaml", [ @@ -244,8 +234,6 @@ def test_invalid_yaml_mirror_collection(invalid_yaml): assert invalid_yaml in exc_msg -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize( "invalid_json, error_message", [ @@ -260,16 +248,12 @@ def test_invalid_json_mirror_collection(invalid_json, error_message): assert error_message in exc_msg -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_mirror_archive_paths_no_version(mock_packages, config, mock_archive): spec = Spec('trivial-install-test-package@nonexistingversion') fetcher = spack.fetch_strategy.URLFetchStrategy(mock_archive.url) spack.mirror.mirror_archive_paths(fetcher, 'per-package-ref', spec) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_mirror_with_url_patches(mock_packages, config, monkeypatch): spec = Spec('patch-several-dependencies') spec.concretize() diff --git a/lib/spack/spack/test/modules/common.py b/lib/spack/spack/test/modules/common.py index 12efc8c9e2..401dc73877 100644 --- a/lib/spack/spack/test/modules/common.py +++ b/lib/spack/spack/test/modules/common.py @@ -6,6 +6,7 @@ import collections import os import stat +import sys import pytest @@ -15,6 +16,9 @@ from spack.modules.common import UpstreamModuleIndex from spack.spec import Spec +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + def test_update_dictionary_extending_list(): target = { @@ -78,7 +82,6 @@ def mock_package_perms(monkeypatch): yield perms -@pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_modules_written_with_proper_permissions(mock_module_filename, mock_package_perms, mock_packages, config): @@ -93,8 +96,6 @@ def test_modules_written_with_proper_permissions(mock_module_filename, mock_module_filename).st_mode == mock_package_perms -@pytest.mark.skipif(str(spack.platforms.host()) == "windows", - reason="test unsupported on Windows") @pytest.mark.parametrize('module_type', ['tcl', 'lmod']) def test_modules_default_symlink( module_type, mock_packages, mock_module_filename, mock_module_defaults, config @@ -220,7 +221,6 @@ def test_get_module_upstream(): spack.modules.common.upstream_module_index = old_index -@pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_load_installed_package_not_in_repo(install_mockery, mock_fetch, monkeypatch): # Get a basic concrete spec for the trivial install package. diff --git a/lib/spack/spack/test/modules/lmod.py b/lib/spack/spack/test/modules/lmod.py index e82c9b8b9d..f2aa048705 100644 --- a/lib/spack/spack/test/modules/lmod.py +++ b/lib/spack/spack/test/modules/lmod.py @@ -2,7 +2,6 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) -import os import re import sys @@ -22,6 +21,9 @@ #: Class of the writer tested in this module writer_cls = spack.modules.lmod.LmodModulefileWriter +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + @pytest.fixture(params=[ 'clang@3.3', @@ -44,7 +46,6 @@ def provider(request): @pytest.mark.usefixtures('config', 'mock_packages',) class TestLmod(object): - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_file_layout( self, compiler, provider, factory, module_configuration ): @@ -82,7 +83,6 @@ def test_file_layout( else: assert repetitions == 1 - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_simple_case(self, modulefile_content, module_configuration): """Tests the generation of a simple TCL module file.""" @@ -94,7 +94,6 @@ def test_simple_case(self, modulefile_content, module_configuration): assert 'whatis([[Version : 3.0.4]])' in content assert 'family("mpi")' in content - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_autoload_direct(self, modulefile_content, module_configuration): """Tests the automatic loading of direct dependencies.""" @@ -103,7 +102,6 @@ def test_autoload_direct(self, modulefile_content, module_configuration): assert len([x for x in content if 'depends_on(' in x]) == 2 - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_autoload_all(self, modulefile_content, module_configuration): """Tests the automatic loading of all dependencies.""" @@ -112,7 +110,6 @@ def test_autoload_all(self, modulefile_content, module_configuration): assert len([x for x in content if 'depends_on(' in x]) == 5 - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_alter_environment(self, modulefile_content, module_configuration): """Tests modifications to run-time environment.""" @@ -135,7 +132,6 @@ def test_alter_environment(self, modulefile_content, module_configuration): assert len([x for x in content if 'setenv("FOO", "foo")' in x]) == 0 assert len([x for x in content if 'unsetenv("BAR")' in x]) == 0 - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_prepend_path_separator(self, modulefile_content, module_configuration): """Tests modifications to run-time environment.""" @@ -149,7 +145,6 @@ def test_prepend_path_separator(self, modulefile_content, elif re.match(r'[a-z]+_path\("SEMICOLON"', line): assert line.endswith('"bar", ";")') - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_blacklist(self, modulefile_content, module_configuration): """Tests blacklisting the generation of selected modules.""" @@ -158,7 +153,6 @@ def test_blacklist(self, modulefile_content, module_configuration): assert len([x for x in content if 'depends_on(' in x]) == 1 - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_no_hash(self, factory, module_configuration): """Makes sure that virtual providers (in the hierarchy) always include a hash. Make sure that the module file for the spec @@ -183,7 +177,6 @@ def test_no_hash(self, factory, module_configuration): assert path.endswith(mpileaks_element) - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_no_core_compilers(self, factory, module_configuration): """Ensures that missing 'core_compilers' in the configuration file raises the right exception. @@ -203,7 +196,6 @@ def test_no_core_compilers(self, factory, module_configuration): with pytest.raises(spack.modules.lmod.CoreCompilersNotFoundError): module.write() - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_non_virtual_in_hierarchy(self, factory, module_configuration): """Ensures that if a non-virtual is in hierarchy, an exception will be raised. @@ -214,7 +206,6 @@ def test_non_virtual_in_hierarchy(self, factory, module_configuration): with pytest.raises(spack.modules.lmod.NonVirtualInHierarchyError): module.write() - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_override_template_in_package( self, modulefile_content, module_configuration ): @@ -225,7 +216,6 @@ def test_override_template_in_package( assert 'Override successful!' in content - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_override_template_in_modules_yaml( self, modulefile_content, module_configuration ): @@ -238,7 +228,6 @@ def test_override_template_in_modules_yaml( content = modulefile_content('mpileaks target=x86_64') assert 'Override even better!' in content - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") @pytest.mark.usefixtures('config') def test_external_configure_args( self, factory @@ -249,7 +238,6 @@ def test_external_configure_args( assert 'unknown' in writer.context.configure_options - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_guess_core_compilers( self, factory, module_configuration, monkeypatch ): @@ -273,7 +261,6 @@ def no_op_set(*args, **kwargs): writer, _ = factory(mpileaks_spec_string) assert writer.conf.core_compilers - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") @pytest.mark.parametrize('spec_str', [ 'mpileaks target=nocona', 'mpileaks target=core2', @@ -290,7 +277,6 @@ def test_only_generic_microarchitectures_in_root( if spec.target.family != spec.target: assert str(spec.target) not in writer.layout.arch_dirname - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_projections_specific(self, factory, module_configuration): """Tests reading the correct naming scheme.""" @@ -309,7 +295,6 @@ def test_projections_specific(self, factory, module_configuration): projection = writer.spec.format(writer.conf.projections['mpileaks']) assert projection in writer.layout.use_name - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_projections_all(self, factory, module_configuration): """Tests reading the correct naming scheme.""" @@ -328,7 +313,6 @@ def test_projections_all(self, factory, module_configuration): projection = writer.spec.format(writer.conf.projections['all']) assert projection in writer.layout.use_name - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_config_backwards_compat(self, mutable_config): settings = { 'enable': ['lmod'], @@ -346,7 +330,6 @@ def test_config_backwards_compat(self, mutable_config): assert old_format == new_format assert old_format == settings['lmod'] - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_modules_relative_to_view( self, tmpdir, modulefile_content, module_configuration, install_mockery, mock_fetch diff --git a/lib/spack/spack/test/modules/tcl.py b/lib/spack/spack/test/modules/tcl.py index db8b7e1335..121e47422b 100644 --- a/lib/spack/spack/test/modules/tcl.py +++ b/lib/spack/spack/test/modules/tcl.py @@ -3,7 +3,6 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) -import os import sys import pytest @@ -19,11 +18,13 @@ #: Class of the writer tested in this module writer_cls = spack.modules.tcl.TclModulefileWriter +pytestmark = pytest.mark.skipif(sys.platform == "win32", + reason="does not run on windows") + @pytest.mark.usefixtures('config', 'mock_packages') class TestTcl(object): - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_simple_case(self, modulefile_content, module_configuration): """Tests the generation of a simple TCL module file.""" @@ -32,7 +33,6 @@ def test_simple_case(self, modulefile_content, module_configuration): assert 'module-whatis "mpich @3.0.4"' in content - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_autoload_direct(self, modulefile_content, module_configuration): """Tests the automatic loading of direct dependencies.""" @@ -56,7 +56,6 @@ def test_autoload_direct(self, modulefile_content, module_configuration): messages = [x for x in content if 'puts stderr "Autoloading' in x] assert len(messages) == 0 - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_autoload_all(self, modulefile_content, module_configuration): """Tests the automatic loading of all dependencies.""" @@ -80,7 +79,6 @@ def test_autoload_all(self, modulefile_content, module_configuration): messages = [x for x in content if 'puts stderr "Autoloading' in x] assert len(messages) == 2 - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_prerequisites_direct( self, modulefile_content, module_configuration ): @@ -91,7 +89,6 @@ def test_prerequisites_direct( assert len([x for x in content if 'prereq' in x]) == 2 - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_prerequisites_all(self, modulefile_content, module_configuration): """Tests asking all dependencies as prerequisites.""" @@ -100,7 +97,6 @@ def test_prerequisites_all(self, modulefile_content, module_configuration): assert len([x for x in content if 'prereq' in x]) == 5 - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") def test_alter_environment(self, modulefile_content, module_configuration): """Tests modifications to run-time environment.""" @@ -133,7 +129,6 @@ def test_alter_environment(self, modulefile_content, module_configuration): assert len([x for x in content if 'module load foo/bar' in x]) == 1 assert len([x for x in content if 'setenv LIBDWARF_ROOT' in x]) == 1 - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_blacklist(self, modulefile_content, module_configuration): """Tests blacklisting the generation of selected modules.""" @@ -154,7 +149,6 @@ def test_blacklist(self, modulefile_content, module_configuration): assert len([x for x in content if 'is-loaded' in x]) == 1 assert len([x for x in content if 'module load ' in x]) == 1 - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_naming_scheme_compat(self, factory, module_configuration): """Tests backwards compatibility for naming_scheme key""" module_configuration('naming_scheme') @@ -169,7 +163,6 @@ def test_naming_scheme_compat(self, factory, module_configuration): projection = writer.spec.format(writer.conf.projections['all']) assert projection in writer.layout.use_name - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_projections_specific(self, factory, module_configuration): """Tests reading the correct naming scheme.""" @@ -188,7 +181,6 @@ def test_projections_specific(self, factory, module_configuration): projection = writer.spec.format(writer.conf.projections['mpileaks']) assert projection in writer.layout.use_name - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_projections_all(self, factory, module_configuration): """Tests reading the correct naming scheme.""" @@ -207,7 +199,6 @@ def test_projections_all(self, factory, module_configuration): projection = writer.spec.format(writer.conf.projections['all']) assert projection in writer.layout.use_name - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_invalid_naming_scheme(self, factory, module_configuration): """Tests the evaluation of an invalid naming scheme.""" @@ -219,7 +210,6 @@ def test_invalid_naming_scheme(self, factory, module_configuration): with pytest.raises(RuntimeError): writer.layout.use_name - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_invalid_token_in_env_name(self, factory, module_configuration): """Tests setting environment variables with an invalid name.""" @@ -229,7 +219,6 @@ def test_invalid_token_in_env_name(self, factory, module_configuration): with pytest.raises(RuntimeError): writer.write() - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_conflicts(self, modulefile_content, module_configuration): """Tests adding conflicts to the module.""" @@ -247,7 +236,6 @@ def test_conflicts(self, modulefile_content, module_configuration): with pytest.raises(SystemExit): modulefile_content('mpileaks') - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_module_index( self, module_configuration, factory, tmpdir_factory): @@ -282,7 +270,6 @@ def test_module_index( assert len(index) == 1 assert index[s3.dag_hash()].use_name == w3.layout.use_name - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_suffixes(self, module_configuration, factory): """Tests adding suffixes to module file name.""" module_configuration('suffix') @@ -298,7 +285,6 @@ def test_suffixes(self, module_configuration, factory): writer, spec = factory('mpileaks~debug+opt target=x86_64') assert 'baz-foo-bar' in writer.layout.use_name - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_setup_environment(self, modulefile_content, module_configuration): """Tests the internal set-up of run-time environment.""" @@ -319,7 +305,6 @@ def test_setup_environment(self, modulefile_content, module_configuration): [x for x in content if 'setenv FOOBAR "callpath"' in x] ) == 1 - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_override_config(self, module_configuration, factory): """Tests overriding some sections of the configuration file.""" module_configuration('override_config') @@ -334,7 +319,6 @@ def test_override_config(self, module_configuration, factory): assert 'mpich' not in writer.layout.use_name assert 'static' not in writer.layout.use_name - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_override_template_in_package( self, modulefile_content, module_configuration ): @@ -345,7 +329,6 @@ def test_override_template_in_package( assert 'Override successful!' in content - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_override_template_in_modules_yaml( self, modulefile_content, module_configuration ): @@ -358,7 +341,6 @@ def test_override_template_in_modules_yaml( content = modulefile_content('mpileaks target=x86_64') assert 'Override even better!' in content - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_extend_context( self, modulefile_content, module_configuration ): @@ -371,7 +353,6 @@ def test_extend_context( short_description = 'module-whatis "This package updates the context for TCL modulefiles."' # NOQA: ignore=E501 assert short_description in content - @pytest.mark.skipif(os.name == 'nt', reason="Skip test on Windows") @pytest.mark.regression('4400') @pytest.mark.db def test_blacklist_implicits( @@ -393,7 +374,6 @@ def test_blacklist_implicits( writer = writer_cls(item, 'default') assert writer.conf.blacklisted - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") @pytest.mark.regression('9624') @pytest.mark.db def test_autoload_with_constraints( @@ -411,7 +391,6 @@ def test_autoload_with_constraints( content = modulefile_content('mpileaks ^mpich') assert len([x for x in content if 'is-loaded' in x]) == 0 - @pytest.mark.skipif(sys.platform == 'win32', reason="All Fetchers Failed") def test_config_backwards_compat(self, mutable_config): settings = { 'enable': ['tcl'], diff --git a/lib/spack/spack/test/relocate.py b/lib/spack/spack/test/relocate.py index 9b95e0d2f9..ac490b5fb2 100644 --- a/lib/spack/spack/test/relocate.py +++ b/lib/spack/spack/test/relocate.py @@ -284,8 +284,7 @@ def test_set_elf_rpaths(mock_patchelf): assert patchelf in output -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") +@skip_unless_linux def test_set_elf_rpaths_warning(mock_patchelf): # Mock a failing patchelf command and ensure it warns users patchelf = mock_patchelf('exit 1') diff --git a/lib/spack/spack/test/sbang.py b/lib/spack/spack/test/sbang.py index 6e0c647a6b..ce64d0669b 100644 --- a/lib/spack/spack/test/sbang.py +++ b/lib/spack/spack/test/sbang.py @@ -186,8 +186,6 @@ def script_dir(sbang_line): sdir.destroy() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize('shebang,interpreter', [ (b'#!/path/to/interpreter argument\n', b'/path/to/interpreter'), (b'#! /path/to/interpreter truncated-argum', b'/path/to/interpreter'), @@ -203,8 +201,6 @@ def test_shebang_interpreter_regex(shebang, interpreter): sbang.get_interpreter(shebang) == interpreter -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_shebang_handling(script_dir, sbang_line): sbang.filter_shebangs_in_directory(script_dir.tempdir) @@ -258,8 +254,6 @@ def test_shebang_handling(script_dir, sbang_line): assert f.readline() == last_line -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_shebang_handles_non_writable_files(script_dir, sbang_line): # make a file non-writable st = os.stat(script_dir.long_shebang) @@ -345,20 +339,14 @@ def run_test_install_sbang(group): check_sbang_installation(group) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_install_group_sbang(install_mockery, configure_group_perms): run_test_install_sbang(True) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_install_user_sbang(install_mockery, configure_user_perms): run_test_install_sbang(False) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_install_sbang_too_long(tmpdir): root = str(tmpdir) num_extend = sbang.system_shebang_limit - len(root) - len('/bin/sbang') @@ -377,8 +365,6 @@ def test_install_sbang_too_long(tmpdir): assert 'cannot patch' in err -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_sbang_hook_skips_nonexecutable_blobs(tmpdir): # Write a binary blob to non-executable.sh, with a long interpreter "path" # consisting of invalid UTF-8. The latter is technically not really necessary for @@ -396,8 +382,6 @@ def test_sbang_hook_skips_nonexecutable_blobs(tmpdir): assert b'sbang' not in f.readline() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_sbang_handles_non_utf8_files(tmpdir): # We have an executable with a copyright sign as filename contents = (b'#!' + b'\xa9' * sbang.system_shebang_limit + @@ -432,8 +416,6 @@ def shebang_limits_system_8_spack_16(): sbang.spack_shebang_limit = spack_limit -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_shebang_exceeds_spack_shebang_limit(shebang_limits_system_8_spack_16, tmpdir): """Tests whether shebangs longer than Spack's limit are skipped""" file = str(tmpdir.join('longer_than_spack_limit.sh')) @@ -447,8 +429,6 @@ def test_shebang_exceeds_spack_shebang_limit(shebang_limits_system_8_spack_16, t assert b'sbang' not in f.read() -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_sbang_hook_handles_non_writable_files_preserving_permissions(tmpdir): path = str(tmpdir.join('file.sh')) with open(path, 'w') as f: diff --git a/lib/spack/spack/test/spec_dag.py b/lib/spack/spack/test/spec_dag.py index 929d2c36bb..991adc5fc3 100644 --- a/lib/spack/spack/test/spec_dag.py +++ b/lib/spack/spack/test/spec_dag.py @@ -57,8 +57,6 @@ def _mock(pkg_name, spec, deptypes=all_deptypes): return _mock -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') def test_test_deptype(): """Ensure that test-only dependencies are only included for specified @@ -90,8 +88,6 @@ def test_test_deptype(): assert ('z' not in spec) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') def test_installed_deps(): """Preinstall a package P with a constrained build dependency D, then @@ -140,8 +136,6 @@ def test_installed_deps(): assert a_spec['e'].version == spack.version.Version('2') -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') def test_specify_preinstalled_dep(): """Specify the use of a preinstalled package during concretization with a @@ -167,8 +161,6 @@ def test_specify_preinstalled_dep(): assert set(x.name for x in a_spec.traverse()) == set(['a', 'b', 'c']) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') @pytest.mark.parametrize('spec_str,expr_str,expected', [ ('x ^y@2', 'y@2', True), @@ -207,8 +199,6 @@ def test_conditional_dep_with_user_constraints(spec_str, expr_str, expected): assert result is expected, '{0} in {1}'.format(expr_str, spec) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('mutable_mock_repo', 'config') class TestSpecDag(object): def test_conflicting_package_constraints(self, set_dependency): diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py index 81ce8c6344..681bf42659 100644 --- a/lib/spack/spack/test/spec_syntax.py +++ b/lib/spack/spack/test/spec_syntax.py @@ -287,8 +287,6 @@ def _check_hash_parse(self, spec): str(spec), spec.name + '@' + str(spec.version) + ' /' + spec.dag_hash()[:6]) - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_spec_by_hash(self, database): specs = database.query() @@ -297,8 +295,6 @@ def test_spec_by_hash(self, database): for spec in specs: self._check_hash_parse(spec) - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_dep_spec_by_hash(self, database): mpileaks_zmpi = database.query_one('mpileaks ^zmpi') @@ -327,8 +323,6 @@ def test_dep_spec_by_hash(self, database): assert 'fake' in mpileaks_hash_fake_and_zmpi assert mpileaks_hash_fake_and_zmpi['fake'] == fake - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_multiple_specs_with_hash(self, database): mpileaks_zmpi = database.query_one('mpileaks ^zmpi') @@ -362,8 +356,6 @@ def test_multiple_specs_with_hash(self, database): ' / ' + callpath_mpich2.dag_hash()) assert len(specs) == 2 - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_ambiguous_hash(self, mutable_database): x1 = Spec('a') @@ -382,8 +374,6 @@ def test_ambiguous_hash(self, mutable_database): # ambiguity in first hash character AND spec name self._check_raises(AmbiguousHashError, ['a/x']) - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_invalid_hash(self, database): mpileaks_zmpi = database.query_one('mpileaks ^zmpi') @@ -402,8 +392,6 @@ def test_invalid_hash(self, database): 'mpileaks ^mpich /' + mpileaks_zmpi.dag_hash(), 'mpileaks ^zmpi /' + mpileaks_mpich.dag_hash()]) - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_nonexistent_hash(self, database): """Ensure we get errors for nonexistant hashes.""" @@ -418,8 +406,6 @@ def test_nonexistent_hash(self, database): '/' + no_such_hash, 'mpileaks /' + no_such_hash]) - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.db def test_redundant_spec(self, database): """Check that redundant spec constraints raise errors. @@ -506,8 +492,6 @@ def test_duplicate_architecture_component(self): ] self._check_raises(DuplicateArchitectureError, duplicates) - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') def test_parse_yaml_simple(self, mock_packages, tmpdir): s = Spec('libdwarf') @@ -528,8 +512,6 @@ def test_parse_yaml_simple(self, mock_packages, tmpdir): specs = sp.parse('mvapich_foo {0}'.format(specfile.strpath)) assert len(specs) == 2 - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') def test_parse_filename_missing_slash_as_spec(self, mock_packages, tmpdir): """Ensure that libelf.yaml parses as a spec, NOT a file.""" @@ -573,8 +555,6 @@ def test_parse_filename_missing_slash_as_spec(self, mock_packages, tmpdir): ) ) - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') def test_parse_yaml_dependency(self, mock_packages, tmpdir): s = Spec('libdwarf') @@ -590,8 +570,6 @@ def test_parse_yaml_dependency(self, mock_packages, tmpdir): specs = sp.parse('libdwarf ^ {0}'.format(specfile.strpath)) assert len(specs) == 1 - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') def test_parse_yaml_relative_paths(self, mock_packages, tmpdir): s = Spec('libdwarf') @@ -627,8 +605,6 @@ def test_parse_yaml_relative_paths(self, mock_packages, tmpdir): parent_dir, file_name)) assert len(specs) == 2 - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') def test_parse_yaml_relative_subdir_path(self, mock_packages, tmpdir): s = Spec('libdwarf') @@ -649,8 +625,6 @@ def test_parse_yaml_relative_subdir_path(self, mock_packages, tmpdir): specs = sp.parse('subdir/{0}'.format(file_name)) assert len(specs) == 1 - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') def test_parse_yaml_dependency_relative_paths(self, mock_packages, tmpdir): s = Spec('libdwarf') @@ -710,8 +684,6 @@ def test_yaml_spec_not_filename(self, mock_packages, tmpdir): with pytest.raises(spack.repo.UnknownPackageError): Spec('builtin.mock.yamlfoobar').concretize() - @pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.usefixtures('config') def test_parse_yaml_variant_error(self, mock_packages, tmpdir): s = Spec('a') diff --git a/lib/spack/spack/test/spec_yaml.py b/lib/spack/spack/test/spec_yaml.py index abeeec8f36..b676653849 100644 --- a/lib/spack/spack/test/spec_yaml.py +++ b/lib/spack/spack/test/spec_yaml.py @@ -53,8 +53,6 @@ def test_normal_spec(mock_packages): check_json_round_trip(spec) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize( "invalid_yaml", [ @@ -69,8 +67,6 @@ def test_invalid_yaml_spec(invalid_yaml): assert invalid_yaml in exc_msg -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") @pytest.mark.parametrize( "invalid_json, error_message", [ @@ -85,8 +81,6 @@ def test_invalid_json_spec(invalid_json, error_message): assert error_message in exc_msg -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_external_spec(config, mock_packages): spec = Spec('externaltool') spec.concretize() @@ -106,8 +100,6 @@ def test_ambiguous_version_spec(mock_packages): check_json_round_trip(spec) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_concrete_spec(config, mock_packages): spec = Spec('mpileaks+debug~opt') spec.concretize() @@ -115,8 +107,6 @@ def test_concrete_spec(config, mock_packages): check_json_round_trip(spec) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_yaml_multivalue(config, mock_packages): spec = Spec('multivalue-variant foo="bar,baz"') spec.concretize() @@ -124,8 +114,6 @@ def test_yaml_multivalue(config, mock_packages): check_json_round_trip(spec) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_yaml_subdag(config, mock_packages): spec = Spec('mpileaks^mpich+debug') spec.concretize() @@ -170,8 +158,6 @@ def descend_and_check(iterable, level=0): ht.build_hash, ht.full_hash ]) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_ordered_read_not_required_for_consistent_dag_hash( hash_type, config, mock_packages ): @@ -346,8 +332,6 @@ def check_specs_equal(original_spec, spec_yaml_path): return original_spec.eq_dag(spec_from_yaml) -@pytest.mark.skipif(sys.platform == 'win32', - reason="Not supported on Windows (yet)") def test_save_dependency_spec_jsons_subset(tmpdir, config): output_path = str(tmpdir.mkdir('spec_jsons')) diff --git a/lib/spack/spack/test/stage.py b/lib/spack/spack/test/stage.py index 223769b29b..61228dd40c 100644 --- a/lib/spack/spack/test/stage.py +++ b/lib/spack/spack/test/stage.py @@ -11,7 +11,6 @@ import shutil import stat import sys -import tempfile import pytest diff --git a/lib/spack/spack/test/util/util_url.py b/lib/spack/spack/test/util/util_url.py index 3e5a4816e5..b0316aaf3f 100644 --- a/lib/spack/spack/test/util/util_url.py +++ b/lib/spack/spack/test/util/util_url.py @@ -6,6 +6,7 @@ """Test Spack's URL handling utility functions.""" import os import os.path +import posixpath import sys import pytest @@ -38,7 +39,7 @@ def test_url_parse(): if sys.platform != 'win32': parsed = url_util.parse('file://path/to/resource') assert(parsed.scheme == 'file') - expected = os.path.abspath(os.path.join('path', 'to', 'resource')) + expected = os.path.abspath(posixpath.join('path', 'to', 'resource')) assert(parsed.path == expected) parsed = url_util.parse('https://path/to/resource') diff --git a/lib/spack/spack/test/verification.py b/lib/spack/spack/test/verification.py index 2ad81bb39f..fbfefab1c8 100644 --- a/lib/spack/spack/test/verification.py +++ b/lib/spack/spack/test/verification.py @@ -27,7 +27,7 @@ def test_link_manifest_entry(tmpdir): file = str(tmpdir.join('file')) open(file, 'a').close() link = str(tmpdir.join('link')) - symlink(file, link) + os.symlink(file, link) data = spack.verify.create_manifest_entry(link) assert data['type'] == 'link' @@ -49,7 +49,7 @@ def test_link_manifest_entry(tmpdir): file2 = str(tmpdir.join('file2')) open(file2, 'a').close() os.remove(link) - symlink(file2, link) + os.symlink(file2, link) results = spack.verify.check_entry(link, data) assert results.has_errors() diff --git a/lib/spack/spack/util/compression.py b/lib/spack/spack/util/compression.py index 44d19bd00c..60b43e34ce 100644 --- a/lib/spack/spack/util/compression.py +++ b/lib/spack/spack/util/compression.py @@ -43,7 +43,7 @@ def _unzip(archive_file): """Try to use Python's zipfile, but extract in the current working directory instead of in-place. - If unavailable, try unzip + If unavailable, search for 'unzip' executable on system and use instead Args: archive_file (str): absolute path of the file to be decompressed diff --git a/lib/spack/spack/util/debug.py b/lib/spack/spack/util/debug.py index 580146d288..64f7132a6f 100644 --- a/lib/spack/spack/util/debug.py +++ b/lib/spack/spack/util/debug.py @@ -39,6 +39,19 @@ def register_interrupt_handler(): # Subclass of the debugger to keep readline working. See # https://stackoverflow.com/questions/4716533/how-to-attach-debugger-to-a-python-subproccess/23654936 class ForkablePdb(pdb.Pdb): + """ + This class allows the python debugger to follow forked processes + and can set tracepoints allowing the Python Debugger Pdb to be used + from a python multiprocessing child process. + + This is used the same way one would normally use Pdb, simply import this + class and use as a drop in for Pdb, although the syntax here is slightly different, + requiring the instantiton of this class, i.e. ForkablePdb().set_trace(). + + This should be used when attempting to call a debugger from a + child process spawned by the python multiprocessing such as during + the run of Spack.install, or any where else Spack spawns a child process. + """ _original_stdin_fd = sys.stdin.fileno() _original_stdin = None diff --git a/lib/spack/spack/util/editor.py b/lib/spack/spack/util/editor.py index 1a2c44f8ab..e3f740adac 100644 --- a/lib/spack/spack/util/editor.py +++ b/lib/spack/spack/util/editor.py @@ -14,7 +14,6 @@ """ import os import shlex -import sys import llnl.util.tty as tty @@ -40,10 +39,6 @@ def _find_exe_from_env_var(var): if not exe: return None, [] - if sys.platform == "win32": - # Fix separators - exe = exe.replace('\\', '/') - # split env var into executable and args if needed args = shlex.split(str(exe)) diff --git a/lib/spack/spack/util/lock.py b/lib/spack/spack/util/lock.py index f310627208..ff3e0dd14b 100644 --- a/lib/spack/spack/util/lock.py +++ b/lib/spack/spack/util/lock.py @@ -6,6 +6,7 @@ """Wrapper for ``llnl.util.lock`` allows locking to be enabled/disabled.""" import os import stat +import sys import llnl.util.lock @@ -15,6 +16,8 @@ from llnl.util.lock import * # noqa +is_windows = sys.platform == 'win32' + class Lock(llnl.util.lock.Lock): # type: ignore[no-redef] """Lock that can be disabled. @@ -25,7 +28,7 @@ class Lock(llnl.util.lock.Lock): # type: ignore[no-redef] """ def __init__(self, *args, **kwargs): super(Lock, self).__init__(*args, **kwargs) - self._enable = spack.config.get('config:locks', True) + self._enable = spack.config.get('config:locks', not is_windows) def _lock(self, op, timeout=0): if self._enable: diff --git a/lib/spack/spack/util/path.py b/lib/spack/spack/util/path.py index c8fb9aaea4..b56ec11ede 100644 --- a/lib/spack/spack/util/path.py +++ b/lib/spack/spack/util/path.py @@ -167,6 +167,14 @@ def marshall_path(path, mode=Path.unix): return path +def convert_to_posix_path(path): + return path.replace('\\', '/') + + +def convert_to_windows_path(path): + return path.replace('/', '\\') + + def substitute_config_variables(path): """Substitute placeholders into paths. diff --git a/lib/spack/spack/util/url.py b/lib/spack/spack/util/url.py index 656c13fa87..7f7554e838 100644 --- a/lib/spack/spack/util/url.py +++ b/lib/spack/spack/util/url.py @@ -15,7 +15,6 @@ import six.moves.urllib.parse as urllib_parse from six import string_types -from six.moves.urllib.request import url2pathname import spack.util.path diff --git a/lib/spack/spack/util/web.py b/lib/spack/spack/util/web.py index f42087dcc6..b13bde2e98 100644 --- a/lib/spack/spack/util/web.py +++ b/lib/spack/spack/util/web.py @@ -167,7 +167,7 @@ def push_to_url( local_file_path, remote_path, keep_original=True, extra_args=None): if sys.platform == "win32": if remote_path[1] == ':': - remote_path = "file:///" + remote_path + remote_path = "file://" + remote_path remote_url = url_util.parse(remote_path) verify_ssl = spack.config.get('config:verify_ssl') diff --git a/share/spack/spack-completion.bash b/share/spack/spack-completion.bash index 99572bea14..9e4586abbb 100755 --- a/share/spack/spack-completion.bash +++ b/share/spack/spack-completion.bash @@ -1241,7 +1241,7 @@ _spack_maintainers() { _spack_make_installer() { if $list_options then - SPACK_COMPREPLY="-h --help -v --spack_version -s --spack_source -g --git-installer-verbosity" + SPACK_COMPREPLY="-h --help -v --spack-version -s --spack-source -g --git-installer-verbosity" else SPACK_COMPREPLY="" fi diff --git a/var/spack/repos/builtin/packages/cmake/package.py b/var/spack/repos/builtin/packages/cmake/package.py index e431dc62e5..618c6297f2 100644 --- a/var/spack/repos/builtin/packages/cmake/package.py +++ b/var/spack/repos/builtin/packages/cmake/package.py @@ -5,7 +5,6 @@ import os import re -import shutil import sys import spack.build_environment @@ -145,11 +144,7 @@ class Cmake(Package): # https://gitlab.kitware.com/cmake/cmake/merge_requests/4075 patch('fix-xlf-ninja-mr-4075.patch', sha256="42d8b2163a2f37a745800ec13a96c08a3a20d5e67af51031e51f63313d0dedd1", when="@3.15.5") - generator = "Unix Makefiles" - - if sys.platform == 'win32': - generator = "Ninja" - depends_on('ninja') + depends_on('ninja', when='platform=windows') # We default ownlibs to true because it greatly speeds up the CMake # build, and CMake is built frequently. Also, CMake is almost always @@ -232,6 +227,18 @@ class Cmake(Package): conflicts('%intel@:14', when='@3.14:', msg="Intel 14 has immature C++11 support") + resource(name='cmake-bootstrap', + url='https://cmake.org/files/v3.21/cmake-3.21.2-windows-x86_64.zip', + checksum='213a4e6485b711cb0a48cbd97b10dfe161a46bfe37b8f3205f47e99ffec434d2', + placement='cmake-bootstrap', + when='@3.0.2: platform=windows') + + resource(name='cmake-bootstrap', + url='https://cmake.org/files/v2.8/cmake-2.8.4-win32-x86.zip', + checksum='8b9b520f3372ce67e33d086421c1cb29a5826d0b9b074f44a8a0304e44cf88f3', + placement='cmake-bootstrap', + when='@:2.8.10.2 platform=windows') + phases = ['bootstrap', 'build', 'install'] @classmethod @@ -259,7 +266,9 @@ def setup_build_environment(self, env): def bootstrap_args(self): spec = self.spec args = [] - if not os.name == 'nt': + self.generator = make + + if not sys.platform == 'win32': args.extend( ['--prefix={0}'.format(self.prefix), '--parallel={0}'.format(make_jobs)] @@ -290,9 +299,9 @@ def bootstrap_args(self): args.append('--') else: args.append('-DCMAKE_INSTALL_PREFIX=%s' % self.prefix) - if self.spec.satisfies('generator=Ninja'): + if self.spec.satisfies('platform=windows'): args.append('-GNinja') - + self.generator = ninja args.append('-DCMAKE_BUILD_TYPE={0}'.format( self.spec.variants['build_type'].value)) @@ -318,35 +327,15 @@ def bootstrap_args(self): return args - def winbootcmake(self, spec): - from spack import fetch_strategy, stage - urls = { - '3': ('https://cmake.org/files/v3.21/cmake-3.21.2-windows-x86_64.zip', "f21e72ede9d15070602b60b2c14dc779"), - '2': ('https://cmake.org/files/v2.8/cmake-2.8.4-win32-x86.zip', "a2525342e495518101381203bf4484c4") - } - if spec.satisfies('@3.0.2:'): - bootstrap_url = urls['3'] - else: - bootstrap_url = urls['2'] - remote = fetch_strategy.URLFetchStrategy(url=bootstrap_url[0], - checksum=bootstrap_url[1]) - bootstrap_stage_path = os.path.join(self.stage.path, "cmake-bootstraper") - with stage.Stage(remote, path=bootstrap_stage_path) as bootstrap_stage: - remote.stage = bootstrap_stage - remote.fetch() - remote.check() - remote.expand() - shutil.move(bootstrap_stage.source_path, self.stage.source_path) - def cmake_bootstrap(self): exe_prefix = self.stage.source_path - relative_cmake_exe = os.path.join('spack-src', 'bin', 'cmake.exe') + relative_cmake_exe = os.path.join('cmake-bootstrap', 'bin', 'cmake.exe') return Executable(os.path.join(exe_prefix, relative_cmake_exe)) def bootstrap(self, spec, prefix): bootstrap_args = self.bootstrap_args() - if os.name == 'nt': - self.winbootcmake(spec) + if sys.platform == 'win32': + # self.winbootcmake(spec) bootstrap = self.cmake_bootstrap() bootstrap_args.extend(['.']) else: @@ -354,25 +343,16 @@ def bootstrap(self, spec, prefix): bootstrap(*bootstrap_args) def build(self, spec, prefix): - if self.generator == "Ninja": - ninja() - else: - make() + self.generator() @run_after('build') @on_package_attributes(run_tests=True) def build_test(self): # Some tests fail, takes forever - if self.generator == "Ninja": - ninja('test') - else: - make('test') + self.generator('test') def install(self, spec, prefix): - if self.generator == "Ninja": - ninja('install') - else: - make('install') + self.generator('install') if spec.satisfies('%fj'): for f in find(self.prefix, 'FindMPI.cmake', recursive=True): diff --git a/var/spack/repos/builtin/packages/nasm/package.py b/var/spack/repos/builtin/packages/nasm/package.py index b4794eecfb..be39246736 100644 --- a/var/spack/repos/builtin/packages/nasm/package.py +++ b/var/spack/repos/builtin/packages/nasm/package.py @@ -16,18 +16,17 @@ class Nasm(Package): url = "https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz" list_url = "https://www.nasm.us/pub/nasm/releasebuilds" list_depth = 1 - a = '3caf6729c1073bf96629b57cee31eeb54f4f8129b01902c73428836550b30a3f' version('2.15.05', sha256='9182a118244b058651c576baa9d0366ee05983c4d4ae1d9ddd3236a9f2304997') - version('2.14.02', sha256='e24ade3e928f7253aa8c14aa44726d1edf3f98643f87c9d72ec1df44b26be8f5') - version('2.13.03', sha256='812ecfb0dcbc5bd409aaa8f61c7de94c5b8752a7b00c632883d15b2ed6452573') - version('2.11.06', sha256='90f60d95a15b8a54bf34d87b9be53da89ee3d6213ea739fb2305846f4585868a') + version('2.14.02', sha256='b34bae344a3f2ed93b2ca7bf25f1ed3fb12da89eeda6096e3551fd66adeae9fc') + version('2.13.03', sha256='23e1b679d64024863e2991e5c166e19309f0fe58a9765622b35bd31be5b2cc99') + version('2.11.06', sha256='3a72476f3cb45294d303f4d34f20961b15323ac24e84eb41bc130714979123bb') # Fix compilation with GCC 8 # https://bugzilla.nasm.us/show_bug.cgi?id=3392461 patch('https://src.fedoraproject.org/rpms/nasm/raw/0cc3eb244bd971df81a7f02bc12c5ec259e1a5d6/f/0001-Remove-invalid-pure_func-qualifiers.patch', level=1, sha256='ac9f315d204afa6b99ceefa1fe46d4eed2b8a23c7315d32d33c0f378d930e950', when='@2.13.03 %gcc@8:') - patch('msvc.mak.patch', when='platform=windows') + patch('msvc.mak.patch', when='@2.15.05 platform=windows') conflicts('%intel@:14', when='@2.14:', msg="Intel 14 has immature C11 support") diff --git a/var/spack/repos/builtin/packages/openssl/package.py b/var/spack/repos/builtin/packages/openssl/package.py index f57a65271a..94c1dccf4c 100644 --- a/var/spack/repos/builtin/packages/openssl/package.py +++ b/var/spack/repos/builtin/packages/openssl/package.py @@ -91,7 +91,8 @@ class Openssl(Package): # Uses Fake Autotools, should subclass Package 'package, symlink system certificates, or none')) variant('docs', default=False, description='Install docs and manpages') variant('shared', default=False, description="Build shared library version") - variant('dynamic', default=False, description="Link with MSVC's dynamic runtime library") + with when('platform=windows'): + variant('dynamic', default=False, description="Link with MSVC's dynamic runtime library") depends_on('zlib') depends_on('perl@5.14.0:', type=('build', 'test')) @@ -144,25 +145,35 @@ def install(self, spec, prefix): if spec.satisfies('~shared'): shared_flag = 'no-shared' + def configure_args(): + base_args = ['--prefix=%s' % prefix, + '--openssldir=%s' + % join_path(prefix, 'etc', 'openssl')] + if spec.satisfies('platform=windows'): + base_args.extend([ + 'CC=%s' % os.environ.get('CC'), + 'CXX=%s' % os.environ.get('CXX'), + '%s' % shared_flag, + 'VC-WIN64A', + ]) + base_args.insert(0, 'Configure') + else: + base_args.extend( + [ + '-I{0}'.format(self.spec['zlib'].prefix.include), + '-L{0}'.format(self.spec['zlib'].prefix.lib) + ] + ) + base_args.extend(options) + return base_args # On Windows, we use perl for configuration and build through MSVC # nmake. if spec.satisfies('platform=windows'): config = Executable('perl') - config('Configure', - '--prefix=%s' % prefix, - '--openssldir=%s' % join_path(prefix, 'etc', 'openssl'), - 'CC=\"%s\"' % os.environ.get('SPACK_CC'), - 'CXX=\"%s\"' % os.environ.get('SPACK_CXX'), - '%s' % shared_flag, - 'VC-WIN64A', ignore_quotes=True) else: config = Executable('./config') - config('--prefix=%s' % prefix, - '--openssldir=%s' % join_path(prefix, 'etc', 'openssl'), - '-I{0}'.format(self.spec['zlib'].prefix.include), - '-L{0}'.format(self.spec['zlib'].prefix.lib), - *options) + config(*configure_args()) # Remove non-standard compiler options if present. These options are # present e.g. on Darwin. They are non-standard, i.e. most compilers # (e.g. gcc) will not accept them. @@ -178,26 +189,17 @@ def install(self, spec, prefix): "+dynamic to suppress this warning.") if spec.satisfies('platform=windows'): - nmake = Executable('nmake') - nmake() + host_make = nmake else: - make() + host_make = make if self.run_tests: - if spec.satisfies('platform=windows'): - nmake = Executable('nmake') - nmake('test', parallel=False) - else: - make('test', parallel=False) # 'VERBOSE=1' + host_make('test', parallel=False) # 'VERBOSE=1' install_tgt = 'install' if self.spec.satisfies('+docs') else 'install_sw' # See https://github.com/openssl/openssl/issues/7466#issuecomment-432148137 - if spec.satisfies('platform=windows'): - nmake = Executable('nmake') - nmake(install_tgt, parallel=False) - else: - make(install_tgt, parallel=False) + host_make(install_tgt, parallel=False) @run_after('install') def link_system_certs(self): diff --git a/var/spack/repos/builtin/packages/perl/package.py b/var/spack/repos/builtin/packages/perl/package.py index a16bfc95de..e44a711d45 100644 --- a/var/spack/repos/builtin/packages/perl/package.py +++ b/var/spack/repos/builtin/packages/perl/package.py @@ -13,6 +13,7 @@ # import os +import platform import re from contextlib import contextmanager @@ -22,8 +23,7 @@ from spack import * from spack.operating_systems.mac_os import macos_version -host = spack.platforms.host() -is_windows = str(host) == 'windows' +is_windows = str(spack.platforms.host()) == 'windows' class Perl(Package): # Perl doesn't use Autotools, it should subclass Package @@ -200,10 +200,13 @@ def nmake_arguments(self): args.append("ALL_STATIC=%s" % "define") if self.spec.satisfies('~threads'): args.extend(["USE_MULTI=undef", "USE_ITHREADS=undef", "USE_IMP_SYS=undef"]) - if not host.is_64bit(): + if not self.is_64bit(): args.append("WIN64=undef") return args + def is_64bit(self): + return platform.machine().endswith('64') + def configure_args(self): spec = self.spec prefix = self.prefix @@ -286,7 +289,7 @@ def symlink_windows(self): if not is_windows: return win_install_path = os.path.join(self.prefix.bin, "MSWin32") - if host.is_64bit(): + if self.is_64bit(): win_install_path += "-x64" else: win_install_path += "-x86" @@ -305,12 +308,12 @@ def symlink_windows(self): def install_cpanm(self): spec = self.spec maker = make - win_prefix = '' + cpan_dir = join_path('cpanm', 'cpanm') if is_windows: maker = nmake - win_prefix = self.stage.source_path + cpan_dir = join_path(self.stage.source_path, cpan_dir) if '+cpanm' in spec: - with working_dir(join_path(win_prefix, 'cpanm', 'cpanm')): + with working_dir(cpan_dir): perl = spec['perl'].command perl('Makefile.PL') maker() diff --git a/var/spack/repos/builtin/packages/python/package.py b/var/spack/repos/builtin/packages/python/package.py index 0e38a56325..d0499b7c49 100644 --- a/var/spack/repos/builtin/packages/python/package.py +++ b/var/spack/repos/builtin/packages/python/package.py @@ -22,9 +22,7 @@ from spack.util.environment import is_system_path from spack.util.prefix import Prefix -arch_map = {"AMD64": "x64", "x86": "Win32", - "IA64": "Win32", "EM64T": "Win32"} -is_windows = os.name == 'nt' +is_windows = sys.platform == 'win32' class Python(Package): @@ -37,7 +35,6 @@ class Python(Package): maintainers = ['adamjstewart', 'skosukhin', 'scheibelp', 'varioustoxins'] - phases = ['configure', 'build', 'install'] #: phase @@ -182,7 +179,7 @@ class Python(Package): variant('tix', default=False, description='Build Tix module') variant('ensurepip', default=True, description='Build ensurepip module', when='@2.7.9:2,3.4:') - if os.name != 'nt': + if not is_windows: depends_on('pkgconfig@0.9.0:', type='build') depends_on('gettext +libxml2', when='+libxml2') depends_on('gettext ~libxml2', when='~libxml2') @@ -456,20 +453,20 @@ def flag_handler(self, name, flags): # allow flags to be passed through compiler wrapper return (flags, None, None) - @property - def configure_directory(self): - """Returns the directory where 'configure' resides. - :return: directory where to find configure - """ - return self.stage.source_path - - @property - def build_directory(self): - """Override to provide another place to build the package""" - return self.configure_directory - @property def plat_arch(self): + """ + String referencing platform architecture + filtered through Python's Windows build file + architecture support map + + Note: This function really only makes + sense to use on Windows, could be overridden to + cross compile however. + """ + + arch_map = {"AMD64": "x64", "x86": "Win32", + "IA64": "Win32", "EM64T": "Win32"} arch = platform.machine() if arch in arch_map: arch = arch_map[arch] @@ -477,6 +474,13 @@ def plat_arch(self): @property def win_build_params(self): + """ + Arguments must be passed to the Python build batch script + in order to configure it to spec and system. + A number of these toggle optional MSBuild Projects + directly corresponding to the python support of the same + name. + """ args = [] args.append("-p %s" % self.plat_arch) if self.spec.satisfies('+debug'): @@ -490,6 +494,15 @@ def win_build_params(self): return args def win_installer(self, prefix): + """ + Python on Windows does not export an install target + so we must handcraft one here. This structure + directly mimics the install tree of the Python + Installer on Windows. + + Parameters: + prefix (str): Install prefix for package + """ proj_root = self.stage.source_path pcbuild_root = os.path.join(proj_root, "PCbuild") build_root = os.path.join(pcbuild_root, platform.machine().lower()) @@ -636,7 +649,7 @@ def configure(self, spec, prefix): :meth:`~spack.build_systems.autotools.AutotoolsPackage.configure_args` and an appropriately set prefix. """ - with working_dir(self.build_directory, create=True): + with working_dir(self.stage.source_path, create=True): if is_windows: pass else: @@ -651,7 +664,7 @@ def build(self, spec, prefix): """ # Windows builds use a batch script to drive # configure and build in one step - with working_dir(self.build_directory): + with working_dir(self.stage.source_path): if is_windows: pcbuild_root = os.path.join(self.stage.source_path, "PCbuild") builder_cmd = os.path.join(pcbuild_root, 'build.bat') @@ -673,7 +686,7 @@ def install(self, spec, prefix): """Makes the install targets specified by :py:attr:``~.AutotoolsPackage.install_targets`` """ - with working_dir(self.build_directory): + with working_dir(self.stage.source_path): if is_windows: self.win_installer(prefix) else: @@ -846,7 +859,7 @@ 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": + if not is_windows: path = os.path.join(self.prefix.bin, 'python{0}'.format(ver)) else: path = os.path.join(self.prefix, 'python{0}.exe'.format(ver)) @@ -897,10 +910,6 @@ def config_vars(self): dict: variable definitions """ - # TODO: distutils is deprecated in Python 3.10 and will be removed in - # Python 3.12, find a different way to access this information. - # Also, calling the python executable disallows us from cross-compiling, - # so we want to try to avoid that if possible. cmd = """ import json from sysconfig import ( @@ -1007,9 +1016,6 @@ def libs(self): # In Ubuntu 16.04.6 and python 2.7.12 from the system, lib could be # in LBPL # https://mail.python.org/pipermail/python-dev/2013-April/125733.html - # LIBPL does not exist in Windows, avoid uneccesary KeyError while allowing - # later failures. - # Return empty string rather than none so os.path doesn't complain libpl = self.config_vars['LIBPL'] # The system Python installation on macOS and Homebrew installations @@ -1359,7 +1365,7 @@ def deactivate(self, ext_pkg, view, **args): )) def add_files_to_view(self, view, merge_map): - bin_dir = self.spec.prefix.bin if os.name != 'nt'\ + bin_dir = self.spec.prefix.bin if sys.platform != 'win32'\ else self.spec.prefix for src, dst in merge_map.items(): if not path_contains_subdirectory(src, bin_dir): @@ -1392,7 +1398,7 @@ def add_files_to_view(self, view, merge_map): view.link(new_link_target, dst, spec=self.spec) def remove_files_from_view(self, view, merge_map): - bin_dir = self.spec.prefix.bin if os.name != 'nt'\ + bin_dir = self.spec.prefix.bin if not is_windows\ else self.spec.prefix for src, dst in merge_map.items(): if not path_contains_subdirectory(src, bin_dir): diff --git a/var/spack/repos/builtin/packages/ruby/package.py b/var/spack/repos/builtin/packages/ruby/package.py index 9d83c7b66b..4db2feb1ad 100644 --- a/var/spack/repos/builtin/packages/ruby/package.py +++ b/var/spack/repos/builtin/packages/ruby/package.py @@ -4,10 +4,11 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) import re +import sys from spack import * -is_windows = str(spack.platforms.host()) == 'windows' +is_windows = sys.platform == 'win32' class Ruby(Package): @@ -123,13 +124,13 @@ def setup_dependent_package(self, module, dependent_spec): def configure(self, spec, prefix): 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) + 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.stage.source_path): diff --git a/var/spack/repos/builtin/packages/wrf/package.py b/var/spack/repos/builtin/packages/wrf/package.py index 7beeee61b1..84c8f9dafa 100644 --- a/var/spack/repos/builtin/packages/wrf/package.py +++ b/var/spack/repos/builtin/packages/wrf/package.py @@ -10,14 +10,15 @@ from os import O_NONBLOCK from os.path import basename from subprocess import PIPE, Popen -from sys import platform as _platform -from sys import stdout +from sys import platform, stdout from llnl.util import tty from spack import * -if _platform != 'win32': +is_windows = platform == 'win32' + +if not is_windows: from fcntl import F_GETFL, F_SETFL, fcntl from os import O_NONBLOCK, rename else: @@ -36,9 +37,8 @@ def setNonBlocking(fd): Set the given file descriptor to non-blocking Non-blocking pipes are not supported on windows """ - if _platform != 'win32': - flags = fcntl(fd, F_GETFL) | O_NONBLOCK - fcntl(fd, F_SETFL, flags) + flags = fcntl(fd, F_GETFL) | O_NONBLOCK + fcntl(fd, F_SETFL, flags) def collect_platform_options(stdoutpipe): @@ -303,8 +303,9 @@ def configure(self, spec, prefix): ) p = Popen("./configure", stdin=PIPE, stdout=PIPE, stderr=PIPE) - setNonBlocking(p.stdout) - setNonBlocking(p.stderr) + if not is_windows: + setNonBlocking(p.stdout) + setNonBlocking(p.stderr) # Because of WRFs custom configure scripts that require interactive # input we need to parse and respond to questions. The details can diff --git a/var/spack/repos/builtin/packages/zlib/package.py b/var/spack/repos/builtin/packages/zlib/package.py index 3b6b1fd18d..85a09f555c 100644 --- a/var/spack/repos/builtin/packages/zlib/package.py +++ b/var/spack/repos/builtin/packages/zlib/package.py @@ -49,20 +49,19 @@ def win_install(self): compose_src_path = lambda x: os.path.join(build_dir, x) install_tree["include"] = [compose_src_path("zlib.h"), compose_src_path("zconf.h")] - install_tree["share"] = {"man": {"man3": [compose_src_path("zlib.3")]}} + # Windows path seps are fine here as this method is Windows specific. + install_tree["share\\man\\man3"] = [compose_src_path("zlib.3")] def installtree(dst, tree): for inst_dir in tree: - if type(tree[inst_dir]) is list: - install_dst = getattr(dst, inst_dir) - try: - os.makedirs(install_dst) - except OSError: - pass - for file in tree[inst_dir]: - copy(file, install_dst) - else: - installtree(getattr(dst, inst_dir), tree[inst_dir]) + install_dst = getattr(dst, inst_dir) + try: + os.makedirs(install_dst) + except OSError: + pass + for file in tree[inst_dir]: + install(file, install_dst) + installtree(self.prefix, install_tree) def setup_build_environment(self, env):