1from unittest.case import TestCase
2import oe, oe.path
3import tempfile
4import os
5import errno
6import shutil
7
8class TestRealPath(TestCase):
9    DIRS = [ "a", "b", "etc", "sbin", "usr", "usr/bin", "usr/binX", "usr/sbin", "usr/include", "usr/include/gdbm" ]
10    FILES = [ "etc/passwd", "b/file" ]
11    LINKS = [
12        ( "bin",             "/usr/bin",             "/usr/bin" ),
13        ( "binX",            "usr/binX",             "/usr/binX" ),
14        ( "c",               "broken",               "/broken" ),
15        ( "etc/passwd-1",    "passwd",               "/etc/passwd" ),
16        ( "etc/passwd-2",    "passwd-1",             "/etc/passwd" ),
17        ( "etc/passwd-3",    "/etc/passwd-1",        "/etc/passwd" ),
18        ( "etc/shadow-1",    "/etc/shadow",          "/etc/shadow" ),
19        ( "etc/shadow-2",    "/etc/shadow-1",        "/etc/shadow" ),
20        ( "prog-A",          "bin/prog-A",           "/usr/bin/prog-A" ),
21        ( "prog-B",          "/bin/prog-B",          "/usr/bin/prog-B" ),
22        ( "usr/bin/prog-C",  "../../sbin/prog-C",    "/sbin/prog-C" ),
23        ( "usr/bin/prog-D",  "/sbin/prog-D",         "/sbin/prog-D" ),
24        ( "usr/binX/prog-E", "../sbin/prog-E",       None ),
25        ( "usr/bin/prog-F",  "../../../sbin/prog-F", "/sbin/prog-F" ),
26        ( "loop",            "a/loop",               None ),
27        ( "a/loop",          "../loop",              None ),
28        ( "b/test",          "file/foo",             "/b/file/foo" ),
29    ]
30
31    LINKS_PHYS = [
32        ( "./",          "/",                "" ),
33        ( "binX/prog-E", "/usr/sbin/prog-E", "/sbin/prog-E" ),
34    ]
35
36    EXCEPTIONS = [
37        ( "loop",   errno.ELOOP ),
38        ( "b/test", errno.ENOENT ),
39    ]
40
41    def __del__(self):
42        try:
43            #os.system("tree -F %s" % self.tmpdir)
44            shutil.rmtree(self.tmpdir)
45        except:
46            pass
47
48    def setUp(self):
49        self.tmpdir = tempfile.mkdtemp(prefix = "oe-test_path")
50        self.root = os.path.join(self.tmpdir, "R")
51
52        os.mkdir(os.path.join(self.tmpdir, "_real"))
53        os.symlink("_real", self.root)
54
55        for d in self.DIRS:
56            os.mkdir(os.path.join(self.root, d))
57        for f in self.FILES:
58            open(os.path.join(self.root, f), "w")
59        for l in self.LINKS:
60            os.symlink(l[1], os.path.join(self.root, l[0]))
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