1# 2# SPDX-License-Identifier: MIT 3# 4 5from unittest.case import TestCase 6import oe, oe.path 7import tempfile 8import os 9import errno 10import shutil 11 12class TestRealPath(TestCase): 13 DIRS = [ "a", "b", "etc", "sbin", "usr", "usr/bin", "usr/binX", "usr/sbin", "usr/include", "usr/include/gdbm" ] 14 FILES = [ "etc/passwd", "b/file" ] 15 LINKS = [ 16 ( "bin", "/usr/bin", "/usr/bin" ), 17 ( "binX", "usr/binX", "/usr/binX" ), 18 ( "c", "broken", "/broken" ), 19 ( "etc/passwd-1", "passwd", "/etc/passwd" ), 20 ( "etc/passwd-2", "passwd-1", "/etc/passwd" ), 21 ( "etc/passwd-3", "/etc/passwd-1", "/etc/passwd" ), 22 ( "etc/shadow-1", "/etc/shadow", "/etc/shadow" ), 23 ( "etc/shadow-2", "/etc/shadow-1", "/etc/shadow" ), 24 ( "prog-A", "bin/prog-A", "/usr/bin/prog-A" ), 25 ( "prog-B", "/bin/prog-B", "/usr/bin/prog-B" ), 26 ( "usr/bin/prog-C", "../../sbin/prog-C", "/sbin/prog-C" ), 27 ( "usr/bin/prog-D", "/sbin/prog-D", "/sbin/prog-D" ), 28 ( "usr/binX/prog-E", "../sbin/prog-E", None ), 29 ( "usr/bin/prog-F", "../../../sbin/prog-F", "/sbin/prog-F" ), 30 ( "loop", "a/loop", None ), 31 ( "a/loop", "../loop", None ), 32 ( "b/test", "file/foo", "/b/file/foo" ), 33 ] 34 35 LINKS_PHYS = [ 36 ( "./", "/", "" ), 37 ( "binX/prog-E", "/usr/sbin/prog-E", "/sbin/prog-E" ), 38 ] 39 40 EXCEPTIONS = [ 41 ( "loop", errno.ELOOP ), 42 ( "b/test", errno.ENOENT ), 43 ] 44 45 def setUp(self): 46 self.tmpdir = tempfile.mkdtemp(prefix = "oe-test_path") 47 self.root = os.path.join(self.tmpdir, "R") 48 49 os.mkdir(os.path.join(self.tmpdir, "_real")) 50 os.symlink("_real", self.root) 51 52 for d in self.DIRS: 53 os.mkdir(os.path.join(self.root, d)) 54 for f in self.FILES: 55 open(os.path.join(self.root, f), "w") 56 for l in self.LINKS: 57 os.symlink(l[1], os.path.join(self.root, l[0])) 58 59 def tearDown(self): 60 shutil.rmtree(self.tmpdir) 61 62 def __realpath(self, file, use_physdir, assume_dir = True): 63 return oe.path.realpath(os.path.join(self.root, file), self.root, 64 use_physdir, assume_dir = assume_dir) 65 66 def test_norm(self): 67 for l in self.LINKS: 68 if l[2] == None: 69 continue 70 71 target_p = self.__realpath(l[0], True) 72 target_l = self.__realpath(l[0], False) 73 74 if l[2] != False: 75 self.assertEqual(target_p, target_l) 76 self.assertEqual(l[2], target_p[len(self.root):]) 77 78 def test_phys(self): 79 for l in self.LINKS_PHYS: 80 target_p = self.__realpath(l[0], True) 81 target_l = self.__realpath(l[0], False) 82 83 self.assertEqual(l[1], target_p[len(self.root):]) 84 self.assertEqual(l[2], target_l[len(self.root):]) 85 86 def test_loop(self): 87 for e in self.EXCEPTIONS: 88 self.assertRaisesRegex(OSError, r'\[Errno %u\]' % e[1], 89 self.__realpath, e[0], False, False) 90