From 1a90a607957acfdc289d2a82a1d2aa94baa31e01 Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Fri, 25 Oct 2019 08:30:33 -0400 Subject: [PATCH 01/14] fixes windows test failures. filesystem.FileSystemPackageRepository.location is lowercased on platforms with case-insensitive filesystems. Note that these test failures did *not* appear when using `pytest` as a testrunner. --- src/rez/tests/test_packages.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/rez/tests/test_packages.py b/src/rez/tests/test_packages.py index 7a781696b..c917bb168 100644 --- a/src/rez/tests/test_packages.py +++ b/src/rez/tests/test_packages.py @@ -3,11 +3,12 @@ """ from rez.packages_ import iter_package_families, iter_packages, get_package, \ create_package, get_developer_package -from rez.package_resources_ import package_release_keys -from rez.package_repository import create_memory_package_repository from rez.package_py_utils import expand_requirement +from rez.package_repository import create_memory_package_repository +from rez.package_resources_ import package_release_keys from rez.tests.util import TestBase, TempdirMixin from rez.utils.formatting import PackageRequest +from rez.utils.platform_ import platform_ from rez.utils.sourcecode import SourceCode import unittest from rez.vendor.version.version import Version @@ -119,21 +120,27 @@ def test_2(self): def test_3(self): """check package contents.""" + def _format_platformpath(path): + """ `FileSystemPackageRepository` lower-cases paths for case-insensitive filesystems. + """ + if platform_.has_case_sensitive_filesystem: + return path + return path.lower() # a py-based package package = get_package("versioned", "3.0") expected_data = dict( name="versioned", version=Version("3.0"), - base=os.path.join(self.py_packages_path, "versioned", "3.0"), + base=_format_platformpath(os.path.join(self.py_packages_path, "versioned", "3.0")), commands=SourceCode('env.PATH.append("{root}/bin")')) data = package.validated_data() self.assertDictEqual(data, expected_data) # a yaml-based package package = get_package("versioned", "2.0") - expected_uri = os.path.join(self.yaml_packages_path, - "versioned", "2.0", "package.yaml") + expected_uri = _format_platformpath(os.path.join(self.yaml_packages_path, + "versioned", "2.0", "package.yaml")) self.assertEqual(package.uri, expected_uri) # a py-based package with late binding attribute functions @@ -142,7 +149,7 @@ def test_3(self): # a 'combined' type package package = get_package("multi", "1.0") - expected_uri = os.path.join(self.yaml_packages_path, "multi.yaml<1.0>") + expected_uri = _format_platformpath(os.path.join(self.yaml_packages_path, "multi.yaml<1.0>")) self.assertEqual(package.uri, expected_uri) expected_data = dict( name="multi", @@ -153,7 +160,7 @@ def test_3(self): # a 'combined' type package, with version overrides package = get_package("multi", "1.1") - expected_uri = os.path.join(self.yaml_packages_path, "multi.yaml<1.1>") + expected_uri = _format_platformpath(os.path.join(self.yaml_packages_path, "multi.yaml<1.1>")) self.assertEqual(package.uri, expected_uri) expected_data = dict( name="multi", @@ -164,7 +171,7 @@ def test_3(self): # check that visibility of 'combined' packages is correct package = get_package("multi", "2.0") - expected_uri = os.path.join(self.py_packages_path, "multi.py<2.0>") + expected_uri = _format_platformpath(os.path.join(self.py_packages_path, "multi.py<2.0>")) self.assertEqual(package.uri, expected_uri) def test_4(self): @@ -309,11 +316,17 @@ def preprocess(this, data): def test_6(self): """test variant iteration.""" + # ensure that differing case doesn't get interpreted as different repos + # on case-insensitive platforms (eg windows) + base = os.path.join(self.py_packages_path, "variants_py", "2.0") + if not platform_.has_case_sensitive_filesystem: + base = base.lower() + expected_data = dict( name="variants_py", version=Version("2.0"), description="package with variants", - base=os.path.join(self.py_packages_path, "variants_py", "2.0"), + base=base, requires=[PackageRequest("python-2.7")], commands=SourceCode('env.PATH.append("{root}/bin")')) From 5ed01f83f9c01912ef2f11b669890b7e27e6b9eb Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Fri, 25 Oct 2019 11:39:50 -0400 Subject: [PATCH 02/14] adds 'SYSTEMROOT' environment variable to Python() so python startup does not fail on windows. python -m unittest src/rez/test_context.py test ``test_execute_command_environ`` failed under windows with python3.6. Subprocess failed printing the following to stderr: Fatal Python Error: failed to get random numbers to initialize Python Problem only appears *if* %PATH% is configured with python on it, but without %SYSTEMROOT%. example: # Works Popen(['python', '-V']) # Works Popen(['python', '-V'], env={'PATH': 'C:\\Python-3.6.5', 'SYSTEMROOT': 'C:\Windows'}) # Fails Popen(['python', '-V'], env={'PATH': 'C:\\Python-3.6.5'}) --- src/rez/rex.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/rez/rex.py b/src/rez/rex.py index 1fd3bdd03..45ae928df 100644 --- a/src/rez/rex.py +++ b/src/rez/rex.py @@ -591,6 +591,7 @@ def apply_environ(self): "interpreter before using it.") self.target_environ.update(self.manager.environ) + self.target_environ = self.adjust_env_for_platform(self.target_environ) def get_output(self, style=OutputStyle.file): self.apply_environ() @@ -633,6 +634,7 @@ def error(self, value): def subprocess(self, args, **subproc_kwargs): if self.manager: self.target_environ.update(self.manager.environ) + self.target_environ = self.adjust_env_for_platform(self.target_environ) shell_mode = isinstance(args, basestring) return Popen(args, @@ -684,6 +686,57 @@ def get_key_token(self, key): # here because the API requires it. return "${%s}" % key + def adjust_env_for_platform(self, env): + """ Make required platform-specific adjustments to env. + """ + if sys.platform.startswith('win'): + env = self._add_systemroot_to_env_win32(env) + return env.copy() + + def _add_systemroot_to_env_win32(self, env): + """ Sets ``%SYSTEMROOT%`` environment variable, if not present. + + Args: + env (dict): desired environment variables + + Notes: + on windows, python-3.6 startup fails within an environment + where it ``%PATH%`` includes python3, but ``%SYSTEMROOT%`` is not + present. + + for example. + + .. code-block:: python + + from subprocess import Popen + cmds = ['python', '--version'] + + # successful + Popen(cmds) + Popen(cmds, env={'PATH': 'C:\\Python-3.6.5', + 'SYSTEMROOT': 'C:\Windows'}) + + # failure + Popen(cmds, env={'PATH': 'C:\\Python-3.6.5'}) + + #> Fatal Python Error: failed to get random numbers to initialize Python + + """ + if not sys.platform.startswith('win'): + return env + if 'SYSTEMROOT' in env: + return env + if 'SYSTEMROOT' not in os.environ: + return env + + if env is None: + env = {'SYSTEMROOT': os.environ['SYSTEMROOT']} + return env + else: + new_env = env.copy() + new_env['SYSTEMROOT'] = os.environ['SYSTEMROOT'] + return new_env + #=============================================================================== # String manipulation From a4072701cd1c8d1aa4a374c7218b6a0b02d66c36 Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Fri, 25 Oct 2019 11:47:42 -0400 Subject: [PATCH 03/14] updates version and changelog --- CHANGELOG.md | 10 ++++++++++ src/rez/utils/_version.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa0a0f4b2..601351b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Change Log + +## 2.47.10 (2019-10-26) +[Source](https://github.com/repos/nerdvegas/rez/tree/2.47.10) | [Diff](https://github.com/repos/nerdvegas/rez/compare/2.47.9...2.47.10) + +Notes + +* corrects failing tests in `rez/tests/test_packages.py` on windows +* adds %SYSTEMROOT% envvar to Python(ActionInterpreter) so `rez/tests/test_context.py` tests pass on windows + + ## 2.47.9 (2019-10-25) [Source](https://github.com/repos/nerdvegas/rez/tree/2.47.9) | [Diff](https://github.com/repos/nerdvegas/rez/compare/2.47.8...2.47.9) diff --git a/src/rez/utils/_version.py b/src/rez/utils/_version.py index be052760f..7848f88d9 100644 --- a/src/rez/utils/_version.py +++ b/src/rez/utils/_version.py @@ -1,7 +1,7 @@ # Update this value to version up Rez. Do not place anything else in this file. -_rez_version = "2.47.9" +_rez_version = "2.47.10" # Copyright 2013-2016 Allan Johns. From 119d801c4355b0dfe93ed9ccb92de4ae9a6bdfc0 Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Fri, 25 Oct 2019 14:24:33 -0400 Subject: [PATCH 04/14] Corrects logic. env==None is acceptable. --- src/rez/rex.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/rez/rex.py b/src/rez/rex.py index 45ae928df..d987b2fbd 100644 --- a/src/rez/rex.py +++ b/src/rez/rex.py @@ -722,20 +722,22 @@ def _add_systemroot_to_env_win32(self, env): #> Fatal Python Error: failed to get random numbers to initialize Python """ + # 'SYSTEMROOT' only relevant on windows if not sys.platform.startswith('win'): return env + # 'SYSTEMROOT' unecessary unless 'PATH' is set. + if env is None: + return env + # leave SYSTEMROOT alone if set by user if 'SYSTEMROOT' in env: return env + # not enough info to set SYSTEMROOT if 'SYSTEMROOT' not in os.environ: return env - if env is None: - env = {'SYSTEMROOT': os.environ['SYSTEMROOT']} - return env - else: - new_env = env.copy() - new_env['SYSTEMROOT'] = os.environ['SYSTEMROOT'] - return new_env + new_env = env.copy() + new_env['SYSTEMROOT'] = os.environ['SYSTEMROOT'] + return new_env #=============================================================================== From ddab4c7b39a6675f8394fd3cd98702aa4ef96ce6 Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Sat, 26 Oct 2019 11:32:39 -0400 Subject: [PATCH 05/14] Adds `canonical_path()` to `rez.utils.filesystem` , alongside new tests. --- src/rez/tests/test_utils/__init__.py | 0 src/rez/tests/test_utils/test_filesystem.py | 40 +++++++++++++++++++++ src/rez/utils/filesystem.py | 27 ++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 src/rez/tests/test_utils/__init__.py create mode 100644 src/rez/tests/test_utils/test_filesystem.py diff --git a/src/rez/tests/test_utils/__init__.py b/src/rez/tests/test_utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/rez/tests/test_utils/test_filesystem.py b/src/rez/tests/test_utils/test_filesystem.py new file mode 100644 index 000000000..45197dcd2 --- /dev/null +++ b/src/rez/tests/test_utils/test_filesystem.py @@ -0,0 +1,40 @@ +from rez.tests.util import TestBase +from rez.utils.platform_ import Platform, platform_ +from rez.utils import filesystem +import os + + +class TestCanonicalPath(TestBase): + class CaseSensitivePlatform(Platform): + @property + def has_case_sensitive_filesystem(self): + return True + + class CaseInsensitivePlatform(Platform): + @property + def has_case_sensitive_filesystem(self): + return False + + def test_win32_case_insensitive(self): + if platform_.name != 'windows': + self.skipTest('os.path.realpath() treats ntpath as relpath, and prepends os.getcwd') + platform = self.CaseInsensitivePlatform() + path = filesystem.canonical_path('C:\\dir\\File.txt', platform) + expects = 'c:\\dir\\file.txt'.replace('\\', os.sep) + self.assertEqual(path, expects) + + def test_unix_case_sensistive_platform(self): + if platform_.name == 'windows': + self.skipTest('os.path.realpath() treats unixpath as relpath, and prepends C:\\') + platform = self.CaseSensitivePlatform() + path = filesystem.canonical_path('/var/tmp/File.txt', platform) + expects = '/var/tmp/File.txt'.replace('\\', os.sep) + self.assertEqual(path, expects) + + def test_unix_case_insensistive_platform(self): + if platform_.name == 'windows': + self.skipTest('os.path.realpath() treats unixpath as relpath, and prepends C:\\') + platform = self.CaseInsensitivePlatform() + path = filesystem.canonical_path('/var/tmp/File.txt', platform) + expects = '/var/tmp/file.txt'.replace('\\', os.sep) + self.assertEqual(path, expects) diff --git a/src/rez/utils/filesystem.py b/src/rez/utils/filesystem.py index b7a386dd4..9ba97bebe 100644 --- a/src/rez/utils/filesystem.py +++ b/src/rez/utils/filesystem.py @@ -435,6 +435,33 @@ def to_posixpath(path): return posixpath.sep.join(path.split(ntpath.sep)) +def canonical_path(path, platform=None): + """ Resolves symlinks, and formats filepath. + + Resolves symlinks, lowercases if filesystem is case-insensitive, + formats filepath using slashes appropriate for platform. + + Args: + path (str): + filepath being formatted + + platform (rez.utils.platform_.Platform, NoneType): + indicates platform path is being formatted for. + Defaults to current platform. + + Returns: + str: provided path, formatted for platform. + """ + if platform is None: + platform = platform_.platform_ + + path = os.path.normpath(os.path.realpath(path)) + + if not platform.has_case_sensitive_filesystem: + return path.lower() + return path + + def encode_filesystem_name(input_str): """Encodes an arbitrary unicode string to a generic filesystem-compatible non-unicode filename. From 6e9b3853a70e2faea7fe487c25948db31b894c42 Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Sat, 26 Oct 2019 11:34:42 -0400 Subject: [PATCH 06/14] correction to `rez.utils.filesystem.to_nativepath()` so that it runs, and handles windows directory-separators (`\\`). --- src/rez/utils/filesystem.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/rez/utils/filesystem.py b/src/rez/utils/filesystem.py index 9ba97bebe..5e8b8874b 100644 --- a/src/rez/utils/filesystem.py +++ b/src/rez/utils/filesystem.py @@ -19,6 +19,7 @@ import platform from rez.vendor.six import six +from rez.utils.platform_ import platform_ class TempDirs(object): @@ -424,7 +425,8 @@ def safe_chmod(path, mode): def to_nativepath(path): - return os.path.join(path.split('/')) + path = path.replace('\\', '/') + return os.path.join(*path.split('/')) def to_ntpath(path): @@ -453,7 +455,7 @@ def canonical_path(path, platform=None): str: provided path, formatted for platform. """ if platform is None: - platform = platform_.platform_ + platform = platform_ path = os.path.normpath(os.path.realpath(path)) From 5fe1ab45b22e0e91dd60b4034b5176e587b8834c Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Sat, 26 Oct 2019 11:44:21 -0400 Subject: [PATCH 07/14] replaces `_format_platformpath` with `rez.utils.filesystem.canonical_path` --- src/rez/tests/test_packages.py | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/rez/tests/test_packages.py b/src/rez/tests/test_packages.py index c917bb168..4fc798679 100644 --- a/src/rez/tests/test_packages.py +++ b/src/rez/tests/test_packages.py @@ -13,6 +13,7 @@ import unittest from rez.vendor.version.version import Version from rez.vendor.version.util import VersionError +from rez.utils.filesystem import canonical_path import os.path import os @@ -120,26 +121,19 @@ def test_2(self): def test_3(self): """check package contents.""" - def _format_platformpath(path): - """ `FileSystemPackageRepository` lower-cases paths for case-insensitive filesystems. - """ - if platform_.has_case_sensitive_filesystem: - return path - return path.lower() - # a py-based package package = get_package("versioned", "3.0") expected_data = dict( name="versioned", version=Version("3.0"), - base=_format_platformpath(os.path.join(self.py_packages_path, "versioned", "3.0")), + base=canonical_path(os.path.join(self.py_packages_path, "versioned", "3.0")), commands=SourceCode('env.PATH.append("{root}/bin")')) data = package.validated_data() self.assertDictEqual(data, expected_data) # a yaml-based package package = get_package("versioned", "2.0") - expected_uri = _format_platformpath(os.path.join(self.yaml_packages_path, + expected_uri = canonical_path(os.path.join(self.yaml_packages_path, "versioned", "2.0", "package.yaml")) self.assertEqual(package.uri, expected_uri) @@ -149,7 +143,7 @@ def _format_platformpath(path): # a 'combined' type package package = get_package("multi", "1.0") - expected_uri = _format_platformpath(os.path.join(self.yaml_packages_path, "multi.yaml<1.0>")) + expected_uri = canonical_path(os.path.join(self.yaml_packages_path, "multi.yaml<1.0>")) self.assertEqual(package.uri, expected_uri) expected_data = dict( name="multi", @@ -160,7 +154,7 @@ def _format_platformpath(path): # a 'combined' type package, with version overrides package = get_package("multi", "1.1") - expected_uri = _format_platformpath(os.path.join(self.yaml_packages_path, "multi.yaml<1.1>")) + expected_uri = canonical_path(os.path.join(self.yaml_packages_path, "multi.yaml<1.1>")) self.assertEqual(package.uri, expected_uri) expected_data = dict( name="multi", @@ -171,7 +165,7 @@ def _format_platformpath(path): # check that visibility of 'combined' packages is correct package = get_package("multi", "2.0") - expected_uri = _format_platformpath(os.path.join(self.py_packages_path, "multi.py<2.0>")) + expected_uri = canonical_path(os.path.join(self.py_packages_path, "multi.py<2.0>")) self.assertEqual(package.uri, expected_uri) def test_4(self): @@ -316,12 +310,7 @@ def preprocess(this, data): def test_6(self): """test variant iteration.""" - # ensure that differing case doesn't get interpreted as different repos - # on case-insensitive platforms (eg windows) - base = os.path.join(self.py_packages_path, "variants_py", "2.0") - if not platform_.has_case_sensitive_filesystem: - base = base.lower() - + base = canonical_path(os.path.join(self.py_packages_path, "variants_py", "2.0")) expected_data = dict( name="variants_py", version=Version("2.0"), From e39cf7e3fdf558445cf360c9b721e0f016ca41d9 Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Sat, 26 Oct 2019 11:45:33 -0400 Subject: [PATCH 08/14] `self.target_environ` assigned directly rather than modifiying/returning a copy. --- src/rez/rex.py | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/rez/rex.py b/src/rez/rex.py index d987b2fbd..4f0c22d74 100644 --- a/src/rez/rex.py +++ b/src/rez/rex.py @@ -591,7 +591,7 @@ def apply_environ(self): "interpreter before using it.") self.target_environ.update(self.manager.environ) - self.target_environ = self.adjust_env_for_platform(self.target_environ) + self.adjust_env_for_platform(self.target_environ) def get_output(self, style=OutputStyle.file): self.apply_environ() @@ -634,7 +634,7 @@ def error(self, value): def subprocess(self, args, **subproc_kwargs): if self.manager: self.target_environ.update(self.manager.environ) - self.target_environ = self.adjust_env_for_platform(self.target_environ) + self.adjust_env_for_platform(self.target_environ) shell_mode = isinstance(args, basestring) return Popen(args, @@ -690,11 +690,11 @@ def adjust_env_for_platform(self, env): """ Make required platform-specific adjustments to env. """ if sys.platform.startswith('win'): - env = self._add_systemroot_to_env_win32(env) - return env.copy() + self._add_systemroot_to_env_win32(env) def _add_systemroot_to_env_win32(self, env): - """ Sets ``%SYSTEMROOT%`` environment variable, if not present. + """ Sets ``%SYSTEMROOT%`` environment variable, if not present + in :py:attr:`target_environ` . Args: env (dict): desired environment variables @@ -722,22 +722,17 @@ def _add_systemroot_to_env_win32(self, env): #> Fatal Python Error: failed to get random numbers to initialize Python """ - # 'SYSTEMROOT' only relevant on windows - if not sys.platform.startswith('win'): - return env # 'SYSTEMROOT' unecessary unless 'PATH' is set. if env is None: - return env + return # leave SYSTEMROOT alone if set by user if 'SYSTEMROOT' in env: - return env + return # not enough info to set SYSTEMROOT if 'SYSTEMROOT' not in os.environ: - return env + return - new_env = env.copy() - new_env['SYSTEMROOT'] = os.environ['SYSTEMROOT'] - return new_env + env['SYSTEMROOT'] = os.environ['SYSTEMROOT'] #=============================================================================== From f8f66668378a19f3228ba192ec3e0cfb59d876ee Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Sat, 26 Oct 2019 12:18:30 -0400 Subject: [PATCH 09/14] replaces conditional with `canonical_path()` --- src/rezplugins/package_repository/filesystem.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/rezplugins/package_repository/filesystem.py b/src/rezplugins/package_repository/filesystem.py index 8becadbce..0c2833641 100644 --- a/src/rezplugins/package_repository/filesystem.py +++ b/src/rezplugins/package_repository/filesystem.py @@ -21,7 +21,7 @@ from rez.utils.resources import cached_property from rez.utils.logging_ import print_warning from rez.utils.memcached import memcached, pool_memcached_connections -from rez.utils.filesystem import make_path_writable +from rez.utils.filesystem import make_path_writable, canonical_path from rez.utils.platform_ import platform_ from rez.serialise import load_from_file, FileFormat from rez.config import config @@ -470,8 +470,7 @@ def __init__(self, location, resource_pool): # ensure that differing case doesn't get interpreted as different repos # on case-insensitive platforms (eg windows) - if not platform_.has_case_sensitive_filesystem: - location = location.lower() + location = canonical_path(location, platform_) super(FileSystemPackageRepository, self).__init__(location, resource_pool) From 6cdf914a3c46d6b0b127bbe4fb5d8b17fd50d7a7 Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Sat, 26 Oct 2019 13:00:19 -0400 Subject: [PATCH 10/14] PEP8 fixes. sorry --- src/rez/tests/test_utils/test_filesystem.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/rez/tests/test_utils/test_filesystem.py b/src/rez/tests/test_utils/test_filesystem.py index 45197dcd2..ac596b191 100644 --- a/src/rez/tests/test_utils/test_filesystem.py +++ b/src/rez/tests/test_utils/test_filesystem.py @@ -17,7 +17,9 @@ def has_case_sensitive_filesystem(self): def test_win32_case_insensitive(self): if platform_.name != 'windows': - self.skipTest('os.path.realpath() treats ntpath as relpath, and prepends os.getcwd') + self.skipTest('os.path.realpath() treats ntpath as relpath, ' + 'and prepends os.getcwd ' + '(py-3.6 only, corrected in py-3.7)') platform = self.CaseInsensitivePlatform() path = filesystem.canonical_path('C:\\dir\\File.txt', platform) expects = 'c:\\dir\\file.txt'.replace('\\', os.sep) @@ -25,7 +27,8 @@ def test_win32_case_insensitive(self): def test_unix_case_sensistive_platform(self): if platform_.name == 'windows': - self.skipTest('os.path.realpath() treats unixpath as relpath, and prepends C:\\') + self.skipTest('os.path.realpath() treats unixpath as relpath, and ' + 'prepends C:\\ (py-3.6 only, corrected in py-3.7)') platform = self.CaseSensitivePlatform() path = filesystem.canonical_path('/var/tmp/File.txt', platform) expects = '/var/tmp/File.txt'.replace('\\', os.sep) @@ -33,7 +36,8 @@ def test_unix_case_sensistive_platform(self): def test_unix_case_insensistive_platform(self): if platform_.name == 'windows': - self.skipTest('os.path.realpath() treats unixpath as relpath, and prepends C:\\') + self.skipTest('os.path.realpath() treats unixpath as relpath, and ' + 'prepends C:\\ (py-3.6 only, corrected in py-3.7)') platform = self.CaseInsensitivePlatform() path = filesystem.canonical_path('/var/tmp/File.txt', platform) expects = '/var/tmp/file.txt'.replace('\\', os.sep) From cab6b8ddd06c6c1ebfb3509119f006944f12feed Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Thu, 31 Oct 2019 11:10:02 -0400 Subject: [PATCH 11/14] moves test_utils/test_filesystem -> test_utils_filesystem. Adds header/footer so more consistent with other tests. --- src/rez/tests/test_utils/__init__.py | 0 ...filesystem.py => test_utils_filesystem.py} | 23 +++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) delete mode 100644 src/rez/tests/test_utils/__init__.py rename src/rez/tests/{test_utils/test_filesystem.py => test_utils_filesystem.py} (71%) diff --git a/src/rez/tests/test_utils/__init__.py b/src/rez/tests/test_utils/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/rez/tests/test_utils/test_filesystem.py b/src/rez/tests/test_utils_filesystem.py similarity index 71% rename from src/rez/tests/test_utils/test_filesystem.py rename to src/rez/tests/test_utils_filesystem.py index ac596b191..ad8271667 100644 --- a/src/rez/tests/test_utils/test_filesystem.py +++ b/src/rez/tests/test_utils_filesystem.py @@ -1,7 +1,10 @@ +""" +unit tests for 'utils.filesystem' module +""" +import os from rez.tests.util import TestBase -from rez.utils.platform_ import Platform, platform_ from rez.utils import filesystem -import os +from rez.utils.platform_ import Platform, platform_ class TestCanonicalPath(TestBase): @@ -42,3 +45,19 @@ def test_unix_case_insensistive_platform(self): path = filesystem.canonical_path('/var/tmp/File.txt', platform) expects = '/var/tmp/file.txt'.replace('\\', os.sep) self.assertEqual(path, expects) + + +# Copyright 2013-2016 Allan Johns. +# +# This library is free software: you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation, either +# version 3 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library. If not, see . From 3c020f58310917791c0121c0bdd641b85064acb0 Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Thu, 31 Oct 2019 19:11:42 -0400 Subject: [PATCH 12/14] replaces testpath `/var/tmp` with a contrived path. Addresses failing MacOS tests - `/var/tmp` is symlinked to `/private/var/tmp` on MacOS --- src/rez/tests/test_utils_filesystem.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rez/tests/test_utils_filesystem.py b/src/rez/tests/test_utils_filesystem.py index ad8271667..7db68125a 100644 --- a/src/rez/tests/test_utils_filesystem.py +++ b/src/rez/tests/test_utils_filesystem.py @@ -33,8 +33,8 @@ def test_unix_case_sensistive_platform(self): self.skipTest('os.path.realpath() treats unixpath as relpath, and ' 'prepends C:\\ (py-3.6 only, corrected in py-3.7)') platform = self.CaseSensitivePlatform() - path = filesystem.canonical_path('/var/tmp/File.txt', platform) - expects = '/var/tmp/File.txt'.replace('\\', os.sep) + path = filesystem.canonical_path('/a/b/File.txt', platform) + expects = '/a/b/File.txt'.replace('\\', os.sep) self.assertEqual(path, expects) def test_unix_case_insensistive_platform(self): @@ -42,8 +42,8 @@ def test_unix_case_insensistive_platform(self): self.skipTest('os.path.realpath() treats unixpath as relpath, and ' 'prepends C:\\ (py-3.6 only, corrected in py-3.7)') platform = self.CaseInsensitivePlatform() - path = filesystem.canonical_path('/var/tmp/File.txt', platform) - expects = '/var/tmp/file.txt'.replace('\\', os.sep) + path = filesystem.canonical_path('/a/b/File.txt', platform) + expects = '/a/b/file.txt'.replace('\\', os.sep) self.assertEqual(path, expects) From 7022990bd425fc2404ff50398d168f464de1a099 Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Thu, 31 Oct 2019 19:26:42 -0400 Subject: [PATCH 13/14] skip message is more explicit. realpath() behaviour has nothing to do with python version. --- src/rez/tests/test_utils_filesystem.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/rez/tests/test_utils_filesystem.py b/src/rez/tests/test_utils_filesystem.py index 7db68125a..c79721e76 100644 --- a/src/rez/tests/test_utils_filesystem.py +++ b/src/rez/tests/test_utils_filesystem.py @@ -20,9 +20,8 @@ def has_case_sensitive_filesystem(self): def test_win32_case_insensitive(self): if platform_.name != 'windows': - self.skipTest('os.path.realpath() treats ntpath as relpath, ' - 'and prepends os.getcwd ' - '(py-3.6 only, corrected in py-3.7)') + self.skipTest('on linux/macos, `os.path.realpath()` treats windows ' + 'abspaths as relpaths, and prepends `os.getcwd()`') platform = self.CaseInsensitivePlatform() path = filesystem.canonical_path('C:\\dir\\File.txt', platform) expects = 'c:\\dir\\file.txt'.replace('\\', os.sep) @@ -30,8 +29,8 @@ def test_win32_case_insensitive(self): def test_unix_case_sensistive_platform(self): if platform_.name == 'windows': - self.skipTest('os.path.realpath() treats unixpath as relpath, and ' - 'prepends C:\\ (py-3.6 only, corrected in py-3.7)') + self.skipTest('on windows, `os.path.realpath()` treats unix abspaths ' + 'as relpaths, and prepends `os.getcwd()`') platform = self.CaseSensitivePlatform() path = filesystem.canonical_path('/a/b/File.txt', platform) expects = '/a/b/File.txt'.replace('\\', os.sep) @@ -39,8 +38,8 @@ def test_unix_case_sensistive_platform(self): def test_unix_case_insensistive_platform(self): if platform_.name == 'windows': - self.skipTest('os.path.realpath() treats unixpath as relpath, and ' - 'prepends C:\\ (py-3.6 only, corrected in py-3.7)') + self.skipTest('on windows, `os.path.realpath()` treats unix abspaths ' + 'as relpaths, and prepends `os.getcwd()`') platform = self.CaseInsensitivePlatform() path = filesystem.canonical_path('/a/b/File.txt', platform) expects = '/a/b/file.txt'.replace('\\', os.sep) From fa24878344f3eb95330ea039d29d3eb54e55f27c Mon Sep 17 00:00:00 2001 From: Will Pittman Date: Tue, 5 Nov 2019 19:45:31 -0500 Subject: [PATCH 14/14] renames test_utils_filesystem -> test_utils --- src/rez/tests/{test_utils_filesystem.py => test_utils.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/rez/tests/{test_utils_filesystem.py => test_utils.py} (100%) diff --git a/src/rez/tests/test_utils_filesystem.py b/src/rez/tests/test_utils.py similarity index 100% rename from src/rez/tests/test_utils_filesystem.py rename to src/rez/tests/test_utils.py