1#!/pxrpythonsubst 2# 3# Copyright 2016 Pixar 4# 5# Licensed under the Apache License, Version 2.0 (the "Apache License") 6# with the following modification; you may not use this file except in 7# compliance with the Apache License and the following modification to it: 8# Section 6. Trademarks. is deleted and replaced with: 9# 10# 6. Trademarks. This License does not grant permission to use the trade 11# names, trademarks, service marks, or product names of the Licensor 12# and its affiliates, except as required to comply with Section 4(c) of 13# the License and to reproduce the content of the NOTICE file. 14# 15# You may obtain a copy of the Apache License at 16# 17# http://www.apache.org/licenses/LICENSE-2.0 18# 19# Unless required by applicable law or agreed to in writing, software 20# distributed under the Apache License with the above modification is 21# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 22# KIND, either express or implied. See the Apache License for the specific 23# language governing permissions and limitations under the Apache License. 24# 25 26import logging 27import os 28from pxr import Tf 29import unittest 30import platform 31 32class TestPathUtils(unittest.TestCase): 33 34 def setUp(self): 35 self.log = logging.getLogger() 36 37 def test_TfRealPath(self): 38 if not os.path.isdir('subdir/e'): 39 os.makedirs('subdir/e') 40 self.log.info('no symlinks') 41 self.assertEqual(os.path.abspath('subdir'), Tf.RealPath('subdir', True)) 42 43 if hasattr(os, 'symlink'): 44 try: 45 if not os.path.islink('b'): 46 os.symlink('subdir', 'b') 47 if not os.path.islink('c'): 48 os.symlink('b', 'c') 49 if not os.path.islink('d'): 50 os.symlink('c', 'd') 51 if not os.path.islink('e'): 52 os.symlink('missing', 'e') 53 if not os.path.islink('f'): 54 os.symlink('e', 'f') 55 if not os.path.islink('g'): 56 os.symlink('f', 'g') 57 58 # XXX: 59 # On Windows, TfRealPath explicitly lower-cases drive letters 60 # if the given path contains symlinks, otherwise it returns 61 # the same as os.path.abspath. This is inconsistent but 62 # fixing it is a bit riskier. So for now, we just test the 63 # the current behavior. 64 def _TestSymlink(expected, got): 65 if platform.system() == 'Windows': 66 drive, tail = os.path.splitdrive(expected) 67 expected = drive.lower() + tail 68 self.assertEqual(expected, got) 69 70 self.log.info('leaf dir is symlink') 71 _TestSymlink(os.path.abspath('subdir'), 72 Tf.RealPath('d', True)) 73 self.log.info('symlinks through to dir') 74 _TestSymlink(os.path.abspath('subdir/e'), 75 Tf.RealPath('d/e', True)) 76 self.log.info('symlinks through to nonexistent dirs') 77 _TestSymlink(os.path.abspath('subdir/e/f/g/h'), 78 Tf.RealPath('d/e/f/g/h', True)) 79 self.log.info('symlinks through to broken link') 80 _TestSymlink('', Tf.RealPath('g', True)) 81 82 self.log.info('symlinks through to broken link, ' 83 'raiseOnError=True') 84 with self.assertRaises(RuntimeError): 85 Tf.RealPath('g', True, raiseOnError=True) 86 87 if platform.system() == 'Windows': 88 try: 89 # Test repro from USD-6557 90 if not os.path.isdir(r'C:/symlink-test'): 91 os.makedirs(r'C:/symlink-test') 92 93 if not os.path.islink(r'C:/symlink-test-link'): 94 os.symlink(r'C:/symlink-test', 'C:/symlink-test-link') 95 cwd = os.getcwd() 96 try: 97 os.chdir(r'C:/symlink-test-link') 98 _TestSymlink(os.path.abspath('C:/symlink-test'), 99 Tf.RealPath(r'C:/symlink-test-link')) 100 finally: 101 # Restore cwd before trying to remove the test 102 # dirs, otherwise Windows will disallow it. 103 os.chdir(cwd) 104 finally: 105 if os.path.isdir(r'C:/symlink-test-link'): 106 os.rmdir(r'C:/symlink-test-link') 107 if os.path.isdir(r'C:/symlink-test'): 108 os.rmdir(r'C:/symlink-test') 109 110 except OSError: 111 # On windows this is expected if run by a non-administrator 112 if platform.system() == 'Windows': 113 pass 114 else: 115 raise 116 117if __name__ == '__main__': 118 unittest.main() 119