17db96d56Sopenharmony_ci# As a test suite for the os module, this is woefully inadequate, but this
27db96d56Sopenharmony_ci# does add tests for a few functions which have been determined to be more
37db96d56Sopenharmony_ci# portable than they had been thought to be.
47db96d56Sopenharmony_ci
57db96d56Sopenharmony_ciimport asyncio
67db96d56Sopenharmony_ciimport codecs
77db96d56Sopenharmony_ciimport contextlib
87db96d56Sopenharmony_ciimport decimal
97db96d56Sopenharmony_ciimport errno
107db96d56Sopenharmony_ciimport fnmatch
117db96d56Sopenharmony_ciimport fractions
127db96d56Sopenharmony_ciimport itertools
137db96d56Sopenharmony_ciimport locale
147db96d56Sopenharmony_ciimport os
157db96d56Sopenharmony_ciimport pickle
167db96d56Sopenharmony_ciimport select
177db96d56Sopenharmony_ciimport shutil
187db96d56Sopenharmony_ciimport signal
197db96d56Sopenharmony_ciimport socket
207db96d56Sopenharmony_ciimport stat
217db96d56Sopenharmony_ciimport struct
227db96d56Sopenharmony_ciimport subprocess
237db96d56Sopenharmony_ciimport sys
247db96d56Sopenharmony_ciimport sysconfig
257db96d56Sopenharmony_ciimport tempfile
267db96d56Sopenharmony_ciimport textwrap
277db96d56Sopenharmony_ciimport time
287db96d56Sopenharmony_ciimport types
297db96d56Sopenharmony_ciimport unittest
307db96d56Sopenharmony_ciimport uuid
317db96d56Sopenharmony_ciimport warnings
327db96d56Sopenharmony_cifrom test import support
337db96d56Sopenharmony_cifrom test.support import import_helper
347db96d56Sopenharmony_cifrom test.support import os_helper
357db96d56Sopenharmony_cifrom test.support import socket_helper
367db96d56Sopenharmony_cifrom test.support import warnings_helper
377db96d56Sopenharmony_cifrom platform import win32_is_iot
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_citry:
407db96d56Sopenharmony_ci    import resource
417db96d56Sopenharmony_ciexcept ImportError:
427db96d56Sopenharmony_ci    resource = None
437db96d56Sopenharmony_citry:
447db96d56Sopenharmony_ci    import fcntl
457db96d56Sopenharmony_ciexcept ImportError:
467db96d56Sopenharmony_ci    fcntl = None
477db96d56Sopenharmony_citry:
487db96d56Sopenharmony_ci    import _winapi
497db96d56Sopenharmony_ciexcept ImportError:
507db96d56Sopenharmony_ci    _winapi = None
517db96d56Sopenharmony_citry:
527db96d56Sopenharmony_ci    import pwd
537db96d56Sopenharmony_ci    all_users = [u.pw_uid for u in pwd.getpwall()]
547db96d56Sopenharmony_ciexcept (ImportError, AttributeError):
557db96d56Sopenharmony_ci    all_users = []
567db96d56Sopenharmony_citry:
577db96d56Sopenharmony_ci    from _testcapi import INT_MAX, PY_SSIZE_T_MAX
587db96d56Sopenharmony_ciexcept ImportError:
597db96d56Sopenharmony_ci    INT_MAX = PY_SSIZE_T_MAX = sys.maxsize
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_citry:
627db96d56Sopenharmony_ci    import mmap
637db96d56Sopenharmony_ciexcept ImportError:
647db96d56Sopenharmony_ci    mmap = None
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_cifrom test.support.script_helper import assert_python_ok
677db96d56Sopenharmony_cifrom test.support import unix_shell
687db96d56Sopenharmony_cifrom test.support.os_helper import FakePath
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ciroot_in_posix = False
727db96d56Sopenharmony_ciif hasattr(os, 'geteuid'):
737db96d56Sopenharmony_ci    root_in_posix = (os.geteuid() == 0)
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_ci# Detect whether we're on a Linux system that uses the (now outdated
767db96d56Sopenharmony_ci# and unmaintained) linuxthreads threading library.  There's an issue
777db96d56Sopenharmony_ci# when combining linuxthreads with a failed execv call: see
787db96d56Sopenharmony_ci# http://bugs.python.org/issue4970.
797db96d56Sopenharmony_ciif hasattr(sys, 'thread_info') and sys.thread_info.version:
807db96d56Sopenharmony_ci    USING_LINUXTHREADS = sys.thread_info.version.startswith("linuxthreads")
817db96d56Sopenharmony_cielse:
827db96d56Sopenharmony_ci    USING_LINUXTHREADS = False
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci# Issue #14110: Some tests fail on FreeBSD if the user is in the wheel group.
857db96d56Sopenharmony_ciHAVE_WHEEL_GROUP = sys.platform.startswith('freebsd') and os.getgid() == 0
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_cidef requires_os_func(name):
897db96d56Sopenharmony_ci    return unittest.skipUnless(hasattr(os, name), 'requires os.%s' % name)
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_cidef create_file(filename, content=b'content'):
937db96d56Sopenharmony_ci    with open(filename, "xb", 0) as fp:
947db96d56Sopenharmony_ci        fp.write(content)
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci# bpo-41625: On AIX, splice() only works with a socket, not with a pipe.
987db96d56Sopenharmony_cirequires_splice_pipe = unittest.skipIf(sys.platform.startswith("aix"),
997db96d56Sopenharmony_ci                                       'on AIX, splice() only accepts sockets')
1007db96d56Sopenharmony_ci
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_cidef tearDownModule():
1037db96d56Sopenharmony_ci    asyncio.set_event_loop_policy(None)
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_ciclass MiscTests(unittest.TestCase):
1077db96d56Sopenharmony_ci    def test_getcwd(self):
1087db96d56Sopenharmony_ci        cwd = os.getcwd()
1097db96d56Sopenharmony_ci        self.assertIsInstance(cwd, str)
1107db96d56Sopenharmony_ci
1117db96d56Sopenharmony_ci    def test_getcwd_long_path(self):
1127db96d56Sopenharmony_ci        # bpo-37412: On Linux, PATH_MAX is usually around 4096 bytes. On
1137db96d56Sopenharmony_ci        # Windows, MAX_PATH is defined as 260 characters, but Windows supports
1147db96d56Sopenharmony_ci        # longer path if longer paths support is enabled. Internally, the os
1157db96d56Sopenharmony_ci        # module uses MAXPATHLEN which is at least 1024.
1167db96d56Sopenharmony_ci        #
1177db96d56Sopenharmony_ci        # Use a directory name of 200 characters to fit into Windows MAX_PATH
1187db96d56Sopenharmony_ci        # limit.
1197db96d56Sopenharmony_ci        #
1207db96d56Sopenharmony_ci        # On Windows, the test can stop when trying to create a path longer
1217db96d56Sopenharmony_ci        # than MAX_PATH if long paths support is disabled:
1227db96d56Sopenharmony_ci        # see RtlAreLongPathsEnabled().
1237db96d56Sopenharmony_ci        min_len = 2000   # characters
1247db96d56Sopenharmony_ci        # On VxWorks, PATH_MAX is defined as 1024 bytes. Creating a path
1257db96d56Sopenharmony_ci        # longer than PATH_MAX will fail.
1267db96d56Sopenharmony_ci        if sys.platform == 'vxworks':
1277db96d56Sopenharmony_ci            min_len = 1000
1287db96d56Sopenharmony_ci        dirlen = 200     # characters
1297db96d56Sopenharmony_ci        dirname = 'python_test_dir_'
1307db96d56Sopenharmony_ci        dirname = dirname + ('a' * (dirlen - len(dirname)))
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_ci        with tempfile.TemporaryDirectory() as tmpdir:
1337db96d56Sopenharmony_ci            with os_helper.change_cwd(tmpdir) as path:
1347db96d56Sopenharmony_ci                expected = path
1357db96d56Sopenharmony_ci
1367db96d56Sopenharmony_ci                while True:
1377db96d56Sopenharmony_ci                    cwd = os.getcwd()
1387db96d56Sopenharmony_ci                    self.assertEqual(cwd, expected)
1397db96d56Sopenharmony_ci
1407db96d56Sopenharmony_ci                    need = min_len - (len(cwd) + len(os.path.sep))
1417db96d56Sopenharmony_ci                    if need <= 0:
1427db96d56Sopenharmony_ci                        break
1437db96d56Sopenharmony_ci                    if len(dirname) > need and need > 0:
1447db96d56Sopenharmony_ci                        dirname = dirname[:need]
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ci                    path = os.path.join(path, dirname)
1477db96d56Sopenharmony_ci                    try:
1487db96d56Sopenharmony_ci                        os.mkdir(path)
1497db96d56Sopenharmony_ci                        # On Windows, chdir() can fail
1507db96d56Sopenharmony_ci                        # even if mkdir() succeeded
1517db96d56Sopenharmony_ci                        os.chdir(path)
1527db96d56Sopenharmony_ci                    except FileNotFoundError:
1537db96d56Sopenharmony_ci                        # On Windows, catch ERROR_PATH_NOT_FOUND (3) and
1547db96d56Sopenharmony_ci                        # ERROR_FILENAME_EXCED_RANGE (206) errors
1557db96d56Sopenharmony_ci                        # ("The filename or extension is too long")
1567db96d56Sopenharmony_ci                        break
1577db96d56Sopenharmony_ci                    except OSError as exc:
1587db96d56Sopenharmony_ci                        if exc.errno == errno.ENAMETOOLONG:
1597db96d56Sopenharmony_ci                            break
1607db96d56Sopenharmony_ci                        else:
1617db96d56Sopenharmony_ci                            raise
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci                    expected = path
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ci                if support.verbose:
1667db96d56Sopenharmony_ci                    print(f"Tested current directory length: {len(cwd)}")
1677db96d56Sopenharmony_ci
1687db96d56Sopenharmony_ci    def test_getcwdb(self):
1697db96d56Sopenharmony_ci        cwd = os.getcwdb()
1707db96d56Sopenharmony_ci        self.assertIsInstance(cwd, bytes)
1717db96d56Sopenharmony_ci        self.assertEqual(os.fsdecode(cwd), os.getcwd())
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_ci# Tests creating TESTFN
1757db96d56Sopenharmony_ciclass FileTests(unittest.TestCase):
1767db96d56Sopenharmony_ci    def setUp(self):
1777db96d56Sopenharmony_ci        if os.path.lexists(os_helper.TESTFN):
1787db96d56Sopenharmony_ci            os.unlink(os_helper.TESTFN)
1797db96d56Sopenharmony_ci    tearDown = setUp
1807db96d56Sopenharmony_ci
1817db96d56Sopenharmony_ci    def test_access(self):
1827db96d56Sopenharmony_ci        f = os.open(os_helper.TESTFN, os.O_CREAT|os.O_RDWR)
1837db96d56Sopenharmony_ci        os.close(f)
1847db96d56Sopenharmony_ci        self.assertTrue(os.access(os_helper.TESTFN, os.W_OK))
1857db96d56Sopenharmony_ci
1867db96d56Sopenharmony_ci    @unittest.skipIf(
1877db96d56Sopenharmony_ci        support.is_emscripten, "Test is unstable under Emscripten."
1887db96d56Sopenharmony_ci    )
1897db96d56Sopenharmony_ci    @unittest.skipIf(
1907db96d56Sopenharmony_ci        support.is_wasi, "WASI does not support dup."
1917db96d56Sopenharmony_ci    )
1927db96d56Sopenharmony_ci    def test_closerange(self):
1937db96d56Sopenharmony_ci        first = os.open(os_helper.TESTFN, os.O_CREAT|os.O_RDWR)
1947db96d56Sopenharmony_ci        # We must allocate two consecutive file descriptors, otherwise
1957db96d56Sopenharmony_ci        # it will mess up other file descriptors (perhaps even the three
1967db96d56Sopenharmony_ci        # standard ones).
1977db96d56Sopenharmony_ci        second = os.dup(first)
1987db96d56Sopenharmony_ci        try:
1997db96d56Sopenharmony_ci            retries = 0
2007db96d56Sopenharmony_ci            while second != first + 1:
2017db96d56Sopenharmony_ci                os.close(first)
2027db96d56Sopenharmony_ci                retries += 1
2037db96d56Sopenharmony_ci                if retries > 10:
2047db96d56Sopenharmony_ci                    # XXX test skipped
2057db96d56Sopenharmony_ci                    self.skipTest("couldn't allocate two consecutive fds")
2067db96d56Sopenharmony_ci                first, second = second, os.dup(second)
2077db96d56Sopenharmony_ci        finally:
2087db96d56Sopenharmony_ci            os.close(second)
2097db96d56Sopenharmony_ci        # close a fd that is open, and one that isn't
2107db96d56Sopenharmony_ci        os.closerange(first, first + 2)
2117db96d56Sopenharmony_ci        self.assertRaises(OSError, os.write, first, b"a")
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ci    @support.cpython_only
2147db96d56Sopenharmony_ci    def test_rename(self):
2157db96d56Sopenharmony_ci        path = os_helper.TESTFN
2167db96d56Sopenharmony_ci        old = sys.getrefcount(path)
2177db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.rename, path, 0)
2187db96d56Sopenharmony_ci        new = sys.getrefcount(path)
2197db96d56Sopenharmony_ci        self.assertEqual(old, new)
2207db96d56Sopenharmony_ci
2217db96d56Sopenharmony_ci    def test_read(self):
2227db96d56Sopenharmony_ci        with open(os_helper.TESTFN, "w+b") as fobj:
2237db96d56Sopenharmony_ci            fobj.write(b"spam")
2247db96d56Sopenharmony_ci            fobj.flush()
2257db96d56Sopenharmony_ci            fd = fobj.fileno()
2267db96d56Sopenharmony_ci            os.lseek(fd, 0, 0)
2277db96d56Sopenharmony_ci            s = os.read(fd, 4)
2287db96d56Sopenharmony_ci            self.assertEqual(type(s), bytes)
2297db96d56Sopenharmony_ci            self.assertEqual(s, b"spam")
2307db96d56Sopenharmony_ci
2317db96d56Sopenharmony_ci    @support.cpython_only
2327db96d56Sopenharmony_ci    # Skip the test on 32-bit platforms: the number of bytes must fit in a
2337db96d56Sopenharmony_ci    # Py_ssize_t type
2347db96d56Sopenharmony_ci    @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX,
2357db96d56Sopenharmony_ci                         "needs INT_MAX < PY_SSIZE_T_MAX")
2367db96d56Sopenharmony_ci    @support.bigmemtest(size=INT_MAX + 10, memuse=1, dry_run=False)
2377db96d56Sopenharmony_ci    def test_large_read(self, size):
2387db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
2397db96d56Sopenharmony_ci        create_file(os_helper.TESTFN, b'test')
2407db96d56Sopenharmony_ci
2417db96d56Sopenharmony_ci        # Issue #21932: Make sure that os.read() does not raise an
2427db96d56Sopenharmony_ci        # OverflowError for size larger than INT_MAX
2437db96d56Sopenharmony_ci        with open(os_helper.TESTFN, "rb") as fp:
2447db96d56Sopenharmony_ci            data = os.read(fp.fileno(), size)
2457db96d56Sopenharmony_ci
2467db96d56Sopenharmony_ci        # The test does not try to read more than 2 GiB at once because the
2477db96d56Sopenharmony_ci        # operating system is free to return less bytes than requested.
2487db96d56Sopenharmony_ci        self.assertEqual(data, b'test')
2497db96d56Sopenharmony_ci
2507db96d56Sopenharmony_ci    def test_write(self):
2517db96d56Sopenharmony_ci        # os.write() accepts bytes- and buffer-like objects but not strings
2527db96d56Sopenharmony_ci        fd = os.open(os_helper.TESTFN, os.O_CREAT | os.O_WRONLY)
2537db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.write, fd, "beans")
2547db96d56Sopenharmony_ci        os.write(fd, b"bacon\n")
2557db96d56Sopenharmony_ci        os.write(fd, bytearray(b"eggs\n"))
2567db96d56Sopenharmony_ci        os.write(fd, memoryview(b"spam\n"))
2577db96d56Sopenharmony_ci        os.close(fd)
2587db96d56Sopenharmony_ci        with open(os_helper.TESTFN, "rb") as fobj:
2597db96d56Sopenharmony_ci            self.assertEqual(fobj.read().splitlines(),
2607db96d56Sopenharmony_ci                [b"bacon", b"eggs", b"spam"])
2617db96d56Sopenharmony_ci
2627db96d56Sopenharmony_ci    def write_windows_console(self, *args):
2637db96d56Sopenharmony_ci        retcode = subprocess.call(args,
2647db96d56Sopenharmony_ci            # use a new console to not flood the test output
2657db96d56Sopenharmony_ci            creationflags=subprocess.CREATE_NEW_CONSOLE,
2667db96d56Sopenharmony_ci            # use a shell to hide the console window (SW_HIDE)
2677db96d56Sopenharmony_ci            shell=True)
2687db96d56Sopenharmony_ci        self.assertEqual(retcode, 0)
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci    @unittest.skipUnless(sys.platform == 'win32',
2717db96d56Sopenharmony_ci                         'test specific to the Windows console')
2727db96d56Sopenharmony_ci    def test_write_windows_console(self):
2737db96d56Sopenharmony_ci        # Issue #11395: the Windows console returns an error (12: not enough
2747db96d56Sopenharmony_ci        # space error) on writing into stdout if stdout mode is binary and the
2757db96d56Sopenharmony_ci        # length is greater than 66,000 bytes (or less, depending on heap
2767db96d56Sopenharmony_ci        # usage).
2777db96d56Sopenharmony_ci        code = "print('x' * 100000)"
2787db96d56Sopenharmony_ci        self.write_windows_console(sys.executable, "-c", code)
2797db96d56Sopenharmony_ci        self.write_windows_console(sys.executable, "-u", "-c", code)
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_ci    def fdopen_helper(self, *args):
2827db96d56Sopenharmony_ci        fd = os.open(os_helper.TESTFN, os.O_RDONLY)
2837db96d56Sopenharmony_ci        f = os.fdopen(fd, *args, encoding="utf-8")
2847db96d56Sopenharmony_ci        f.close()
2857db96d56Sopenharmony_ci
2867db96d56Sopenharmony_ci    def test_fdopen(self):
2877db96d56Sopenharmony_ci        fd = os.open(os_helper.TESTFN, os.O_CREAT|os.O_RDWR)
2887db96d56Sopenharmony_ci        os.close(fd)
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ci        self.fdopen_helper()
2917db96d56Sopenharmony_ci        self.fdopen_helper('r')
2927db96d56Sopenharmony_ci        self.fdopen_helper('r', 100)
2937db96d56Sopenharmony_ci
2947db96d56Sopenharmony_ci    def test_replace(self):
2957db96d56Sopenharmony_ci        TESTFN2 = os_helper.TESTFN + ".2"
2967db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
2977db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, TESTFN2)
2987db96d56Sopenharmony_ci
2997db96d56Sopenharmony_ci        create_file(os_helper.TESTFN, b"1")
3007db96d56Sopenharmony_ci        create_file(TESTFN2, b"2")
3017db96d56Sopenharmony_ci
3027db96d56Sopenharmony_ci        os.replace(os_helper.TESTFN, TESTFN2)
3037db96d56Sopenharmony_ci        self.assertRaises(FileNotFoundError, os.stat, os_helper.TESTFN)
3047db96d56Sopenharmony_ci        with open(TESTFN2, 'r', encoding='utf-8') as f:
3057db96d56Sopenharmony_ci            self.assertEqual(f.read(), "1")
3067db96d56Sopenharmony_ci
3077db96d56Sopenharmony_ci    def test_open_keywords(self):
3087db96d56Sopenharmony_ci        f = os.open(path=__file__, flags=os.O_RDONLY, mode=0o777,
3097db96d56Sopenharmony_ci            dir_fd=None)
3107db96d56Sopenharmony_ci        os.close(f)
3117db96d56Sopenharmony_ci
3127db96d56Sopenharmony_ci    def test_symlink_keywords(self):
3137db96d56Sopenharmony_ci        symlink = support.get_attribute(os, "symlink")
3147db96d56Sopenharmony_ci        try:
3157db96d56Sopenharmony_ci            symlink(src='target', dst=os_helper.TESTFN,
3167db96d56Sopenharmony_ci                target_is_directory=False, dir_fd=None)
3177db96d56Sopenharmony_ci        except (NotImplementedError, OSError):
3187db96d56Sopenharmony_ci            pass  # No OS support or unprivileged user
3197db96d56Sopenharmony_ci
3207db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()')
3217db96d56Sopenharmony_ci    def test_copy_file_range_invalid_values(self):
3227db96d56Sopenharmony_ci        with self.assertRaises(ValueError):
3237db96d56Sopenharmony_ci            os.copy_file_range(0, 1, -10)
3247db96d56Sopenharmony_ci
3257db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()')
3267db96d56Sopenharmony_ci    def test_copy_file_range(self):
3277db96d56Sopenharmony_ci        TESTFN2 = os_helper.TESTFN + ".3"
3287db96d56Sopenharmony_ci        data = b'0123456789'
3297db96d56Sopenharmony_ci
3307db96d56Sopenharmony_ci        create_file(os_helper.TESTFN, data)
3317db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci        in_file = open(os_helper.TESTFN, 'rb')
3347db96d56Sopenharmony_ci        self.addCleanup(in_file.close)
3357db96d56Sopenharmony_ci        in_fd = in_file.fileno()
3367db96d56Sopenharmony_ci
3377db96d56Sopenharmony_ci        out_file = open(TESTFN2, 'w+b')
3387db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, TESTFN2)
3397db96d56Sopenharmony_ci        self.addCleanup(out_file.close)
3407db96d56Sopenharmony_ci        out_fd = out_file.fileno()
3417db96d56Sopenharmony_ci
3427db96d56Sopenharmony_ci        try:
3437db96d56Sopenharmony_ci            i = os.copy_file_range(in_fd, out_fd, 5)
3447db96d56Sopenharmony_ci        except OSError as e:
3457db96d56Sopenharmony_ci            # Handle the case in which Python was compiled
3467db96d56Sopenharmony_ci            # in a system with the syscall but without support
3477db96d56Sopenharmony_ci            # in the kernel.
3487db96d56Sopenharmony_ci            if e.errno != errno.ENOSYS:
3497db96d56Sopenharmony_ci                raise
3507db96d56Sopenharmony_ci            self.skipTest(e)
3517db96d56Sopenharmony_ci        else:
3527db96d56Sopenharmony_ci            # The number of copied bytes can be less than
3537db96d56Sopenharmony_ci            # the number of bytes originally requested.
3547db96d56Sopenharmony_ci            self.assertIn(i, range(0, 6));
3557db96d56Sopenharmony_ci
3567db96d56Sopenharmony_ci            with open(TESTFN2, 'rb') as in_file:
3577db96d56Sopenharmony_ci                self.assertEqual(in_file.read(), data[:i])
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'copy_file_range'), 'test needs os.copy_file_range()')
3607db96d56Sopenharmony_ci    def test_copy_file_range_offset(self):
3617db96d56Sopenharmony_ci        TESTFN4 = os_helper.TESTFN + ".4"
3627db96d56Sopenharmony_ci        data = b'0123456789'
3637db96d56Sopenharmony_ci        bytes_to_copy = 6
3647db96d56Sopenharmony_ci        in_skip = 3
3657db96d56Sopenharmony_ci        out_seek = 5
3667db96d56Sopenharmony_ci
3677db96d56Sopenharmony_ci        create_file(os_helper.TESTFN, data)
3687db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
3697db96d56Sopenharmony_ci
3707db96d56Sopenharmony_ci        in_file = open(os_helper.TESTFN, 'rb')
3717db96d56Sopenharmony_ci        self.addCleanup(in_file.close)
3727db96d56Sopenharmony_ci        in_fd = in_file.fileno()
3737db96d56Sopenharmony_ci
3747db96d56Sopenharmony_ci        out_file = open(TESTFN4, 'w+b')
3757db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, TESTFN4)
3767db96d56Sopenharmony_ci        self.addCleanup(out_file.close)
3777db96d56Sopenharmony_ci        out_fd = out_file.fileno()
3787db96d56Sopenharmony_ci
3797db96d56Sopenharmony_ci        try:
3807db96d56Sopenharmony_ci            i = os.copy_file_range(in_fd, out_fd, bytes_to_copy,
3817db96d56Sopenharmony_ci                                   offset_src=in_skip,
3827db96d56Sopenharmony_ci                                   offset_dst=out_seek)
3837db96d56Sopenharmony_ci        except OSError as e:
3847db96d56Sopenharmony_ci            # Handle the case in which Python was compiled
3857db96d56Sopenharmony_ci            # in a system with the syscall but without support
3867db96d56Sopenharmony_ci            # in the kernel.
3877db96d56Sopenharmony_ci            if e.errno != errno.ENOSYS:
3887db96d56Sopenharmony_ci                raise
3897db96d56Sopenharmony_ci            self.skipTest(e)
3907db96d56Sopenharmony_ci        else:
3917db96d56Sopenharmony_ci            # The number of copied bytes can be less than
3927db96d56Sopenharmony_ci            # the number of bytes originally requested.
3937db96d56Sopenharmony_ci            self.assertIn(i, range(0, bytes_to_copy+1));
3947db96d56Sopenharmony_ci
3957db96d56Sopenharmony_ci            with open(TESTFN4, 'rb') as in_file:
3967db96d56Sopenharmony_ci                read = in_file.read()
3977db96d56Sopenharmony_ci            # seeked bytes (5) are zero'ed
3987db96d56Sopenharmony_ci            self.assertEqual(read[:out_seek], b'\x00'*out_seek)
3997db96d56Sopenharmony_ci            # 012 are skipped (in_skip)
4007db96d56Sopenharmony_ci            # 345678 are copied in the file (in_skip + bytes_to_copy)
4017db96d56Sopenharmony_ci            self.assertEqual(read[out_seek:],
4027db96d56Sopenharmony_ci                             data[in_skip:in_skip+i])
4037db96d56Sopenharmony_ci
4047db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'splice'), 'test needs os.splice()')
4057db96d56Sopenharmony_ci    def test_splice_invalid_values(self):
4067db96d56Sopenharmony_ci        with self.assertRaises(ValueError):
4077db96d56Sopenharmony_ci            os.splice(0, 1, -10)
4087db96d56Sopenharmony_ci
4097db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'splice'), 'test needs os.splice()')
4107db96d56Sopenharmony_ci    @requires_splice_pipe
4117db96d56Sopenharmony_ci    def test_splice(self):
4127db96d56Sopenharmony_ci        TESTFN2 = os_helper.TESTFN + ".3"
4137db96d56Sopenharmony_ci        data = b'0123456789'
4147db96d56Sopenharmony_ci
4157db96d56Sopenharmony_ci        create_file(os_helper.TESTFN, data)
4167db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
4177db96d56Sopenharmony_ci
4187db96d56Sopenharmony_ci        in_file = open(os_helper.TESTFN, 'rb')
4197db96d56Sopenharmony_ci        self.addCleanup(in_file.close)
4207db96d56Sopenharmony_ci        in_fd = in_file.fileno()
4217db96d56Sopenharmony_ci
4227db96d56Sopenharmony_ci        read_fd, write_fd = os.pipe()
4237db96d56Sopenharmony_ci        self.addCleanup(lambda: os.close(read_fd))
4247db96d56Sopenharmony_ci        self.addCleanup(lambda: os.close(write_fd))
4257db96d56Sopenharmony_ci
4267db96d56Sopenharmony_ci        try:
4277db96d56Sopenharmony_ci            i = os.splice(in_fd, write_fd, 5)
4287db96d56Sopenharmony_ci        except OSError as e:
4297db96d56Sopenharmony_ci            # Handle the case in which Python was compiled
4307db96d56Sopenharmony_ci            # in a system with the syscall but without support
4317db96d56Sopenharmony_ci            # in the kernel.
4327db96d56Sopenharmony_ci            if e.errno != errno.ENOSYS:
4337db96d56Sopenharmony_ci                raise
4347db96d56Sopenharmony_ci            self.skipTest(e)
4357db96d56Sopenharmony_ci        else:
4367db96d56Sopenharmony_ci            # The number of copied bytes can be less than
4377db96d56Sopenharmony_ci            # the number of bytes originally requested.
4387db96d56Sopenharmony_ci            self.assertIn(i, range(0, 6));
4397db96d56Sopenharmony_ci
4407db96d56Sopenharmony_ci            self.assertEqual(os.read(read_fd, 100), data[:i])
4417db96d56Sopenharmony_ci
4427db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'splice'), 'test needs os.splice()')
4437db96d56Sopenharmony_ci    @requires_splice_pipe
4447db96d56Sopenharmony_ci    def test_splice_offset_in(self):
4457db96d56Sopenharmony_ci        TESTFN4 = os_helper.TESTFN + ".4"
4467db96d56Sopenharmony_ci        data = b'0123456789'
4477db96d56Sopenharmony_ci        bytes_to_copy = 6
4487db96d56Sopenharmony_ci        in_skip = 3
4497db96d56Sopenharmony_ci
4507db96d56Sopenharmony_ci        create_file(os_helper.TESTFN, data)
4517db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
4527db96d56Sopenharmony_ci
4537db96d56Sopenharmony_ci        in_file = open(os_helper.TESTFN, 'rb')
4547db96d56Sopenharmony_ci        self.addCleanup(in_file.close)
4557db96d56Sopenharmony_ci        in_fd = in_file.fileno()
4567db96d56Sopenharmony_ci
4577db96d56Sopenharmony_ci        read_fd, write_fd = os.pipe()
4587db96d56Sopenharmony_ci        self.addCleanup(lambda: os.close(read_fd))
4597db96d56Sopenharmony_ci        self.addCleanup(lambda: os.close(write_fd))
4607db96d56Sopenharmony_ci
4617db96d56Sopenharmony_ci        try:
4627db96d56Sopenharmony_ci            i = os.splice(in_fd, write_fd, bytes_to_copy, offset_src=in_skip)
4637db96d56Sopenharmony_ci        except OSError as e:
4647db96d56Sopenharmony_ci            # Handle the case in which Python was compiled
4657db96d56Sopenharmony_ci            # in a system with the syscall but without support
4667db96d56Sopenharmony_ci            # in the kernel.
4677db96d56Sopenharmony_ci            if e.errno != errno.ENOSYS:
4687db96d56Sopenharmony_ci                raise
4697db96d56Sopenharmony_ci            self.skipTest(e)
4707db96d56Sopenharmony_ci        else:
4717db96d56Sopenharmony_ci            # The number of copied bytes can be less than
4727db96d56Sopenharmony_ci            # the number of bytes originally requested.
4737db96d56Sopenharmony_ci            self.assertIn(i, range(0, bytes_to_copy+1));
4747db96d56Sopenharmony_ci
4757db96d56Sopenharmony_ci            read = os.read(read_fd, 100)
4767db96d56Sopenharmony_ci            # 012 are skipped (in_skip)
4777db96d56Sopenharmony_ci            # 345678 are copied in the file (in_skip + bytes_to_copy)
4787db96d56Sopenharmony_ci            self.assertEqual(read, data[in_skip:in_skip+i])
4797db96d56Sopenharmony_ci
4807db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'splice'), 'test needs os.splice()')
4817db96d56Sopenharmony_ci    @requires_splice_pipe
4827db96d56Sopenharmony_ci    def test_splice_offset_out(self):
4837db96d56Sopenharmony_ci        TESTFN4 = os_helper.TESTFN + ".4"
4847db96d56Sopenharmony_ci        data = b'0123456789'
4857db96d56Sopenharmony_ci        bytes_to_copy = 6
4867db96d56Sopenharmony_ci        out_seek = 3
4877db96d56Sopenharmony_ci
4887db96d56Sopenharmony_ci        create_file(os_helper.TESTFN, data)
4897db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
4907db96d56Sopenharmony_ci
4917db96d56Sopenharmony_ci        read_fd, write_fd = os.pipe()
4927db96d56Sopenharmony_ci        self.addCleanup(lambda: os.close(read_fd))
4937db96d56Sopenharmony_ci        self.addCleanup(lambda: os.close(write_fd))
4947db96d56Sopenharmony_ci        os.write(write_fd, data)
4957db96d56Sopenharmony_ci
4967db96d56Sopenharmony_ci        out_file = open(TESTFN4, 'w+b')
4977db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, TESTFN4)
4987db96d56Sopenharmony_ci        self.addCleanup(out_file.close)
4997db96d56Sopenharmony_ci        out_fd = out_file.fileno()
5007db96d56Sopenharmony_ci
5017db96d56Sopenharmony_ci        try:
5027db96d56Sopenharmony_ci            i = os.splice(read_fd, out_fd, bytes_to_copy, offset_dst=out_seek)
5037db96d56Sopenharmony_ci        except OSError as e:
5047db96d56Sopenharmony_ci            # Handle the case in which Python was compiled
5057db96d56Sopenharmony_ci            # in a system with the syscall but without support
5067db96d56Sopenharmony_ci            # in the kernel.
5077db96d56Sopenharmony_ci            if e.errno != errno.ENOSYS:
5087db96d56Sopenharmony_ci                raise
5097db96d56Sopenharmony_ci            self.skipTest(e)
5107db96d56Sopenharmony_ci        else:
5117db96d56Sopenharmony_ci            # The number of copied bytes can be less than
5127db96d56Sopenharmony_ci            # the number of bytes originally requested.
5137db96d56Sopenharmony_ci            self.assertIn(i, range(0, bytes_to_copy+1));
5147db96d56Sopenharmony_ci
5157db96d56Sopenharmony_ci            with open(TESTFN4, 'rb') as in_file:
5167db96d56Sopenharmony_ci                read = in_file.read()
5177db96d56Sopenharmony_ci            # seeked bytes (5) are zero'ed
5187db96d56Sopenharmony_ci            self.assertEqual(read[:out_seek], b'\x00'*out_seek)
5197db96d56Sopenharmony_ci            # 012 are skipped (in_skip)
5207db96d56Sopenharmony_ci            # 345678 are copied in the file (in_skip + bytes_to_copy)
5217db96d56Sopenharmony_ci            self.assertEqual(read[out_seek:], data[:i])
5227db96d56Sopenharmony_ci
5237db96d56Sopenharmony_ci
5247db96d56Sopenharmony_ci# Test attributes on return values from os.*stat* family.
5257db96d56Sopenharmony_ciclass StatAttributeTests(unittest.TestCase):
5267db96d56Sopenharmony_ci    def setUp(self):
5277db96d56Sopenharmony_ci        self.fname = os_helper.TESTFN
5287db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, self.fname)
5297db96d56Sopenharmony_ci        create_file(self.fname, b"ABC")
5307db96d56Sopenharmony_ci
5317db96d56Sopenharmony_ci    def check_stat_attributes(self, fname):
5327db96d56Sopenharmony_ci        result = os.stat(fname)
5337db96d56Sopenharmony_ci
5347db96d56Sopenharmony_ci        # Make sure direct access works
5357db96d56Sopenharmony_ci        self.assertEqual(result[stat.ST_SIZE], 3)
5367db96d56Sopenharmony_ci        self.assertEqual(result.st_size, 3)
5377db96d56Sopenharmony_ci
5387db96d56Sopenharmony_ci        # Make sure all the attributes are there
5397db96d56Sopenharmony_ci        members = dir(result)
5407db96d56Sopenharmony_ci        for name in dir(stat):
5417db96d56Sopenharmony_ci            if name[:3] == 'ST_':
5427db96d56Sopenharmony_ci                attr = name.lower()
5437db96d56Sopenharmony_ci                if name.endswith("TIME"):
5447db96d56Sopenharmony_ci                    def trunc(x): return int(x)
5457db96d56Sopenharmony_ci                else:
5467db96d56Sopenharmony_ci                    def trunc(x): return x
5477db96d56Sopenharmony_ci                self.assertEqual(trunc(getattr(result, attr)),
5487db96d56Sopenharmony_ci                                  result[getattr(stat, name)])
5497db96d56Sopenharmony_ci                self.assertIn(attr, members)
5507db96d56Sopenharmony_ci
5517db96d56Sopenharmony_ci        # Make sure that the st_?time and st_?time_ns fields roughly agree
5527db96d56Sopenharmony_ci        # (they should always agree up to around tens-of-microseconds)
5537db96d56Sopenharmony_ci        for name in 'st_atime st_mtime st_ctime'.split():
5547db96d56Sopenharmony_ci            floaty = int(getattr(result, name) * 100000)
5557db96d56Sopenharmony_ci            nanosecondy = getattr(result, name + "_ns") // 10000
5567db96d56Sopenharmony_ci            self.assertAlmostEqual(floaty, nanosecondy, delta=2)
5577db96d56Sopenharmony_ci
5587db96d56Sopenharmony_ci        try:
5597db96d56Sopenharmony_ci            result[200]
5607db96d56Sopenharmony_ci            self.fail("No exception raised")
5617db96d56Sopenharmony_ci        except IndexError:
5627db96d56Sopenharmony_ci            pass
5637db96d56Sopenharmony_ci
5647db96d56Sopenharmony_ci        # Make sure that assignment fails
5657db96d56Sopenharmony_ci        try:
5667db96d56Sopenharmony_ci            result.st_mode = 1
5677db96d56Sopenharmony_ci            self.fail("No exception raised")
5687db96d56Sopenharmony_ci        except AttributeError:
5697db96d56Sopenharmony_ci            pass
5707db96d56Sopenharmony_ci
5717db96d56Sopenharmony_ci        try:
5727db96d56Sopenharmony_ci            result.st_rdev = 1
5737db96d56Sopenharmony_ci            self.fail("No exception raised")
5747db96d56Sopenharmony_ci        except (AttributeError, TypeError):
5757db96d56Sopenharmony_ci            pass
5767db96d56Sopenharmony_ci
5777db96d56Sopenharmony_ci        try:
5787db96d56Sopenharmony_ci            result.parrot = 1
5797db96d56Sopenharmony_ci            self.fail("No exception raised")
5807db96d56Sopenharmony_ci        except AttributeError:
5817db96d56Sopenharmony_ci            pass
5827db96d56Sopenharmony_ci
5837db96d56Sopenharmony_ci        # Use the stat_result constructor with a too-short tuple.
5847db96d56Sopenharmony_ci        try:
5857db96d56Sopenharmony_ci            result2 = os.stat_result((10,))
5867db96d56Sopenharmony_ci            self.fail("No exception raised")
5877db96d56Sopenharmony_ci        except TypeError:
5887db96d56Sopenharmony_ci            pass
5897db96d56Sopenharmony_ci
5907db96d56Sopenharmony_ci        # Use the constructor with a too-long tuple.
5917db96d56Sopenharmony_ci        try:
5927db96d56Sopenharmony_ci            result2 = os.stat_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
5937db96d56Sopenharmony_ci        except TypeError:
5947db96d56Sopenharmony_ci            pass
5957db96d56Sopenharmony_ci
5967db96d56Sopenharmony_ci    def test_stat_attributes(self):
5977db96d56Sopenharmony_ci        self.check_stat_attributes(self.fname)
5987db96d56Sopenharmony_ci
5997db96d56Sopenharmony_ci    def test_stat_attributes_bytes(self):
6007db96d56Sopenharmony_ci        try:
6017db96d56Sopenharmony_ci            fname = self.fname.encode(sys.getfilesystemencoding())
6027db96d56Sopenharmony_ci        except UnicodeEncodeError:
6037db96d56Sopenharmony_ci            self.skipTest("cannot encode %a for the filesystem" % self.fname)
6047db96d56Sopenharmony_ci        self.check_stat_attributes(fname)
6057db96d56Sopenharmony_ci
6067db96d56Sopenharmony_ci    def test_stat_result_pickle(self):
6077db96d56Sopenharmony_ci        result = os.stat(self.fname)
6087db96d56Sopenharmony_ci        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
6097db96d56Sopenharmony_ci            p = pickle.dumps(result, proto)
6107db96d56Sopenharmony_ci            self.assertIn(b'stat_result', p)
6117db96d56Sopenharmony_ci            if proto < 4:
6127db96d56Sopenharmony_ci                self.assertIn(b'cos\nstat_result\n', p)
6137db96d56Sopenharmony_ci            unpickled = pickle.loads(p)
6147db96d56Sopenharmony_ci            self.assertEqual(result, unpickled)
6157db96d56Sopenharmony_ci
6167db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()')
6177db96d56Sopenharmony_ci    def test_statvfs_attributes(self):
6187db96d56Sopenharmony_ci        result = os.statvfs(self.fname)
6197db96d56Sopenharmony_ci
6207db96d56Sopenharmony_ci        # Make sure direct access works
6217db96d56Sopenharmony_ci        self.assertEqual(result.f_bfree, result[3])
6227db96d56Sopenharmony_ci
6237db96d56Sopenharmony_ci        # Make sure all the attributes are there.
6247db96d56Sopenharmony_ci        members = ('bsize', 'frsize', 'blocks', 'bfree', 'bavail', 'files',
6257db96d56Sopenharmony_ci                    'ffree', 'favail', 'flag', 'namemax')
6267db96d56Sopenharmony_ci        for value, member in enumerate(members):
6277db96d56Sopenharmony_ci            self.assertEqual(getattr(result, 'f_' + member), result[value])
6287db96d56Sopenharmony_ci
6297db96d56Sopenharmony_ci        self.assertTrue(isinstance(result.f_fsid, int))
6307db96d56Sopenharmony_ci
6317db96d56Sopenharmony_ci        # Test that the size of the tuple doesn't change
6327db96d56Sopenharmony_ci        self.assertEqual(len(result), 10)
6337db96d56Sopenharmony_ci
6347db96d56Sopenharmony_ci        # Make sure that assignment really fails
6357db96d56Sopenharmony_ci        try:
6367db96d56Sopenharmony_ci            result.f_bfree = 1
6377db96d56Sopenharmony_ci            self.fail("No exception raised")
6387db96d56Sopenharmony_ci        except AttributeError:
6397db96d56Sopenharmony_ci            pass
6407db96d56Sopenharmony_ci
6417db96d56Sopenharmony_ci        try:
6427db96d56Sopenharmony_ci            result.parrot = 1
6437db96d56Sopenharmony_ci            self.fail("No exception raised")
6447db96d56Sopenharmony_ci        except AttributeError:
6457db96d56Sopenharmony_ci            pass
6467db96d56Sopenharmony_ci
6477db96d56Sopenharmony_ci        # Use the constructor with a too-short tuple.
6487db96d56Sopenharmony_ci        try:
6497db96d56Sopenharmony_ci            result2 = os.statvfs_result((10,))
6507db96d56Sopenharmony_ci            self.fail("No exception raised")
6517db96d56Sopenharmony_ci        except TypeError:
6527db96d56Sopenharmony_ci            pass
6537db96d56Sopenharmony_ci
6547db96d56Sopenharmony_ci        # Use the constructor with a too-long tuple.
6557db96d56Sopenharmony_ci        try:
6567db96d56Sopenharmony_ci            result2 = os.statvfs_result((0,1,2,3,4,5,6,7,8,9,10,11,12,13,14))
6577db96d56Sopenharmony_ci        except TypeError:
6587db96d56Sopenharmony_ci            pass
6597db96d56Sopenharmony_ci
6607db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'statvfs'),
6617db96d56Sopenharmony_ci                         "need os.statvfs()")
6627db96d56Sopenharmony_ci    def test_statvfs_result_pickle(self):
6637db96d56Sopenharmony_ci        result = os.statvfs(self.fname)
6647db96d56Sopenharmony_ci
6657db96d56Sopenharmony_ci        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
6667db96d56Sopenharmony_ci            p = pickle.dumps(result, proto)
6677db96d56Sopenharmony_ci            self.assertIn(b'statvfs_result', p)
6687db96d56Sopenharmony_ci            if proto < 4:
6697db96d56Sopenharmony_ci                self.assertIn(b'cos\nstatvfs_result\n', p)
6707db96d56Sopenharmony_ci            unpickled = pickle.loads(p)
6717db96d56Sopenharmony_ci            self.assertEqual(result, unpickled)
6727db96d56Sopenharmony_ci
6737db96d56Sopenharmony_ci    @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
6747db96d56Sopenharmony_ci    def test_1686475(self):
6757db96d56Sopenharmony_ci        # Verify that an open file can be stat'ed
6767db96d56Sopenharmony_ci        try:
6777db96d56Sopenharmony_ci            os.stat(r"c:\pagefile.sys")
6787db96d56Sopenharmony_ci        except FileNotFoundError:
6797db96d56Sopenharmony_ci            self.skipTest(r'c:\pagefile.sys does not exist')
6807db96d56Sopenharmony_ci        except OSError as e:
6817db96d56Sopenharmony_ci            self.fail("Could not stat pagefile.sys")
6827db96d56Sopenharmony_ci
6837db96d56Sopenharmony_ci    @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
6847db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()")
6857db96d56Sopenharmony_ci    def test_15261(self):
6867db96d56Sopenharmony_ci        # Verify that stat'ing a closed fd does not cause crash
6877db96d56Sopenharmony_ci        r, w = os.pipe()
6887db96d56Sopenharmony_ci        try:
6897db96d56Sopenharmony_ci            os.stat(r)          # should not raise error
6907db96d56Sopenharmony_ci        finally:
6917db96d56Sopenharmony_ci            os.close(r)
6927db96d56Sopenharmony_ci            os.close(w)
6937db96d56Sopenharmony_ci        with self.assertRaises(OSError) as ctx:
6947db96d56Sopenharmony_ci            os.stat(r)
6957db96d56Sopenharmony_ci        self.assertEqual(ctx.exception.errno, errno.EBADF)
6967db96d56Sopenharmony_ci
6977db96d56Sopenharmony_ci    def check_file_attributes(self, result):
6987db96d56Sopenharmony_ci        self.assertTrue(hasattr(result, 'st_file_attributes'))
6997db96d56Sopenharmony_ci        self.assertTrue(isinstance(result.st_file_attributes, int))
7007db96d56Sopenharmony_ci        self.assertTrue(0 <= result.st_file_attributes <= 0xFFFFFFFF)
7017db96d56Sopenharmony_ci
7027db96d56Sopenharmony_ci    @unittest.skipUnless(sys.platform == "win32",
7037db96d56Sopenharmony_ci                         "st_file_attributes is Win32 specific")
7047db96d56Sopenharmony_ci    def test_file_attributes(self):
7057db96d56Sopenharmony_ci        # test file st_file_attributes (FILE_ATTRIBUTE_DIRECTORY not set)
7067db96d56Sopenharmony_ci        result = os.stat(self.fname)
7077db96d56Sopenharmony_ci        self.check_file_attributes(result)
7087db96d56Sopenharmony_ci        self.assertEqual(
7097db96d56Sopenharmony_ci            result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY,
7107db96d56Sopenharmony_ci            0)
7117db96d56Sopenharmony_ci
7127db96d56Sopenharmony_ci        # test directory st_file_attributes (FILE_ATTRIBUTE_DIRECTORY set)
7137db96d56Sopenharmony_ci        dirname = os_helper.TESTFN + "dir"
7147db96d56Sopenharmony_ci        os.mkdir(dirname)
7157db96d56Sopenharmony_ci        self.addCleanup(os.rmdir, dirname)
7167db96d56Sopenharmony_ci
7177db96d56Sopenharmony_ci        result = os.stat(dirname)
7187db96d56Sopenharmony_ci        self.check_file_attributes(result)
7197db96d56Sopenharmony_ci        self.assertEqual(
7207db96d56Sopenharmony_ci            result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY,
7217db96d56Sopenharmony_ci            stat.FILE_ATTRIBUTE_DIRECTORY)
7227db96d56Sopenharmony_ci
7237db96d56Sopenharmony_ci    @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
7247db96d56Sopenharmony_ci    def test_access_denied(self):
7257db96d56Sopenharmony_ci        # Default to FindFirstFile WIN32_FIND_DATA when access is
7267db96d56Sopenharmony_ci        # denied. See issue 28075.
7277db96d56Sopenharmony_ci        # os.environ['TEMP'] should be located on a volume that
7287db96d56Sopenharmony_ci        # supports file ACLs.
7297db96d56Sopenharmony_ci        fname = os.path.join(os.environ['TEMP'], self.fname)
7307db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, fname)
7317db96d56Sopenharmony_ci        create_file(fname, b'ABC')
7327db96d56Sopenharmony_ci        # Deny the right to [S]YNCHRONIZE on the file to
7337db96d56Sopenharmony_ci        # force CreateFile to fail with ERROR_ACCESS_DENIED.
7347db96d56Sopenharmony_ci        DETACHED_PROCESS = 8
7357db96d56Sopenharmony_ci        subprocess.check_call(
7367db96d56Sopenharmony_ci            # bpo-30584: Use security identifier *S-1-5-32-545 instead
7377db96d56Sopenharmony_ci            # of localized "Users" to not depend on the locale.
7387db96d56Sopenharmony_ci            ['icacls.exe', fname, '/deny', '*S-1-5-32-545:(S)'],
7397db96d56Sopenharmony_ci            creationflags=DETACHED_PROCESS
7407db96d56Sopenharmony_ci        )
7417db96d56Sopenharmony_ci        result = os.stat(fname)
7427db96d56Sopenharmony_ci        self.assertNotEqual(result.st_size, 0)
7437db96d56Sopenharmony_ci
7447db96d56Sopenharmony_ci    @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
7457db96d56Sopenharmony_ci    def test_stat_block_device(self):
7467db96d56Sopenharmony_ci        # bpo-38030: os.stat fails for block devices
7477db96d56Sopenharmony_ci        # Test a filename like "//./C:"
7487db96d56Sopenharmony_ci        fname = "//./" + os.path.splitdrive(os.getcwd())[0]
7497db96d56Sopenharmony_ci        result = os.stat(fname)
7507db96d56Sopenharmony_ci        self.assertEqual(result.st_mode, stat.S_IFBLK)
7517db96d56Sopenharmony_ci
7527db96d56Sopenharmony_ci
7537db96d56Sopenharmony_ciclass UtimeTests(unittest.TestCase):
7547db96d56Sopenharmony_ci    def setUp(self):
7557db96d56Sopenharmony_ci        self.dirname = os_helper.TESTFN
7567db96d56Sopenharmony_ci        self.fname = os.path.join(self.dirname, "f1")
7577db96d56Sopenharmony_ci
7587db96d56Sopenharmony_ci        self.addCleanup(os_helper.rmtree, self.dirname)
7597db96d56Sopenharmony_ci        os.mkdir(self.dirname)
7607db96d56Sopenharmony_ci        create_file(self.fname)
7617db96d56Sopenharmony_ci
7627db96d56Sopenharmony_ci    def support_subsecond(self, filename):
7637db96d56Sopenharmony_ci        # Heuristic to check if the filesystem supports timestamp with
7647db96d56Sopenharmony_ci        # subsecond resolution: check if float and int timestamps are different
7657db96d56Sopenharmony_ci        st = os.stat(filename)
7667db96d56Sopenharmony_ci        return ((st.st_atime != st[7])
7677db96d56Sopenharmony_ci                or (st.st_mtime != st[8])
7687db96d56Sopenharmony_ci                or (st.st_ctime != st[9]))
7697db96d56Sopenharmony_ci
7707db96d56Sopenharmony_ci    def _test_utime(self, set_time, filename=None):
7717db96d56Sopenharmony_ci        if not filename:
7727db96d56Sopenharmony_ci            filename = self.fname
7737db96d56Sopenharmony_ci
7747db96d56Sopenharmony_ci        support_subsecond = self.support_subsecond(filename)
7757db96d56Sopenharmony_ci        if support_subsecond:
7767db96d56Sopenharmony_ci            # Timestamp with a resolution of 1 microsecond (10^-6).
7777db96d56Sopenharmony_ci            #
7787db96d56Sopenharmony_ci            # The resolution of the C internal function used by os.utime()
7797db96d56Sopenharmony_ci            # depends on the platform: 1 sec, 1 us, 1 ns. Writing a portable
7807db96d56Sopenharmony_ci            # test with a resolution of 1 ns requires more work:
7817db96d56Sopenharmony_ci            # see the issue #15745.
7827db96d56Sopenharmony_ci            atime_ns = 1002003000   # 1.002003 seconds
7837db96d56Sopenharmony_ci            mtime_ns = 4005006000   # 4.005006 seconds
7847db96d56Sopenharmony_ci        else:
7857db96d56Sopenharmony_ci            # use a resolution of 1 second
7867db96d56Sopenharmony_ci            atime_ns = 5 * 10**9
7877db96d56Sopenharmony_ci            mtime_ns = 8 * 10**9
7887db96d56Sopenharmony_ci
7897db96d56Sopenharmony_ci        set_time(filename, (atime_ns, mtime_ns))
7907db96d56Sopenharmony_ci        st = os.stat(filename)
7917db96d56Sopenharmony_ci
7927db96d56Sopenharmony_ci        if support_subsecond:
7937db96d56Sopenharmony_ci            self.assertAlmostEqual(st.st_atime, atime_ns * 1e-9, delta=1e-6)
7947db96d56Sopenharmony_ci            self.assertAlmostEqual(st.st_mtime, mtime_ns * 1e-9, delta=1e-6)
7957db96d56Sopenharmony_ci        else:
7967db96d56Sopenharmony_ci            self.assertEqual(st.st_atime, atime_ns * 1e-9)
7977db96d56Sopenharmony_ci            self.assertEqual(st.st_mtime, mtime_ns * 1e-9)
7987db96d56Sopenharmony_ci        self.assertEqual(st.st_atime_ns, atime_ns)
7997db96d56Sopenharmony_ci        self.assertEqual(st.st_mtime_ns, mtime_ns)
8007db96d56Sopenharmony_ci
8017db96d56Sopenharmony_ci    def test_utime(self):
8027db96d56Sopenharmony_ci        def set_time(filename, ns):
8037db96d56Sopenharmony_ci            # test the ns keyword parameter
8047db96d56Sopenharmony_ci            os.utime(filename, ns=ns)
8057db96d56Sopenharmony_ci        self._test_utime(set_time)
8067db96d56Sopenharmony_ci
8077db96d56Sopenharmony_ci    @staticmethod
8087db96d56Sopenharmony_ci    def ns_to_sec(ns):
8097db96d56Sopenharmony_ci        # Convert a number of nanosecond (int) to a number of seconds (float).
8107db96d56Sopenharmony_ci        # Round towards infinity by adding 0.5 nanosecond to avoid rounding
8117db96d56Sopenharmony_ci        # issue, os.utime() rounds towards minus infinity.
8127db96d56Sopenharmony_ci        return (ns * 1e-9) + 0.5e-9
8137db96d56Sopenharmony_ci
8147db96d56Sopenharmony_ci    def test_utime_by_indexed(self):
8157db96d56Sopenharmony_ci        # pass times as floating point seconds as the second indexed parameter
8167db96d56Sopenharmony_ci        def set_time(filename, ns):
8177db96d56Sopenharmony_ci            atime_ns, mtime_ns = ns
8187db96d56Sopenharmony_ci            atime = self.ns_to_sec(atime_ns)
8197db96d56Sopenharmony_ci            mtime = self.ns_to_sec(mtime_ns)
8207db96d56Sopenharmony_ci            # test utimensat(timespec), utimes(timeval), utime(utimbuf)
8217db96d56Sopenharmony_ci            # or utime(time_t)
8227db96d56Sopenharmony_ci            os.utime(filename, (atime, mtime))
8237db96d56Sopenharmony_ci        self._test_utime(set_time)
8247db96d56Sopenharmony_ci
8257db96d56Sopenharmony_ci    def test_utime_by_times(self):
8267db96d56Sopenharmony_ci        def set_time(filename, ns):
8277db96d56Sopenharmony_ci            atime_ns, mtime_ns = ns
8287db96d56Sopenharmony_ci            atime = self.ns_to_sec(atime_ns)
8297db96d56Sopenharmony_ci            mtime = self.ns_to_sec(mtime_ns)
8307db96d56Sopenharmony_ci            # test the times keyword parameter
8317db96d56Sopenharmony_ci            os.utime(filename, times=(atime, mtime))
8327db96d56Sopenharmony_ci        self._test_utime(set_time)
8337db96d56Sopenharmony_ci
8347db96d56Sopenharmony_ci    @unittest.skipUnless(os.utime in os.supports_follow_symlinks,
8357db96d56Sopenharmony_ci                         "follow_symlinks support for utime required "
8367db96d56Sopenharmony_ci                         "for this test.")
8377db96d56Sopenharmony_ci    def test_utime_nofollow_symlinks(self):
8387db96d56Sopenharmony_ci        def set_time(filename, ns):
8397db96d56Sopenharmony_ci            # use follow_symlinks=False to test utimensat(timespec)
8407db96d56Sopenharmony_ci            # or lutimes(timeval)
8417db96d56Sopenharmony_ci            os.utime(filename, ns=ns, follow_symlinks=False)
8427db96d56Sopenharmony_ci        self._test_utime(set_time)
8437db96d56Sopenharmony_ci
8447db96d56Sopenharmony_ci    @unittest.skipUnless(os.utime in os.supports_fd,
8457db96d56Sopenharmony_ci                         "fd support for utime required for this test.")
8467db96d56Sopenharmony_ci    def test_utime_fd(self):
8477db96d56Sopenharmony_ci        def set_time(filename, ns):
8487db96d56Sopenharmony_ci            with open(filename, 'wb', 0) as fp:
8497db96d56Sopenharmony_ci                # use a file descriptor to test futimens(timespec)
8507db96d56Sopenharmony_ci                # or futimes(timeval)
8517db96d56Sopenharmony_ci                os.utime(fp.fileno(), ns=ns)
8527db96d56Sopenharmony_ci        self._test_utime(set_time)
8537db96d56Sopenharmony_ci
8547db96d56Sopenharmony_ci    @unittest.skipUnless(os.utime in os.supports_dir_fd,
8557db96d56Sopenharmony_ci                         "dir_fd support for utime required for this test.")
8567db96d56Sopenharmony_ci    def test_utime_dir_fd(self):
8577db96d56Sopenharmony_ci        def set_time(filename, ns):
8587db96d56Sopenharmony_ci            dirname, name = os.path.split(filename)
8597db96d56Sopenharmony_ci            with os_helper.open_dir_fd(dirname) as dirfd:
8607db96d56Sopenharmony_ci                # pass dir_fd to test utimensat(timespec) or futimesat(timeval)
8617db96d56Sopenharmony_ci                os.utime(name, dir_fd=dirfd, ns=ns)
8627db96d56Sopenharmony_ci        self._test_utime(set_time)
8637db96d56Sopenharmony_ci
8647db96d56Sopenharmony_ci    def test_utime_directory(self):
8657db96d56Sopenharmony_ci        def set_time(filename, ns):
8667db96d56Sopenharmony_ci            # test calling os.utime() on a directory
8677db96d56Sopenharmony_ci            os.utime(filename, ns=ns)
8687db96d56Sopenharmony_ci        self._test_utime(set_time, filename=self.dirname)
8697db96d56Sopenharmony_ci
8707db96d56Sopenharmony_ci    def _test_utime_current(self, set_time):
8717db96d56Sopenharmony_ci        # Get the system clock
8727db96d56Sopenharmony_ci        current = time.time()
8737db96d56Sopenharmony_ci
8747db96d56Sopenharmony_ci        # Call os.utime() to set the timestamp to the current system clock
8757db96d56Sopenharmony_ci        set_time(self.fname)
8767db96d56Sopenharmony_ci
8777db96d56Sopenharmony_ci        if not self.support_subsecond(self.fname):
8787db96d56Sopenharmony_ci            delta = 1.0
8797db96d56Sopenharmony_ci        else:
8807db96d56Sopenharmony_ci            # On Windows, the usual resolution of time.time() is 15.6 ms.
8817db96d56Sopenharmony_ci            # bpo-30649: Tolerate 50 ms for slow Windows buildbots.
8827db96d56Sopenharmony_ci            #
8837db96d56Sopenharmony_ci            # x86 Gentoo Refleaks 3.x once failed with dt=20.2 ms. So use
8847db96d56Sopenharmony_ci            # also 50 ms on other platforms.
8857db96d56Sopenharmony_ci            delta = 0.050
8867db96d56Sopenharmony_ci        st = os.stat(self.fname)
8877db96d56Sopenharmony_ci        msg = ("st_time=%r, current=%r, dt=%r"
8887db96d56Sopenharmony_ci               % (st.st_mtime, current, st.st_mtime - current))
8897db96d56Sopenharmony_ci        self.assertAlmostEqual(st.st_mtime, current,
8907db96d56Sopenharmony_ci                               delta=delta, msg=msg)
8917db96d56Sopenharmony_ci
8927db96d56Sopenharmony_ci    def test_utime_current(self):
8937db96d56Sopenharmony_ci        def set_time(filename):
8947db96d56Sopenharmony_ci            # Set to the current time in the new way
8957db96d56Sopenharmony_ci            os.utime(self.fname)
8967db96d56Sopenharmony_ci        self._test_utime_current(set_time)
8977db96d56Sopenharmony_ci
8987db96d56Sopenharmony_ci    def test_utime_current_old(self):
8997db96d56Sopenharmony_ci        def set_time(filename):
9007db96d56Sopenharmony_ci            # Set to the current time in the old explicit way.
9017db96d56Sopenharmony_ci            os.utime(self.fname, None)
9027db96d56Sopenharmony_ci        self._test_utime_current(set_time)
9037db96d56Sopenharmony_ci
9047db96d56Sopenharmony_ci    def get_file_system(self, path):
9057db96d56Sopenharmony_ci        if sys.platform == 'win32':
9067db96d56Sopenharmony_ci            root = os.path.splitdrive(os.path.abspath(path))[0] + '\\'
9077db96d56Sopenharmony_ci            import ctypes
9087db96d56Sopenharmony_ci            kernel32 = ctypes.windll.kernel32
9097db96d56Sopenharmony_ci            buf = ctypes.create_unicode_buffer("", 100)
9107db96d56Sopenharmony_ci            ok = kernel32.GetVolumeInformationW(root, None, 0,
9117db96d56Sopenharmony_ci                                                None, None, None,
9127db96d56Sopenharmony_ci                                                buf, len(buf))
9137db96d56Sopenharmony_ci            if ok:
9147db96d56Sopenharmony_ci                return buf.value
9157db96d56Sopenharmony_ci        # return None if the filesystem is unknown
9167db96d56Sopenharmony_ci
9177db96d56Sopenharmony_ci    def test_large_time(self):
9187db96d56Sopenharmony_ci        # Many filesystems are limited to the year 2038. At least, the test
9197db96d56Sopenharmony_ci        # pass with NTFS filesystem.
9207db96d56Sopenharmony_ci        if self.get_file_system(self.dirname) != "NTFS":
9217db96d56Sopenharmony_ci            self.skipTest("requires NTFS")
9227db96d56Sopenharmony_ci
9237db96d56Sopenharmony_ci        large = 5000000000   # some day in 2128
9247db96d56Sopenharmony_ci        os.utime(self.fname, (large, large))
9257db96d56Sopenharmony_ci        self.assertEqual(os.stat(self.fname).st_mtime, large)
9267db96d56Sopenharmony_ci
9277db96d56Sopenharmony_ci    def test_utime_invalid_arguments(self):
9287db96d56Sopenharmony_ci        # seconds and nanoseconds parameters are mutually exclusive
9297db96d56Sopenharmony_ci        with self.assertRaises(ValueError):
9307db96d56Sopenharmony_ci            os.utime(self.fname, (5, 5), ns=(5, 5))
9317db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
9327db96d56Sopenharmony_ci            os.utime(self.fname, [5, 5])
9337db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
9347db96d56Sopenharmony_ci            os.utime(self.fname, (5,))
9357db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
9367db96d56Sopenharmony_ci            os.utime(self.fname, (5, 5, 5))
9377db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
9387db96d56Sopenharmony_ci            os.utime(self.fname, ns=[5, 5])
9397db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
9407db96d56Sopenharmony_ci            os.utime(self.fname, ns=(5,))
9417db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
9427db96d56Sopenharmony_ci            os.utime(self.fname, ns=(5, 5, 5))
9437db96d56Sopenharmony_ci
9447db96d56Sopenharmony_ci        if os.utime not in os.supports_follow_symlinks:
9457db96d56Sopenharmony_ci            with self.assertRaises(NotImplementedError):
9467db96d56Sopenharmony_ci                os.utime(self.fname, (5, 5), follow_symlinks=False)
9477db96d56Sopenharmony_ci        if os.utime not in os.supports_fd:
9487db96d56Sopenharmony_ci            with open(self.fname, 'wb', 0) as fp:
9497db96d56Sopenharmony_ci                with self.assertRaises(TypeError):
9507db96d56Sopenharmony_ci                    os.utime(fp.fileno(), (5, 5))
9517db96d56Sopenharmony_ci        if os.utime not in os.supports_dir_fd:
9527db96d56Sopenharmony_ci            with self.assertRaises(NotImplementedError):
9537db96d56Sopenharmony_ci                os.utime(self.fname, (5, 5), dir_fd=0)
9547db96d56Sopenharmony_ci
9557db96d56Sopenharmony_ci    @support.cpython_only
9567db96d56Sopenharmony_ci    def test_issue31577(self):
9577db96d56Sopenharmony_ci        # The interpreter shouldn't crash in case utime() received a bad
9587db96d56Sopenharmony_ci        # ns argument.
9597db96d56Sopenharmony_ci        def get_bad_int(divmod_ret_val):
9607db96d56Sopenharmony_ci            class BadInt:
9617db96d56Sopenharmony_ci                def __divmod__(*args):
9627db96d56Sopenharmony_ci                    return divmod_ret_val
9637db96d56Sopenharmony_ci            return BadInt()
9647db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
9657db96d56Sopenharmony_ci            os.utime(self.fname, ns=(get_bad_int(42), 1))
9667db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
9677db96d56Sopenharmony_ci            os.utime(self.fname, ns=(get_bad_int(()), 1))
9687db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
9697db96d56Sopenharmony_ci            os.utime(self.fname, ns=(get_bad_int((1, 2, 3)), 1))
9707db96d56Sopenharmony_ci
9717db96d56Sopenharmony_ci
9727db96d56Sopenharmony_cifrom test import mapping_tests
9737db96d56Sopenharmony_ci
9747db96d56Sopenharmony_ciclass EnvironTests(mapping_tests.BasicTestMappingProtocol):
9757db96d56Sopenharmony_ci    """check that os.environ object conform to mapping protocol"""
9767db96d56Sopenharmony_ci    type2test = None
9777db96d56Sopenharmony_ci
9787db96d56Sopenharmony_ci    def setUp(self):
9797db96d56Sopenharmony_ci        self.__save = dict(os.environ)
9807db96d56Sopenharmony_ci        if os.supports_bytes_environ:
9817db96d56Sopenharmony_ci            self.__saveb = dict(os.environb)
9827db96d56Sopenharmony_ci        for key, value in self._reference().items():
9837db96d56Sopenharmony_ci            os.environ[key] = value
9847db96d56Sopenharmony_ci
9857db96d56Sopenharmony_ci    def tearDown(self):
9867db96d56Sopenharmony_ci        os.environ.clear()
9877db96d56Sopenharmony_ci        os.environ.update(self.__save)
9887db96d56Sopenharmony_ci        if os.supports_bytes_environ:
9897db96d56Sopenharmony_ci            os.environb.clear()
9907db96d56Sopenharmony_ci            os.environb.update(self.__saveb)
9917db96d56Sopenharmony_ci
9927db96d56Sopenharmony_ci    def _reference(self):
9937db96d56Sopenharmony_ci        return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"}
9947db96d56Sopenharmony_ci
9957db96d56Sopenharmony_ci    def _empty_mapping(self):
9967db96d56Sopenharmony_ci        os.environ.clear()
9977db96d56Sopenharmony_ci        return os.environ
9987db96d56Sopenharmony_ci
9997db96d56Sopenharmony_ci    # Bug 1110478
10007db96d56Sopenharmony_ci    @unittest.skipUnless(unix_shell and os.path.exists(unix_shell),
10017db96d56Sopenharmony_ci                         'requires a shell')
10027db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'popen'), "needs os.popen()")
10037db96d56Sopenharmony_ci    @support.requires_subprocess()
10047db96d56Sopenharmony_ci    def test_update2(self):
10057db96d56Sopenharmony_ci        os.environ.clear()
10067db96d56Sopenharmony_ci        os.environ.update(HELLO="World")
10077db96d56Sopenharmony_ci        with os.popen("%s -c 'echo $HELLO'" % unix_shell) as popen:
10087db96d56Sopenharmony_ci            value = popen.read().strip()
10097db96d56Sopenharmony_ci            self.assertEqual(value, "World")
10107db96d56Sopenharmony_ci
10117db96d56Sopenharmony_ci    @unittest.skipUnless(unix_shell and os.path.exists(unix_shell),
10127db96d56Sopenharmony_ci                         'requires a shell')
10137db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'popen'), "needs os.popen()")
10147db96d56Sopenharmony_ci    @support.requires_subprocess()
10157db96d56Sopenharmony_ci    def test_os_popen_iter(self):
10167db96d56Sopenharmony_ci        with os.popen("%s -c 'echo \"line1\nline2\nline3\"'"
10177db96d56Sopenharmony_ci                      % unix_shell) as popen:
10187db96d56Sopenharmony_ci            it = iter(popen)
10197db96d56Sopenharmony_ci            self.assertEqual(next(it), "line1\n")
10207db96d56Sopenharmony_ci            self.assertEqual(next(it), "line2\n")
10217db96d56Sopenharmony_ci            self.assertEqual(next(it), "line3\n")
10227db96d56Sopenharmony_ci            self.assertRaises(StopIteration, next, it)
10237db96d56Sopenharmony_ci
10247db96d56Sopenharmony_ci    # Verify environ keys and values from the OS are of the
10257db96d56Sopenharmony_ci    # correct str type.
10267db96d56Sopenharmony_ci    def test_keyvalue_types(self):
10277db96d56Sopenharmony_ci        for key, val in os.environ.items():
10287db96d56Sopenharmony_ci            self.assertEqual(type(key), str)
10297db96d56Sopenharmony_ci            self.assertEqual(type(val), str)
10307db96d56Sopenharmony_ci
10317db96d56Sopenharmony_ci    def test_items(self):
10327db96d56Sopenharmony_ci        for key, value in self._reference().items():
10337db96d56Sopenharmony_ci            self.assertEqual(os.environ.get(key), value)
10347db96d56Sopenharmony_ci
10357db96d56Sopenharmony_ci    # Issue 7310
10367db96d56Sopenharmony_ci    def test___repr__(self):
10377db96d56Sopenharmony_ci        """Check that the repr() of os.environ looks like environ({...})."""
10387db96d56Sopenharmony_ci        env = os.environ
10397db96d56Sopenharmony_ci        formatted_items = ", ".join(
10407db96d56Sopenharmony_ci            f"{key!r}: {value!r}"
10417db96d56Sopenharmony_ci            for key, value in env.items()
10427db96d56Sopenharmony_ci        )
10437db96d56Sopenharmony_ci        self.assertEqual(repr(env), f"environ({{{formatted_items}}})")
10447db96d56Sopenharmony_ci
10457db96d56Sopenharmony_ci    def test_get_exec_path(self):
10467db96d56Sopenharmony_ci        defpath_list = os.defpath.split(os.pathsep)
10477db96d56Sopenharmony_ci        test_path = ['/monty', '/python', '', '/flying/circus']
10487db96d56Sopenharmony_ci        test_env = {'PATH': os.pathsep.join(test_path)}
10497db96d56Sopenharmony_ci
10507db96d56Sopenharmony_ci        saved_environ = os.environ
10517db96d56Sopenharmony_ci        try:
10527db96d56Sopenharmony_ci            os.environ = dict(test_env)
10537db96d56Sopenharmony_ci            # Test that defaulting to os.environ works.
10547db96d56Sopenharmony_ci            self.assertSequenceEqual(test_path, os.get_exec_path())
10557db96d56Sopenharmony_ci            self.assertSequenceEqual(test_path, os.get_exec_path(env=None))
10567db96d56Sopenharmony_ci        finally:
10577db96d56Sopenharmony_ci            os.environ = saved_environ
10587db96d56Sopenharmony_ci
10597db96d56Sopenharmony_ci        # No PATH environment variable
10607db96d56Sopenharmony_ci        self.assertSequenceEqual(defpath_list, os.get_exec_path({}))
10617db96d56Sopenharmony_ci        # Empty PATH environment variable
10627db96d56Sopenharmony_ci        self.assertSequenceEqual(('',), os.get_exec_path({'PATH':''}))
10637db96d56Sopenharmony_ci        # Supplied PATH environment variable
10647db96d56Sopenharmony_ci        self.assertSequenceEqual(test_path, os.get_exec_path(test_env))
10657db96d56Sopenharmony_ci
10667db96d56Sopenharmony_ci        if os.supports_bytes_environ:
10677db96d56Sopenharmony_ci            # env cannot contain 'PATH' and b'PATH' keys
10687db96d56Sopenharmony_ci            try:
10697db96d56Sopenharmony_ci                # ignore BytesWarning warning
10707db96d56Sopenharmony_ci                with warnings.catch_warnings(record=True):
10717db96d56Sopenharmony_ci                    mixed_env = {'PATH': '1', b'PATH': b'2'}
10727db96d56Sopenharmony_ci            except BytesWarning:
10737db96d56Sopenharmony_ci                # mixed_env cannot be created with python -bb
10747db96d56Sopenharmony_ci                pass
10757db96d56Sopenharmony_ci            else:
10767db96d56Sopenharmony_ci                self.assertRaises(ValueError, os.get_exec_path, mixed_env)
10777db96d56Sopenharmony_ci
10787db96d56Sopenharmony_ci            # bytes key and/or value
10797db96d56Sopenharmony_ci            self.assertSequenceEqual(os.get_exec_path({b'PATH': b'abc'}),
10807db96d56Sopenharmony_ci                ['abc'])
10817db96d56Sopenharmony_ci            self.assertSequenceEqual(os.get_exec_path({b'PATH': 'abc'}),
10827db96d56Sopenharmony_ci                ['abc'])
10837db96d56Sopenharmony_ci            self.assertSequenceEqual(os.get_exec_path({'PATH': b'abc'}),
10847db96d56Sopenharmony_ci                ['abc'])
10857db96d56Sopenharmony_ci
10867db96d56Sopenharmony_ci    @unittest.skipUnless(os.supports_bytes_environ,
10877db96d56Sopenharmony_ci                         "os.environb required for this test.")
10887db96d56Sopenharmony_ci    def test_environb(self):
10897db96d56Sopenharmony_ci        # os.environ -> os.environb
10907db96d56Sopenharmony_ci        value = 'euro\u20ac'
10917db96d56Sopenharmony_ci        try:
10927db96d56Sopenharmony_ci            value_bytes = value.encode(sys.getfilesystemencoding(),
10937db96d56Sopenharmony_ci                                       'surrogateescape')
10947db96d56Sopenharmony_ci        except UnicodeEncodeError:
10957db96d56Sopenharmony_ci            msg = "U+20AC character is not encodable to %s" % (
10967db96d56Sopenharmony_ci                sys.getfilesystemencoding(),)
10977db96d56Sopenharmony_ci            self.skipTest(msg)
10987db96d56Sopenharmony_ci        os.environ['unicode'] = value
10997db96d56Sopenharmony_ci        self.assertEqual(os.environ['unicode'], value)
11007db96d56Sopenharmony_ci        self.assertEqual(os.environb[b'unicode'], value_bytes)
11017db96d56Sopenharmony_ci
11027db96d56Sopenharmony_ci        # os.environb -> os.environ
11037db96d56Sopenharmony_ci        value = b'\xff'
11047db96d56Sopenharmony_ci        os.environb[b'bytes'] = value
11057db96d56Sopenharmony_ci        self.assertEqual(os.environb[b'bytes'], value)
11067db96d56Sopenharmony_ci        value_str = value.decode(sys.getfilesystemencoding(), 'surrogateescape')
11077db96d56Sopenharmony_ci        self.assertEqual(os.environ['bytes'], value_str)
11087db96d56Sopenharmony_ci
11097db96d56Sopenharmony_ci    @support.requires_subprocess()
11107db96d56Sopenharmony_ci    def test_putenv_unsetenv(self):
11117db96d56Sopenharmony_ci        name = "PYTHONTESTVAR"
11127db96d56Sopenharmony_ci        value = "testvalue"
11137db96d56Sopenharmony_ci        code = f'import os; print(repr(os.environ.get({name!r})))'
11147db96d56Sopenharmony_ci
11157db96d56Sopenharmony_ci        with os_helper.EnvironmentVarGuard() as env:
11167db96d56Sopenharmony_ci            env.pop(name, None)
11177db96d56Sopenharmony_ci
11187db96d56Sopenharmony_ci            os.putenv(name, value)
11197db96d56Sopenharmony_ci            proc = subprocess.run([sys.executable, '-c', code], check=True,
11207db96d56Sopenharmony_ci                                  stdout=subprocess.PIPE, text=True)
11217db96d56Sopenharmony_ci            self.assertEqual(proc.stdout.rstrip(), repr(value))
11227db96d56Sopenharmony_ci
11237db96d56Sopenharmony_ci            os.unsetenv(name)
11247db96d56Sopenharmony_ci            proc = subprocess.run([sys.executable, '-c', code], check=True,
11257db96d56Sopenharmony_ci                                  stdout=subprocess.PIPE, text=True)
11267db96d56Sopenharmony_ci            self.assertEqual(proc.stdout.rstrip(), repr(None))
11277db96d56Sopenharmony_ci
11287db96d56Sopenharmony_ci    # On OS X < 10.6, unsetenv() doesn't return a value (bpo-13415).
11297db96d56Sopenharmony_ci    @support.requires_mac_ver(10, 6)
11307db96d56Sopenharmony_ci    def test_putenv_unsetenv_error(self):
11317db96d56Sopenharmony_ci        # Empty variable name is invalid.
11327db96d56Sopenharmony_ci        # "=" and null character are not allowed in a variable name.
11337db96d56Sopenharmony_ci        for name in ('', '=name', 'na=me', 'name=', 'name\0', 'na\0me'):
11347db96d56Sopenharmony_ci            self.assertRaises((OSError, ValueError), os.putenv, name, "value")
11357db96d56Sopenharmony_ci            self.assertRaises((OSError, ValueError), os.unsetenv, name)
11367db96d56Sopenharmony_ci
11377db96d56Sopenharmony_ci        if sys.platform == "win32":
11387db96d56Sopenharmony_ci            # On Windows, an environment variable string ("name=value" string)
11397db96d56Sopenharmony_ci            # is limited to 32,767 characters
11407db96d56Sopenharmony_ci            longstr = 'x' * 32_768
11417db96d56Sopenharmony_ci            self.assertRaises(ValueError, os.putenv, longstr, "1")
11427db96d56Sopenharmony_ci            self.assertRaises(ValueError, os.putenv, "X", longstr)
11437db96d56Sopenharmony_ci            self.assertRaises(ValueError, os.unsetenv, longstr)
11447db96d56Sopenharmony_ci
11457db96d56Sopenharmony_ci    def test_key_type(self):
11467db96d56Sopenharmony_ci        missing = 'missingkey'
11477db96d56Sopenharmony_ci        self.assertNotIn(missing, os.environ)
11487db96d56Sopenharmony_ci
11497db96d56Sopenharmony_ci        with self.assertRaises(KeyError) as cm:
11507db96d56Sopenharmony_ci            os.environ[missing]
11517db96d56Sopenharmony_ci        self.assertIs(cm.exception.args[0], missing)
11527db96d56Sopenharmony_ci        self.assertTrue(cm.exception.__suppress_context__)
11537db96d56Sopenharmony_ci
11547db96d56Sopenharmony_ci        with self.assertRaises(KeyError) as cm:
11557db96d56Sopenharmony_ci            del os.environ[missing]
11567db96d56Sopenharmony_ci        self.assertIs(cm.exception.args[0], missing)
11577db96d56Sopenharmony_ci        self.assertTrue(cm.exception.__suppress_context__)
11587db96d56Sopenharmony_ci
11597db96d56Sopenharmony_ci    def _test_environ_iteration(self, collection):
11607db96d56Sopenharmony_ci        iterator = iter(collection)
11617db96d56Sopenharmony_ci        new_key = "__new_key__"
11627db96d56Sopenharmony_ci
11637db96d56Sopenharmony_ci        next(iterator)  # start iteration over os.environ.items
11647db96d56Sopenharmony_ci
11657db96d56Sopenharmony_ci        # add a new key in os.environ mapping
11667db96d56Sopenharmony_ci        os.environ[new_key] = "test_environ_iteration"
11677db96d56Sopenharmony_ci
11687db96d56Sopenharmony_ci        try:
11697db96d56Sopenharmony_ci            next(iterator)  # force iteration over modified mapping
11707db96d56Sopenharmony_ci            self.assertEqual(os.environ[new_key], "test_environ_iteration")
11717db96d56Sopenharmony_ci        finally:
11727db96d56Sopenharmony_ci            del os.environ[new_key]
11737db96d56Sopenharmony_ci
11747db96d56Sopenharmony_ci    def test_iter_error_when_changing_os_environ(self):
11757db96d56Sopenharmony_ci        self._test_environ_iteration(os.environ)
11767db96d56Sopenharmony_ci
11777db96d56Sopenharmony_ci    def test_iter_error_when_changing_os_environ_items(self):
11787db96d56Sopenharmony_ci        self._test_environ_iteration(os.environ.items())
11797db96d56Sopenharmony_ci
11807db96d56Sopenharmony_ci    def test_iter_error_when_changing_os_environ_values(self):
11817db96d56Sopenharmony_ci        self._test_environ_iteration(os.environ.values())
11827db96d56Sopenharmony_ci
11837db96d56Sopenharmony_ci    def _test_underlying_process_env(self, var, expected):
11847db96d56Sopenharmony_ci        if not (unix_shell and os.path.exists(unix_shell)):
11857db96d56Sopenharmony_ci            return
11867db96d56Sopenharmony_ci        elif not support.has_subprocess_support:
11877db96d56Sopenharmony_ci            return
11887db96d56Sopenharmony_ci
11897db96d56Sopenharmony_ci        with os.popen(f"{unix_shell} -c 'echo ${var}'") as popen:
11907db96d56Sopenharmony_ci            value = popen.read().strip()
11917db96d56Sopenharmony_ci
11927db96d56Sopenharmony_ci        self.assertEqual(expected, value)
11937db96d56Sopenharmony_ci
11947db96d56Sopenharmony_ci    def test_or_operator(self):
11957db96d56Sopenharmony_ci        overridden_key = '_TEST_VAR_'
11967db96d56Sopenharmony_ci        original_value = 'original_value'
11977db96d56Sopenharmony_ci        os.environ[overridden_key] = original_value
11987db96d56Sopenharmony_ci
11997db96d56Sopenharmony_ci        new_vars_dict = {'_A_': '1', '_B_': '2', overridden_key: '3'}
12007db96d56Sopenharmony_ci        expected = dict(os.environ)
12017db96d56Sopenharmony_ci        expected.update(new_vars_dict)
12027db96d56Sopenharmony_ci
12037db96d56Sopenharmony_ci        actual = os.environ | new_vars_dict
12047db96d56Sopenharmony_ci        self.assertDictEqual(expected, actual)
12057db96d56Sopenharmony_ci        self.assertEqual('3', actual[overridden_key])
12067db96d56Sopenharmony_ci
12077db96d56Sopenharmony_ci        new_vars_items = new_vars_dict.items()
12087db96d56Sopenharmony_ci        self.assertIs(NotImplemented, os.environ.__or__(new_vars_items))
12097db96d56Sopenharmony_ci
12107db96d56Sopenharmony_ci        self._test_underlying_process_env('_A_', '')
12117db96d56Sopenharmony_ci        self._test_underlying_process_env(overridden_key, original_value)
12127db96d56Sopenharmony_ci
12137db96d56Sopenharmony_ci    def test_ior_operator(self):
12147db96d56Sopenharmony_ci        overridden_key = '_TEST_VAR_'
12157db96d56Sopenharmony_ci        os.environ[overridden_key] = 'original_value'
12167db96d56Sopenharmony_ci
12177db96d56Sopenharmony_ci        new_vars_dict = {'_A_': '1', '_B_': '2', overridden_key: '3'}
12187db96d56Sopenharmony_ci        expected = dict(os.environ)
12197db96d56Sopenharmony_ci        expected.update(new_vars_dict)
12207db96d56Sopenharmony_ci
12217db96d56Sopenharmony_ci        os.environ |= new_vars_dict
12227db96d56Sopenharmony_ci        self.assertEqual(expected, os.environ)
12237db96d56Sopenharmony_ci        self.assertEqual('3', os.environ[overridden_key])
12247db96d56Sopenharmony_ci
12257db96d56Sopenharmony_ci        self._test_underlying_process_env('_A_', '1')
12267db96d56Sopenharmony_ci        self._test_underlying_process_env(overridden_key, '3')
12277db96d56Sopenharmony_ci
12287db96d56Sopenharmony_ci    def test_ior_operator_invalid_dicts(self):
12297db96d56Sopenharmony_ci        os_environ_copy = os.environ.copy()
12307db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
12317db96d56Sopenharmony_ci            dict_with_bad_key = {1: '_A_'}
12327db96d56Sopenharmony_ci            os.environ |= dict_with_bad_key
12337db96d56Sopenharmony_ci
12347db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
12357db96d56Sopenharmony_ci            dict_with_bad_val = {'_A_': 1}
12367db96d56Sopenharmony_ci            os.environ |= dict_with_bad_val
12377db96d56Sopenharmony_ci
12387db96d56Sopenharmony_ci        # Check nothing was added.
12397db96d56Sopenharmony_ci        self.assertEqual(os_environ_copy, os.environ)
12407db96d56Sopenharmony_ci
12417db96d56Sopenharmony_ci    def test_ior_operator_key_value_iterable(self):
12427db96d56Sopenharmony_ci        overridden_key = '_TEST_VAR_'
12437db96d56Sopenharmony_ci        os.environ[overridden_key] = 'original_value'
12447db96d56Sopenharmony_ci
12457db96d56Sopenharmony_ci        new_vars_items = (('_A_', '1'), ('_B_', '2'), (overridden_key, '3'))
12467db96d56Sopenharmony_ci        expected = dict(os.environ)
12477db96d56Sopenharmony_ci        expected.update(new_vars_items)
12487db96d56Sopenharmony_ci
12497db96d56Sopenharmony_ci        os.environ |= new_vars_items
12507db96d56Sopenharmony_ci        self.assertEqual(expected, os.environ)
12517db96d56Sopenharmony_ci        self.assertEqual('3', os.environ[overridden_key])
12527db96d56Sopenharmony_ci
12537db96d56Sopenharmony_ci        self._test_underlying_process_env('_A_', '1')
12547db96d56Sopenharmony_ci        self._test_underlying_process_env(overridden_key, '3')
12557db96d56Sopenharmony_ci
12567db96d56Sopenharmony_ci    def test_ror_operator(self):
12577db96d56Sopenharmony_ci        overridden_key = '_TEST_VAR_'
12587db96d56Sopenharmony_ci        original_value = 'original_value'
12597db96d56Sopenharmony_ci        os.environ[overridden_key] = original_value
12607db96d56Sopenharmony_ci
12617db96d56Sopenharmony_ci        new_vars_dict = {'_A_': '1', '_B_': '2', overridden_key: '3'}
12627db96d56Sopenharmony_ci        expected = dict(new_vars_dict)
12637db96d56Sopenharmony_ci        expected.update(os.environ)
12647db96d56Sopenharmony_ci
12657db96d56Sopenharmony_ci        actual = new_vars_dict | os.environ
12667db96d56Sopenharmony_ci        self.assertDictEqual(expected, actual)
12677db96d56Sopenharmony_ci        self.assertEqual(original_value, actual[overridden_key])
12687db96d56Sopenharmony_ci
12697db96d56Sopenharmony_ci        new_vars_items = new_vars_dict.items()
12707db96d56Sopenharmony_ci        self.assertIs(NotImplemented, os.environ.__ror__(new_vars_items))
12717db96d56Sopenharmony_ci
12727db96d56Sopenharmony_ci        self._test_underlying_process_env('_A_', '')
12737db96d56Sopenharmony_ci        self._test_underlying_process_env(overridden_key, original_value)
12747db96d56Sopenharmony_ci
12757db96d56Sopenharmony_ci
12767db96d56Sopenharmony_ciclass WalkTests(unittest.TestCase):
12777db96d56Sopenharmony_ci    """Tests for os.walk()."""
12787db96d56Sopenharmony_ci
12797db96d56Sopenharmony_ci    # Wrapper to hide minor differences between os.walk and os.fwalk
12807db96d56Sopenharmony_ci    # to tests both functions with the same code base
12817db96d56Sopenharmony_ci    def walk(self, top, **kwargs):
12827db96d56Sopenharmony_ci        if 'follow_symlinks' in kwargs:
12837db96d56Sopenharmony_ci            kwargs['followlinks'] = kwargs.pop('follow_symlinks')
12847db96d56Sopenharmony_ci        return os.walk(top, **kwargs)
12857db96d56Sopenharmony_ci
12867db96d56Sopenharmony_ci    def setUp(self):
12877db96d56Sopenharmony_ci        join = os.path.join
12887db96d56Sopenharmony_ci        self.addCleanup(os_helper.rmtree, os_helper.TESTFN)
12897db96d56Sopenharmony_ci
12907db96d56Sopenharmony_ci        # Build:
12917db96d56Sopenharmony_ci        #     TESTFN/
12927db96d56Sopenharmony_ci        #       TEST1/              a file kid and two directory kids
12937db96d56Sopenharmony_ci        #         tmp1
12947db96d56Sopenharmony_ci        #         SUB1/             a file kid and a directory kid
12957db96d56Sopenharmony_ci        #           tmp2
12967db96d56Sopenharmony_ci        #           SUB11/          no kids
12977db96d56Sopenharmony_ci        #         SUB2/             a file kid and a dirsymlink kid
12987db96d56Sopenharmony_ci        #           tmp3
12997db96d56Sopenharmony_ci        #           SUB21/          not readable
13007db96d56Sopenharmony_ci        #             tmp5
13017db96d56Sopenharmony_ci        #           link/           a symlink to TESTFN.2
13027db96d56Sopenharmony_ci        #           broken_link
13037db96d56Sopenharmony_ci        #           broken_link2
13047db96d56Sopenharmony_ci        #           broken_link3
13057db96d56Sopenharmony_ci        #       TEST2/
13067db96d56Sopenharmony_ci        #         tmp4              a lone file
13077db96d56Sopenharmony_ci        self.walk_path = join(os_helper.TESTFN, "TEST1")
13087db96d56Sopenharmony_ci        self.sub1_path = join(self.walk_path, "SUB1")
13097db96d56Sopenharmony_ci        self.sub11_path = join(self.sub1_path, "SUB11")
13107db96d56Sopenharmony_ci        sub2_path = join(self.walk_path, "SUB2")
13117db96d56Sopenharmony_ci        sub21_path = join(sub2_path, "SUB21")
13127db96d56Sopenharmony_ci        tmp1_path = join(self.walk_path, "tmp1")
13137db96d56Sopenharmony_ci        tmp2_path = join(self.sub1_path, "tmp2")
13147db96d56Sopenharmony_ci        tmp3_path = join(sub2_path, "tmp3")
13157db96d56Sopenharmony_ci        tmp5_path = join(sub21_path, "tmp3")
13167db96d56Sopenharmony_ci        self.link_path = join(sub2_path, "link")
13177db96d56Sopenharmony_ci        t2_path = join(os_helper.TESTFN, "TEST2")
13187db96d56Sopenharmony_ci        tmp4_path = join(os_helper.TESTFN, "TEST2", "tmp4")
13197db96d56Sopenharmony_ci        broken_link_path = join(sub2_path, "broken_link")
13207db96d56Sopenharmony_ci        broken_link2_path = join(sub2_path, "broken_link2")
13217db96d56Sopenharmony_ci        broken_link3_path = join(sub2_path, "broken_link3")
13227db96d56Sopenharmony_ci
13237db96d56Sopenharmony_ci        # Create stuff.
13247db96d56Sopenharmony_ci        os.makedirs(self.sub11_path)
13257db96d56Sopenharmony_ci        os.makedirs(sub2_path)
13267db96d56Sopenharmony_ci        os.makedirs(sub21_path)
13277db96d56Sopenharmony_ci        os.makedirs(t2_path)
13287db96d56Sopenharmony_ci
13297db96d56Sopenharmony_ci        for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path, tmp5_path:
13307db96d56Sopenharmony_ci            with open(path, "x", encoding='utf-8') as f:
13317db96d56Sopenharmony_ci                f.write("I'm " + path + " and proud of it.  Blame test_os.\n")
13327db96d56Sopenharmony_ci
13337db96d56Sopenharmony_ci        if os_helper.can_symlink():
13347db96d56Sopenharmony_ci            os.symlink(os.path.abspath(t2_path), self.link_path)
13357db96d56Sopenharmony_ci            os.symlink('broken', broken_link_path, True)
13367db96d56Sopenharmony_ci            os.symlink(join('tmp3', 'broken'), broken_link2_path, True)
13377db96d56Sopenharmony_ci            os.symlink(join('SUB21', 'tmp5'), broken_link3_path, True)
13387db96d56Sopenharmony_ci            self.sub2_tree = (sub2_path, ["SUB21", "link"],
13397db96d56Sopenharmony_ci                              ["broken_link", "broken_link2", "broken_link3",
13407db96d56Sopenharmony_ci                               "tmp3"])
13417db96d56Sopenharmony_ci        else:
13427db96d56Sopenharmony_ci            self.sub2_tree = (sub2_path, ["SUB21"], ["tmp3"])
13437db96d56Sopenharmony_ci
13447db96d56Sopenharmony_ci        if not support.is_emscripten:
13457db96d56Sopenharmony_ci            # Emscripten fails with inaccessible directory
13467db96d56Sopenharmony_ci            os.chmod(sub21_path, 0)
13477db96d56Sopenharmony_ci        try:
13487db96d56Sopenharmony_ci            os.listdir(sub21_path)
13497db96d56Sopenharmony_ci        except PermissionError:
13507db96d56Sopenharmony_ci            self.addCleanup(os.chmod, sub21_path, stat.S_IRWXU)
13517db96d56Sopenharmony_ci        else:
13527db96d56Sopenharmony_ci            os.chmod(sub21_path, stat.S_IRWXU)
13537db96d56Sopenharmony_ci            os.unlink(tmp5_path)
13547db96d56Sopenharmony_ci            os.rmdir(sub21_path)
13557db96d56Sopenharmony_ci            del self.sub2_tree[1][:1]
13567db96d56Sopenharmony_ci
13577db96d56Sopenharmony_ci    def test_walk_topdown(self):
13587db96d56Sopenharmony_ci        # Walk top-down.
13597db96d56Sopenharmony_ci        all = list(self.walk(self.walk_path))
13607db96d56Sopenharmony_ci
13617db96d56Sopenharmony_ci        self.assertEqual(len(all), 4)
13627db96d56Sopenharmony_ci        # We can't know which order SUB1 and SUB2 will appear in.
13637db96d56Sopenharmony_ci        # Not flipped:  TESTFN, SUB1, SUB11, SUB2
13647db96d56Sopenharmony_ci        #     flipped:  TESTFN, SUB2, SUB1, SUB11
13657db96d56Sopenharmony_ci        flipped = all[0][1][0] != "SUB1"
13667db96d56Sopenharmony_ci        all[0][1].sort()
13677db96d56Sopenharmony_ci        all[3 - 2 * flipped][-1].sort()
13687db96d56Sopenharmony_ci        all[3 - 2 * flipped][1].sort()
13697db96d56Sopenharmony_ci        self.assertEqual(all[0], (self.walk_path, ["SUB1", "SUB2"], ["tmp1"]))
13707db96d56Sopenharmony_ci        self.assertEqual(all[1 + flipped], (self.sub1_path, ["SUB11"], ["tmp2"]))
13717db96d56Sopenharmony_ci        self.assertEqual(all[2 + flipped], (self.sub11_path, [], []))
13727db96d56Sopenharmony_ci        self.assertEqual(all[3 - 2 * flipped], self.sub2_tree)
13737db96d56Sopenharmony_ci
13747db96d56Sopenharmony_ci    def test_walk_prune(self, walk_path=None):
13757db96d56Sopenharmony_ci        if walk_path is None:
13767db96d56Sopenharmony_ci            walk_path = self.walk_path
13777db96d56Sopenharmony_ci        # Prune the search.
13787db96d56Sopenharmony_ci        all = []
13797db96d56Sopenharmony_ci        for root, dirs, files in self.walk(walk_path):
13807db96d56Sopenharmony_ci            all.append((root, dirs, files))
13817db96d56Sopenharmony_ci            # Don't descend into SUB1.
13827db96d56Sopenharmony_ci            if 'SUB1' in dirs:
13837db96d56Sopenharmony_ci                # Note that this also mutates the dirs we appended to all!
13847db96d56Sopenharmony_ci                dirs.remove('SUB1')
13857db96d56Sopenharmony_ci
13867db96d56Sopenharmony_ci        self.assertEqual(len(all), 2)
13877db96d56Sopenharmony_ci        self.assertEqual(all[0], (self.walk_path, ["SUB2"], ["tmp1"]))
13887db96d56Sopenharmony_ci
13897db96d56Sopenharmony_ci        all[1][-1].sort()
13907db96d56Sopenharmony_ci        all[1][1].sort()
13917db96d56Sopenharmony_ci        self.assertEqual(all[1], self.sub2_tree)
13927db96d56Sopenharmony_ci
13937db96d56Sopenharmony_ci    def test_file_like_path(self):
13947db96d56Sopenharmony_ci        self.test_walk_prune(FakePath(self.walk_path))
13957db96d56Sopenharmony_ci
13967db96d56Sopenharmony_ci    def test_walk_bottom_up(self):
13977db96d56Sopenharmony_ci        # Walk bottom-up.
13987db96d56Sopenharmony_ci        all = list(self.walk(self.walk_path, topdown=False))
13997db96d56Sopenharmony_ci
14007db96d56Sopenharmony_ci        self.assertEqual(len(all), 4, all)
14017db96d56Sopenharmony_ci        # We can't know which order SUB1 and SUB2 will appear in.
14027db96d56Sopenharmony_ci        # Not flipped:  SUB11, SUB1, SUB2, TESTFN
14037db96d56Sopenharmony_ci        #     flipped:  SUB2, SUB11, SUB1, TESTFN
14047db96d56Sopenharmony_ci        flipped = all[3][1][0] != "SUB1"
14057db96d56Sopenharmony_ci        all[3][1].sort()
14067db96d56Sopenharmony_ci        all[2 - 2 * flipped][-1].sort()
14077db96d56Sopenharmony_ci        all[2 - 2 * flipped][1].sort()
14087db96d56Sopenharmony_ci        self.assertEqual(all[3],
14097db96d56Sopenharmony_ci                         (self.walk_path, ["SUB1", "SUB2"], ["tmp1"]))
14107db96d56Sopenharmony_ci        self.assertEqual(all[flipped],
14117db96d56Sopenharmony_ci                         (self.sub11_path, [], []))
14127db96d56Sopenharmony_ci        self.assertEqual(all[flipped + 1],
14137db96d56Sopenharmony_ci                         (self.sub1_path, ["SUB11"], ["tmp2"]))
14147db96d56Sopenharmony_ci        self.assertEqual(all[2 - 2 * flipped],
14157db96d56Sopenharmony_ci                         self.sub2_tree)
14167db96d56Sopenharmony_ci
14177db96d56Sopenharmony_ci    def test_walk_symlink(self):
14187db96d56Sopenharmony_ci        if not os_helper.can_symlink():
14197db96d56Sopenharmony_ci            self.skipTest("need symlink support")
14207db96d56Sopenharmony_ci
14217db96d56Sopenharmony_ci        # Walk, following symlinks.
14227db96d56Sopenharmony_ci        walk_it = self.walk(self.walk_path, follow_symlinks=True)
14237db96d56Sopenharmony_ci        for root, dirs, files in walk_it:
14247db96d56Sopenharmony_ci            if root == self.link_path:
14257db96d56Sopenharmony_ci                self.assertEqual(dirs, [])
14267db96d56Sopenharmony_ci                self.assertEqual(files, ["tmp4"])
14277db96d56Sopenharmony_ci                break
14287db96d56Sopenharmony_ci        else:
14297db96d56Sopenharmony_ci            self.fail("Didn't follow symlink with followlinks=True")
14307db96d56Sopenharmony_ci
14317db96d56Sopenharmony_ci    def test_walk_bad_dir(self):
14327db96d56Sopenharmony_ci        # Walk top-down.
14337db96d56Sopenharmony_ci        errors = []
14347db96d56Sopenharmony_ci        walk_it = self.walk(self.walk_path, onerror=errors.append)
14357db96d56Sopenharmony_ci        root, dirs, files = next(walk_it)
14367db96d56Sopenharmony_ci        self.assertEqual(errors, [])
14377db96d56Sopenharmony_ci        dir1 = 'SUB1'
14387db96d56Sopenharmony_ci        path1 = os.path.join(root, dir1)
14397db96d56Sopenharmony_ci        path1new = os.path.join(root, dir1 + '.new')
14407db96d56Sopenharmony_ci        os.rename(path1, path1new)
14417db96d56Sopenharmony_ci        try:
14427db96d56Sopenharmony_ci            roots = [r for r, d, f in walk_it]
14437db96d56Sopenharmony_ci            self.assertTrue(errors)
14447db96d56Sopenharmony_ci            self.assertNotIn(path1, roots)
14457db96d56Sopenharmony_ci            self.assertNotIn(path1new, roots)
14467db96d56Sopenharmony_ci            for dir2 in dirs:
14477db96d56Sopenharmony_ci                if dir2 != dir1:
14487db96d56Sopenharmony_ci                    self.assertIn(os.path.join(root, dir2), roots)
14497db96d56Sopenharmony_ci        finally:
14507db96d56Sopenharmony_ci            os.rename(path1new, path1)
14517db96d56Sopenharmony_ci
14527db96d56Sopenharmony_ci    def test_walk_many_open_files(self):
14537db96d56Sopenharmony_ci        depth = 30
14547db96d56Sopenharmony_ci        base = os.path.join(os_helper.TESTFN, 'deep')
14557db96d56Sopenharmony_ci        p = os.path.join(base, *(['d']*depth))
14567db96d56Sopenharmony_ci        os.makedirs(p)
14577db96d56Sopenharmony_ci
14587db96d56Sopenharmony_ci        iters = [self.walk(base, topdown=False) for j in range(100)]
14597db96d56Sopenharmony_ci        for i in range(depth + 1):
14607db96d56Sopenharmony_ci            expected = (p, ['d'] if i else [], [])
14617db96d56Sopenharmony_ci            for it in iters:
14627db96d56Sopenharmony_ci                self.assertEqual(next(it), expected)
14637db96d56Sopenharmony_ci            p = os.path.dirname(p)
14647db96d56Sopenharmony_ci
14657db96d56Sopenharmony_ci        iters = [self.walk(base, topdown=True) for j in range(100)]
14667db96d56Sopenharmony_ci        p = base
14677db96d56Sopenharmony_ci        for i in range(depth + 1):
14687db96d56Sopenharmony_ci            expected = (p, ['d'] if i < depth else [], [])
14697db96d56Sopenharmony_ci            for it in iters:
14707db96d56Sopenharmony_ci                self.assertEqual(next(it), expected)
14717db96d56Sopenharmony_ci            p = os.path.join(p, 'd')
14727db96d56Sopenharmony_ci
14737db96d56Sopenharmony_ci
14747db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'fwalk'), "Test needs os.fwalk()")
14757db96d56Sopenharmony_ciclass FwalkTests(WalkTests):
14767db96d56Sopenharmony_ci    """Tests for os.fwalk()."""
14777db96d56Sopenharmony_ci
14787db96d56Sopenharmony_ci    def walk(self, top, **kwargs):
14797db96d56Sopenharmony_ci        for root, dirs, files, root_fd in self.fwalk(top, **kwargs):
14807db96d56Sopenharmony_ci            yield (root, dirs, files)
14817db96d56Sopenharmony_ci
14827db96d56Sopenharmony_ci    def fwalk(self, *args, **kwargs):
14837db96d56Sopenharmony_ci        return os.fwalk(*args, **kwargs)
14847db96d56Sopenharmony_ci
14857db96d56Sopenharmony_ci    def _compare_to_walk(self, walk_kwargs, fwalk_kwargs):
14867db96d56Sopenharmony_ci        """
14877db96d56Sopenharmony_ci        compare with walk() results.
14887db96d56Sopenharmony_ci        """
14897db96d56Sopenharmony_ci        walk_kwargs = walk_kwargs.copy()
14907db96d56Sopenharmony_ci        fwalk_kwargs = fwalk_kwargs.copy()
14917db96d56Sopenharmony_ci        for topdown, follow_symlinks in itertools.product((True, False), repeat=2):
14927db96d56Sopenharmony_ci            walk_kwargs.update(topdown=topdown, followlinks=follow_symlinks)
14937db96d56Sopenharmony_ci            fwalk_kwargs.update(topdown=topdown, follow_symlinks=follow_symlinks)
14947db96d56Sopenharmony_ci
14957db96d56Sopenharmony_ci            expected = {}
14967db96d56Sopenharmony_ci            for root, dirs, files in os.walk(**walk_kwargs):
14977db96d56Sopenharmony_ci                expected[root] = (set(dirs), set(files))
14987db96d56Sopenharmony_ci
14997db96d56Sopenharmony_ci            for root, dirs, files, rootfd in self.fwalk(**fwalk_kwargs):
15007db96d56Sopenharmony_ci                self.assertIn(root, expected)
15017db96d56Sopenharmony_ci                self.assertEqual(expected[root], (set(dirs), set(files)))
15027db96d56Sopenharmony_ci
15037db96d56Sopenharmony_ci    def test_compare_to_walk(self):
15047db96d56Sopenharmony_ci        kwargs = {'top': os_helper.TESTFN}
15057db96d56Sopenharmony_ci        self._compare_to_walk(kwargs, kwargs)
15067db96d56Sopenharmony_ci
15077db96d56Sopenharmony_ci    def test_dir_fd(self):
15087db96d56Sopenharmony_ci        try:
15097db96d56Sopenharmony_ci            fd = os.open(".", os.O_RDONLY)
15107db96d56Sopenharmony_ci            walk_kwargs = {'top': os_helper.TESTFN}
15117db96d56Sopenharmony_ci            fwalk_kwargs = walk_kwargs.copy()
15127db96d56Sopenharmony_ci            fwalk_kwargs['dir_fd'] = fd
15137db96d56Sopenharmony_ci            self._compare_to_walk(walk_kwargs, fwalk_kwargs)
15147db96d56Sopenharmony_ci        finally:
15157db96d56Sopenharmony_ci            os.close(fd)
15167db96d56Sopenharmony_ci
15177db96d56Sopenharmony_ci    def test_yields_correct_dir_fd(self):
15187db96d56Sopenharmony_ci        # check returned file descriptors
15197db96d56Sopenharmony_ci        for topdown, follow_symlinks in itertools.product((True, False), repeat=2):
15207db96d56Sopenharmony_ci            args = os_helper.TESTFN, topdown, None
15217db96d56Sopenharmony_ci            for root, dirs, files, rootfd in self.fwalk(*args, follow_symlinks=follow_symlinks):
15227db96d56Sopenharmony_ci                # check that the FD is valid
15237db96d56Sopenharmony_ci                os.fstat(rootfd)
15247db96d56Sopenharmony_ci                # redundant check
15257db96d56Sopenharmony_ci                os.stat(rootfd)
15267db96d56Sopenharmony_ci                # check that listdir() returns consistent information
15277db96d56Sopenharmony_ci                self.assertEqual(set(os.listdir(rootfd)), set(dirs) | set(files))
15287db96d56Sopenharmony_ci
15297db96d56Sopenharmony_ci    @unittest.skipIf(
15307db96d56Sopenharmony_ci        support.is_emscripten, "Cannot dup stdout on Emscripten"
15317db96d56Sopenharmony_ci    )
15327db96d56Sopenharmony_ci    def test_fd_leak(self):
15337db96d56Sopenharmony_ci        # Since we're opening a lot of FDs, we must be careful to avoid leaks:
15347db96d56Sopenharmony_ci        # we both check that calling fwalk() a large number of times doesn't
15357db96d56Sopenharmony_ci        # yield EMFILE, and that the minimum allocated FD hasn't changed.
15367db96d56Sopenharmony_ci        minfd = os.dup(1)
15377db96d56Sopenharmony_ci        os.close(minfd)
15387db96d56Sopenharmony_ci        for i in range(256):
15397db96d56Sopenharmony_ci            for x in self.fwalk(os_helper.TESTFN):
15407db96d56Sopenharmony_ci                pass
15417db96d56Sopenharmony_ci        newfd = os.dup(1)
15427db96d56Sopenharmony_ci        self.addCleanup(os.close, newfd)
15437db96d56Sopenharmony_ci        self.assertEqual(newfd, minfd)
15447db96d56Sopenharmony_ci
15457db96d56Sopenharmony_ci    # fwalk() keeps file descriptors open
15467db96d56Sopenharmony_ci    test_walk_many_open_files = None
15477db96d56Sopenharmony_ci
15487db96d56Sopenharmony_ci
15497db96d56Sopenharmony_ciclass BytesWalkTests(WalkTests):
15507db96d56Sopenharmony_ci    """Tests for os.walk() with bytes."""
15517db96d56Sopenharmony_ci    def walk(self, top, **kwargs):
15527db96d56Sopenharmony_ci        if 'follow_symlinks' in kwargs:
15537db96d56Sopenharmony_ci            kwargs['followlinks'] = kwargs.pop('follow_symlinks')
15547db96d56Sopenharmony_ci        for broot, bdirs, bfiles in os.walk(os.fsencode(top), **kwargs):
15557db96d56Sopenharmony_ci            root = os.fsdecode(broot)
15567db96d56Sopenharmony_ci            dirs = list(map(os.fsdecode, bdirs))
15577db96d56Sopenharmony_ci            files = list(map(os.fsdecode, bfiles))
15587db96d56Sopenharmony_ci            yield (root, dirs, files)
15597db96d56Sopenharmony_ci            bdirs[:] = list(map(os.fsencode, dirs))
15607db96d56Sopenharmony_ci            bfiles[:] = list(map(os.fsencode, files))
15617db96d56Sopenharmony_ci
15627db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'fwalk'), "Test needs os.fwalk()")
15637db96d56Sopenharmony_ciclass BytesFwalkTests(FwalkTests):
15647db96d56Sopenharmony_ci    """Tests for os.walk() with bytes."""
15657db96d56Sopenharmony_ci    def fwalk(self, top='.', *args, **kwargs):
15667db96d56Sopenharmony_ci        for broot, bdirs, bfiles, topfd in os.fwalk(os.fsencode(top), *args, **kwargs):
15677db96d56Sopenharmony_ci            root = os.fsdecode(broot)
15687db96d56Sopenharmony_ci            dirs = list(map(os.fsdecode, bdirs))
15697db96d56Sopenharmony_ci            files = list(map(os.fsdecode, bfiles))
15707db96d56Sopenharmony_ci            yield (root, dirs, files, topfd)
15717db96d56Sopenharmony_ci            bdirs[:] = list(map(os.fsencode, dirs))
15727db96d56Sopenharmony_ci            bfiles[:] = list(map(os.fsencode, files))
15737db96d56Sopenharmony_ci
15747db96d56Sopenharmony_ci
15757db96d56Sopenharmony_ciclass MakedirTests(unittest.TestCase):
15767db96d56Sopenharmony_ci    def setUp(self):
15777db96d56Sopenharmony_ci        os.mkdir(os_helper.TESTFN)
15787db96d56Sopenharmony_ci
15797db96d56Sopenharmony_ci    def test_makedir(self):
15807db96d56Sopenharmony_ci        base = os_helper.TESTFN
15817db96d56Sopenharmony_ci        path = os.path.join(base, 'dir1', 'dir2', 'dir3')
15827db96d56Sopenharmony_ci        os.makedirs(path)             # Should work
15837db96d56Sopenharmony_ci        path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4')
15847db96d56Sopenharmony_ci        os.makedirs(path)
15857db96d56Sopenharmony_ci
15867db96d56Sopenharmony_ci        # Try paths with a '.' in them
15877db96d56Sopenharmony_ci        self.assertRaises(OSError, os.makedirs, os.curdir)
15887db96d56Sopenharmony_ci        path = os.path.join(base, 'dir1', 'dir2', 'dir3', 'dir4', 'dir5', os.curdir)
15897db96d56Sopenharmony_ci        os.makedirs(path)
15907db96d56Sopenharmony_ci        path = os.path.join(base, 'dir1', os.curdir, 'dir2', 'dir3', 'dir4',
15917db96d56Sopenharmony_ci                            'dir5', 'dir6')
15927db96d56Sopenharmony_ci        os.makedirs(path)
15937db96d56Sopenharmony_ci
15947db96d56Sopenharmony_ci    @unittest.skipIf(
15957db96d56Sopenharmony_ci        support.is_emscripten or support.is_wasi,
15967db96d56Sopenharmony_ci        "Emscripten's/WASI's umask is a stub."
15977db96d56Sopenharmony_ci    )
15987db96d56Sopenharmony_ci    def test_mode(self):
15997db96d56Sopenharmony_ci        with os_helper.temp_umask(0o002):
16007db96d56Sopenharmony_ci            base = os_helper.TESTFN
16017db96d56Sopenharmony_ci            parent = os.path.join(base, 'dir1')
16027db96d56Sopenharmony_ci            path = os.path.join(parent, 'dir2')
16037db96d56Sopenharmony_ci            os.makedirs(path, 0o555)
16047db96d56Sopenharmony_ci            self.assertTrue(os.path.exists(path))
16057db96d56Sopenharmony_ci            self.assertTrue(os.path.isdir(path))
16067db96d56Sopenharmony_ci            if os.name != 'nt':
16077db96d56Sopenharmony_ci                self.assertEqual(os.stat(path).st_mode & 0o777, 0o555)
16087db96d56Sopenharmony_ci                self.assertEqual(os.stat(parent).st_mode & 0o777, 0o775)
16097db96d56Sopenharmony_ci
16107db96d56Sopenharmony_ci    @unittest.skipIf(
16117db96d56Sopenharmony_ci        support.is_emscripten or support.is_wasi,
16127db96d56Sopenharmony_ci        "Emscripten's/WASI's umask is a stub."
16137db96d56Sopenharmony_ci    )
16147db96d56Sopenharmony_ci    def test_exist_ok_existing_directory(self):
16157db96d56Sopenharmony_ci        path = os.path.join(os_helper.TESTFN, 'dir1')
16167db96d56Sopenharmony_ci        mode = 0o777
16177db96d56Sopenharmony_ci        old_mask = os.umask(0o022)
16187db96d56Sopenharmony_ci        os.makedirs(path, mode)
16197db96d56Sopenharmony_ci        self.assertRaises(OSError, os.makedirs, path, mode)
16207db96d56Sopenharmony_ci        self.assertRaises(OSError, os.makedirs, path, mode, exist_ok=False)
16217db96d56Sopenharmony_ci        os.makedirs(path, 0o776, exist_ok=True)
16227db96d56Sopenharmony_ci        os.makedirs(path, mode=mode, exist_ok=True)
16237db96d56Sopenharmony_ci        os.umask(old_mask)
16247db96d56Sopenharmony_ci
16257db96d56Sopenharmony_ci        # Issue #25583: A drive root could raise PermissionError on Windows
16267db96d56Sopenharmony_ci        os.makedirs(os.path.abspath('/'), exist_ok=True)
16277db96d56Sopenharmony_ci
16287db96d56Sopenharmony_ci    @unittest.skipIf(
16297db96d56Sopenharmony_ci        support.is_emscripten or support.is_wasi,
16307db96d56Sopenharmony_ci        "Emscripten's/WASI's umask is a stub."
16317db96d56Sopenharmony_ci    )
16327db96d56Sopenharmony_ci    def test_exist_ok_s_isgid_directory(self):
16337db96d56Sopenharmony_ci        path = os.path.join(os_helper.TESTFN, 'dir1')
16347db96d56Sopenharmony_ci        S_ISGID = stat.S_ISGID
16357db96d56Sopenharmony_ci        mode = 0o777
16367db96d56Sopenharmony_ci        old_mask = os.umask(0o022)
16377db96d56Sopenharmony_ci        try:
16387db96d56Sopenharmony_ci            existing_testfn_mode = stat.S_IMODE(
16397db96d56Sopenharmony_ci                    os.lstat(os_helper.TESTFN).st_mode)
16407db96d56Sopenharmony_ci            try:
16417db96d56Sopenharmony_ci                os.chmod(os_helper.TESTFN, existing_testfn_mode | S_ISGID)
16427db96d56Sopenharmony_ci            except PermissionError:
16437db96d56Sopenharmony_ci                raise unittest.SkipTest('Cannot set S_ISGID for dir.')
16447db96d56Sopenharmony_ci            if (os.lstat(os_helper.TESTFN).st_mode & S_ISGID != S_ISGID):
16457db96d56Sopenharmony_ci                raise unittest.SkipTest('No support for S_ISGID dir mode.')
16467db96d56Sopenharmony_ci            # The os should apply S_ISGID from the parent dir for us, but
16477db96d56Sopenharmony_ci            # this test need not depend on that behavior.  Be explicit.
16487db96d56Sopenharmony_ci            os.makedirs(path, mode | S_ISGID)
16497db96d56Sopenharmony_ci            # http://bugs.python.org/issue14992
16507db96d56Sopenharmony_ci            # Should not fail when the bit is already set.
16517db96d56Sopenharmony_ci            os.makedirs(path, mode, exist_ok=True)
16527db96d56Sopenharmony_ci            # remove the bit.
16537db96d56Sopenharmony_ci            os.chmod(path, stat.S_IMODE(os.lstat(path).st_mode) & ~S_ISGID)
16547db96d56Sopenharmony_ci            # May work even when the bit is not already set when demanded.
16557db96d56Sopenharmony_ci            os.makedirs(path, mode | S_ISGID, exist_ok=True)
16567db96d56Sopenharmony_ci        finally:
16577db96d56Sopenharmony_ci            os.umask(old_mask)
16587db96d56Sopenharmony_ci
16597db96d56Sopenharmony_ci    def test_exist_ok_existing_regular_file(self):
16607db96d56Sopenharmony_ci        base = os_helper.TESTFN
16617db96d56Sopenharmony_ci        path = os.path.join(os_helper.TESTFN, 'dir1')
16627db96d56Sopenharmony_ci        with open(path, 'w', encoding='utf-8') as f:
16637db96d56Sopenharmony_ci            f.write('abc')
16647db96d56Sopenharmony_ci        self.assertRaises(OSError, os.makedirs, path)
16657db96d56Sopenharmony_ci        self.assertRaises(OSError, os.makedirs, path, exist_ok=False)
16667db96d56Sopenharmony_ci        self.assertRaises(OSError, os.makedirs, path, exist_ok=True)
16677db96d56Sopenharmony_ci        os.remove(path)
16687db96d56Sopenharmony_ci
16697db96d56Sopenharmony_ci    @unittest.skipUnless(os.name == 'nt', "requires Windows")
16707db96d56Sopenharmony_ci    def test_win32_mkdir_700(self):
16717db96d56Sopenharmony_ci        base = os_helper.TESTFN
16727db96d56Sopenharmony_ci        path = os.path.abspath(os.path.join(os_helper.TESTFN, 'dir'))
16737db96d56Sopenharmony_ci        os.mkdir(path, mode=0o700)
16747db96d56Sopenharmony_ci        out = subprocess.check_output(["cacls.exe", path, "/s"], encoding="oem")
16757db96d56Sopenharmony_ci        os.rmdir(path)
16767db96d56Sopenharmony_ci        self.assertEqual(
16777db96d56Sopenharmony_ci            out.strip(),
16787db96d56Sopenharmony_ci            f'{path} "D:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;OW)"',
16797db96d56Sopenharmony_ci        )
16807db96d56Sopenharmony_ci
16817db96d56Sopenharmony_ci    def tearDown(self):
16827db96d56Sopenharmony_ci        path = os.path.join(os_helper.TESTFN, 'dir1', 'dir2', 'dir3',
16837db96d56Sopenharmony_ci                            'dir4', 'dir5', 'dir6')
16847db96d56Sopenharmony_ci        # If the tests failed, the bottom-most directory ('../dir6')
16857db96d56Sopenharmony_ci        # may not have been created, so we look for the outermost directory
16867db96d56Sopenharmony_ci        # that exists.
16877db96d56Sopenharmony_ci        while not os.path.exists(path) and path != os_helper.TESTFN:
16887db96d56Sopenharmony_ci            path = os.path.dirname(path)
16897db96d56Sopenharmony_ci
16907db96d56Sopenharmony_ci        os.removedirs(path)
16917db96d56Sopenharmony_ci
16927db96d56Sopenharmony_ci
16937db96d56Sopenharmony_ci@os_helper.skip_unless_working_chmod
16947db96d56Sopenharmony_ciclass ChownFileTests(unittest.TestCase):
16957db96d56Sopenharmony_ci
16967db96d56Sopenharmony_ci    @classmethod
16977db96d56Sopenharmony_ci    def setUpClass(cls):
16987db96d56Sopenharmony_ci        os.mkdir(os_helper.TESTFN)
16997db96d56Sopenharmony_ci
17007db96d56Sopenharmony_ci    def test_chown_uid_gid_arguments_must_be_index(self):
17017db96d56Sopenharmony_ci        stat = os.stat(os_helper.TESTFN)
17027db96d56Sopenharmony_ci        uid = stat.st_uid
17037db96d56Sopenharmony_ci        gid = stat.st_gid
17047db96d56Sopenharmony_ci        for value in (-1.0, -1j, decimal.Decimal(-1), fractions.Fraction(-2, 2)):
17057db96d56Sopenharmony_ci            self.assertRaises(TypeError, os.chown, os_helper.TESTFN, value, gid)
17067db96d56Sopenharmony_ci            self.assertRaises(TypeError, os.chown, os_helper.TESTFN, uid, value)
17077db96d56Sopenharmony_ci        self.assertIsNone(os.chown(os_helper.TESTFN, uid, gid))
17087db96d56Sopenharmony_ci        self.assertIsNone(os.chown(os_helper.TESTFN, -1, -1))
17097db96d56Sopenharmony_ci
17107db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'getgroups'), 'need os.getgroups')
17117db96d56Sopenharmony_ci    def test_chown_gid(self):
17127db96d56Sopenharmony_ci        groups = os.getgroups()
17137db96d56Sopenharmony_ci        if len(groups) < 2:
17147db96d56Sopenharmony_ci            self.skipTest("test needs at least 2 groups")
17157db96d56Sopenharmony_ci
17167db96d56Sopenharmony_ci        gid_1, gid_2 = groups[:2]
17177db96d56Sopenharmony_ci        uid = os.stat(os_helper.TESTFN).st_uid
17187db96d56Sopenharmony_ci
17197db96d56Sopenharmony_ci        os.chown(os_helper.TESTFN, uid, gid_1)
17207db96d56Sopenharmony_ci        gid = os.stat(os_helper.TESTFN).st_gid
17217db96d56Sopenharmony_ci        self.assertEqual(gid, gid_1)
17227db96d56Sopenharmony_ci
17237db96d56Sopenharmony_ci        os.chown(os_helper.TESTFN, uid, gid_2)
17247db96d56Sopenharmony_ci        gid = os.stat(os_helper.TESTFN).st_gid
17257db96d56Sopenharmony_ci        self.assertEqual(gid, gid_2)
17267db96d56Sopenharmony_ci
17277db96d56Sopenharmony_ci    @unittest.skipUnless(root_in_posix and len(all_users) > 1,
17287db96d56Sopenharmony_ci                         "test needs root privilege and more than one user")
17297db96d56Sopenharmony_ci    def test_chown_with_root(self):
17307db96d56Sopenharmony_ci        uid_1, uid_2 = all_users[:2]
17317db96d56Sopenharmony_ci        gid = os.stat(os_helper.TESTFN).st_gid
17327db96d56Sopenharmony_ci        os.chown(os_helper.TESTFN, uid_1, gid)
17337db96d56Sopenharmony_ci        uid = os.stat(os_helper.TESTFN).st_uid
17347db96d56Sopenharmony_ci        self.assertEqual(uid, uid_1)
17357db96d56Sopenharmony_ci        os.chown(os_helper.TESTFN, uid_2, gid)
17367db96d56Sopenharmony_ci        uid = os.stat(os_helper.TESTFN).st_uid
17377db96d56Sopenharmony_ci        self.assertEqual(uid, uid_2)
17387db96d56Sopenharmony_ci
17397db96d56Sopenharmony_ci    @unittest.skipUnless(not root_in_posix and len(all_users) > 1,
17407db96d56Sopenharmony_ci                         "test needs non-root account and more than one user")
17417db96d56Sopenharmony_ci    def test_chown_without_permission(self):
17427db96d56Sopenharmony_ci        uid_1, uid_2 = all_users[:2]
17437db96d56Sopenharmony_ci        gid = os.stat(os_helper.TESTFN).st_gid
17447db96d56Sopenharmony_ci        with self.assertRaises(PermissionError):
17457db96d56Sopenharmony_ci            os.chown(os_helper.TESTFN, uid_1, gid)
17467db96d56Sopenharmony_ci            os.chown(os_helper.TESTFN, uid_2, gid)
17477db96d56Sopenharmony_ci
17487db96d56Sopenharmony_ci    @classmethod
17497db96d56Sopenharmony_ci    def tearDownClass(cls):
17507db96d56Sopenharmony_ci        os.rmdir(os_helper.TESTFN)
17517db96d56Sopenharmony_ci
17527db96d56Sopenharmony_ci
17537db96d56Sopenharmony_ciclass RemoveDirsTests(unittest.TestCase):
17547db96d56Sopenharmony_ci    def setUp(self):
17557db96d56Sopenharmony_ci        os.makedirs(os_helper.TESTFN)
17567db96d56Sopenharmony_ci
17577db96d56Sopenharmony_ci    def tearDown(self):
17587db96d56Sopenharmony_ci        os_helper.rmtree(os_helper.TESTFN)
17597db96d56Sopenharmony_ci
17607db96d56Sopenharmony_ci    def test_remove_all(self):
17617db96d56Sopenharmony_ci        dira = os.path.join(os_helper.TESTFN, 'dira')
17627db96d56Sopenharmony_ci        os.mkdir(dira)
17637db96d56Sopenharmony_ci        dirb = os.path.join(dira, 'dirb')
17647db96d56Sopenharmony_ci        os.mkdir(dirb)
17657db96d56Sopenharmony_ci        os.removedirs(dirb)
17667db96d56Sopenharmony_ci        self.assertFalse(os.path.exists(dirb))
17677db96d56Sopenharmony_ci        self.assertFalse(os.path.exists(dira))
17687db96d56Sopenharmony_ci        self.assertFalse(os.path.exists(os_helper.TESTFN))
17697db96d56Sopenharmony_ci
17707db96d56Sopenharmony_ci    def test_remove_partial(self):
17717db96d56Sopenharmony_ci        dira = os.path.join(os_helper.TESTFN, 'dira')
17727db96d56Sopenharmony_ci        os.mkdir(dira)
17737db96d56Sopenharmony_ci        dirb = os.path.join(dira, 'dirb')
17747db96d56Sopenharmony_ci        os.mkdir(dirb)
17757db96d56Sopenharmony_ci        create_file(os.path.join(dira, 'file.txt'))
17767db96d56Sopenharmony_ci        os.removedirs(dirb)
17777db96d56Sopenharmony_ci        self.assertFalse(os.path.exists(dirb))
17787db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(dira))
17797db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(os_helper.TESTFN))
17807db96d56Sopenharmony_ci
17817db96d56Sopenharmony_ci    def test_remove_nothing(self):
17827db96d56Sopenharmony_ci        dira = os.path.join(os_helper.TESTFN, 'dira')
17837db96d56Sopenharmony_ci        os.mkdir(dira)
17847db96d56Sopenharmony_ci        dirb = os.path.join(dira, 'dirb')
17857db96d56Sopenharmony_ci        os.mkdir(dirb)
17867db96d56Sopenharmony_ci        create_file(os.path.join(dirb, 'file.txt'))
17877db96d56Sopenharmony_ci        with self.assertRaises(OSError):
17887db96d56Sopenharmony_ci            os.removedirs(dirb)
17897db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(dirb))
17907db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(dira))
17917db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(os_helper.TESTFN))
17927db96d56Sopenharmony_ci
17937db96d56Sopenharmony_ci
17947db96d56Sopenharmony_ci@unittest.skipIf(support.is_wasi, "WASI has no /dev/null")
17957db96d56Sopenharmony_ciclass DevNullTests(unittest.TestCase):
17967db96d56Sopenharmony_ci    def test_devnull(self):
17977db96d56Sopenharmony_ci        with open(os.devnull, 'wb', 0) as f:
17987db96d56Sopenharmony_ci            f.write(b'hello')
17997db96d56Sopenharmony_ci            f.close()
18007db96d56Sopenharmony_ci        with open(os.devnull, 'rb') as f:
18017db96d56Sopenharmony_ci            self.assertEqual(f.read(), b'')
18027db96d56Sopenharmony_ci
18037db96d56Sopenharmony_ci
18047db96d56Sopenharmony_ciclass URandomTests(unittest.TestCase):
18057db96d56Sopenharmony_ci    def test_urandom_length(self):
18067db96d56Sopenharmony_ci        self.assertEqual(len(os.urandom(0)), 0)
18077db96d56Sopenharmony_ci        self.assertEqual(len(os.urandom(1)), 1)
18087db96d56Sopenharmony_ci        self.assertEqual(len(os.urandom(10)), 10)
18097db96d56Sopenharmony_ci        self.assertEqual(len(os.urandom(100)), 100)
18107db96d56Sopenharmony_ci        self.assertEqual(len(os.urandom(1000)), 1000)
18117db96d56Sopenharmony_ci
18127db96d56Sopenharmony_ci    def test_urandom_value(self):
18137db96d56Sopenharmony_ci        data1 = os.urandom(16)
18147db96d56Sopenharmony_ci        self.assertIsInstance(data1, bytes)
18157db96d56Sopenharmony_ci        data2 = os.urandom(16)
18167db96d56Sopenharmony_ci        self.assertNotEqual(data1, data2)
18177db96d56Sopenharmony_ci
18187db96d56Sopenharmony_ci    def get_urandom_subprocess(self, count):
18197db96d56Sopenharmony_ci        code = '\n'.join((
18207db96d56Sopenharmony_ci            'import os, sys',
18217db96d56Sopenharmony_ci            'data = os.urandom(%s)' % count,
18227db96d56Sopenharmony_ci            'sys.stdout.buffer.write(data)',
18237db96d56Sopenharmony_ci            'sys.stdout.buffer.flush()'))
18247db96d56Sopenharmony_ci        out = assert_python_ok('-c', code)
18257db96d56Sopenharmony_ci        stdout = out[1]
18267db96d56Sopenharmony_ci        self.assertEqual(len(stdout), count)
18277db96d56Sopenharmony_ci        return stdout
18287db96d56Sopenharmony_ci
18297db96d56Sopenharmony_ci    def test_urandom_subprocess(self):
18307db96d56Sopenharmony_ci        data1 = self.get_urandom_subprocess(16)
18317db96d56Sopenharmony_ci        data2 = self.get_urandom_subprocess(16)
18327db96d56Sopenharmony_ci        self.assertNotEqual(data1, data2)
18337db96d56Sopenharmony_ci
18347db96d56Sopenharmony_ci
18357db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'getrandom'), 'need os.getrandom()')
18367db96d56Sopenharmony_ciclass GetRandomTests(unittest.TestCase):
18377db96d56Sopenharmony_ci    @classmethod
18387db96d56Sopenharmony_ci    def setUpClass(cls):
18397db96d56Sopenharmony_ci        try:
18407db96d56Sopenharmony_ci            os.getrandom(1)
18417db96d56Sopenharmony_ci        except OSError as exc:
18427db96d56Sopenharmony_ci            if exc.errno == errno.ENOSYS:
18437db96d56Sopenharmony_ci                # Python compiled on a more recent Linux version
18447db96d56Sopenharmony_ci                # than the current Linux kernel
18457db96d56Sopenharmony_ci                raise unittest.SkipTest("getrandom() syscall fails with ENOSYS")
18467db96d56Sopenharmony_ci            else:
18477db96d56Sopenharmony_ci                raise
18487db96d56Sopenharmony_ci
18497db96d56Sopenharmony_ci    def test_getrandom_type(self):
18507db96d56Sopenharmony_ci        data = os.getrandom(16)
18517db96d56Sopenharmony_ci        self.assertIsInstance(data, bytes)
18527db96d56Sopenharmony_ci        self.assertEqual(len(data), 16)
18537db96d56Sopenharmony_ci
18547db96d56Sopenharmony_ci    def test_getrandom0(self):
18557db96d56Sopenharmony_ci        empty = os.getrandom(0)
18567db96d56Sopenharmony_ci        self.assertEqual(empty, b'')
18577db96d56Sopenharmony_ci
18587db96d56Sopenharmony_ci    def test_getrandom_random(self):
18597db96d56Sopenharmony_ci        self.assertTrue(hasattr(os, 'GRND_RANDOM'))
18607db96d56Sopenharmony_ci
18617db96d56Sopenharmony_ci        # Don't test os.getrandom(1, os.GRND_RANDOM) to not consume the rare
18627db96d56Sopenharmony_ci        # resource /dev/random
18637db96d56Sopenharmony_ci
18647db96d56Sopenharmony_ci    def test_getrandom_nonblock(self):
18657db96d56Sopenharmony_ci        # The call must not fail. Check also that the flag exists
18667db96d56Sopenharmony_ci        try:
18677db96d56Sopenharmony_ci            os.getrandom(1, os.GRND_NONBLOCK)
18687db96d56Sopenharmony_ci        except BlockingIOError:
18697db96d56Sopenharmony_ci            # System urandom is not initialized yet
18707db96d56Sopenharmony_ci            pass
18717db96d56Sopenharmony_ci
18727db96d56Sopenharmony_ci    def test_getrandom_value(self):
18737db96d56Sopenharmony_ci        data1 = os.getrandom(16)
18747db96d56Sopenharmony_ci        data2 = os.getrandom(16)
18757db96d56Sopenharmony_ci        self.assertNotEqual(data1, data2)
18767db96d56Sopenharmony_ci
18777db96d56Sopenharmony_ci
18787db96d56Sopenharmony_ci# os.urandom() doesn't use a file descriptor when it is implemented with the
18797db96d56Sopenharmony_ci# getentropy() function, the getrandom() function or the getrandom() syscall
18807db96d56Sopenharmony_ciOS_URANDOM_DONT_USE_FD = (
18817db96d56Sopenharmony_ci    sysconfig.get_config_var('HAVE_GETENTROPY') == 1
18827db96d56Sopenharmony_ci    or sysconfig.get_config_var('HAVE_GETRANDOM') == 1
18837db96d56Sopenharmony_ci    or sysconfig.get_config_var('HAVE_GETRANDOM_SYSCALL') == 1)
18847db96d56Sopenharmony_ci
18857db96d56Sopenharmony_ci@unittest.skipIf(OS_URANDOM_DONT_USE_FD ,
18867db96d56Sopenharmony_ci                 "os.random() does not use a file descriptor")
18877db96d56Sopenharmony_ci@unittest.skipIf(sys.platform == "vxworks",
18887db96d56Sopenharmony_ci                 "VxWorks can't set RLIMIT_NOFILE to 1")
18897db96d56Sopenharmony_ciclass URandomFDTests(unittest.TestCase):
18907db96d56Sopenharmony_ci    @unittest.skipUnless(resource, "test requires the resource module")
18917db96d56Sopenharmony_ci    def test_urandom_failure(self):
18927db96d56Sopenharmony_ci        # Check urandom() failing when it is not able to open /dev/random.
18937db96d56Sopenharmony_ci        # We spawn a new process to make the test more robust (if getrlimit()
18947db96d56Sopenharmony_ci        # failed to restore the file descriptor limit after this, the whole
18957db96d56Sopenharmony_ci        # test suite would crash; this actually happened on the OS X Tiger
18967db96d56Sopenharmony_ci        # buildbot).
18977db96d56Sopenharmony_ci        code = """if 1:
18987db96d56Sopenharmony_ci            import errno
18997db96d56Sopenharmony_ci            import os
19007db96d56Sopenharmony_ci            import resource
19017db96d56Sopenharmony_ci
19027db96d56Sopenharmony_ci            soft_limit, hard_limit = resource.getrlimit(resource.RLIMIT_NOFILE)
19037db96d56Sopenharmony_ci            resource.setrlimit(resource.RLIMIT_NOFILE, (1, hard_limit))
19047db96d56Sopenharmony_ci            try:
19057db96d56Sopenharmony_ci                os.urandom(16)
19067db96d56Sopenharmony_ci            except OSError as e:
19077db96d56Sopenharmony_ci                assert e.errno == errno.EMFILE, e.errno
19087db96d56Sopenharmony_ci            else:
19097db96d56Sopenharmony_ci                raise AssertionError("OSError not raised")
19107db96d56Sopenharmony_ci            """
19117db96d56Sopenharmony_ci        assert_python_ok('-c', code)
19127db96d56Sopenharmony_ci
19137db96d56Sopenharmony_ci    def test_urandom_fd_closed(self):
19147db96d56Sopenharmony_ci        # Issue #21207: urandom() should reopen its fd to /dev/urandom if
19157db96d56Sopenharmony_ci        # closed.
19167db96d56Sopenharmony_ci        code = """if 1:
19177db96d56Sopenharmony_ci            import os
19187db96d56Sopenharmony_ci            import sys
19197db96d56Sopenharmony_ci            import test.support
19207db96d56Sopenharmony_ci            os.urandom(4)
19217db96d56Sopenharmony_ci            with test.support.SuppressCrashReport():
19227db96d56Sopenharmony_ci                os.closerange(3, 256)
19237db96d56Sopenharmony_ci            sys.stdout.buffer.write(os.urandom(4))
19247db96d56Sopenharmony_ci            """
19257db96d56Sopenharmony_ci        rc, out, err = assert_python_ok('-Sc', code)
19267db96d56Sopenharmony_ci
19277db96d56Sopenharmony_ci    def test_urandom_fd_reopened(self):
19287db96d56Sopenharmony_ci        # Issue #21207: urandom() should detect its fd to /dev/urandom
19297db96d56Sopenharmony_ci        # changed to something else, and reopen it.
19307db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
19317db96d56Sopenharmony_ci        create_file(os_helper.TESTFN, b"x" * 256)
19327db96d56Sopenharmony_ci
19337db96d56Sopenharmony_ci        code = """if 1:
19347db96d56Sopenharmony_ci            import os
19357db96d56Sopenharmony_ci            import sys
19367db96d56Sopenharmony_ci            import test.support
19377db96d56Sopenharmony_ci            os.urandom(4)
19387db96d56Sopenharmony_ci            with test.support.SuppressCrashReport():
19397db96d56Sopenharmony_ci                for fd in range(3, 256):
19407db96d56Sopenharmony_ci                    try:
19417db96d56Sopenharmony_ci                        os.close(fd)
19427db96d56Sopenharmony_ci                    except OSError:
19437db96d56Sopenharmony_ci                        pass
19447db96d56Sopenharmony_ci                    else:
19457db96d56Sopenharmony_ci                        # Found the urandom fd (XXX hopefully)
19467db96d56Sopenharmony_ci                        break
19477db96d56Sopenharmony_ci                os.closerange(3, 256)
19487db96d56Sopenharmony_ci            with open({TESTFN!r}, 'rb') as f:
19497db96d56Sopenharmony_ci                new_fd = f.fileno()
19507db96d56Sopenharmony_ci                # Issue #26935: posix allows new_fd and fd to be equal but
19517db96d56Sopenharmony_ci                # some libc implementations have dup2 return an error in this
19527db96d56Sopenharmony_ci                # case.
19537db96d56Sopenharmony_ci                if new_fd != fd:
19547db96d56Sopenharmony_ci                    os.dup2(new_fd, fd)
19557db96d56Sopenharmony_ci                sys.stdout.buffer.write(os.urandom(4))
19567db96d56Sopenharmony_ci                sys.stdout.buffer.write(os.urandom(4))
19577db96d56Sopenharmony_ci            """.format(TESTFN=os_helper.TESTFN)
19587db96d56Sopenharmony_ci        rc, out, err = assert_python_ok('-Sc', code)
19597db96d56Sopenharmony_ci        self.assertEqual(len(out), 8)
19607db96d56Sopenharmony_ci        self.assertNotEqual(out[0:4], out[4:8])
19617db96d56Sopenharmony_ci        rc, out2, err2 = assert_python_ok('-Sc', code)
19627db96d56Sopenharmony_ci        self.assertEqual(len(out2), 8)
19637db96d56Sopenharmony_ci        self.assertNotEqual(out2, out)
19647db96d56Sopenharmony_ci
19657db96d56Sopenharmony_ci
19667db96d56Sopenharmony_ci@contextlib.contextmanager
19677db96d56Sopenharmony_cidef _execvpe_mockup(defpath=None):
19687db96d56Sopenharmony_ci    """
19697db96d56Sopenharmony_ci    Stubs out execv and execve functions when used as context manager.
19707db96d56Sopenharmony_ci    Records exec calls. The mock execv and execve functions always raise an
19717db96d56Sopenharmony_ci    exception as they would normally never return.
19727db96d56Sopenharmony_ci    """
19737db96d56Sopenharmony_ci    # A list of tuples containing (function name, first arg, args)
19747db96d56Sopenharmony_ci    # of calls to execv or execve that have been made.
19757db96d56Sopenharmony_ci    calls = []
19767db96d56Sopenharmony_ci
19777db96d56Sopenharmony_ci    def mock_execv(name, *args):
19787db96d56Sopenharmony_ci        calls.append(('execv', name, args))
19797db96d56Sopenharmony_ci        raise RuntimeError("execv called")
19807db96d56Sopenharmony_ci
19817db96d56Sopenharmony_ci    def mock_execve(name, *args):
19827db96d56Sopenharmony_ci        calls.append(('execve', name, args))
19837db96d56Sopenharmony_ci        raise OSError(errno.ENOTDIR, "execve called")
19847db96d56Sopenharmony_ci
19857db96d56Sopenharmony_ci    try:
19867db96d56Sopenharmony_ci        orig_execv = os.execv
19877db96d56Sopenharmony_ci        orig_execve = os.execve
19887db96d56Sopenharmony_ci        orig_defpath = os.defpath
19897db96d56Sopenharmony_ci        os.execv = mock_execv
19907db96d56Sopenharmony_ci        os.execve = mock_execve
19917db96d56Sopenharmony_ci        if defpath is not None:
19927db96d56Sopenharmony_ci            os.defpath = defpath
19937db96d56Sopenharmony_ci        yield calls
19947db96d56Sopenharmony_ci    finally:
19957db96d56Sopenharmony_ci        os.execv = orig_execv
19967db96d56Sopenharmony_ci        os.execve = orig_execve
19977db96d56Sopenharmony_ci        os.defpath = orig_defpath
19987db96d56Sopenharmony_ci
19997db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'execv'),
20007db96d56Sopenharmony_ci                     "need os.execv()")
20017db96d56Sopenharmony_ciclass ExecTests(unittest.TestCase):
20027db96d56Sopenharmony_ci    @unittest.skipIf(USING_LINUXTHREADS,
20037db96d56Sopenharmony_ci                     "avoid triggering a linuxthreads bug: see issue #4970")
20047db96d56Sopenharmony_ci    def test_execvpe_with_bad_program(self):
20057db96d56Sopenharmony_ci        self.assertRaises(OSError, os.execvpe, 'no such app-',
20067db96d56Sopenharmony_ci                          ['no such app-'], None)
20077db96d56Sopenharmony_ci
20087db96d56Sopenharmony_ci    def test_execv_with_bad_arglist(self):
20097db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.execv, 'notepad', ())
20107db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.execv, 'notepad', [])
20117db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.execv, 'notepad', ('',))
20127db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.execv, 'notepad', [''])
20137db96d56Sopenharmony_ci
20147db96d56Sopenharmony_ci    def test_execvpe_with_bad_arglist(self):
20157db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.execvpe, 'notepad', [], None)
20167db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.execvpe, 'notepad', [], {})
20177db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.execvpe, 'notepad', [''], {})
20187db96d56Sopenharmony_ci
20197db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, '_execvpe'),
20207db96d56Sopenharmony_ci                         "No internal os._execvpe function to test.")
20217db96d56Sopenharmony_ci    def _test_internal_execvpe(self, test_type):
20227db96d56Sopenharmony_ci        program_path = os.sep + 'absolutepath'
20237db96d56Sopenharmony_ci        if test_type is bytes:
20247db96d56Sopenharmony_ci            program = b'executable'
20257db96d56Sopenharmony_ci            fullpath = os.path.join(os.fsencode(program_path), program)
20267db96d56Sopenharmony_ci            native_fullpath = fullpath
20277db96d56Sopenharmony_ci            arguments = [b'progname', 'arg1', 'arg2']
20287db96d56Sopenharmony_ci        else:
20297db96d56Sopenharmony_ci            program = 'executable'
20307db96d56Sopenharmony_ci            arguments = ['progname', 'arg1', 'arg2']
20317db96d56Sopenharmony_ci            fullpath = os.path.join(program_path, program)
20327db96d56Sopenharmony_ci            if os.name != "nt":
20337db96d56Sopenharmony_ci                native_fullpath = os.fsencode(fullpath)
20347db96d56Sopenharmony_ci            else:
20357db96d56Sopenharmony_ci                native_fullpath = fullpath
20367db96d56Sopenharmony_ci        env = {'spam': 'beans'}
20377db96d56Sopenharmony_ci
20387db96d56Sopenharmony_ci        # test os._execvpe() with an absolute path
20397db96d56Sopenharmony_ci        with _execvpe_mockup() as calls:
20407db96d56Sopenharmony_ci            self.assertRaises(RuntimeError,
20417db96d56Sopenharmony_ci                os._execvpe, fullpath, arguments)
20427db96d56Sopenharmony_ci            self.assertEqual(len(calls), 1)
20437db96d56Sopenharmony_ci            self.assertEqual(calls[0], ('execv', fullpath, (arguments,)))
20447db96d56Sopenharmony_ci
20457db96d56Sopenharmony_ci        # test os._execvpe() with a relative path:
20467db96d56Sopenharmony_ci        # os.get_exec_path() returns defpath
20477db96d56Sopenharmony_ci        with _execvpe_mockup(defpath=program_path) as calls:
20487db96d56Sopenharmony_ci            self.assertRaises(OSError,
20497db96d56Sopenharmony_ci                os._execvpe, program, arguments, env=env)
20507db96d56Sopenharmony_ci            self.assertEqual(len(calls), 1)
20517db96d56Sopenharmony_ci            self.assertSequenceEqual(calls[0],
20527db96d56Sopenharmony_ci                ('execve', native_fullpath, (arguments, env)))
20537db96d56Sopenharmony_ci
20547db96d56Sopenharmony_ci        # test os._execvpe() with a relative path:
20557db96d56Sopenharmony_ci        # os.get_exec_path() reads the 'PATH' variable
20567db96d56Sopenharmony_ci        with _execvpe_mockup() as calls:
20577db96d56Sopenharmony_ci            env_path = env.copy()
20587db96d56Sopenharmony_ci            if test_type is bytes:
20597db96d56Sopenharmony_ci                env_path[b'PATH'] = program_path
20607db96d56Sopenharmony_ci            else:
20617db96d56Sopenharmony_ci                env_path['PATH'] = program_path
20627db96d56Sopenharmony_ci            self.assertRaises(OSError,
20637db96d56Sopenharmony_ci                os._execvpe, program, arguments, env=env_path)
20647db96d56Sopenharmony_ci            self.assertEqual(len(calls), 1)
20657db96d56Sopenharmony_ci            self.assertSequenceEqual(calls[0],
20667db96d56Sopenharmony_ci                ('execve', native_fullpath, (arguments, env_path)))
20677db96d56Sopenharmony_ci
20687db96d56Sopenharmony_ci    def test_internal_execvpe_str(self):
20697db96d56Sopenharmony_ci        self._test_internal_execvpe(str)
20707db96d56Sopenharmony_ci        if os.name != "nt":
20717db96d56Sopenharmony_ci            self._test_internal_execvpe(bytes)
20727db96d56Sopenharmony_ci
20737db96d56Sopenharmony_ci    def test_execve_invalid_env(self):
20747db96d56Sopenharmony_ci        args = [sys.executable, '-c', 'pass']
20757db96d56Sopenharmony_ci
20767db96d56Sopenharmony_ci        # null character in the environment variable name
20777db96d56Sopenharmony_ci        newenv = os.environ.copy()
20787db96d56Sopenharmony_ci        newenv["FRUIT\0VEGETABLE"] = "cabbage"
20797db96d56Sopenharmony_ci        with self.assertRaises(ValueError):
20807db96d56Sopenharmony_ci            os.execve(args[0], args, newenv)
20817db96d56Sopenharmony_ci
20827db96d56Sopenharmony_ci        # null character in the environment variable value
20837db96d56Sopenharmony_ci        newenv = os.environ.copy()
20847db96d56Sopenharmony_ci        newenv["FRUIT"] = "orange\0VEGETABLE=cabbage"
20857db96d56Sopenharmony_ci        with self.assertRaises(ValueError):
20867db96d56Sopenharmony_ci            os.execve(args[0], args, newenv)
20877db96d56Sopenharmony_ci
20887db96d56Sopenharmony_ci        # equal character in the environment variable name
20897db96d56Sopenharmony_ci        newenv = os.environ.copy()
20907db96d56Sopenharmony_ci        newenv["FRUIT=ORANGE"] = "lemon"
20917db96d56Sopenharmony_ci        with self.assertRaises(ValueError):
20927db96d56Sopenharmony_ci            os.execve(args[0], args, newenv)
20937db96d56Sopenharmony_ci
20947db96d56Sopenharmony_ci    @unittest.skipUnless(sys.platform == "win32", "Win32-specific test")
20957db96d56Sopenharmony_ci    def test_execve_with_empty_path(self):
20967db96d56Sopenharmony_ci        # bpo-32890: Check GetLastError() misuse
20977db96d56Sopenharmony_ci        try:
20987db96d56Sopenharmony_ci            os.execve('', ['arg'], {})
20997db96d56Sopenharmony_ci        except OSError as e:
21007db96d56Sopenharmony_ci            self.assertTrue(e.winerror is None or e.winerror != 0)
21017db96d56Sopenharmony_ci        else:
21027db96d56Sopenharmony_ci            self.fail('No OSError raised')
21037db96d56Sopenharmony_ci
21047db96d56Sopenharmony_ci
21057db96d56Sopenharmony_ci@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
21067db96d56Sopenharmony_ciclass Win32ErrorTests(unittest.TestCase):
21077db96d56Sopenharmony_ci    def setUp(self):
21087db96d56Sopenharmony_ci        try:
21097db96d56Sopenharmony_ci            os.stat(os_helper.TESTFN)
21107db96d56Sopenharmony_ci        except FileNotFoundError:
21117db96d56Sopenharmony_ci            exists = False
21127db96d56Sopenharmony_ci        except OSError as exc:
21137db96d56Sopenharmony_ci            exists = True
21147db96d56Sopenharmony_ci            self.fail("file %s must not exist; os.stat failed with %s"
21157db96d56Sopenharmony_ci                      % (os_helper.TESTFN, exc))
21167db96d56Sopenharmony_ci        else:
21177db96d56Sopenharmony_ci            self.fail("file %s must not exist" % os_helper.TESTFN)
21187db96d56Sopenharmony_ci
21197db96d56Sopenharmony_ci    def test_rename(self):
21207db96d56Sopenharmony_ci        self.assertRaises(OSError, os.rename, os_helper.TESTFN, os_helper.TESTFN+".bak")
21217db96d56Sopenharmony_ci
21227db96d56Sopenharmony_ci    def test_remove(self):
21237db96d56Sopenharmony_ci        self.assertRaises(OSError, os.remove, os_helper.TESTFN)
21247db96d56Sopenharmony_ci
21257db96d56Sopenharmony_ci    def test_chdir(self):
21267db96d56Sopenharmony_ci        self.assertRaises(OSError, os.chdir, os_helper.TESTFN)
21277db96d56Sopenharmony_ci
21287db96d56Sopenharmony_ci    def test_mkdir(self):
21297db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
21307db96d56Sopenharmony_ci
21317db96d56Sopenharmony_ci        with open(os_helper.TESTFN, "x") as f:
21327db96d56Sopenharmony_ci            self.assertRaises(OSError, os.mkdir, os_helper.TESTFN)
21337db96d56Sopenharmony_ci
21347db96d56Sopenharmony_ci    def test_utime(self):
21357db96d56Sopenharmony_ci        self.assertRaises(OSError, os.utime, os_helper.TESTFN, None)
21367db96d56Sopenharmony_ci
21377db96d56Sopenharmony_ci    def test_chmod(self):
21387db96d56Sopenharmony_ci        self.assertRaises(OSError, os.chmod, os_helper.TESTFN, 0)
21397db96d56Sopenharmony_ci
21407db96d56Sopenharmony_ci
21417db96d56Sopenharmony_ci@unittest.skipIf(support.is_wasi, "Cannot create invalid FD on WASI.")
21427db96d56Sopenharmony_ciclass TestInvalidFD(unittest.TestCase):
21437db96d56Sopenharmony_ci    singles = ["fchdir", "dup", "fdatasync", "fstat",
21447db96d56Sopenharmony_ci               "fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
21457db96d56Sopenharmony_ci    #singles.append("close")
21467db96d56Sopenharmony_ci    #We omit close because it doesn't raise an exception on some platforms
21477db96d56Sopenharmony_ci    def get_single(f):
21487db96d56Sopenharmony_ci        def helper(self):
21497db96d56Sopenharmony_ci            if  hasattr(os, f):
21507db96d56Sopenharmony_ci                self.check(getattr(os, f))
21517db96d56Sopenharmony_ci        return helper
21527db96d56Sopenharmony_ci    for f in singles:
21537db96d56Sopenharmony_ci        locals()["test_"+f] = get_single(f)
21547db96d56Sopenharmony_ci
21557db96d56Sopenharmony_ci    def check(self, f, *args, **kwargs):
21567db96d56Sopenharmony_ci        try:
21577db96d56Sopenharmony_ci            f(os_helper.make_bad_fd(), *args, **kwargs)
21587db96d56Sopenharmony_ci        except OSError as e:
21597db96d56Sopenharmony_ci            self.assertEqual(e.errno, errno.EBADF)
21607db96d56Sopenharmony_ci        else:
21617db96d56Sopenharmony_ci            self.fail("%r didn't raise an OSError with a bad file descriptor"
21627db96d56Sopenharmony_ci                      % f)
21637db96d56Sopenharmony_ci
21647db96d56Sopenharmony_ci    def test_fdopen(self):
21657db96d56Sopenharmony_ci        self.check(os.fdopen, encoding="utf-8")
21667db96d56Sopenharmony_ci
21677db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()')
21687db96d56Sopenharmony_ci    def test_isatty(self):
21697db96d56Sopenharmony_ci        self.assertEqual(os.isatty(os_helper.make_bad_fd()), False)
21707db96d56Sopenharmony_ci
21717db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'closerange'), 'test needs os.closerange()')
21727db96d56Sopenharmony_ci    def test_closerange(self):
21737db96d56Sopenharmony_ci        fd = os_helper.make_bad_fd()
21747db96d56Sopenharmony_ci        # Make sure none of the descriptors we are about to close are
21757db96d56Sopenharmony_ci        # currently valid (issue 6542).
21767db96d56Sopenharmony_ci        for i in range(10):
21777db96d56Sopenharmony_ci            try: os.fstat(fd+i)
21787db96d56Sopenharmony_ci            except OSError:
21797db96d56Sopenharmony_ci                pass
21807db96d56Sopenharmony_ci            else:
21817db96d56Sopenharmony_ci                break
21827db96d56Sopenharmony_ci        if i < 2:
21837db96d56Sopenharmony_ci            raise unittest.SkipTest(
21847db96d56Sopenharmony_ci                "Unable to acquire a range of invalid file descriptors")
21857db96d56Sopenharmony_ci        self.assertEqual(os.closerange(fd, fd + i-1), None)
21867db96d56Sopenharmony_ci
21877db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'dup2'), 'test needs os.dup2()')
21887db96d56Sopenharmony_ci    def test_dup2(self):
21897db96d56Sopenharmony_ci        self.check(os.dup2, 20)
21907db96d56Sopenharmony_ci
21917db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'dup2'), 'test needs os.dup2()')
21927db96d56Sopenharmony_ci    @unittest.skipIf(
21937db96d56Sopenharmony_ci        support.is_emscripten,
21947db96d56Sopenharmony_ci        "dup2() with negative fds is broken on Emscripten (see gh-102179)"
21957db96d56Sopenharmony_ci    )
21967db96d56Sopenharmony_ci    def test_dup2_negative_fd(self):
21977db96d56Sopenharmony_ci        valid_fd = os.open(__file__, os.O_RDONLY)
21987db96d56Sopenharmony_ci        self.addCleanup(os.close, valid_fd)
21997db96d56Sopenharmony_ci        fds = [
22007db96d56Sopenharmony_ci            valid_fd,
22017db96d56Sopenharmony_ci            -1,
22027db96d56Sopenharmony_ci            -2**31,
22037db96d56Sopenharmony_ci        ]
22047db96d56Sopenharmony_ci        for fd, fd2 in itertools.product(fds, repeat=2):
22057db96d56Sopenharmony_ci            if fd != fd2:
22067db96d56Sopenharmony_ci                with self.subTest(fd=fd, fd2=fd2):
22077db96d56Sopenharmony_ci                    with self.assertRaises(OSError) as ctx:
22087db96d56Sopenharmony_ci                        os.dup2(fd, fd2)
22097db96d56Sopenharmony_ci                    self.assertEqual(ctx.exception.errno, errno.EBADF)
22107db96d56Sopenharmony_ci
22117db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'fchmod'), 'test needs os.fchmod()')
22127db96d56Sopenharmony_ci    def test_fchmod(self):
22137db96d56Sopenharmony_ci        self.check(os.fchmod, 0)
22147db96d56Sopenharmony_ci
22157db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'fchown'), 'test needs os.fchown()')
22167db96d56Sopenharmony_ci    def test_fchown(self):
22177db96d56Sopenharmony_ci        self.check(os.fchown, -1, -1)
22187db96d56Sopenharmony_ci
22197db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'fpathconf'), 'test needs os.fpathconf()')
22207db96d56Sopenharmony_ci    @unittest.skipIf(
22217db96d56Sopenharmony_ci        support.is_emscripten or support.is_wasi,
22227db96d56Sopenharmony_ci        "musl libc issue on Emscripten/WASI, bpo-46390"
22237db96d56Sopenharmony_ci    )
22247db96d56Sopenharmony_ci    def test_fpathconf(self):
22257db96d56Sopenharmony_ci        self.check(os.pathconf, "PC_NAME_MAX")
22267db96d56Sopenharmony_ci        self.check(os.fpathconf, "PC_NAME_MAX")
22277db96d56Sopenharmony_ci
22287db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()')
22297db96d56Sopenharmony_ci    def test_ftruncate(self):
22307db96d56Sopenharmony_ci        self.check(os.truncate, 0)
22317db96d56Sopenharmony_ci        self.check(os.ftruncate, 0)
22327db96d56Sopenharmony_ci
22337db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'lseek'), 'test needs os.lseek()')
22347db96d56Sopenharmony_ci    def test_lseek(self):
22357db96d56Sopenharmony_ci        self.check(os.lseek, 0, 0)
22367db96d56Sopenharmony_ci
22377db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'read'), 'test needs os.read()')
22387db96d56Sopenharmony_ci    def test_read(self):
22397db96d56Sopenharmony_ci        self.check(os.read, 1)
22407db96d56Sopenharmony_ci
22417db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'readv'), 'test needs os.readv()')
22427db96d56Sopenharmony_ci    def test_readv(self):
22437db96d56Sopenharmony_ci        buf = bytearray(10)
22447db96d56Sopenharmony_ci        self.check(os.readv, [buf])
22457db96d56Sopenharmony_ci
22467db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'tcsetpgrp'), 'test needs os.tcsetpgrp()')
22477db96d56Sopenharmony_ci    def test_tcsetpgrpt(self):
22487db96d56Sopenharmony_ci        self.check(os.tcsetpgrp, 0)
22497db96d56Sopenharmony_ci
22507db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'write'), 'test needs os.write()')
22517db96d56Sopenharmony_ci    def test_write(self):
22527db96d56Sopenharmony_ci        self.check(os.write, b" ")
22537db96d56Sopenharmony_ci
22547db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'writev'), 'test needs os.writev()')
22557db96d56Sopenharmony_ci    def test_writev(self):
22567db96d56Sopenharmony_ci        self.check(os.writev, [b'abc'])
22577db96d56Sopenharmony_ci
22587db96d56Sopenharmony_ci    @support.requires_subprocess()
22597db96d56Sopenharmony_ci    def test_inheritable(self):
22607db96d56Sopenharmony_ci        self.check(os.get_inheritable)
22617db96d56Sopenharmony_ci        self.check(os.set_inheritable, True)
22627db96d56Sopenharmony_ci
22637db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'get_blocking'),
22647db96d56Sopenharmony_ci                         'needs os.get_blocking() and os.set_blocking()')
22657db96d56Sopenharmony_ci    def test_blocking(self):
22667db96d56Sopenharmony_ci        self.check(os.get_blocking)
22677db96d56Sopenharmony_ci        self.check(os.set_blocking, True)
22687db96d56Sopenharmony_ci
22697db96d56Sopenharmony_ci
22707db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'link'), 'requires os.link')
22717db96d56Sopenharmony_ciclass LinkTests(unittest.TestCase):
22727db96d56Sopenharmony_ci    def setUp(self):
22737db96d56Sopenharmony_ci        self.file1 = os_helper.TESTFN
22747db96d56Sopenharmony_ci        self.file2 = os.path.join(os_helper.TESTFN + "2")
22757db96d56Sopenharmony_ci
22767db96d56Sopenharmony_ci    def tearDown(self):
22777db96d56Sopenharmony_ci        for file in (self.file1, self.file2):
22787db96d56Sopenharmony_ci            if os.path.exists(file):
22797db96d56Sopenharmony_ci                os.unlink(file)
22807db96d56Sopenharmony_ci
22817db96d56Sopenharmony_ci    def _test_link(self, file1, file2):
22827db96d56Sopenharmony_ci        create_file(file1)
22837db96d56Sopenharmony_ci
22847db96d56Sopenharmony_ci        try:
22857db96d56Sopenharmony_ci            os.link(file1, file2)
22867db96d56Sopenharmony_ci        except PermissionError as e:
22877db96d56Sopenharmony_ci            self.skipTest('os.link(): %s' % e)
22887db96d56Sopenharmony_ci        with open(file1, "rb") as f1, open(file2, "rb") as f2:
22897db96d56Sopenharmony_ci            self.assertTrue(os.path.sameopenfile(f1.fileno(), f2.fileno()))
22907db96d56Sopenharmony_ci
22917db96d56Sopenharmony_ci    def test_link(self):
22927db96d56Sopenharmony_ci        self._test_link(self.file1, self.file2)
22937db96d56Sopenharmony_ci
22947db96d56Sopenharmony_ci    def test_link_bytes(self):
22957db96d56Sopenharmony_ci        self._test_link(bytes(self.file1, sys.getfilesystemencoding()),
22967db96d56Sopenharmony_ci                        bytes(self.file2, sys.getfilesystemencoding()))
22977db96d56Sopenharmony_ci
22987db96d56Sopenharmony_ci    def test_unicode_name(self):
22997db96d56Sopenharmony_ci        try:
23007db96d56Sopenharmony_ci            os.fsencode("\xf1")
23017db96d56Sopenharmony_ci        except UnicodeError:
23027db96d56Sopenharmony_ci            raise unittest.SkipTest("Unable to encode for this platform.")
23037db96d56Sopenharmony_ci
23047db96d56Sopenharmony_ci        self.file1 += "\xf1"
23057db96d56Sopenharmony_ci        self.file2 = self.file1 + "2"
23067db96d56Sopenharmony_ci        self._test_link(self.file1, self.file2)
23077db96d56Sopenharmony_ci
23087db96d56Sopenharmony_ci@unittest.skipIf(sys.platform == "win32", "Posix specific tests")
23097db96d56Sopenharmony_ciclass PosixUidGidTests(unittest.TestCase):
23107db96d56Sopenharmony_ci    # uid_t and gid_t are 32-bit unsigned integers on Linux
23117db96d56Sopenharmony_ci    UID_OVERFLOW = (1 << 32)
23127db96d56Sopenharmony_ci    GID_OVERFLOW = (1 << 32)
23137db96d56Sopenharmony_ci
23147db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'setuid'), 'test needs os.setuid()')
23157db96d56Sopenharmony_ci    def test_setuid(self):
23167db96d56Sopenharmony_ci        if os.getuid() != 0:
23177db96d56Sopenharmony_ci            self.assertRaises(OSError, os.setuid, 0)
23187db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.setuid, 'not an int')
23197db96d56Sopenharmony_ci        self.assertRaises(OverflowError, os.setuid, self.UID_OVERFLOW)
23207db96d56Sopenharmony_ci
23217db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'setgid'), 'test needs os.setgid()')
23227db96d56Sopenharmony_ci    def test_setgid(self):
23237db96d56Sopenharmony_ci        if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
23247db96d56Sopenharmony_ci            self.assertRaises(OSError, os.setgid, 0)
23257db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.setgid, 'not an int')
23267db96d56Sopenharmony_ci        self.assertRaises(OverflowError, os.setgid, self.GID_OVERFLOW)
23277db96d56Sopenharmony_ci
23287db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'seteuid'), 'test needs os.seteuid()')
23297db96d56Sopenharmony_ci    def test_seteuid(self):
23307db96d56Sopenharmony_ci        if os.getuid() != 0:
23317db96d56Sopenharmony_ci            self.assertRaises(OSError, os.seteuid, 0)
23327db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.setegid, 'not an int')
23337db96d56Sopenharmony_ci        self.assertRaises(OverflowError, os.seteuid, self.UID_OVERFLOW)
23347db96d56Sopenharmony_ci
23357db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'setegid'), 'test needs os.setegid()')
23367db96d56Sopenharmony_ci    def test_setegid(self):
23377db96d56Sopenharmony_ci        if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
23387db96d56Sopenharmony_ci            self.assertRaises(OSError, os.setegid, 0)
23397db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.setegid, 'not an int')
23407db96d56Sopenharmony_ci        self.assertRaises(OverflowError, os.setegid, self.GID_OVERFLOW)
23417db96d56Sopenharmony_ci
23427db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
23437db96d56Sopenharmony_ci    def test_setreuid(self):
23447db96d56Sopenharmony_ci        if os.getuid() != 0:
23457db96d56Sopenharmony_ci            self.assertRaises(OSError, os.setreuid, 0, 0)
23467db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.setreuid, 'not an int', 0)
23477db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.setreuid, 0, 'not an int')
23487db96d56Sopenharmony_ci        self.assertRaises(OverflowError, os.setreuid, self.UID_OVERFLOW, 0)
23497db96d56Sopenharmony_ci        self.assertRaises(OverflowError, os.setreuid, 0, self.UID_OVERFLOW)
23507db96d56Sopenharmony_ci
23517db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()')
23527db96d56Sopenharmony_ci    @support.requires_subprocess()
23537db96d56Sopenharmony_ci    def test_setreuid_neg1(self):
23547db96d56Sopenharmony_ci        # Needs to accept -1.  We run this in a subprocess to avoid
23557db96d56Sopenharmony_ci        # altering the test runner's process state (issue8045).
23567db96d56Sopenharmony_ci        subprocess.check_call([
23577db96d56Sopenharmony_ci                sys.executable, '-c',
23587db96d56Sopenharmony_ci                'import os,sys;os.setreuid(-1,-1);sys.exit(0)'])
23597db96d56Sopenharmony_ci
23607db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()')
23617db96d56Sopenharmony_ci    @support.requires_subprocess()
23627db96d56Sopenharmony_ci    def test_setregid(self):
23637db96d56Sopenharmony_ci        if os.getuid() != 0 and not HAVE_WHEEL_GROUP:
23647db96d56Sopenharmony_ci            self.assertRaises(OSError, os.setregid, 0, 0)
23657db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.setregid, 'not an int', 0)
23667db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.setregid, 0, 'not an int')
23677db96d56Sopenharmony_ci        self.assertRaises(OverflowError, os.setregid, self.GID_OVERFLOW, 0)
23687db96d56Sopenharmony_ci        self.assertRaises(OverflowError, os.setregid, 0, self.GID_OVERFLOW)
23697db96d56Sopenharmony_ci
23707db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'setregid'), 'test needs os.setregid()')
23717db96d56Sopenharmony_ci    @support.requires_subprocess()
23727db96d56Sopenharmony_ci    def test_setregid_neg1(self):
23737db96d56Sopenharmony_ci        # Needs to accept -1.  We run this in a subprocess to avoid
23747db96d56Sopenharmony_ci        # altering the test runner's process state (issue8045).
23757db96d56Sopenharmony_ci        subprocess.check_call([
23767db96d56Sopenharmony_ci                sys.executable, '-c',
23777db96d56Sopenharmony_ci                'import os,sys;os.setregid(-1,-1);sys.exit(0)'])
23787db96d56Sopenharmony_ci
23797db96d56Sopenharmony_ci@unittest.skipIf(sys.platform == "win32", "Posix specific tests")
23807db96d56Sopenharmony_ciclass Pep383Tests(unittest.TestCase):
23817db96d56Sopenharmony_ci    def setUp(self):
23827db96d56Sopenharmony_ci        if os_helper.TESTFN_UNENCODABLE:
23837db96d56Sopenharmony_ci            self.dir = os_helper.TESTFN_UNENCODABLE
23847db96d56Sopenharmony_ci        elif os_helper.TESTFN_NONASCII:
23857db96d56Sopenharmony_ci            self.dir = os_helper.TESTFN_NONASCII
23867db96d56Sopenharmony_ci        else:
23877db96d56Sopenharmony_ci            self.dir = os_helper.TESTFN
23887db96d56Sopenharmony_ci        self.bdir = os.fsencode(self.dir)
23897db96d56Sopenharmony_ci
23907db96d56Sopenharmony_ci        bytesfn = []
23917db96d56Sopenharmony_ci        def add_filename(fn):
23927db96d56Sopenharmony_ci            try:
23937db96d56Sopenharmony_ci                fn = os.fsencode(fn)
23947db96d56Sopenharmony_ci            except UnicodeEncodeError:
23957db96d56Sopenharmony_ci                return
23967db96d56Sopenharmony_ci            bytesfn.append(fn)
23977db96d56Sopenharmony_ci        add_filename(os_helper.TESTFN_UNICODE)
23987db96d56Sopenharmony_ci        if os_helper.TESTFN_UNENCODABLE:
23997db96d56Sopenharmony_ci            add_filename(os_helper.TESTFN_UNENCODABLE)
24007db96d56Sopenharmony_ci        if os_helper.TESTFN_NONASCII:
24017db96d56Sopenharmony_ci            add_filename(os_helper.TESTFN_NONASCII)
24027db96d56Sopenharmony_ci        if not bytesfn:
24037db96d56Sopenharmony_ci            self.skipTest("couldn't create any non-ascii filename")
24047db96d56Sopenharmony_ci
24057db96d56Sopenharmony_ci        self.unicodefn = set()
24067db96d56Sopenharmony_ci        os.mkdir(self.dir)
24077db96d56Sopenharmony_ci        try:
24087db96d56Sopenharmony_ci            for fn in bytesfn:
24097db96d56Sopenharmony_ci                os_helper.create_empty_file(os.path.join(self.bdir, fn))
24107db96d56Sopenharmony_ci                fn = os.fsdecode(fn)
24117db96d56Sopenharmony_ci                if fn in self.unicodefn:
24127db96d56Sopenharmony_ci                    raise ValueError("duplicate filename")
24137db96d56Sopenharmony_ci                self.unicodefn.add(fn)
24147db96d56Sopenharmony_ci        except:
24157db96d56Sopenharmony_ci            shutil.rmtree(self.dir)
24167db96d56Sopenharmony_ci            raise
24177db96d56Sopenharmony_ci
24187db96d56Sopenharmony_ci    def tearDown(self):
24197db96d56Sopenharmony_ci        shutil.rmtree(self.dir)
24207db96d56Sopenharmony_ci
24217db96d56Sopenharmony_ci    def test_listdir(self):
24227db96d56Sopenharmony_ci        expected = self.unicodefn
24237db96d56Sopenharmony_ci        found = set(os.listdir(self.dir))
24247db96d56Sopenharmony_ci        self.assertEqual(found, expected)
24257db96d56Sopenharmony_ci        # test listdir without arguments
24267db96d56Sopenharmony_ci        current_directory = os.getcwd()
24277db96d56Sopenharmony_ci        try:
24287db96d56Sopenharmony_ci            os.chdir(os.sep)
24297db96d56Sopenharmony_ci            self.assertEqual(set(os.listdir()), set(os.listdir(os.sep)))
24307db96d56Sopenharmony_ci        finally:
24317db96d56Sopenharmony_ci            os.chdir(current_directory)
24327db96d56Sopenharmony_ci
24337db96d56Sopenharmony_ci    def test_open(self):
24347db96d56Sopenharmony_ci        for fn in self.unicodefn:
24357db96d56Sopenharmony_ci            f = open(os.path.join(self.dir, fn), 'rb')
24367db96d56Sopenharmony_ci            f.close()
24377db96d56Sopenharmony_ci
24387db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'statvfs'),
24397db96d56Sopenharmony_ci                            "need os.statvfs()")
24407db96d56Sopenharmony_ci    def test_statvfs(self):
24417db96d56Sopenharmony_ci        # issue #9645
24427db96d56Sopenharmony_ci        for fn in self.unicodefn:
24437db96d56Sopenharmony_ci            # should not fail with file not found error
24447db96d56Sopenharmony_ci            fullname = os.path.join(self.dir, fn)
24457db96d56Sopenharmony_ci            os.statvfs(fullname)
24467db96d56Sopenharmony_ci
24477db96d56Sopenharmony_ci    def test_stat(self):
24487db96d56Sopenharmony_ci        for fn in self.unicodefn:
24497db96d56Sopenharmony_ci            os.stat(os.path.join(self.dir, fn))
24507db96d56Sopenharmony_ci
24517db96d56Sopenharmony_ci@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
24527db96d56Sopenharmony_ciclass Win32KillTests(unittest.TestCase):
24537db96d56Sopenharmony_ci    def _kill(self, sig):
24547db96d56Sopenharmony_ci        # Start sys.executable as a subprocess and communicate from the
24557db96d56Sopenharmony_ci        # subprocess to the parent that the interpreter is ready. When it
24567db96d56Sopenharmony_ci        # becomes ready, send *sig* via os.kill to the subprocess and check
24577db96d56Sopenharmony_ci        # that the return code is equal to *sig*.
24587db96d56Sopenharmony_ci        import ctypes
24597db96d56Sopenharmony_ci        from ctypes import wintypes
24607db96d56Sopenharmony_ci        import msvcrt
24617db96d56Sopenharmony_ci
24627db96d56Sopenharmony_ci        # Since we can't access the contents of the process' stdout until the
24637db96d56Sopenharmony_ci        # process has exited, use PeekNamedPipe to see what's inside stdout
24647db96d56Sopenharmony_ci        # without waiting. This is done so we can tell that the interpreter
24657db96d56Sopenharmony_ci        # is started and running at a point where it could handle a signal.
24667db96d56Sopenharmony_ci        PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe
24677db96d56Sopenharmony_ci        PeekNamedPipe.restype = wintypes.BOOL
24687db96d56Sopenharmony_ci        PeekNamedPipe.argtypes = (wintypes.HANDLE, # Pipe handle
24697db96d56Sopenharmony_ci                                  ctypes.POINTER(ctypes.c_char), # stdout buf
24707db96d56Sopenharmony_ci                                  wintypes.DWORD, # Buffer size
24717db96d56Sopenharmony_ci                                  ctypes.POINTER(wintypes.DWORD), # bytes read
24727db96d56Sopenharmony_ci                                  ctypes.POINTER(wintypes.DWORD), # bytes avail
24737db96d56Sopenharmony_ci                                  ctypes.POINTER(wintypes.DWORD)) # bytes left
24747db96d56Sopenharmony_ci        msg = "running"
24757db96d56Sopenharmony_ci        proc = subprocess.Popen([sys.executable, "-c",
24767db96d56Sopenharmony_ci                                 "import sys;"
24777db96d56Sopenharmony_ci                                 "sys.stdout.write('{}');"
24787db96d56Sopenharmony_ci                                 "sys.stdout.flush();"
24797db96d56Sopenharmony_ci                                 "input()".format(msg)],
24807db96d56Sopenharmony_ci                                stdout=subprocess.PIPE,
24817db96d56Sopenharmony_ci                                stderr=subprocess.PIPE,
24827db96d56Sopenharmony_ci                                stdin=subprocess.PIPE)
24837db96d56Sopenharmony_ci        self.addCleanup(proc.stdout.close)
24847db96d56Sopenharmony_ci        self.addCleanup(proc.stderr.close)
24857db96d56Sopenharmony_ci        self.addCleanup(proc.stdin.close)
24867db96d56Sopenharmony_ci
24877db96d56Sopenharmony_ci        count, max = 0, 100
24887db96d56Sopenharmony_ci        while count < max and proc.poll() is None:
24897db96d56Sopenharmony_ci            # Create a string buffer to store the result of stdout from the pipe
24907db96d56Sopenharmony_ci            buf = ctypes.create_string_buffer(len(msg))
24917db96d56Sopenharmony_ci            # Obtain the text currently in proc.stdout
24927db96d56Sopenharmony_ci            # Bytes read/avail/left are left as NULL and unused
24937db96d56Sopenharmony_ci            rslt = PeekNamedPipe(msvcrt.get_osfhandle(proc.stdout.fileno()),
24947db96d56Sopenharmony_ci                                 buf, ctypes.sizeof(buf), None, None, None)
24957db96d56Sopenharmony_ci            self.assertNotEqual(rslt, 0, "PeekNamedPipe failed")
24967db96d56Sopenharmony_ci            if buf.value:
24977db96d56Sopenharmony_ci                self.assertEqual(msg, buf.value.decode())
24987db96d56Sopenharmony_ci                break
24997db96d56Sopenharmony_ci            time.sleep(0.1)
25007db96d56Sopenharmony_ci            count += 1
25017db96d56Sopenharmony_ci        else:
25027db96d56Sopenharmony_ci            self.fail("Did not receive communication from the subprocess")
25037db96d56Sopenharmony_ci
25047db96d56Sopenharmony_ci        os.kill(proc.pid, sig)
25057db96d56Sopenharmony_ci        self.assertEqual(proc.wait(), sig)
25067db96d56Sopenharmony_ci
25077db96d56Sopenharmony_ci    def test_kill_sigterm(self):
25087db96d56Sopenharmony_ci        # SIGTERM doesn't mean anything special, but make sure it works
25097db96d56Sopenharmony_ci        self._kill(signal.SIGTERM)
25107db96d56Sopenharmony_ci
25117db96d56Sopenharmony_ci    def test_kill_int(self):
25127db96d56Sopenharmony_ci        # os.kill on Windows can take an int which gets set as the exit code
25137db96d56Sopenharmony_ci        self._kill(100)
25147db96d56Sopenharmony_ci
25157db96d56Sopenharmony_ci    @unittest.skipIf(mmap is None, "requires mmap")
25167db96d56Sopenharmony_ci    def _kill_with_event(self, event, name):
25177db96d56Sopenharmony_ci        tagname = "test_os_%s" % uuid.uuid1()
25187db96d56Sopenharmony_ci        m = mmap.mmap(-1, 1, tagname)
25197db96d56Sopenharmony_ci        m[0] = 0
25207db96d56Sopenharmony_ci        # Run a script which has console control handling enabled.
25217db96d56Sopenharmony_ci        proc = subprocess.Popen([sys.executable,
25227db96d56Sopenharmony_ci                   os.path.join(os.path.dirname(__file__),
25237db96d56Sopenharmony_ci                                "win_console_handler.py"), tagname],
25247db96d56Sopenharmony_ci                   creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
25257db96d56Sopenharmony_ci        # Let the interpreter startup before we send signals. See #3137.
25267db96d56Sopenharmony_ci        count, max = 0, 100
25277db96d56Sopenharmony_ci        while count < max and proc.poll() is None:
25287db96d56Sopenharmony_ci            if m[0] == 1:
25297db96d56Sopenharmony_ci                break
25307db96d56Sopenharmony_ci            time.sleep(0.1)
25317db96d56Sopenharmony_ci            count += 1
25327db96d56Sopenharmony_ci        else:
25337db96d56Sopenharmony_ci            # Forcefully kill the process if we weren't able to signal it.
25347db96d56Sopenharmony_ci            os.kill(proc.pid, signal.SIGINT)
25357db96d56Sopenharmony_ci            self.fail("Subprocess didn't finish initialization")
25367db96d56Sopenharmony_ci        os.kill(proc.pid, event)
25377db96d56Sopenharmony_ci        # proc.send_signal(event) could also be done here.
25387db96d56Sopenharmony_ci        # Allow time for the signal to be passed and the process to exit.
25397db96d56Sopenharmony_ci        time.sleep(0.5)
25407db96d56Sopenharmony_ci        if not proc.poll():
25417db96d56Sopenharmony_ci            # Forcefully kill the process if we weren't able to signal it.
25427db96d56Sopenharmony_ci            os.kill(proc.pid, signal.SIGINT)
25437db96d56Sopenharmony_ci            self.fail("subprocess did not stop on {}".format(name))
25447db96d56Sopenharmony_ci
25457db96d56Sopenharmony_ci    @unittest.skip("subprocesses aren't inheriting Ctrl+C property")
25467db96d56Sopenharmony_ci    @support.requires_subprocess()
25477db96d56Sopenharmony_ci    def test_CTRL_C_EVENT(self):
25487db96d56Sopenharmony_ci        from ctypes import wintypes
25497db96d56Sopenharmony_ci        import ctypes
25507db96d56Sopenharmony_ci
25517db96d56Sopenharmony_ci        # Make a NULL value by creating a pointer with no argument.
25527db96d56Sopenharmony_ci        NULL = ctypes.POINTER(ctypes.c_int)()
25537db96d56Sopenharmony_ci        SetConsoleCtrlHandler = ctypes.windll.kernel32.SetConsoleCtrlHandler
25547db96d56Sopenharmony_ci        SetConsoleCtrlHandler.argtypes = (ctypes.POINTER(ctypes.c_int),
25557db96d56Sopenharmony_ci                                          wintypes.BOOL)
25567db96d56Sopenharmony_ci        SetConsoleCtrlHandler.restype = wintypes.BOOL
25577db96d56Sopenharmony_ci
25587db96d56Sopenharmony_ci        # Calling this with NULL and FALSE causes the calling process to
25597db96d56Sopenharmony_ci        # handle Ctrl+C, rather than ignore it. This property is inherited
25607db96d56Sopenharmony_ci        # by subprocesses.
25617db96d56Sopenharmony_ci        SetConsoleCtrlHandler(NULL, 0)
25627db96d56Sopenharmony_ci
25637db96d56Sopenharmony_ci        self._kill_with_event(signal.CTRL_C_EVENT, "CTRL_C_EVENT")
25647db96d56Sopenharmony_ci
25657db96d56Sopenharmony_ci    @support.requires_subprocess()
25667db96d56Sopenharmony_ci    def test_CTRL_BREAK_EVENT(self):
25677db96d56Sopenharmony_ci        self._kill_with_event(signal.CTRL_BREAK_EVENT, "CTRL_BREAK_EVENT")
25687db96d56Sopenharmony_ci
25697db96d56Sopenharmony_ci
25707db96d56Sopenharmony_ci@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
25717db96d56Sopenharmony_ciclass Win32ListdirTests(unittest.TestCase):
25727db96d56Sopenharmony_ci    """Test listdir on Windows."""
25737db96d56Sopenharmony_ci
25747db96d56Sopenharmony_ci    def setUp(self):
25757db96d56Sopenharmony_ci        self.created_paths = []
25767db96d56Sopenharmony_ci        for i in range(2):
25777db96d56Sopenharmony_ci            dir_name = 'SUB%d' % i
25787db96d56Sopenharmony_ci            dir_path = os.path.join(os_helper.TESTFN, dir_name)
25797db96d56Sopenharmony_ci            file_name = 'FILE%d' % i
25807db96d56Sopenharmony_ci            file_path = os.path.join(os_helper.TESTFN, file_name)
25817db96d56Sopenharmony_ci            os.makedirs(dir_path)
25827db96d56Sopenharmony_ci            with open(file_path, 'w', encoding='utf-8') as f:
25837db96d56Sopenharmony_ci                f.write("I'm %s and proud of it. Blame test_os.\n" % file_path)
25847db96d56Sopenharmony_ci            self.created_paths.extend([dir_name, file_name])
25857db96d56Sopenharmony_ci        self.created_paths.sort()
25867db96d56Sopenharmony_ci
25877db96d56Sopenharmony_ci    def tearDown(self):
25887db96d56Sopenharmony_ci        shutil.rmtree(os_helper.TESTFN)
25897db96d56Sopenharmony_ci
25907db96d56Sopenharmony_ci    def test_listdir_no_extended_path(self):
25917db96d56Sopenharmony_ci        """Test when the path is not an "extended" path."""
25927db96d56Sopenharmony_ci        # unicode
25937db96d56Sopenharmony_ci        self.assertEqual(
25947db96d56Sopenharmony_ci                sorted(os.listdir(os_helper.TESTFN)),
25957db96d56Sopenharmony_ci                self.created_paths)
25967db96d56Sopenharmony_ci
25977db96d56Sopenharmony_ci        # bytes
25987db96d56Sopenharmony_ci        self.assertEqual(
25997db96d56Sopenharmony_ci                sorted(os.listdir(os.fsencode(os_helper.TESTFN))),
26007db96d56Sopenharmony_ci                [os.fsencode(path) for path in self.created_paths])
26017db96d56Sopenharmony_ci
26027db96d56Sopenharmony_ci    def test_listdir_extended_path(self):
26037db96d56Sopenharmony_ci        """Test when the path starts with '\\\\?\\'."""
26047db96d56Sopenharmony_ci        # See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
26057db96d56Sopenharmony_ci        # unicode
26067db96d56Sopenharmony_ci        path = '\\\\?\\' + os.path.abspath(os_helper.TESTFN)
26077db96d56Sopenharmony_ci        self.assertEqual(
26087db96d56Sopenharmony_ci                sorted(os.listdir(path)),
26097db96d56Sopenharmony_ci                self.created_paths)
26107db96d56Sopenharmony_ci
26117db96d56Sopenharmony_ci        # bytes
26127db96d56Sopenharmony_ci        path = b'\\\\?\\' + os.fsencode(os.path.abspath(os_helper.TESTFN))
26137db96d56Sopenharmony_ci        self.assertEqual(
26147db96d56Sopenharmony_ci                sorted(os.listdir(path)),
26157db96d56Sopenharmony_ci                [os.fsencode(path) for path in self.created_paths])
26167db96d56Sopenharmony_ci
26177db96d56Sopenharmony_ci
26187db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'readlink'), 'needs os.readlink()')
26197db96d56Sopenharmony_ciclass ReadlinkTests(unittest.TestCase):
26207db96d56Sopenharmony_ci    filelink = 'readlinktest'
26217db96d56Sopenharmony_ci    filelink_target = os.path.abspath(__file__)
26227db96d56Sopenharmony_ci    filelinkb = os.fsencode(filelink)
26237db96d56Sopenharmony_ci    filelinkb_target = os.fsencode(filelink_target)
26247db96d56Sopenharmony_ci
26257db96d56Sopenharmony_ci    def assertPathEqual(self, left, right):
26267db96d56Sopenharmony_ci        left = os.path.normcase(left)
26277db96d56Sopenharmony_ci        right = os.path.normcase(right)
26287db96d56Sopenharmony_ci        if sys.platform == 'win32':
26297db96d56Sopenharmony_ci            # Bad practice to blindly strip the prefix as it may be required to
26307db96d56Sopenharmony_ci            # correctly refer to the file, but we're only comparing paths here.
26317db96d56Sopenharmony_ci            has_prefix = lambda p: p.startswith(
26327db96d56Sopenharmony_ci                b'\\\\?\\' if isinstance(p, bytes) else '\\\\?\\')
26337db96d56Sopenharmony_ci            if has_prefix(left):
26347db96d56Sopenharmony_ci                left = left[4:]
26357db96d56Sopenharmony_ci            if has_prefix(right):
26367db96d56Sopenharmony_ci                right = right[4:]
26377db96d56Sopenharmony_ci        self.assertEqual(left, right)
26387db96d56Sopenharmony_ci
26397db96d56Sopenharmony_ci    def setUp(self):
26407db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(self.filelink_target))
26417db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(self.filelinkb_target))
26427db96d56Sopenharmony_ci        self.assertFalse(os.path.exists(self.filelink))
26437db96d56Sopenharmony_ci        self.assertFalse(os.path.exists(self.filelinkb))
26447db96d56Sopenharmony_ci
26457db96d56Sopenharmony_ci    def test_not_symlink(self):
26467db96d56Sopenharmony_ci        filelink_target = FakePath(self.filelink_target)
26477db96d56Sopenharmony_ci        self.assertRaises(OSError, os.readlink, self.filelink_target)
26487db96d56Sopenharmony_ci        self.assertRaises(OSError, os.readlink, filelink_target)
26497db96d56Sopenharmony_ci
26507db96d56Sopenharmony_ci    def test_missing_link(self):
26517db96d56Sopenharmony_ci        self.assertRaises(FileNotFoundError, os.readlink, 'missing-link')
26527db96d56Sopenharmony_ci        self.assertRaises(FileNotFoundError, os.readlink,
26537db96d56Sopenharmony_ci                          FakePath('missing-link'))
26547db96d56Sopenharmony_ci
26557db96d56Sopenharmony_ci    @os_helper.skip_unless_symlink
26567db96d56Sopenharmony_ci    def test_pathlike(self):
26577db96d56Sopenharmony_ci        os.symlink(self.filelink_target, self.filelink)
26587db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, self.filelink)
26597db96d56Sopenharmony_ci        filelink = FakePath(self.filelink)
26607db96d56Sopenharmony_ci        self.assertPathEqual(os.readlink(filelink), self.filelink_target)
26617db96d56Sopenharmony_ci
26627db96d56Sopenharmony_ci    @os_helper.skip_unless_symlink
26637db96d56Sopenharmony_ci    def test_pathlike_bytes(self):
26647db96d56Sopenharmony_ci        os.symlink(self.filelinkb_target, self.filelinkb)
26657db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, self.filelinkb)
26667db96d56Sopenharmony_ci        path = os.readlink(FakePath(self.filelinkb))
26677db96d56Sopenharmony_ci        self.assertPathEqual(path, self.filelinkb_target)
26687db96d56Sopenharmony_ci        self.assertIsInstance(path, bytes)
26697db96d56Sopenharmony_ci
26707db96d56Sopenharmony_ci    @os_helper.skip_unless_symlink
26717db96d56Sopenharmony_ci    def test_bytes(self):
26727db96d56Sopenharmony_ci        os.symlink(self.filelinkb_target, self.filelinkb)
26737db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, self.filelinkb)
26747db96d56Sopenharmony_ci        path = os.readlink(self.filelinkb)
26757db96d56Sopenharmony_ci        self.assertPathEqual(path, self.filelinkb_target)
26767db96d56Sopenharmony_ci        self.assertIsInstance(path, bytes)
26777db96d56Sopenharmony_ci
26787db96d56Sopenharmony_ci
26797db96d56Sopenharmony_ci@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
26807db96d56Sopenharmony_ci@os_helper.skip_unless_symlink
26817db96d56Sopenharmony_ciclass Win32SymlinkTests(unittest.TestCase):
26827db96d56Sopenharmony_ci    filelink = 'filelinktest'
26837db96d56Sopenharmony_ci    filelink_target = os.path.abspath(__file__)
26847db96d56Sopenharmony_ci    dirlink = 'dirlinktest'
26857db96d56Sopenharmony_ci    dirlink_target = os.path.dirname(filelink_target)
26867db96d56Sopenharmony_ci    missing_link = 'missing link'
26877db96d56Sopenharmony_ci
26887db96d56Sopenharmony_ci    def setUp(self):
26897db96d56Sopenharmony_ci        assert os.path.exists(self.dirlink_target)
26907db96d56Sopenharmony_ci        assert os.path.exists(self.filelink_target)
26917db96d56Sopenharmony_ci        assert not os.path.exists(self.dirlink)
26927db96d56Sopenharmony_ci        assert not os.path.exists(self.filelink)
26937db96d56Sopenharmony_ci        assert not os.path.exists(self.missing_link)
26947db96d56Sopenharmony_ci
26957db96d56Sopenharmony_ci    def tearDown(self):
26967db96d56Sopenharmony_ci        if os.path.exists(self.filelink):
26977db96d56Sopenharmony_ci            os.remove(self.filelink)
26987db96d56Sopenharmony_ci        if os.path.exists(self.dirlink):
26997db96d56Sopenharmony_ci            os.rmdir(self.dirlink)
27007db96d56Sopenharmony_ci        if os.path.lexists(self.missing_link):
27017db96d56Sopenharmony_ci            os.remove(self.missing_link)
27027db96d56Sopenharmony_ci
27037db96d56Sopenharmony_ci    def test_directory_link(self):
27047db96d56Sopenharmony_ci        os.symlink(self.dirlink_target, self.dirlink)
27057db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(self.dirlink))
27067db96d56Sopenharmony_ci        self.assertTrue(os.path.isdir(self.dirlink))
27077db96d56Sopenharmony_ci        self.assertTrue(os.path.islink(self.dirlink))
27087db96d56Sopenharmony_ci        self.check_stat(self.dirlink, self.dirlink_target)
27097db96d56Sopenharmony_ci
27107db96d56Sopenharmony_ci    def test_file_link(self):
27117db96d56Sopenharmony_ci        os.symlink(self.filelink_target, self.filelink)
27127db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(self.filelink))
27137db96d56Sopenharmony_ci        self.assertTrue(os.path.isfile(self.filelink))
27147db96d56Sopenharmony_ci        self.assertTrue(os.path.islink(self.filelink))
27157db96d56Sopenharmony_ci        self.check_stat(self.filelink, self.filelink_target)
27167db96d56Sopenharmony_ci
27177db96d56Sopenharmony_ci    def _create_missing_dir_link(self):
27187db96d56Sopenharmony_ci        'Create a "directory" link to a non-existent target'
27197db96d56Sopenharmony_ci        linkname = self.missing_link
27207db96d56Sopenharmony_ci        if os.path.lexists(linkname):
27217db96d56Sopenharmony_ci            os.remove(linkname)
27227db96d56Sopenharmony_ci        target = r'c:\\target does not exist.29r3c740'
27237db96d56Sopenharmony_ci        assert not os.path.exists(target)
27247db96d56Sopenharmony_ci        target_is_dir = True
27257db96d56Sopenharmony_ci        os.symlink(target, linkname, target_is_dir)
27267db96d56Sopenharmony_ci
27277db96d56Sopenharmony_ci    def test_remove_directory_link_to_missing_target(self):
27287db96d56Sopenharmony_ci        self._create_missing_dir_link()
27297db96d56Sopenharmony_ci        # For compatibility with Unix, os.remove will check the
27307db96d56Sopenharmony_ci        #  directory status and call RemoveDirectory if the symlink
27317db96d56Sopenharmony_ci        #  was created with target_is_dir==True.
27327db96d56Sopenharmony_ci        os.remove(self.missing_link)
27337db96d56Sopenharmony_ci
27347db96d56Sopenharmony_ci    def test_isdir_on_directory_link_to_missing_target(self):
27357db96d56Sopenharmony_ci        self._create_missing_dir_link()
27367db96d56Sopenharmony_ci        self.assertFalse(os.path.isdir(self.missing_link))
27377db96d56Sopenharmony_ci
27387db96d56Sopenharmony_ci    def test_rmdir_on_directory_link_to_missing_target(self):
27397db96d56Sopenharmony_ci        self._create_missing_dir_link()
27407db96d56Sopenharmony_ci        os.rmdir(self.missing_link)
27417db96d56Sopenharmony_ci
27427db96d56Sopenharmony_ci    def check_stat(self, link, target):
27437db96d56Sopenharmony_ci        self.assertEqual(os.stat(link), os.stat(target))
27447db96d56Sopenharmony_ci        self.assertNotEqual(os.lstat(link), os.stat(link))
27457db96d56Sopenharmony_ci
27467db96d56Sopenharmony_ci        bytes_link = os.fsencode(link)
27477db96d56Sopenharmony_ci        self.assertEqual(os.stat(bytes_link), os.stat(target))
27487db96d56Sopenharmony_ci        self.assertNotEqual(os.lstat(bytes_link), os.stat(bytes_link))
27497db96d56Sopenharmony_ci
27507db96d56Sopenharmony_ci    def test_12084(self):
27517db96d56Sopenharmony_ci        level1 = os.path.abspath(os_helper.TESTFN)
27527db96d56Sopenharmony_ci        level2 = os.path.join(level1, "level2")
27537db96d56Sopenharmony_ci        level3 = os.path.join(level2, "level3")
27547db96d56Sopenharmony_ci        self.addCleanup(os_helper.rmtree, level1)
27557db96d56Sopenharmony_ci
27567db96d56Sopenharmony_ci        os.mkdir(level1)
27577db96d56Sopenharmony_ci        os.mkdir(level2)
27587db96d56Sopenharmony_ci        os.mkdir(level3)
27597db96d56Sopenharmony_ci
27607db96d56Sopenharmony_ci        file1 = os.path.abspath(os.path.join(level1, "file1"))
27617db96d56Sopenharmony_ci        create_file(file1)
27627db96d56Sopenharmony_ci
27637db96d56Sopenharmony_ci        orig_dir = os.getcwd()
27647db96d56Sopenharmony_ci        try:
27657db96d56Sopenharmony_ci            os.chdir(level2)
27667db96d56Sopenharmony_ci            link = os.path.join(level2, "link")
27677db96d56Sopenharmony_ci            os.symlink(os.path.relpath(file1), "link")
27687db96d56Sopenharmony_ci            self.assertIn("link", os.listdir(os.getcwd()))
27697db96d56Sopenharmony_ci
27707db96d56Sopenharmony_ci            # Check os.stat calls from the same dir as the link
27717db96d56Sopenharmony_ci            self.assertEqual(os.stat(file1), os.stat("link"))
27727db96d56Sopenharmony_ci
27737db96d56Sopenharmony_ci            # Check os.stat calls from a dir below the link
27747db96d56Sopenharmony_ci            os.chdir(level1)
27757db96d56Sopenharmony_ci            self.assertEqual(os.stat(file1),
27767db96d56Sopenharmony_ci                             os.stat(os.path.relpath(link)))
27777db96d56Sopenharmony_ci
27787db96d56Sopenharmony_ci            # Check os.stat calls from a dir above the link
27797db96d56Sopenharmony_ci            os.chdir(level3)
27807db96d56Sopenharmony_ci            self.assertEqual(os.stat(file1),
27817db96d56Sopenharmony_ci                             os.stat(os.path.relpath(link)))
27827db96d56Sopenharmony_ci        finally:
27837db96d56Sopenharmony_ci            os.chdir(orig_dir)
27847db96d56Sopenharmony_ci
27857db96d56Sopenharmony_ci    @unittest.skipUnless(os.path.lexists(r'C:\Users\All Users')
27867db96d56Sopenharmony_ci                            and os.path.exists(r'C:\ProgramData'),
27877db96d56Sopenharmony_ci                            'Test directories not found')
27887db96d56Sopenharmony_ci    def test_29248(self):
27897db96d56Sopenharmony_ci        # os.symlink() calls CreateSymbolicLink, which creates
27907db96d56Sopenharmony_ci        # the reparse data buffer with the print name stored
27917db96d56Sopenharmony_ci        # first, so the offset is always 0. CreateSymbolicLink
27927db96d56Sopenharmony_ci        # stores the "PrintName" DOS path (e.g. "C:\") first,
27937db96d56Sopenharmony_ci        # with an offset of 0, followed by the "SubstituteName"
27947db96d56Sopenharmony_ci        # NT path (e.g. "\??\C:\"). The "All Users" link, on
27957db96d56Sopenharmony_ci        # the other hand, seems to have been created manually
27967db96d56Sopenharmony_ci        # with an inverted order.
27977db96d56Sopenharmony_ci        target = os.readlink(r'C:\Users\All Users')
27987db96d56Sopenharmony_ci        self.assertTrue(os.path.samefile(target, r'C:\ProgramData'))
27997db96d56Sopenharmony_ci
28007db96d56Sopenharmony_ci    def test_buffer_overflow(self):
28017db96d56Sopenharmony_ci        # Older versions would have a buffer overflow when detecting
28027db96d56Sopenharmony_ci        # whether a link source was a directory. This test ensures we
28037db96d56Sopenharmony_ci        # no longer crash, but does not otherwise validate the behavior
28047db96d56Sopenharmony_ci        segment = 'X' * 27
28057db96d56Sopenharmony_ci        path = os.path.join(*[segment] * 10)
28067db96d56Sopenharmony_ci        test_cases = [
28077db96d56Sopenharmony_ci            # overflow with absolute src
28087db96d56Sopenharmony_ci            ('\\' + path, segment),
28097db96d56Sopenharmony_ci            # overflow dest with relative src
28107db96d56Sopenharmony_ci            (segment, path),
28117db96d56Sopenharmony_ci            # overflow when joining src
28127db96d56Sopenharmony_ci            (path[:180], path[:180]),
28137db96d56Sopenharmony_ci        ]
28147db96d56Sopenharmony_ci        for src, dest in test_cases:
28157db96d56Sopenharmony_ci            try:
28167db96d56Sopenharmony_ci                os.symlink(src, dest)
28177db96d56Sopenharmony_ci            except FileNotFoundError:
28187db96d56Sopenharmony_ci                pass
28197db96d56Sopenharmony_ci            else:
28207db96d56Sopenharmony_ci                try:
28217db96d56Sopenharmony_ci                    os.remove(dest)
28227db96d56Sopenharmony_ci                except OSError:
28237db96d56Sopenharmony_ci                    pass
28247db96d56Sopenharmony_ci            # Also test with bytes, since that is a separate code path.
28257db96d56Sopenharmony_ci            try:
28267db96d56Sopenharmony_ci                os.symlink(os.fsencode(src), os.fsencode(dest))
28277db96d56Sopenharmony_ci            except FileNotFoundError:
28287db96d56Sopenharmony_ci                pass
28297db96d56Sopenharmony_ci            else:
28307db96d56Sopenharmony_ci                try:
28317db96d56Sopenharmony_ci                    os.remove(dest)
28327db96d56Sopenharmony_ci                except OSError:
28337db96d56Sopenharmony_ci                    pass
28347db96d56Sopenharmony_ci
28357db96d56Sopenharmony_ci    def test_appexeclink(self):
28367db96d56Sopenharmony_ci        root = os.path.expandvars(r'%LOCALAPPDATA%\Microsoft\WindowsApps')
28377db96d56Sopenharmony_ci        if not os.path.isdir(root):
28387db96d56Sopenharmony_ci            self.skipTest("test requires a WindowsApps directory")
28397db96d56Sopenharmony_ci
28407db96d56Sopenharmony_ci        aliases = [os.path.join(root, a)
28417db96d56Sopenharmony_ci                   for a in fnmatch.filter(os.listdir(root), '*.exe')]
28427db96d56Sopenharmony_ci
28437db96d56Sopenharmony_ci        for alias in aliases:
28447db96d56Sopenharmony_ci            if support.verbose:
28457db96d56Sopenharmony_ci                print()
28467db96d56Sopenharmony_ci                print("Testing with", alias)
28477db96d56Sopenharmony_ci            st = os.lstat(alias)
28487db96d56Sopenharmony_ci            self.assertEqual(st, os.stat(alias))
28497db96d56Sopenharmony_ci            self.assertFalse(stat.S_ISLNK(st.st_mode))
28507db96d56Sopenharmony_ci            self.assertEqual(st.st_reparse_tag, stat.IO_REPARSE_TAG_APPEXECLINK)
28517db96d56Sopenharmony_ci            # testing the first one we see is sufficient
28527db96d56Sopenharmony_ci            break
28537db96d56Sopenharmony_ci        else:
28547db96d56Sopenharmony_ci            self.skipTest("test requires an app execution alias")
28557db96d56Sopenharmony_ci
28567db96d56Sopenharmony_ci@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
28577db96d56Sopenharmony_ciclass Win32JunctionTests(unittest.TestCase):
28587db96d56Sopenharmony_ci    junction = 'junctiontest'
28597db96d56Sopenharmony_ci    junction_target = os.path.dirname(os.path.abspath(__file__))
28607db96d56Sopenharmony_ci
28617db96d56Sopenharmony_ci    def setUp(self):
28627db96d56Sopenharmony_ci        assert os.path.exists(self.junction_target)
28637db96d56Sopenharmony_ci        assert not os.path.lexists(self.junction)
28647db96d56Sopenharmony_ci
28657db96d56Sopenharmony_ci    def tearDown(self):
28667db96d56Sopenharmony_ci        if os.path.lexists(self.junction):
28677db96d56Sopenharmony_ci            os.unlink(self.junction)
28687db96d56Sopenharmony_ci
28697db96d56Sopenharmony_ci    def test_create_junction(self):
28707db96d56Sopenharmony_ci        _winapi.CreateJunction(self.junction_target, self.junction)
28717db96d56Sopenharmony_ci        self.assertTrue(os.path.lexists(self.junction))
28727db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(self.junction))
28737db96d56Sopenharmony_ci        self.assertTrue(os.path.isdir(self.junction))
28747db96d56Sopenharmony_ci        self.assertNotEqual(os.stat(self.junction), os.lstat(self.junction))
28757db96d56Sopenharmony_ci        self.assertEqual(os.stat(self.junction), os.stat(self.junction_target))
28767db96d56Sopenharmony_ci
28777db96d56Sopenharmony_ci        # bpo-37834: Junctions are not recognized as links.
28787db96d56Sopenharmony_ci        self.assertFalse(os.path.islink(self.junction))
28797db96d56Sopenharmony_ci        self.assertEqual(os.path.normcase("\\\\?\\" + self.junction_target),
28807db96d56Sopenharmony_ci                         os.path.normcase(os.readlink(self.junction)))
28817db96d56Sopenharmony_ci
28827db96d56Sopenharmony_ci    def test_unlink_removes_junction(self):
28837db96d56Sopenharmony_ci        _winapi.CreateJunction(self.junction_target, self.junction)
28847db96d56Sopenharmony_ci        self.assertTrue(os.path.exists(self.junction))
28857db96d56Sopenharmony_ci        self.assertTrue(os.path.lexists(self.junction))
28867db96d56Sopenharmony_ci
28877db96d56Sopenharmony_ci        os.unlink(self.junction)
28887db96d56Sopenharmony_ci        self.assertFalse(os.path.exists(self.junction))
28897db96d56Sopenharmony_ci
28907db96d56Sopenharmony_ci@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
28917db96d56Sopenharmony_ciclass Win32NtTests(unittest.TestCase):
28927db96d56Sopenharmony_ci    def test_getfinalpathname_handles(self):
28937db96d56Sopenharmony_ci        nt = import_helper.import_module('nt')
28947db96d56Sopenharmony_ci        ctypes = import_helper.import_module('ctypes')
28957db96d56Sopenharmony_ci        import ctypes.wintypes
28967db96d56Sopenharmony_ci
28977db96d56Sopenharmony_ci        kernel = ctypes.WinDLL('Kernel32.dll', use_last_error=True)
28987db96d56Sopenharmony_ci        kernel.GetCurrentProcess.restype = ctypes.wintypes.HANDLE
28997db96d56Sopenharmony_ci
29007db96d56Sopenharmony_ci        kernel.GetProcessHandleCount.restype = ctypes.wintypes.BOOL
29017db96d56Sopenharmony_ci        kernel.GetProcessHandleCount.argtypes = (ctypes.wintypes.HANDLE,
29027db96d56Sopenharmony_ci                                                 ctypes.wintypes.LPDWORD)
29037db96d56Sopenharmony_ci
29047db96d56Sopenharmony_ci        # This is a pseudo-handle that doesn't need to be closed
29057db96d56Sopenharmony_ci        hproc = kernel.GetCurrentProcess()
29067db96d56Sopenharmony_ci
29077db96d56Sopenharmony_ci        handle_count = ctypes.wintypes.DWORD()
29087db96d56Sopenharmony_ci        ok = kernel.GetProcessHandleCount(hproc, ctypes.byref(handle_count))
29097db96d56Sopenharmony_ci        self.assertEqual(1, ok)
29107db96d56Sopenharmony_ci
29117db96d56Sopenharmony_ci        before_count = handle_count.value
29127db96d56Sopenharmony_ci
29137db96d56Sopenharmony_ci        # The first two test the error path, __file__ tests the success path
29147db96d56Sopenharmony_ci        filenames = [
29157db96d56Sopenharmony_ci            r'\\?\C:',
29167db96d56Sopenharmony_ci            r'\\?\NUL',
29177db96d56Sopenharmony_ci            r'\\?\CONIN',
29187db96d56Sopenharmony_ci            __file__,
29197db96d56Sopenharmony_ci        ]
29207db96d56Sopenharmony_ci
29217db96d56Sopenharmony_ci        for _ in range(10):
29227db96d56Sopenharmony_ci            for name in filenames:
29237db96d56Sopenharmony_ci                try:
29247db96d56Sopenharmony_ci                    nt._getfinalpathname(name)
29257db96d56Sopenharmony_ci                except Exception:
29267db96d56Sopenharmony_ci                    # Failure is expected
29277db96d56Sopenharmony_ci                    pass
29287db96d56Sopenharmony_ci                try:
29297db96d56Sopenharmony_ci                    os.stat(name)
29307db96d56Sopenharmony_ci                except Exception:
29317db96d56Sopenharmony_ci                    pass
29327db96d56Sopenharmony_ci
29337db96d56Sopenharmony_ci        ok = kernel.GetProcessHandleCount(hproc, ctypes.byref(handle_count))
29347db96d56Sopenharmony_ci        self.assertEqual(1, ok)
29357db96d56Sopenharmony_ci
29367db96d56Sopenharmony_ci        handle_delta = handle_count.value - before_count
29377db96d56Sopenharmony_ci
29387db96d56Sopenharmony_ci        self.assertEqual(0, handle_delta)
29397db96d56Sopenharmony_ci
29407db96d56Sopenharmony_ci    @support.requires_subprocess()
29417db96d56Sopenharmony_ci    def test_stat_unlink_race(self):
29427db96d56Sopenharmony_ci        # bpo-46785: the implementation of os.stat() falls back to reading
29437db96d56Sopenharmony_ci        # the parent directory if CreateFileW() fails with a permission
29447db96d56Sopenharmony_ci        # error. If reading the parent directory fails because the file or
29457db96d56Sopenharmony_ci        # directory are subsequently unlinked, or because the volume or
29467db96d56Sopenharmony_ci        # share are no longer available, then the original permission error
29477db96d56Sopenharmony_ci        # should not be restored.
29487db96d56Sopenharmony_ci        filename =  os_helper.TESTFN
29497db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, filename)
29507db96d56Sopenharmony_ci        deadline = time.time() + 5
29517db96d56Sopenharmony_ci        command = textwrap.dedent("""\
29527db96d56Sopenharmony_ci            import os
29537db96d56Sopenharmony_ci            import sys
29547db96d56Sopenharmony_ci            import time
29557db96d56Sopenharmony_ci
29567db96d56Sopenharmony_ci            filename = sys.argv[1]
29577db96d56Sopenharmony_ci            deadline = float(sys.argv[2])
29587db96d56Sopenharmony_ci
29597db96d56Sopenharmony_ci            while time.time() < deadline:
29607db96d56Sopenharmony_ci                try:
29617db96d56Sopenharmony_ci                    with open(filename, "w") as f:
29627db96d56Sopenharmony_ci                        pass
29637db96d56Sopenharmony_ci                except OSError:
29647db96d56Sopenharmony_ci                    pass
29657db96d56Sopenharmony_ci                try:
29667db96d56Sopenharmony_ci                    os.remove(filename)
29677db96d56Sopenharmony_ci                except OSError:
29687db96d56Sopenharmony_ci                    pass
29697db96d56Sopenharmony_ci            """)
29707db96d56Sopenharmony_ci
29717db96d56Sopenharmony_ci        with subprocess.Popen([sys.executable, '-c', command, filename, str(deadline)]) as proc:
29727db96d56Sopenharmony_ci            while time.time() < deadline:
29737db96d56Sopenharmony_ci                try:
29747db96d56Sopenharmony_ci                    os.stat(filename)
29757db96d56Sopenharmony_ci                except FileNotFoundError as e:
29767db96d56Sopenharmony_ci                    assert e.winerror == 2  # ERROR_FILE_NOT_FOUND
29777db96d56Sopenharmony_ci            try:
29787db96d56Sopenharmony_ci                proc.wait(1)
29797db96d56Sopenharmony_ci            except subprocess.TimeoutExpired:
29807db96d56Sopenharmony_ci                proc.terminate()
29817db96d56Sopenharmony_ci
29827db96d56Sopenharmony_ci
29837db96d56Sopenharmony_ci@os_helper.skip_unless_symlink
29847db96d56Sopenharmony_ciclass NonLocalSymlinkTests(unittest.TestCase):
29857db96d56Sopenharmony_ci
29867db96d56Sopenharmony_ci    def setUp(self):
29877db96d56Sopenharmony_ci        r"""
29887db96d56Sopenharmony_ci        Create this structure:
29897db96d56Sopenharmony_ci
29907db96d56Sopenharmony_ci        base
29917db96d56Sopenharmony_ci         \___ some_dir
29927db96d56Sopenharmony_ci        """
29937db96d56Sopenharmony_ci        os.makedirs('base/some_dir')
29947db96d56Sopenharmony_ci
29957db96d56Sopenharmony_ci    def tearDown(self):
29967db96d56Sopenharmony_ci        shutil.rmtree('base')
29977db96d56Sopenharmony_ci
29987db96d56Sopenharmony_ci    def test_directory_link_nonlocal(self):
29997db96d56Sopenharmony_ci        """
30007db96d56Sopenharmony_ci        The symlink target should resolve relative to the link, not relative
30017db96d56Sopenharmony_ci        to the current directory.
30027db96d56Sopenharmony_ci
30037db96d56Sopenharmony_ci        Then, link base/some_link -> base/some_dir and ensure that some_link
30047db96d56Sopenharmony_ci        is resolved as a directory.
30057db96d56Sopenharmony_ci
30067db96d56Sopenharmony_ci        In issue13772, it was discovered that directory detection failed if
30077db96d56Sopenharmony_ci        the symlink target was not specified relative to the current
30087db96d56Sopenharmony_ci        directory, which was a defect in the implementation.
30097db96d56Sopenharmony_ci        """
30107db96d56Sopenharmony_ci        src = os.path.join('base', 'some_link')
30117db96d56Sopenharmony_ci        os.symlink('some_dir', src)
30127db96d56Sopenharmony_ci        assert os.path.isdir(src)
30137db96d56Sopenharmony_ci
30147db96d56Sopenharmony_ci
30157db96d56Sopenharmony_ciclass FSEncodingTests(unittest.TestCase):
30167db96d56Sopenharmony_ci    def test_nop(self):
30177db96d56Sopenharmony_ci        self.assertEqual(os.fsencode(b'abc\xff'), b'abc\xff')
30187db96d56Sopenharmony_ci        self.assertEqual(os.fsdecode('abc\u0141'), 'abc\u0141')
30197db96d56Sopenharmony_ci
30207db96d56Sopenharmony_ci    def test_identity(self):
30217db96d56Sopenharmony_ci        # assert fsdecode(fsencode(x)) == x
30227db96d56Sopenharmony_ci        for fn in ('unicode\u0141', 'latin\xe9', 'ascii'):
30237db96d56Sopenharmony_ci            try:
30247db96d56Sopenharmony_ci                bytesfn = os.fsencode(fn)
30257db96d56Sopenharmony_ci            except UnicodeEncodeError:
30267db96d56Sopenharmony_ci                continue
30277db96d56Sopenharmony_ci            self.assertEqual(os.fsdecode(bytesfn), fn)
30287db96d56Sopenharmony_ci
30297db96d56Sopenharmony_ci
30307db96d56Sopenharmony_ci
30317db96d56Sopenharmony_ciclass DeviceEncodingTests(unittest.TestCase):
30327db96d56Sopenharmony_ci
30337db96d56Sopenharmony_ci    def test_bad_fd(self):
30347db96d56Sopenharmony_ci        # Return None when an fd doesn't actually exist.
30357db96d56Sopenharmony_ci        self.assertIsNone(os.device_encoding(123456))
30367db96d56Sopenharmony_ci
30377db96d56Sopenharmony_ci    @unittest.skipUnless(os.isatty(0) and not win32_is_iot() and (sys.platform.startswith('win') or
30387db96d56Sopenharmony_ci            (hasattr(locale, 'nl_langinfo') and hasattr(locale, 'CODESET'))),
30397db96d56Sopenharmony_ci            'test requires a tty and either Windows or nl_langinfo(CODESET)')
30407db96d56Sopenharmony_ci    @unittest.skipIf(
30417db96d56Sopenharmony_ci        support.is_emscripten, "Cannot get encoding of stdin on Emscripten"
30427db96d56Sopenharmony_ci    )
30437db96d56Sopenharmony_ci    def test_device_encoding(self):
30447db96d56Sopenharmony_ci        encoding = os.device_encoding(0)
30457db96d56Sopenharmony_ci        self.assertIsNotNone(encoding)
30467db96d56Sopenharmony_ci        self.assertTrue(codecs.lookup(encoding))
30477db96d56Sopenharmony_ci
30487db96d56Sopenharmony_ci
30497db96d56Sopenharmony_ci@support.requires_subprocess()
30507db96d56Sopenharmony_ciclass PidTests(unittest.TestCase):
30517db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid")
30527db96d56Sopenharmony_ci    def test_getppid(self):
30537db96d56Sopenharmony_ci        p = subprocess.Popen([sys.executable, '-c',
30547db96d56Sopenharmony_ci                              'import os; print(os.getppid())'],
30557db96d56Sopenharmony_ci                             stdout=subprocess.PIPE)
30567db96d56Sopenharmony_ci        stdout, _ = p.communicate()
30577db96d56Sopenharmony_ci        # We are the parent of our subprocess
30587db96d56Sopenharmony_ci        self.assertEqual(int(stdout), os.getpid())
30597db96d56Sopenharmony_ci
30607db96d56Sopenharmony_ci    def check_waitpid(self, code, exitcode, callback=None):
30617db96d56Sopenharmony_ci        if sys.platform == 'win32':
30627db96d56Sopenharmony_ci            # On Windows, os.spawnv() simply joins arguments with spaces:
30637db96d56Sopenharmony_ci            # arguments need to be quoted
30647db96d56Sopenharmony_ci            args = [f'"{sys.executable}"', '-c', f'"{code}"']
30657db96d56Sopenharmony_ci        else:
30667db96d56Sopenharmony_ci            args = [sys.executable, '-c', code]
30677db96d56Sopenharmony_ci        pid = os.spawnv(os.P_NOWAIT, sys.executable, args)
30687db96d56Sopenharmony_ci
30697db96d56Sopenharmony_ci        if callback is not None:
30707db96d56Sopenharmony_ci            callback(pid)
30717db96d56Sopenharmony_ci
30727db96d56Sopenharmony_ci        # don't use support.wait_process() to test directly os.waitpid()
30737db96d56Sopenharmony_ci        # and os.waitstatus_to_exitcode()
30747db96d56Sopenharmony_ci        pid2, status = os.waitpid(pid, 0)
30757db96d56Sopenharmony_ci        self.assertEqual(os.waitstatus_to_exitcode(status), exitcode)
30767db96d56Sopenharmony_ci        self.assertEqual(pid2, pid)
30777db96d56Sopenharmony_ci
30787db96d56Sopenharmony_ci    def test_waitpid(self):
30797db96d56Sopenharmony_ci        self.check_waitpid(code='pass', exitcode=0)
30807db96d56Sopenharmony_ci
30817db96d56Sopenharmony_ci    def test_waitstatus_to_exitcode(self):
30827db96d56Sopenharmony_ci        exitcode = 23
30837db96d56Sopenharmony_ci        code = f'import sys; sys.exit({exitcode})'
30847db96d56Sopenharmony_ci        self.check_waitpid(code, exitcode=exitcode)
30857db96d56Sopenharmony_ci
30867db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
30877db96d56Sopenharmony_ci            os.waitstatus_to_exitcode(0.0)
30887db96d56Sopenharmony_ci
30897db96d56Sopenharmony_ci    @unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
30907db96d56Sopenharmony_ci    def test_waitpid_windows(self):
30917db96d56Sopenharmony_ci        # bpo-40138: test os.waitpid() and os.waitstatus_to_exitcode()
30927db96d56Sopenharmony_ci        # with exit code larger than INT_MAX.
30937db96d56Sopenharmony_ci        STATUS_CONTROL_C_EXIT = 0xC000013A
30947db96d56Sopenharmony_ci        code = f'import _winapi; _winapi.ExitProcess({STATUS_CONTROL_C_EXIT})'
30957db96d56Sopenharmony_ci        self.check_waitpid(code, exitcode=STATUS_CONTROL_C_EXIT)
30967db96d56Sopenharmony_ci
30977db96d56Sopenharmony_ci    @unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
30987db96d56Sopenharmony_ci    def test_waitstatus_to_exitcode_windows(self):
30997db96d56Sopenharmony_ci        max_exitcode = 2 ** 32 - 1
31007db96d56Sopenharmony_ci        for exitcode in (0, 1, 5, max_exitcode):
31017db96d56Sopenharmony_ci            self.assertEqual(os.waitstatus_to_exitcode(exitcode << 8),
31027db96d56Sopenharmony_ci                             exitcode)
31037db96d56Sopenharmony_ci
31047db96d56Sopenharmony_ci        # invalid values
31057db96d56Sopenharmony_ci        with self.assertRaises(ValueError):
31067db96d56Sopenharmony_ci            os.waitstatus_to_exitcode((max_exitcode + 1) << 8)
31077db96d56Sopenharmony_ci        with self.assertRaises(OverflowError):
31087db96d56Sopenharmony_ci            os.waitstatus_to_exitcode(-1)
31097db96d56Sopenharmony_ci
31107db96d56Sopenharmony_ci    # Skip the test on Windows
31117db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(signal, 'SIGKILL'), 'need signal.SIGKILL')
31127db96d56Sopenharmony_ci    def test_waitstatus_to_exitcode_kill(self):
31137db96d56Sopenharmony_ci        code = f'import time; time.sleep({support.LONG_TIMEOUT})'
31147db96d56Sopenharmony_ci        signum = signal.SIGKILL
31157db96d56Sopenharmony_ci
31167db96d56Sopenharmony_ci        def kill_process(pid):
31177db96d56Sopenharmony_ci            os.kill(pid, signum)
31187db96d56Sopenharmony_ci
31197db96d56Sopenharmony_ci        self.check_waitpid(code, exitcode=-signum, callback=kill_process)
31207db96d56Sopenharmony_ci
31217db96d56Sopenharmony_ci
31227db96d56Sopenharmony_ci@support.requires_subprocess()
31237db96d56Sopenharmony_ciclass SpawnTests(unittest.TestCase):
31247db96d56Sopenharmony_ci    @staticmethod
31257db96d56Sopenharmony_ci    def quote_args(args):
31267db96d56Sopenharmony_ci        # On Windows, os.spawn* simply joins arguments with spaces:
31277db96d56Sopenharmony_ci        # arguments need to be quoted
31287db96d56Sopenharmony_ci        if os.name != 'nt':
31297db96d56Sopenharmony_ci            return args
31307db96d56Sopenharmony_ci        return [f'"{arg}"' if " " in arg.strip() else arg for arg in args]
31317db96d56Sopenharmony_ci
31327db96d56Sopenharmony_ci    def create_args(self, *, with_env=False, use_bytes=False):
31337db96d56Sopenharmony_ci        self.exitcode = 17
31347db96d56Sopenharmony_ci
31357db96d56Sopenharmony_ci        filename = os_helper.TESTFN
31367db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, filename)
31377db96d56Sopenharmony_ci
31387db96d56Sopenharmony_ci        if not with_env:
31397db96d56Sopenharmony_ci            code = 'import sys; sys.exit(%s)' % self.exitcode
31407db96d56Sopenharmony_ci        else:
31417db96d56Sopenharmony_ci            self.env = dict(os.environ)
31427db96d56Sopenharmony_ci            # create an unique key
31437db96d56Sopenharmony_ci            self.key = str(uuid.uuid4())
31447db96d56Sopenharmony_ci            self.env[self.key] = self.key
31457db96d56Sopenharmony_ci            # read the variable from os.environ to check that it exists
31467db96d56Sopenharmony_ci            code = ('import sys, os; magic = os.environ[%r]; sys.exit(%s)'
31477db96d56Sopenharmony_ci                    % (self.key, self.exitcode))
31487db96d56Sopenharmony_ci
31497db96d56Sopenharmony_ci        with open(filename, "w", encoding="utf-8") as fp:
31507db96d56Sopenharmony_ci            fp.write(code)
31517db96d56Sopenharmony_ci
31527db96d56Sopenharmony_ci        program = sys.executable
31537db96d56Sopenharmony_ci        args = self.quote_args([program, filename])
31547db96d56Sopenharmony_ci        if use_bytes:
31557db96d56Sopenharmony_ci            program = os.fsencode(program)
31567db96d56Sopenharmony_ci            args = [os.fsencode(a) for a in args]
31577db96d56Sopenharmony_ci            self.env = {os.fsencode(k): os.fsencode(v)
31587db96d56Sopenharmony_ci                        for k, v in self.env.items()}
31597db96d56Sopenharmony_ci
31607db96d56Sopenharmony_ci        return program, args
31617db96d56Sopenharmony_ci
31627db96d56Sopenharmony_ci    @requires_os_func('spawnl')
31637db96d56Sopenharmony_ci    def test_spawnl(self):
31647db96d56Sopenharmony_ci        program, args = self.create_args()
31657db96d56Sopenharmony_ci        exitcode = os.spawnl(os.P_WAIT, program, *args)
31667db96d56Sopenharmony_ci        self.assertEqual(exitcode, self.exitcode)
31677db96d56Sopenharmony_ci
31687db96d56Sopenharmony_ci    @requires_os_func('spawnle')
31697db96d56Sopenharmony_ci    def test_spawnle(self):
31707db96d56Sopenharmony_ci        program, args = self.create_args(with_env=True)
31717db96d56Sopenharmony_ci        exitcode = os.spawnle(os.P_WAIT, program, *args, self.env)
31727db96d56Sopenharmony_ci        self.assertEqual(exitcode, self.exitcode)
31737db96d56Sopenharmony_ci
31747db96d56Sopenharmony_ci    @requires_os_func('spawnlp')
31757db96d56Sopenharmony_ci    def test_spawnlp(self):
31767db96d56Sopenharmony_ci        program, args = self.create_args()
31777db96d56Sopenharmony_ci        exitcode = os.spawnlp(os.P_WAIT, program, *args)
31787db96d56Sopenharmony_ci        self.assertEqual(exitcode, self.exitcode)
31797db96d56Sopenharmony_ci
31807db96d56Sopenharmony_ci    @requires_os_func('spawnlpe')
31817db96d56Sopenharmony_ci    def test_spawnlpe(self):
31827db96d56Sopenharmony_ci        program, args = self.create_args(with_env=True)
31837db96d56Sopenharmony_ci        exitcode = os.spawnlpe(os.P_WAIT, program, *args, self.env)
31847db96d56Sopenharmony_ci        self.assertEqual(exitcode, self.exitcode)
31857db96d56Sopenharmony_ci
31867db96d56Sopenharmony_ci    @requires_os_func('spawnv')
31877db96d56Sopenharmony_ci    def test_spawnv(self):
31887db96d56Sopenharmony_ci        program, args = self.create_args()
31897db96d56Sopenharmony_ci        exitcode = os.spawnv(os.P_WAIT, program, args)
31907db96d56Sopenharmony_ci        self.assertEqual(exitcode, self.exitcode)
31917db96d56Sopenharmony_ci
31927db96d56Sopenharmony_ci        # Test for PyUnicode_FSConverter()
31937db96d56Sopenharmony_ci        exitcode = os.spawnv(os.P_WAIT, FakePath(program), args)
31947db96d56Sopenharmony_ci        self.assertEqual(exitcode, self.exitcode)
31957db96d56Sopenharmony_ci
31967db96d56Sopenharmony_ci    @requires_os_func('spawnve')
31977db96d56Sopenharmony_ci    def test_spawnve(self):
31987db96d56Sopenharmony_ci        program, args = self.create_args(with_env=True)
31997db96d56Sopenharmony_ci        exitcode = os.spawnve(os.P_WAIT, program, args, self.env)
32007db96d56Sopenharmony_ci        self.assertEqual(exitcode, self.exitcode)
32017db96d56Sopenharmony_ci
32027db96d56Sopenharmony_ci    @requires_os_func('spawnvp')
32037db96d56Sopenharmony_ci    def test_spawnvp(self):
32047db96d56Sopenharmony_ci        program, args = self.create_args()
32057db96d56Sopenharmony_ci        exitcode = os.spawnvp(os.P_WAIT, program, args)
32067db96d56Sopenharmony_ci        self.assertEqual(exitcode, self.exitcode)
32077db96d56Sopenharmony_ci
32087db96d56Sopenharmony_ci    @requires_os_func('spawnvpe')
32097db96d56Sopenharmony_ci    def test_spawnvpe(self):
32107db96d56Sopenharmony_ci        program, args = self.create_args(with_env=True)
32117db96d56Sopenharmony_ci        exitcode = os.spawnvpe(os.P_WAIT, program, args, self.env)
32127db96d56Sopenharmony_ci        self.assertEqual(exitcode, self.exitcode)
32137db96d56Sopenharmony_ci
32147db96d56Sopenharmony_ci    @requires_os_func('spawnv')
32157db96d56Sopenharmony_ci    def test_nowait(self):
32167db96d56Sopenharmony_ci        program, args = self.create_args()
32177db96d56Sopenharmony_ci        pid = os.spawnv(os.P_NOWAIT, program, args)
32187db96d56Sopenharmony_ci        support.wait_process(pid, exitcode=self.exitcode)
32197db96d56Sopenharmony_ci
32207db96d56Sopenharmony_ci    @requires_os_func('spawnve')
32217db96d56Sopenharmony_ci    def test_spawnve_bytes(self):
32227db96d56Sopenharmony_ci        # Test bytes handling in parse_arglist and parse_envlist (#28114)
32237db96d56Sopenharmony_ci        program, args = self.create_args(with_env=True, use_bytes=True)
32247db96d56Sopenharmony_ci        exitcode = os.spawnve(os.P_WAIT, program, args, self.env)
32257db96d56Sopenharmony_ci        self.assertEqual(exitcode, self.exitcode)
32267db96d56Sopenharmony_ci
32277db96d56Sopenharmony_ci    @requires_os_func('spawnl')
32287db96d56Sopenharmony_ci    def test_spawnl_noargs(self):
32297db96d56Sopenharmony_ci        program, __ = self.create_args()
32307db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, program)
32317db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, program, '')
32327db96d56Sopenharmony_ci
32337db96d56Sopenharmony_ci    @requires_os_func('spawnle')
32347db96d56Sopenharmony_ci    def test_spawnle_noargs(self):
32357db96d56Sopenharmony_ci        program, __ = self.create_args()
32367db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, program, {})
32377db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, program, '', {})
32387db96d56Sopenharmony_ci
32397db96d56Sopenharmony_ci    @requires_os_func('spawnv')
32407db96d56Sopenharmony_ci    def test_spawnv_noargs(self):
32417db96d56Sopenharmony_ci        program, __ = self.create_args()
32427db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ())
32437db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, [])
32447db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ('',))
32457db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, [''])
32467db96d56Sopenharmony_ci
32477db96d56Sopenharmony_ci    @requires_os_func('spawnve')
32487db96d56Sopenharmony_ci    def test_spawnve_noargs(self):
32497db96d56Sopenharmony_ci        program, __ = self.create_args()
32507db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, program, (), {})
32517db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, program, [], {})
32527db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, program, ('',), {})
32537db96d56Sopenharmony_ci        self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, program, [''], {})
32547db96d56Sopenharmony_ci
32557db96d56Sopenharmony_ci    def _test_invalid_env(self, spawn):
32567db96d56Sopenharmony_ci        program = sys.executable
32577db96d56Sopenharmony_ci        args = self.quote_args([program, '-c', 'pass'])
32587db96d56Sopenharmony_ci
32597db96d56Sopenharmony_ci        # null character in the environment variable name
32607db96d56Sopenharmony_ci        newenv = os.environ.copy()
32617db96d56Sopenharmony_ci        newenv["FRUIT\0VEGETABLE"] = "cabbage"
32627db96d56Sopenharmony_ci        try:
32637db96d56Sopenharmony_ci            exitcode = spawn(os.P_WAIT, program, args, newenv)
32647db96d56Sopenharmony_ci        except ValueError:
32657db96d56Sopenharmony_ci            pass
32667db96d56Sopenharmony_ci        else:
32677db96d56Sopenharmony_ci            self.assertEqual(exitcode, 127)
32687db96d56Sopenharmony_ci
32697db96d56Sopenharmony_ci        # null character in the environment variable value
32707db96d56Sopenharmony_ci        newenv = os.environ.copy()
32717db96d56Sopenharmony_ci        newenv["FRUIT"] = "orange\0VEGETABLE=cabbage"
32727db96d56Sopenharmony_ci        try:
32737db96d56Sopenharmony_ci            exitcode = spawn(os.P_WAIT, program, args, newenv)
32747db96d56Sopenharmony_ci        except ValueError:
32757db96d56Sopenharmony_ci            pass
32767db96d56Sopenharmony_ci        else:
32777db96d56Sopenharmony_ci            self.assertEqual(exitcode, 127)
32787db96d56Sopenharmony_ci
32797db96d56Sopenharmony_ci        # equal character in the environment variable name
32807db96d56Sopenharmony_ci        newenv = os.environ.copy()
32817db96d56Sopenharmony_ci        newenv["FRUIT=ORANGE"] = "lemon"
32827db96d56Sopenharmony_ci        try:
32837db96d56Sopenharmony_ci            exitcode = spawn(os.P_WAIT, program, args, newenv)
32847db96d56Sopenharmony_ci        except ValueError:
32857db96d56Sopenharmony_ci            pass
32867db96d56Sopenharmony_ci        else:
32877db96d56Sopenharmony_ci            self.assertEqual(exitcode, 127)
32887db96d56Sopenharmony_ci
32897db96d56Sopenharmony_ci        # equal character in the environment variable value
32907db96d56Sopenharmony_ci        filename = os_helper.TESTFN
32917db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, filename)
32927db96d56Sopenharmony_ci        with open(filename, "w", encoding="utf-8") as fp:
32937db96d56Sopenharmony_ci            fp.write('import sys, os\n'
32947db96d56Sopenharmony_ci                     'if os.getenv("FRUIT") != "orange=lemon":\n'
32957db96d56Sopenharmony_ci                     '    raise AssertionError')
32967db96d56Sopenharmony_ci
32977db96d56Sopenharmony_ci        args = self.quote_args([program, filename])
32987db96d56Sopenharmony_ci        newenv = os.environ.copy()
32997db96d56Sopenharmony_ci        newenv["FRUIT"] = "orange=lemon"
33007db96d56Sopenharmony_ci        exitcode = spawn(os.P_WAIT, program, args, newenv)
33017db96d56Sopenharmony_ci        self.assertEqual(exitcode, 0)
33027db96d56Sopenharmony_ci
33037db96d56Sopenharmony_ci    @requires_os_func('spawnve')
33047db96d56Sopenharmony_ci    def test_spawnve_invalid_env(self):
33057db96d56Sopenharmony_ci        self._test_invalid_env(os.spawnve)
33067db96d56Sopenharmony_ci
33077db96d56Sopenharmony_ci    @requires_os_func('spawnvpe')
33087db96d56Sopenharmony_ci    def test_spawnvpe_invalid_env(self):
33097db96d56Sopenharmony_ci        self._test_invalid_env(os.spawnvpe)
33107db96d56Sopenharmony_ci
33117db96d56Sopenharmony_ci
33127db96d56Sopenharmony_ci# The introduction of this TestCase caused at least two different errors on
33137db96d56Sopenharmony_ci# *nix buildbots. Temporarily skip this to let the buildbots move along.
33147db96d56Sopenharmony_ci@unittest.skip("Skip due to platform/environment differences on *NIX buildbots")
33157db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'getlogin'), "test needs os.getlogin")
33167db96d56Sopenharmony_ciclass LoginTests(unittest.TestCase):
33177db96d56Sopenharmony_ci    def test_getlogin(self):
33187db96d56Sopenharmony_ci        user_name = os.getlogin()
33197db96d56Sopenharmony_ci        self.assertNotEqual(len(user_name), 0)
33207db96d56Sopenharmony_ci
33217db96d56Sopenharmony_ci
33227db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'getpriority') and hasattr(os, 'setpriority'),
33237db96d56Sopenharmony_ci                     "needs os.getpriority and os.setpriority")
33247db96d56Sopenharmony_ciclass ProgramPriorityTests(unittest.TestCase):
33257db96d56Sopenharmony_ci    """Tests for os.getpriority() and os.setpriority()."""
33267db96d56Sopenharmony_ci
33277db96d56Sopenharmony_ci    def test_set_get_priority(self):
33287db96d56Sopenharmony_ci
33297db96d56Sopenharmony_ci        base = os.getpriority(os.PRIO_PROCESS, os.getpid())
33307db96d56Sopenharmony_ci        os.setpriority(os.PRIO_PROCESS, os.getpid(), base + 1)
33317db96d56Sopenharmony_ci        try:
33327db96d56Sopenharmony_ci            new_prio = os.getpriority(os.PRIO_PROCESS, os.getpid())
33337db96d56Sopenharmony_ci            if base >= 19 and new_prio <= 19:
33347db96d56Sopenharmony_ci                raise unittest.SkipTest("unable to reliably test setpriority "
33357db96d56Sopenharmony_ci                                        "at current nice level of %s" % base)
33367db96d56Sopenharmony_ci            else:
33377db96d56Sopenharmony_ci                self.assertEqual(new_prio, base + 1)
33387db96d56Sopenharmony_ci        finally:
33397db96d56Sopenharmony_ci            try:
33407db96d56Sopenharmony_ci                os.setpriority(os.PRIO_PROCESS, os.getpid(), base)
33417db96d56Sopenharmony_ci            except OSError as err:
33427db96d56Sopenharmony_ci                if err.errno != errno.EACCES:
33437db96d56Sopenharmony_ci                    raise
33447db96d56Sopenharmony_ci
33457db96d56Sopenharmony_ci
33467db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'sendfile'), "test needs os.sendfile()")
33477db96d56Sopenharmony_ciclass TestSendfile(unittest.IsolatedAsyncioTestCase):
33487db96d56Sopenharmony_ci
33497db96d56Sopenharmony_ci    DATA = b"12345abcde" * 16 * 1024  # 160 KiB
33507db96d56Sopenharmony_ci    SUPPORT_HEADERS_TRAILERS = not sys.platform.startswith("linux") and \
33517db96d56Sopenharmony_ci                               not sys.platform.startswith("solaris") and \
33527db96d56Sopenharmony_ci                               not sys.platform.startswith("sunos")
33537db96d56Sopenharmony_ci    requires_headers_trailers = unittest.skipUnless(SUPPORT_HEADERS_TRAILERS,
33547db96d56Sopenharmony_ci            'requires headers and trailers support')
33557db96d56Sopenharmony_ci    requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
33567db96d56Sopenharmony_ci            'test is only meaningful on 32-bit builds')
33577db96d56Sopenharmony_ci
33587db96d56Sopenharmony_ci    @classmethod
33597db96d56Sopenharmony_ci    def setUpClass(cls):
33607db96d56Sopenharmony_ci        create_file(os_helper.TESTFN, cls.DATA)
33617db96d56Sopenharmony_ci
33627db96d56Sopenharmony_ci    @classmethod
33637db96d56Sopenharmony_ci    def tearDownClass(cls):
33647db96d56Sopenharmony_ci        os_helper.unlink(os_helper.TESTFN)
33657db96d56Sopenharmony_ci
33667db96d56Sopenharmony_ci    @staticmethod
33677db96d56Sopenharmony_ci    async def chunks(reader):
33687db96d56Sopenharmony_ci        while not reader.at_eof():
33697db96d56Sopenharmony_ci            yield await reader.read()
33707db96d56Sopenharmony_ci
33717db96d56Sopenharmony_ci    async def handle_new_client(self, reader, writer):
33727db96d56Sopenharmony_ci        self.server_buffer = b''.join([x async for x in self.chunks(reader)])
33737db96d56Sopenharmony_ci        writer.close()
33747db96d56Sopenharmony_ci        self.server.close()  # The test server processes a single client only
33757db96d56Sopenharmony_ci
33767db96d56Sopenharmony_ci    async def asyncSetUp(self):
33777db96d56Sopenharmony_ci        self.server_buffer = b''
33787db96d56Sopenharmony_ci        self.server = await asyncio.start_server(self.handle_new_client,
33797db96d56Sopenharmony_ci                                                 socket_helper.HOSTv4)
33807db96d56Sopenharmony_ci        server_name = self.server.sockets[0].getsockname()
33817db96d56Sopenharmony_ci        self.client = socket.socket()
33827db96d56Sopenharmony_ci        self.client.setblocking(False)
33837db96d56Sopenharmony_ci        await asyncio.get_running_loop().sock_connect(self.client, server_name)
33847db96d56Sopenharmony_ci        self.sockno = self.client.fileno()
33857db96d56Sopenharmony_ci        self.file = open(os_helper.TESTFN, 'rb')
33867db96d56Sopenharmony_ci        self.fileno = self.file.fileno()
33877db96d56Sopenharmony_ci
33887db96d56Sopenharmony_ci    async def asyncTearDown(self):
33897db96d56Sopenharmony_ci        self.file.close()
33907db96d56Sopenharmony_ci        self.client.close()
33917db96d56Sopenharmony_ci        await self.server.wait_closed()
33927db96d56Sopenharmony_ci
33937db96d56Sopenharmony_ci    # Use the test subject instead of asyncio.loop.sendfile
33947db96d56Sopenharmony_ci    @staticmethod
33957db96d56Sopenharmony_ci    async def async_sendfile(*args, **kwargs):
33967db96d56Sopenharmony_ci        return await asyncio.to_thread(os.sendfile, *args, **kwargs)
33977db96d56Sopenharmony_ci
33987db96d56Sopenharmony_ci    @staticmethod
33997db96d56Sopenharmony_ci    async def sendfile_wrapper(*args, **kwargs):
34007db96d56Sopenharmony_ci        """A higher level wrapper representing how an application is
34017db96d56Sopenharmony_ci        supposed to use sendfile().
34027db96d56Sopenharmony_ci        """
34037db96d56Sopenharmony_ci        while True:
34047db96d56Sopenharmony_ci            try:
34057db96d56Sopenharmony_ci                return await TestSendfile.async_sendfile(*args, **kwargs)
34067db96d56Sopenharmony_ci            except OSError as err:
34077db96d56Sopenharmony_ci                if err.errno == errno.ECONNRESET:
34087db96d56Sopenharmony_ci                    # disconnected
34097db96d56Sopenharmony_ci                    raise
34107db96d56Sopenharmony_ci                elif err.errno in (errno.EAGAIN, errno.EBUSY):
34117db96d56Sopenharmony_ci                    # we have to retry send data
34127db96d56Sopenharmony_ci                    continue
34137db96d56Sopenharmony_ci                else:
34147db96d56Sopenharmony_ci                    raise
34157db96d56Sopenharmony_ci
34167db96d56Sopenharmony_ci    async def test_send_whole_file(self):
34177db96d56Sopenharmony_ci        # normal send
34187db96d56Sopenharmony_ci        total_sent = 0
34197db96d56Sopenharmony_ci        offset = 0
34207db96d56Sopenharmony_ci        nbytes = 4096
34217db96d56Sopenharmony_ci        while total_sent < len(self.DATA):
34227db96d56Sopenharmony_ci            sent = await self.sendfile_wrapper(self.sockno, self.fileno,
34237db96d56Sopenharmony_ci                                               offset, nbytes)
34247db96d56Sopenharmony_ci            if sent == 0:
34257db96d56Sopenharmony_ci                break
34267db96d56Sopenharmony_ci            offset += sent
34277db96d56Sopenharmony_ci            total_sent += sent
34287db96d56Sopenharmony_ci            self.assertTrue(sent <= nbytes)
34297db96d56Sopenharmony_ci            self.assertEqual(offset, total_sent)
34307db96d56Sopenharmony_ci
34317db96d56Sopenharmony_ci        self.assertEqual(total_sent, len(self.DATA))
34327db96d56Sopenharmony_ci        self.client.shutdown(socket.SHUT_RDWR)
34337db96d56Sopenharmony_ci        self.client.close()
34347db96d56Sopenharmony_ci        await self.server.wait_closed()
34357db96d56Sopenharmony_ci        self.assertEqual(len(self.server_buffer), len(self.DATA))
34367db96d56Sopenharmony_ci        self.assertEqual(self.server_buffer, self.DATA)
34377db96d56Sopenharmony_ci
34387db96d56Sopenharmony_ci    async def test_send_at_certain_offset(self):
34397db96d56Sopenharmony_ci        # start sending a file at a certain offset
34407db96d56Sopenharmony_ci        total_sent = 0
34417db96d56Sopenharmony_ci        offset = len(self.DATA) // 2
34427db96d56Sopenharmony_ci        must_send = len(self.DATA) - offset
34437db96d56Sopenharmony_ci        nbytes = 4096
34447db96d56Sopenharmony_ci        while total_sent < must_send:
34457db96d56Sopenharmony_ci            sent = await self.sendfile_wrapper(self.sockno, self.fileno,
34467db96d56Sopenharmony_ci                                               offset, nbytes)
34477db96d56Sopenharmony_ci            if sent == 0:
34487db96d56Sopenharmony_ci                break
34497db96d56Sopenharmony_ci            offset += sent
34507db96d56Sopenharmony_ci            total_sent += sent
34517db96d56Sopenharmony_ci            self.assertTrue(sent <= nbytes)
34527db96d56Sopenharmony_ci
34537db96d56Sopenharmony_ci        self.client.shutdown(socket.SHUT_RDWR)
34547db96d56Sopenharmony_ci        self.client.close()
34557db96d56Sopenharmony_ci        await self.server.wait_closed()
34567db96d56Sopenharmony_ci        expected = self.DATA[len(self.DATA) // 2:]
34577db96d56Sopenharmony_ci        self.assertEqual(total_sent, len(expected))
34587db96d56Sopenharmony_ci        self.assertEqual(len(self.server_buffer), len(expected))
34597db96d56Sopenharmony_ci        self.assertEqual(self.server_buffer, expected)
34607db96d56Sopenharmony_ci
34617db96d56Sopenharmony_ci    async def test_offset_overflow(self):
34627db96d56Sopenharmony_ci        # specify an offset > file size
34637db96d56Sopenharmony_ci        offset = len(self.DATA) + 4096
34647db96d56Sopenharmony_ci        try:
34657db96d56Sopenharmony_ci            sent = await self.async_sendfile(self.sockno, self.fileno,
34667db96d56Sopenharmony_ci                                             offset, 4096)
34677db96d56Sopenharmony_ci        except OSError as e:
34687db96d56Sopenharmony_ci            # Solaris can raise EINVAL if offset >= file length, ignore.
34697db96d56Sopenharmony_ci            if e.errno != errno.EINVAL:
34707db96d56Sopenharmony_ci                raise
34717db96d56Sopenharmony_ci        else:
34727db96d56Sopenharmony_ci            self.assertEqual(sent, 0)
34737db96d56Sopenharmony_ci        self.client.shutdown(socket.SHUT_RDWR)
34747db96d56Sopenharmony_ci        self.client.close()
34757db96d56Sopenharmony_ci        await self.server.wait_closed()
34767db96d56Sopenharmony_ci        self.assertEqual(self.server_buffer, b'')
34777db96d56Sopenharmony_ci
34787db96d56Sopenharmony_ci    async def test_invalid_offset(self):
34797db96d56Sopenharmony_ci        with self.assertRaises(OSError) as cm:
34807db96d56Sopenharmony_ci            await self.async_sendfile(self.sockno, self.fileno, -1, 4096)
34817db96d56Sopenharmony_ci        self.assertEqual(cm.exception.errno, errno.EINVAL)
34827db96d56Sopenharmony_ci
34837db96d56Sopenharmony_ci    async def test_keywords(self):
34847db96d56Sopenharmony_ci        # Keyword arguments should be supported
34857db96d56Sopenharmony_ci        await self.async_sendfile(out_fd=self.sockno, in_fd=self.fileno,
34867db96d56Sopenharmony_ci                                  offset=0, count=4096)
34877db96d56Sopenharmony_ci        if self.SUPPORT_HEADERS_TRAILERS:
34887db96d56Sopenharmony_ci            await self.async_sendfile(out_fd=self.sockno, in_fd=self.fileno,
34897db96d56Sopenharmony_ci                                      offset=0, count=4096,
34907db96d56Sopenharmony_ci                                      headers=(), trailers=(), flags=0)
34917db96d56Sopenharmony_ci
34927db96d56Sopenharmony_ci    # --- headers / trailers tests
34937db96d56Sopenharmony_ci
34947db96d56Sopenharmony_ci    @requires_headers_trailers
34957db96d56Sopenharmony_ci    async def test_headers(self):
34967db96d56Sopenharmony_ci        total_sent = 0
34977db96d56Sopenharmony_ci        expected_data = b"x" * 512 + b"y" * 256 + self.DATA[:-1]
34987db96d56Sopenharmony_ci        sent = await self.async_sendfile(self.sockno, self.fileno, 0, 4096,
34997db96d56Sopenharmony_ci                                         headers=[b"x" * 512, b"y" * 256])
35007db96d56Sopenharmony_ci        self.assertLessEqual(sent, 512 + 256 + 4096)
35017db96d56Sopenharmony_ci        total_sent += sent
35027db96d56Sopenharmony_ci        offset = 4096
35037db96d56Sopenharmony_ci        while total_sent < len(expected_data):
35047db96d56Sopenharmony_ci            nbytes = min(len(expected_data) - total_sent, 4096)
35057db96d56Sopenharmony_ci            sent = await self.sendfile_wrapper(self.sockno, self.fileno,
35067db96d56Sopenharmony_ci                                               offset, nbytes)
35077db96d56Sopenharmony_ci            if sent == 0:
35087db96d56Sopenharmony_ci                break
35097db96d56Sopenharmony_ci            self.assertLessEqual(sent, nbytes)
35107db96d56Sopenharmony_ci            total_sent += sent
35117db96d56Sopenharmony_ci            offset += sent
35127db96d56Sopenharmony_ci
35137db96d56Sopenharmony_ci        self.assertEqual(total_sent, len(expected_data))
35147db96d56Sopenharmony_ci        self.client.close()
35157db96d56Sopenharmony_ci        await self.server.wait_closed()
35167db96d56Sopenharmony_ci        self.assertEqual(hash(self.server_buffer), hash(expected_data))
35177db96d56Sopenharmony_ci
35187db96d56Sopenharmony_ci    @requires_headers_trailers
35197db96d56Sopenharmony_ci    async def test_trailers(self):
35207db96d56Sopenharmony_ci        TESTFN2 = os_helper.TESTFN + "2"
35217db96d56Sopenharmony_ci        file_data = b"abcdef"
35227db96d56Sopenharmony_ci
35237db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, TESTFN2)
35247db96d56Sopenharmony_ci        create_file(TESTFN2, file_data)
35257db96d56Sopenharmony_ci
35267db96d56Sopenharmony_ci        with open(TESTFN2, 'rb') as f:
35277db96d56Sopenharmony_ci            await self.async_sendfile(self.sockno, f.fileno(), 0, 5,
35287db96d56Sopenharmony_ci                                      trailers=[b"123456", b"789"])
35297db96d56Sopenharmony_ci            self.client.close()
35307db96d56Sopenharmony_ci            await self.server.wait_closed()
35317db96d56Sopenharmony_ci            self.assertEqual(self.server_buffer, b"abcde123456789")
35327db96d56Sopenharmony_ci
35337db96d56Sopenharmony_ci    @requires_headers_trailers
35347db96d56Sopenharmony_ci    @requires_32b
35357db96d56Sopenharmony_ci    async def test_headers_overflow_32bits(self):
35367db96d56Sopenharmony_ci        self.server.handler_instance.accumulate = False
35377db96d56Sopenharmony_ci        with self.assertRaises(OSError) as cm:
35387db96d56Sopenharmony_ci            await self.async_sendfile(self.sockno, self.fileno, 0, 0,
35397db96d56Sopenharmony_ci                                      headers=[b"x" * 2**16] * 2**15)
35407db96d56Sopenharmony_ci        self.assertEqual(cm.exception.errno, errno.EINVAL)
35417db96d56Sopenharmony_ci
35427db96d56Sopenharmony_ci    @requires_headers_trailers
35437db96d56Sopenharmony_ci    @requires_32b
35447db96d56Sopenharmony_ci    async def test_trailers_overflow_32bits(self):
35457db96d56Sopenharmony_ci        self.server.handler_instance.accumulate = False
35467db96d56Sopenharmony_ci        with self.assertRaises(OSError) as cm:
35477db96d56Sopenharmony_ci            await self.async_sendfile(self.sockno, self.fileno, 0, 0,
35487db96d56Sopenharmony_ci                                      trailers=[b"x" * 2**16] * 2**15)
35497db96d56Sopenharmony_ci        self.assertEqual(cm.exception.errno, errno.EINVAL)
35507db96d56Sopenharmony_ci
35517db96d56Sopenharmony_ci    @requires_headers_trailers
35527db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'SF_NODISKIO'),
35537db96d56Sopenharmony_ci                         'test needs os.SF_NODISKIO')
35547db96d56Sopenharmony_ci    async def test_flags(self):
35557db96d56Sopenharmony_ci        try:
35567db96d56Sopenharmony_ci            await self.async_sendfile(self.sockno, self.fileno, 0, 4096,
35577db96d56Sopenharmony_ci                                      flags=os.SF_NODISKIO)
35587db96d56Sopenharmony_ci        except OSError as err:
35597db96d56Sopenharmony_ci            if err.errno not in (errno.EBUSY, errno.EAGAIN):
35607db96d56Sopenharmony_ci                raise
35617db96d56Sopenharmony_ci
35627db96d56Sopenharmony_ci
35637db96d56Sopenharmony_cidef supports_extended_attributes():
35647db96d56Sopenharmony_ci    if not hasattr(os, "setxattr"):
35657db96d56Sopenharmony_ci        return False
35667db96d56Sopenharmony_ci
35677db96d56Sopenharmony_ci    try:
35687db96d56Sopenharmony_ci        with open(os_helper.TESTFN, "xb", 0) as fp:
35697db96d56Sopenharmony_ci            try:
35707db96d56Sopenharmony_ci                os.setxattr(fp.fileno(), b"user.test", b"")
35717db96d56Sopenharmony_ci            except OSError:
35727db96d56Sopenharmony_ci                return False
35737db96d56Sopenharmony_ci    finally:
35747db96d56Sopenharmony_ci        os_helper.unlink(os_helper.TESTFN)
35757db96d56Sopenharmony_ci
35767db96d56Sopenharmony_ci    return True
35777db96d56Sopenharmony_ci
35787db96d56Sopenharmony_ci
35797db96d56Sopenharmony_ci@unittest.skipUnless(supports_extended_attributes(),
35807db96d56Sopenharmony_ci                     "no non-broken extended attribute support")
35817db96d56Sopenharmony_ci# Kernels < 2.6.39 don't respect setxattr flags.
35827db96d56Sopenharmony_ci@support.requires_linux_version(2, 6, 39)
35837db96d56Sopenharmony_ciclass ExtendedAttributeTests(unittest.TestCase):
35847db96d56Sopenharmony_ci
35857db96d56Sopenharmony_ci    def _check_xattrs_str(self, s, getxattr, setxattr, removexattr, listxattr, **kwargs):
35867db96d56Sopenharmony_ci        fn = os_helper.TESTFN
35877db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, fn)
35887db96d56Sopenharmony_ci        create_file(fn)
35897db96d56Sopenharmony_ci
35907db96d56Sopenharmony_ci        with self.assertRaises(OSError) as cm:
35917db96d56Sopenharmony_ci            getxattr(fn, s("user.test"), **kwargs)
35927db96d56Sopenharmony_ci        self.assertEqual(cm.exception.errno, errno.ENODATA)
35937db96d56Sopenharmony_ci
35947db96d56Sopenharmony_ci        init_xattr = listxattr(fn)
35957db96d56Sopenharmony_ci        self.assertIsInstance(init_xattr, list)
35967db96d56Sopenharmony_ci
35977db96d56Sopenharmony_ci        setxattr(fn, s("user.test"), b"", **kwargs)
35987db96d56Sopenharmony_ci        xattr = set(init_xattr)
35997db96d56Sopenharmony_ci        xattr.add("user.test")
36007db96d56Sopenharmony_ci        self.assertEqual(set(listxattr(fn)), xattr)
36017db96d56Sopenharmony_ci        self.assertEqual(getxattr(fn, b"user.test", **kwargs), b"")
36027db96d56Sopenharmony_ci        setxattr(fn, s("user.test"), b"hello", os.XATTR_REPLACE, **kwargs)
36037db96d56Sopenharmony_ci        self.assertEqual(getxattr(fn, b"user.test", **kwargs), b"hello")
36047db96d56Sopenharmony_ci
36057db96d56Sopenharmony_ci        with self.assertRaises(OSError) as cm:
36067db96d56Sopenharmony_ci            setxattr(fn, s("user.test"), b"bye", os.XATTR_CREATE, **kwargs)
36077db96d56Sopenharmony_ci        self.assertEqual(cm.exception.errno, errno.EEXIST)
36087db96d56Sopenharmony_ci
36097db96d56Sopenharmony_ci        with self.assertRaises(OSError) as cm:
36107db96d56Sopenharmony_ci            setxattr(fn, s("user.test2"), b"bye", os.XATTR_REPLACE, **kwargs)
36117db96d56Sopenharmony_ci        self.assertEqual(cm.exception.errno, errno.ENODATA)
36127db96d56Sopenharmony_ci
36137db96d56Sopenharmony_ci        setxattr(fn, s("user.test2"), b"foo", os.XATTR_CREATE, **kwargs)
36147db96d56Sopenharmony_ci        xattr.add("user.test2")
36157db96d56Sopenharmony_ci        self.assertEqual(set(listxattr(fn)), xattr)
36167db96d56Sopenharmony_ci        removexattr(fn, s("user.test"), **kwargs)
36177db96d56Sopenharmony_ci
36187db96d56Sopenharmony_ci        with self.assertRaises(OSError) as cm:
36197db96d56Sopenharmony_ci            getxattr(fn, s("user.test"), **kwargs)
36207db96d56Sopenharmony_ci        self.assertEqual(cm.exception.errno, errno.ENODATA)
36217db96d56Sopenharmony_ci
36227db96d56Sopenharmony_ci        xattr.remove("user.test")
36237db96d56Sopenharmony_ci        self.assertEqual(set(listxattr(fn)), xattr)
36247db96d56Sopenharmony_ci        self.assertEqual(getxattr(fn, s("user.test2"), **kwargs), b"foo")
36257db96d56Sopenharmony_ci        setxattr(fn, s("user.test"), b"a"*1024, **kwargs)
36267db96d56Sopenharmony_ci        self.assertEqual(getxattr(fn, s("user.test"), **kwargs), b"a"*1024)
36277db96d56Sopenharmony_ci        removexattr(fn, s("user.test"), **kwargs)
36287db96d56Sopenharmony_ci        many = sorted("user.test{}".format(i) for i in range(100))
36297db96d56Sopenharmony_ci        for thing in many:
36307db96d56Sopenharmony_ci            setxattr(fn, thing, b"x", **kwargs)
36317db96d56Sopenharmony_ci        self.assertEqual(set(listxattr(fn)), set(init_xattr) | set(many))
36327db96d56Sopenharmony_ci
36337db96d56Sopenharmony_ci    def _check_xattrs(self, *args, **kwargs):
36347db96d56Sopenharmony_ci        self._check_xattrs_str(str, *args, **kwargs)
36357db96d56Sopenharmony_ci        os_helper.unlink(os_helper.TESTFN)
36367db96d56Sopenharmony_ci
36377db96d56Sopenharmony_ci        self._check_xattrs_str(os.fsencode, *args, **kwargs)
36387db96d56Sopenharmony_ci        os_helper.unlink(os_helper.TESTFN)
36397db96d56Sopenharmony_ci
36407db96d56Sopenharmony_ci    def test_simple(self):
36417db96d56Sopenharmony_ci        self._check_xattrs(os.getxattr, os.setxattr, os.removexattr,
36427db96d56Sopenharmony_ci                           os.listxattr)
36437db96d56Sopenharmony_ci
36447db96d56Sopenharmony_ci    def test_lpath(self):
36457db96d56Sopenharmony_ci        self._check_xattrs(os.getxattr, os.setxattr, os.removexattr,
36467db96d56Sopenharmony_ci                           os.listxattr, follow_symlinks=False)
36477db96d56Sopenharmony_ci
36487db96d56Sopenharmony_ci    def test_fds(self):
36497db96d56Sopenharmony_ci        def getxattr(path, *args):
36507db96d56Sopenharmony_ci            with open(path, "rb") as fp:
36517db96d56Sopenharmony_ci                return os.getxattr(fp.fileno(), *args)
36527db96d56Sopenharmony_ci        def setxattr(path, *args):
36537db96d56Sopenharmony_ci            with open(path, "wb", 0) as fp:
36547db96d56Sopenharmony_ci                os.setxattr(fp.fileno(), *args)
36557db96d56Sopenharmony_ci        def removexattr(path, *args):
36567db96d56Sopenharmony_ci            with open(path, "wb", 0) as fp:
36577db96d56Sopenharmony_ci                os.removexattr(fp.fileno(), *args)
36587db96d56Sopenharmony_ci        def listxattr(path, *args):
36597db96d56Sopenharmony_ci            with open(path, "rb") as fp:
36607db96d56Sopenharmony_ci                return os.listxattr(fp.fileno(), *args)
36617db96d56Sopenharmony_ci        self._check_xattrs(getxattr, setxattr, removexattr, listxattr)
36627db96d56Sopenharmony_ci
36637db96d56Sopenharmony_ci
36647db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'get_terminal_size'), "requires os.get_terminal_size")
36657db96d56Sopenharmony_ciclass TermsizeTests(unittest.TestCase):
36667db96d56Sopenharmony_ci    def test_does_not_crash(self):
36677db96d56Sopenharmony_ci        """Check if get_terminal_size() returns a meaningful value.
36687db96d56Sopenharmony_ci
36697db96d56Sopenharmony_ci        There's no easy portable way to actually check the size of the
36707db96d56Sopenharmony_ci        terminal, so let's check if it returns something sensible instead.
36717db96d56Sopenharmony_ci        """
36727db96d56Sopenharmony_ci        try:
36737db96d56Sopenharmony_ci            size = os.get_terminal_size()
36747db96d56Sopenharmony_ci        except OSError as e:
36757db96d56Sopenharmony_ci            if sys.platform == "win32" or e.errno in (errno.EINVAL, errno.ENOTTY):
36767db96d56Sopenharmony_ci                # Under win32 a generic OSError can be thrown if the
36777db96d56Sopenharmony_ci                # handle cannot be retrieved
36787db96d56Sopenharmony_ci                self.skipTest("failed to query terminal size")
36797db96d56Sopenharmony_ci            raise
36807db96d56Sopenharmony_ci
36817db96d56Sopenharmony_ci        self.assertGreaterEqual(size.columns, 0)
36827db96d56Sopenharmony_ci        self.assertGreaterEqual(size.lines, 0)
36837db96d56Sopenharmony_ci
36847db96d56Sopenharmony_ci    def test_stty_match(self):
36857db96d56Sopenharmony_ci        """Check if stty returns the same results
36867db96d56Sopenharmony_ci
36877db96d56Sopenharmony_ci        stty actually tests stdin, so get_terminal_size is invoked on
36887db96d56Sopenharmony_ci        stdin explicitly. If stty succeeded, then get_terminal_size()
36897db96d56Sopenharmony_ci        should work too.
36907db96d56Sopenharmony_ci        """
36917db96d56Sopenharmony_ci        try:
36927db96d56Sopenharmony_ci            size = (
36937db96d56Sopenharmony_ci                subprocess.check_output(
36947db96d56Sopenharmony_ci                    ["stty", "size"], stderr=subprocess.DEVNULL, text=True
36957db96d56Sopenharmony_ci                ).split()
36967db96d56Sopenharmony_ci            )
36977db96d56Sopenharmony_ci        except (FileNotFoundError, subprocess.CalledProcessError,
36987db96d56Sopenharmony_ci                PermissionError):
36997db96d56Sopenharmony_ci            self.skipTest("stty invocation failed")
37007db96d56Sopenharmony_ci        expected = (int(size[1]), int(size[0])) # reversed order
37017db96d56Sopenharmony_ci
37027db96d56Sopenharmony_ci        try:
37037db96d56Sopenharmony_ci            actual = os.get_terminal_size(sys.__stdin__.fileno())
37047db96d56Sopenharmony_ci        except OSError as e:
37057db96d56Sopenharmony_ci            if sys.platform == "win32" or e.errno in (errno.EINVAL, errno.ENOTTY):
37067db96d56Sopenharmony_ci                # Under win32 a generic OSError can be thrown if the
37077db96d56Sopenharmony_ci                # handle cannot be retrieved
37087db96d56Sopenharmony_ci                self.skipTest("failed to query terminal size")
37097db96d56Sopenharmony_ci            raise
37107db96d56Sopenharmony_ci        self.assertEqual(expected, actual)
37117db96d56Sopenharmony_ci
37127db96d56Sopenharmony_ci
37137db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'memfd_create'), 'requires os.memfd_create')
37147db96d56Sopenharmony_ci@support.requires_linux_version(3, 17)
37157db96d56Sopenharmony_ciclass MemfdCreateTests(unittest.TestCase):
37167db96d56Sopenharmony_ci    def test_memfd_create(self):
37177db96d56Sopenharmony_ci        fd = os.memfd_create("Hi", os.MFD_CLOEXEC)
37187db96d56Sopenharmony_ci        self.assertNotEqual(fd, -1)
37197db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
37207db96d56Sopenharmony_ci        self.assertFalse(os.get_inheritable(fd))
37217db96d56Sopenharmony_ci        with open(fd, "wb", closefd=False) as f:
37227db96d56Sopenharmony_ci            f.write(b'memfd_create')
37237db96d56Sopenharmony_ci            self.assertEqual(f.tell(), 12)
37247db96d56Sopenharmony_ci
37257db96d56Sopenharmony_ci        fd2 = os.memfd_create("Hi")
37267db96d56Sopenharmony_ci        self.addCleanup(os.close, fd2)
37277db96d56Sopenharmony_ci        self.assertFalse(os.get_inheritable(fd2))
37287db96d56Sopenharmony_ci
37297db96d56Sopenharmony_ci
37307db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'eventfd'), 'requires os.eventfd')
37317db96d56Sopenharmony_ci@support.requires_linux_version(2, 6, 30)
37327db96d56Sopenharmony_ciclass EventfdTests(unittest.TestCase):
37337db96d56Sopenharmony_ci    def test_eventfd_initval(self):
37347db96d56Sopenharmony_ci        def pack(value):
37357db96d56Sopenharmony_ci            """Pack as native uint64_t
37367db96d56Sopenharmony_ci            """
37377db96d56Sopenharmony_ci            return struct.pack("@Q", value)
37387db96d56Sopenharmony_ci        size = 8  # read/write 8 bytes
37397db96d56Sopenharmony_ci        initval = 42
37407db96d56Sopenharmony_ci        fd = os.eventfd(initval)
37417db96d56Sopenharmony_ci        self.assertNotEqual(fd, -1)
37427db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
37437db96d56Sopenharmony_ci        self.assertFalse(os.get_inheritable(fd))
37447db96d56Sopenharmony_ci
37457db96d56Sopenharmony_ci        # test with raw read/write
37467db96d56Sopenharmony_ci        res = os.read(fd, size)
37477db96d56Sopenharmony_ci        self.assertEqual(res, pack(initval))
37487db96d56Sopenharmony_ci
37497db96d56Sopenharmony_ci        os.write(fd, pack(23))
37507db96d56Sopenharmony_ci        res = os.read(fd, size)
37517db96d56Sopenharmony_ci        self.assertEqual(res, pack(23))
37527db96d56Sopenharmony_ci
37537db96d56Sopenharmony_ci        os.write(fd, pack(40))
37547db96d56Sopenharmony_ci        os.write(fd, pack(2))
37557db96d56Sopenharmony_ci        res = os.read(fd, size)
37567db96d56Sopenharmony_ci        self.assertEqual(res, pack(42))
37577db96d56Sopenharmony_ci
37587db96d56Sopenharmony_ci        # test with eventfd_read/eventfd_write
37597db96d56Sopenharmony_ci        os.eventfd_write(fd, 20)
37607db96d56Sopenharmony_ci        os.eventfd_write(fd, 3)
37617db96d56Sopenharmony_ci        res = os.eventfd_read(fd)
37627db96d56Sopenharmony_ci        self.assertEqual(res, 23)
37637db96d56Sopenharmony_ci
37647db96d56Sopenharmony_ci    def test_eventfd_semaphore(self):
37657db96d56Sopenharmony_ci        initval = 2
37667db96d56Sopenharmony_ci        flags = os.EFD_CLOEXEC | os.EFD_SEMAPHORE | os.EFD_NONBLOCK
37677db96d56Sopenharmony_ci        fd = os.eventfd(initval, flags)
37687db96d56Sopenharmony_ci        self.assertNotEqual(fd, -1)
37697db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
37707db96d56Sopenharmony_ci
37717db96d56Sopenharmony_ci        # semaphore starts has initval 2, two reads return '1'
37727db96d56Sopenharmony_ci        res = os.eventfd_read(fd)
37737db96d56Sopenharmony_ci        self.assertEqual(res, 1)
37747db96d56Sopenharmony_ci        res = os.eventfd_read(fd)
37757db96d56Sopenharmony_ci        self.assertEqual(res, 1)
37767db96d56Sopenharmony_ci        # third read would block
37777db96d56Sopenharmony_ci        with self.assertRaises(BlockingIOError):
37787db96d56Sopenharmony_ci            os.eventfd_read(fd)
37797db96d56Sopenharmony_ci        with self.assertRaises(BlockingIOError):
37807db96d56Sopenharmony_ci            os.read(fd, 8)
37817db96d56Sopenharmony_ci
37827db96d56Sopenharmony_ci        # increase semaphore counter, read one
37837db96d56Sopenharmony_ci        os.eventfd_write(fd, 1)
37847db96d56Sopenharmony_ci        res = os.eventfd_read(fd)
37857db96d56Sopenharmony_ci        self.assertEqual(res, 1)
37867db96d56Sopenharmony_ci        # next read would block, too
37877db96d56Sopenharmony_ci        with self.assertRaises(BlockingIOError):
37887db96d56Sopenharmony_ci            os.eventfd_read(fd)
37897db96d56Sopenharmony_ci
37907db96d56Sopenharmony_ci    def test_eventfd_select(self):
37917db96d56Sopenharmony_ci        flags = os.EFD_CLOEXEC | os.EFD_NONBLOCK
37927db96d56Sopenharmony_ci        fd = os.eventfd(0, flags)
37937db96d56Sopenharmony_ci        self.assertNotEqual(fd, -1)
37947db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
37957db96d56Sopenharmony_ci
37967db96d56Sopenharmony_ci        # counter is zero, only writeable
37977db96d56Sopenharmony_ci        rfd, wfd, xfd = select.select([fd], [fd], [fd], 0)
37987db96d56Sopenharmony_ci        self.assertEqual((rfd, wfd, xfd), ([], [fd], []))
37997db96d56Sopenharmony_ci
38007db96d56Sopenharmony_ci        # counter is non-zero, read and writeable
38017db96d56Sopenharmony_ci        os.eventfd_write(fd, 23)
38027db96d56Sopenharmony_ci        rfd, wfd, xfd = select.select([fd], [fd], [fd], 0)
38037db96d56Sopenharmony_ci        self.assertEqual((rfd, wfd, xfd), ([fd], [fd], []))
38047db96d56Sopenharmony_ci        self.assertEqual(os.eventfd_read(fd), 23)
38057db96d56Sopenharmony_ci
38067db96d56Sopenharmony_ci        # counter at max, only readable
38077db96d56Sopenharmony_ci        os.eventfd_write(fd, (2**64) - 2)
38087db96d56Sopenharmony_ci        rfd, wfd, xfd = select.select([fd], [fd], [fd], 0)
38097db96d56Sopenharmony_ci        self.assertEqual((rfd, wfd, xfd), ([fd], [], []))
38107db96d56Sopenharmony_ci        os.eventfd_read(fd)
38117db96d56Sopenharmony_ci
38127db96d56Sopenharmony_ci
38137db96d56Sopenharmony_ciclass OSErrorTests(unittest.TestCase):
38147db96d56Sopenharmony_ci    def setUp(self):
38157db96d56Sopenharmony_ci        class Str(str):
38167db96d56Sopenharmony_ci            pass
38177db96d56Sopenharmony_ci
38187db96d56Sopenharmony_ci        self.bytes_filenames = []
38197db96d56Sopenharmony_ci        self.unicode_filenames = []
38207db96d56Sopenharmony_ci        if os_helper.TESTFN_UNENCODABLE is not None:
38217db96d56Sopenharmony_ci            decoded = os_helper.TESTFN_UNENCODABLE
38227db96d56Sopenharmony_ci        else:
38237db96d56Sopenharmony_ci            decoded = os_helper.TESTFN
38247db96d56Sopenharmony_ci        self.unicode_filenames.append(decoded)
38257db96d56Sopenharmony_ci        self.unicode_filenames.append(Str(decoded))
38267db96d56Sopenharmony_ci        if os_helper.TESTFN_UNDECODABLE is not None:
38277db96d56Sopenharmony_ci            encoded = os_helper.TESTFN_UNDECODABLE
38287db96d56Sopenharmony_ci        else:
38297db96d56Sopenharmony_ci            encoded = os.fsencode(os_helper.TESTFN)
38307db96d56Sopenharmony_ci        self.bytes_filenames.append(encoded)
38317db96d56Sopenharmony_ci        self.bytes_filenames.append(bytearray(encoded))
38327db96d56Sopenharmony_ci        self.bytes_filenames.append(memoryview(encoded))
38337db96d56Sopenharmony_ci
38347db96d56Sopenharmony_ci        self.filenames = self.bytes_filenames + self.unicode_filenames
38357db96d56Sopenharmony_ci
38367db96d56Sopenharmony_ci    def test_oserror_filename(self):
38377db96d56Sopenharmony_ci        funcs = [
38387db96d56Sopenharmony_ci            (self.filenames, os.chdir,),
38397db96d56Sopenharmony_ci            (self.filenames, os.lstat,),
38407db96d56Sopenharmony_ci            (self.filenames, os.open, os.O_RDONLY),
38417db96d56Sopenharmony_ci            (self.filenames, os.rmdir,),
38427db96d56Sopenharmony_ci            (self.filenames, os.stat,),
38437db96d56Sopenharmony_ci            (self.filenames, os.unlink,),
38447db96d56Sopenharmony_ci        ]
38457db96d56Sopenharmony_ci        if sys.platform == "win32":
38467db96d56Sopenharmony_ci            funcs.extend((
38477db96d56Sopenharmony_ci                (self.bytes_filenames, os.rename, b"dst"),
38487db96d56Sopenharmony_ci                (self.bytes_filenames, os.replace, b"dst"),
38497db96d56Sopenharmony_ci                (self.unicode_filenames, os.rename, "dst"),
38507db96d56Sopenharmony_ci                (self.unicode_filenames, os.replace, "dst"),
38517db96d56Sopenharmony_ci                (self.unicode_filenames, os.listdir, ),
38527db96d56Sopenharmony_ci            ))
38537db96d56Sopenharmony_ci        else:
38547db96d56Sopenharmony_ci            funcs.extend((
38557db96d56Sopenharmony_ci                (self.filenames, os.listdir,),
38567db96d56Sopenharmony_ci                (self.filenames, os.rename, "dst"),
38577db96d56Sopenharmony_ci                (self.filenames, os.replace, "dst"),
38587db96d56Sopenharmony_ci            ))
38597db96d56Sopenharmony_ci        if os_helper.can_chmod():
38607db96d56Sopenharmony_ci            funcs.append((self.filenames, os.chmod, 0o777))
38617db96d56Sopenharmony_ci        if hasattr(os, "chown"):
38627db96d56Sopenharmony_ci            funcs.append((self.filenames, os.chown, 0, 0))
38637db96d56Sopenharmony_ci        if hasattr(os, "lchown"):
38647db96d56Sopenharmony_ci            funcs.append((self.filenames, os.lchown, 0, 0))
38657db96d56Sopenharmony_ci        if hasattr(os, "truncate"):
38667db96d56Sopenharmony_ci            funcs.append((self.filenames, os.truncate, 0))
38677db96d56Sopenharmony_ci        if hasattr(os, "chflags"):
38687db96d56Sopenharmony_ci            funcs.append((self.filenames, os.chflags, 0))
38697db96d56Sopenharmony_ci        if hasattr(os, "lchflags"):
38707db96d56Sopenharmony_ci            funcs.append((self.filenames, os.lchflags, 0))
38717db96d56Sopenharmony_ci        if hasattr(os, "chroot"):
38727db96d56Sopenharmony_ci            funcs.append((self.filenames, os.chroot,))
38737db96d56Sopenharmony_ci        if hasattr(os, "link"):
38747db96d56Sopenharmony_ci            if sys.platform == "win32":
38757db96d56Sopenharmony_ci                funcs.append((self.bytes_filenames, os.link, b"dst"))
38767db96d56Sopenharmony_ci                funcs.append((self.unicode_filenames, os.link, "dst"))
38777db96d56Sopenharmony_ci            else:
38787db96d56Sopenharmony_ci                funcs.append((self.filenames, os.link, "dst"))
38797db96d56Sopenharmony_ci        if hasattr(os, "listxattr"):
38807db96d56Sopenharmony_ci            funcs.extend((
38817db96d56Sopenharmony_ci                (self.filenames, os.listxattr,),
38827db96d56Sopenharmony_ci                (self.filenames, os.getxattr, "user.test"),
38837db96d56Sopenharmony_ci                (self.filenames, os.setxattr, "user.test", b'user'),
38847db96d56Sopenharmony_ci                (self.filenames, os.removexattr, "user.test"),
38857db96d56Sopenharmony_ci            ))
38867db96d56Sopenharmony_ci        if hasattr(os, "lchmod"):
38877db96d56Sopenharmony_ci            funcs.append((self.filenames, os.lchmod, 0o777))
38887db96d56Sopenharmony_ci        if hasattr(os, "readlink"):
38897db96d56Sopenharmony_ci            funcs.append((self.filenames, os.readlink,))
38907db96d56Sopenharmony_ci
38917db96d56Sopenharmony_ci
38927db96d56Sopenharmony_ci        for filenames, func, *func_args in funcs:
38937db96d56Sopenharmony_ci            for name in filenames:
38947db96d56Sopenharmony_ci                try:
38957db96d56Sopenharmony_ci                    if isinstance(name, (str, bytes)):
38967db96d56Sopenharmony_ci                        func(name, *func_args)
38977db96d56Sopenharmony_ci                    else:
38987db96d56Sopenharmony_ci                        with self.assertWarnsRegex(DeprecationWarning, 'should be'):
38997db96d56Sopenharmony_ci                            func(name, *func_args)
39007db96d56Sopenharmony_ci                except OSError as err:
39017db96d56Sopenharmony_ci                    self.assertIs(err.filename, name, str(func))
39027db96d56Sopenharmony_ci                except UnicodeDecodeError:
39037db96d56Sopenharmony_ci                    pass
39047db96d56Sopenharmony_ci                else:
39057db96d56Sopenharmony_ci                    self.fail("No exception thrown by {}".format(func))
39067db96d56Sopenharmony_ci
39077db96d56Sopenharmony_ciclass CPUCountTests(unittest.TestCase):
39087db96d56Sopenharmony_ci    def test_cpu_count(self):
39097db96d56Sopenharmony_ci        cpus = os.cpu_count()
39107db96d56Sopenharmony_ci        if cpus is not None:
39117db96d56Sopenharmony_ci            self.assertIsInstance(cpus, int)
39127db96d56Sopenharmony_ci            self.assertGreater(cpus, 0)
39137db96d56Sopenharmony_ci        else:
39147db96d56Sopenharmony_ci            self.skipTest("Could not determine the number of CPUs")
39157db96d56Sopenharmony_ci
39167db96d56Sopenharmony_ci
39177db96d56Sopenharmony_ci# FD inheritance check is only useful for systems with process support.
39187db96d56Sopenharmony_ci@support.requires_subprocess()
39197db96d56Sopenharmony_ciclass FDInheritanceTests(unittest.TestCase):
39207db96d56Sopenharmony_ci    def test_get_set_inheritable(self):
39217db96d56Sopenharmony_ci        fd = os.open(__file__, os.O_RDONLY)
39227db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
39237db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(fd), False)
39247db96d56Sopenharmony_ci
39257db96d56Sopenharmony_ci        os.set_inheritable(fd, True)
39267db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(fd), True)
39277db96d56Sopenharmony_ci
39287db96d56Sopenharmony_ci    @unittest.skipIf(fcntl is None, "need fcntl")
39297db96d56Sopenharmony_ci    def test_get_inheritable_cloexec(self):
39307db96d56Sopenharmony_ci        fd = os.open(__file__, os.O_RDONLY)
39317db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
39327db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(fd), False)
39337db96d56Sopenharmony_ci
39347db96d56Sopenharmony_ci        # clear FD_CLOEXEC flag
39357db96d56Sopenharmony_ci        flags = fcntl.fcntl(fd, fcntl.F_GETFD)
39367db96d56Sopenharmony_ci        flags &= ~fcntl.FD_CLOEXEC
39377db96d56Sopenharmony_ci        fcntl.fcntl(fd, fcntl.F_SETFD, flags)
39387db96d56Sopenharmony_ci
39397db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(fd), True)
39407db96d56Sopenharmony_ci
39417db96d56Sopenharmony_ci    @unittest.skipIf(fcntl is None, "need fcntl")
39427db96d56Sopenharmony_ci    def test_set_inheritable_cloexec(self):
39437db96d56Sopenharmony_ci        fd = os.open(__file__, os.O_RDONLY)
39447db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
39457db96d56Sopenharmony_ci        self.assertEqual(fcntl.fcntl(fd, fcntl.F_GETFD) & fcntl.FD_CLOEXEC,
39467db96d56Sopenharmony_ci                         fcntl.FD_CLOEXEC)
39477db96d56Sopenharmony_ci
39487db96d56Sopenharmony_ci        os.set_inheritable(fd, True)
39497db96d56Sopenharmony_ci        self.assertEqual(fcntl.fcntl(fd, fcntl.F_GETFD) & fcntl.FD_CLOEXEC,
39507db96d56Sopenharmony_ci                         0)
39517db96d56Sopenharmony_ci
39527db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'O_PATH'), "need os.O_PATH")
39537db96d56Sopenharmony_ci    def test_get_set_inheritable_o_path(self):
39547db96d56Sopenharmony_ci        fd = os.open(__file__, os.O_PATH)
39557db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
39567db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(fd), False)
39577db96d56Sopenharmony_ci
39587db96d56Sopenharmony_ci        os.set_inheritable(fd, True)
39597db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(fd), True)
39607db96d56Sopenharmony_ci
39617db96d56Sopenharmony_ci        os.set_inheritable(fd, False)
39627db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(fd), False)
39637db96d56Sopenharmony_ci
39647db96d56Sopenharmony_ci    def test_get_set_inheritable_badf(self):
39657db96d56Sopenharmony_ci        fd = os_helper.make_bad_fd()
39667db96d56Sopenharmony_ci
39677db96d56Sopenharmony_ci        with self.assertRaises(OSError) as ctx:
39687db96d56Sopenharmony_ci            os.get_inheritable(fd)
39697db96d56Sopenharmony_ci        self.assertEqual(ctx.exception.errno, errno.EBADF)
39707db96d56Sopenharmony_ci
39717db96d56Sopenharmony_ci        with self.assertRaises(OSError) as ctx:
39727db96d56Sopenharmony_ci            os.set_inheritable(fd, True)
39737db96d56Sopenharmony_ci        self.assertEqual(ctx.exception.errno, errno.EBADF)
39747db96d56Sopenharmony_ci
39757db96d56Sopenharmony_ci        with self.assertRaises(OSError) as ctx:
39767db96d56Sopenharmony_ci            os.set_inheritable(fd, False)
39777db96d56Sopenharmony_ci        self.assertEqual(ctx.exception.errno, errno.EBADF)
39787db96d56Sopenharmony_ci
39797db96d56Sopenharmony_ci    def test_open(self):
39807db96d56Sopenharmony_ci        fd = os.open(__file__, os.O_RDONLY)
39817db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
39827db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(fd), False)
39837db96d56Sopenharmony_ci
39847db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'pipe'), "need os.pipe()")
39857db96d56Sopenharmony_ci    def test_pipe(self):
39867db96d56Sopenharmony_ci        rfd, wfd = os.pipe()
39877db96d56Sopenharmony_ci        self.addCleanup(os.close, rfd)
39887db96d56Sopenharmony_ci        self.addCleanup(os.close, wfd)
39897db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(rfd), False)
39907db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(wfd), False)
39917db96d56Sopenharmony_ci
39927db96d56Sopenharmony_ci    def test_dup(self):
39937db96d56Sopenharmony_ci        fd1 = os.open(__file__, os.O_RDONLY)
39947db96d56Sopenharmony_ci        self.addCleanup(os.close, fd1)
39957db96d56Sopenharmony_ci
39967db96d56Sopenharmony_ci        fd2 = os.dup(fd1)
39977db96d56Sopenharmony_ci        self.addCleanup(os.close, fd2)
39987db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(fd2), False)
39997db96d56Sopenharmony_ci
40007db96d56Sopenharmony_ci    def test_dup_standard_stream(self):
40017db96d56Sopenharmony_ci        fd = os.dup(1)
40027db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
40037db96d56Sopenharmony_ci        self.assertGreater(fd, 0)
40047db96d56Sopenharmony_ci
40057db96d56Sopenharmony_ci    @unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
40067db96d56Sopenharmony_ci    def test_dup_nul(self):
40077db96d56Sopenharmony_ci        # os.dup() was creating inheritable fds for character files.
40087db96d56Sopenharmony_ci        fd1 = os.open('NUL', os.O_RDONLY)
40097db96d56Sopenharmony_ci        self.addCleanup(os.close, fd1)
40107db96d56Sopenharmony_ci        fd2 = os.dup(fd1)
40117db96d56Sopenharmony_ci        self.addCleanup(os.close, fd2)
40127db96d56Sopenharmony_ci        self.assertFalse(os.get_inheritable(fd2))
40137db96d56Sopenharmony_ci
40147db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'dup2'), "need os.dup2()")
40157db96d56Sopenharmony_ci    def test_dup2(self):
40167db96d56Sopenharmony_ci        fd = os.open(__file__, os.O_RDONLY)
40177db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
40187db96d56Sopenharmony_ci
40197db96d56Sopenharmony_ci        # inheritable by default
40207db96d56Sopenharmony_ci        fd2 = os.open(__file__, os.O_RDONLY)
40217db96d56Sopenharmony_ci        self.addCleanup(os.close, fd2)
40227db96d56Sopenharmony_ci        self.assertEqual(os.dup2(fd, fd2), fd2)
40237db96d56Sopenharmony_ci        self.assertTrue(os.get_inheritable(fd2))
40247db96d56Sopenharmony_ci
40257db96d56Sopenharmony_ci        # force non-inheritable
40267db96d56Sopenharmony_ci        fd3 = os.open(__file__, os.O_RDONLY)
40277db96d56Sopenharmony_ci        self.addCleanup(os.close, fd3)
40287db96d56Sopenharmony_ci        self.assertEqual(os.dup2(fd, fd3, inheritable=False), fd3)
40297db96d56Sopenharmony_ci        self.assertFalse(os.get_inheritable(fd3))
40307db96d56Sopenharmony_ci
40317db96d56Sopenharmony_ci    @unittest.skipUnless(hasattr(os, 'openpty'), "need os.openpty()")
40327db96d56Sopenharmony_ci    def test_openpty(self):
40337db96d56Sopenharmony_ci        master_fd, slave_fd = os.openpty()
40347db96d56Sopenharmony_ci        self.addCleanup(os.close, master_fd)
40357db96d56Sopenharmony_ci        self.addCleanup(os.close, slave_fd)
40367db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(master_fd), False)
40377db96d56Sopenharmony_ci        self.assertEqual(os.get_inheritable(slave_fd), False)
40387db96d56Sopenharmony_ci
40397db96d56Sopenharmony_ci
40407db96d56Sopenharmony_ciclass PathTConverterTests(unittest.TestCase):
40417db96d56Sopenharmony_ci    # tuples of (function name, allows fd arguments, additional arguments to
40427db96d56Sopenharmony_ci    # function, cleanup function)
40437db96d56Sopenharmony_ci    functions = [
40447db96d56Sopenharmony_ci        ('stat', True, (), None),
40457db96d56Sopenharmony_ci        ('lstat', False, (), None),
40467db96d56Sopenharmony_ci        ('access', False, (os.F_OK,), None),
40477db96d56Sopenharmony_ci        ('chflags', False, (0,), None),
40487db96d56Sopenharmony_ci        ('lchflags', False, (0,), None),
40497db96d56Sopenharmony_ci        ('open', False, (os.O_RDONLY,), getattr(os, 'close', None)),
40507db96d56Sopenharmony_ci    ]
40517db96d56Sopenharmony_ci
40527db96d56Sopenharmony_ci    def test_path_t_converter(self):
40537db96d56Sopenharmony_ci        str_filename = os_helper.TESTFN
40547db96d56Sopenharmony_ci        if os.name == 'nt':
40557db96d56Sopenharmony_ci            bytes_fspath = bytes_filename = None
40567db96d56Sopenharmony_ci        else:
40577db96d56Sopenharmony_ci            bytes_filename = os.fsencode(os_helper.TESTFN)
40587db96d56Sopenharmony_ci            bytes_fspath = FakePath(bytes_filename)
40597db96d56Sopenharmony_ci        fd = os.open(FakePath(str_filename), os.O_WRONLY|os.O_CREAT)
40607db96d56Sopenharmony_ci        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
40617db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
40627db96d56Sopenharmony_ci
40637db96d56Sopenharmony_ci        int_fspath = FakePath(fd)
40647db96d56Sopenharmony_ci        str_fspath = FakePath(str_filename)
40657db96d56Sopenharmony_ci
40667db96d56Sopenharmony_ci        for name, allow_fd, extra_args, cleanup_fn in self.functions:
40677db96d56Sopenharmony_ci            with self.subTest(name=name):
40687db96d56Sopenharmony_ci                try:
40697db96d56Sopenharmony_ci                    fn = getattr(os, name)
40707db96d56Sopenharmony_ci                except AttributeError:
40717db96d56Sopenharmony_ci                    continue
40727db96d56Sopenharmony_ci
40737db96d56Sopenharmony_ci                for path in (str_filename, bytes_filename, str_fspath,
40747db96d56Sopenharmony_ci                             bytes_fspath):
40757db96d56Sopenharmony_ci                    if path is None:
40767db96d56Sopenharmony_ci                        continue
40777db96d56Sopenharmony_ci                    with self.subTest(name=name, path=path):
40787db96d56Sopenharmony_ci                        result = fn(path, *extra_args)
40797db96d56Sopenharmony_ci                        if cleanup_fn is not None:
40807db96d56Sopenharmony_ci                            cleanup_fn(result)
40817db96d56Sopenharmony_ci
40827db96d56Sopenharmony_ci                with self.assertRaisesRegex(
40837db96d56Sopenharmony_ci                        TypeError, 'to return str or bytes'):
40847db96d56Sopenharmony_ci                    fn(int_fspath, *extra_args)
40857db96d56Sopenharmony_ci
40867db96d56Sopenharmony_ci                if allow_fd:
40877db96d56Sopenharmony_ci                    result = fn(fd, *extra_args)  # should not fail
40887db96d56Sopenharmony_ci                    if cleanup_fn is not None:
40897db96d56Sopenharmony_ci                        cleanup_fn(result)
40907db96d56Sopenharmony_ci                else:
40917db96d56Sopenharmony_ci                    with self.assertRaisesRegex(
40927db96d56Sopenharmony_ci                            TypeError,
40937db96d56Sopenharmony_ci                            'os.PathLike'):
40947db96d56Sopenharmony_ci                        fn(fd, *extra_args)
40957db96d56Sopenharmony_ci
40967db96d56Sopenharmony_ci    def test_path_t_converter_and_custom_class(self):
40977db96d56Sopenharmony_ci        msg = r'__fspath__\(\) to return str or bytes, not %s'
40987db96d56Sopenharmony_ci        with self.assertRaisesRegex(TypeError, msg % r'int'):
40997db96d56Sopenharmony_ci            os.stat(FakePath(2))
41007db96d56Sopenharmony_ci        with self.assertRaisesRegex(TypeError, msg % r'float'):
41017db96d56Sopenharmony_ci            os.stat(FakePath(2.34))
41027db96d56Sopenharmony_ci        with self.assertRaisesRegex(TypeError, msg % r'object'):
41037db96d56Sopenharmony_ci            os.stat(FakePath(object()))
41047db96d56Sopenharmony_ci
41057db96d56Sopenharmony_ci
41067db96d56Sopenharmony_ci@unittest.skipUnless(hasattr(os, 'get_blocking'),
41077db96d56Sopenharmony_ci                     'needs os.get_blocking() and os.set_blocking()')
41087db96d56Sopenharmony_ci@unittest.skipIf(support.is_emscripten, "Cannot unset blocking flag")
41097db96d56Sopenharmony_ciclass BlockingTests(unittest.TestCase):
41107db96d56Sopenharmony_ci    def test_blocking(self):
41117db96d56Sopenharmony_ci        fd = os.open(__file__, os.O_RDONLY)
41127db96d56Sopenharmony_ci        self.addCleanup(os.close, fd)
41137db96d56Sopenharmony_ci        self.assertEqual(os.get_blocking(fd), True)
41147db96d56Sopenharmony_ci
41157db96d56Sopenharmony_ci        os.set_blocking(fd, False)
41167db96d56Sopenharmony_ci        self.assertEqual(os.get_blocking(fd), False)
41177db96d56Sopenharmony_ci
41187db96d56Sopenharmony_ci        os.set_blocking(fd, True)
41197db96d56Sopenharmony_ci        self.assertEqual(os.get_blocking(fd), True)
41207db96d56Sopenharmony_ci
41217db96d56Sopenharmony_ci
41227db96d56Sopenharmony_ci
41237db96d56Sopenharmony_ciclass ExportsTests(unittest.TestCase):
41247db96d56Sopenharmony_ci    def test_os_all(self):
41257db96d56Sopenharmony_ci        self.assertIn('open', os.__all__)
41267db96d56Sopenharmony_ci        self.assertIn('walk', os.__all__)
41277db96d56Sopenharmony_ci
41287db96d56Sopenharmony_ci
41297db96d56Sopenharmony_ciclass TestDirEntry(unittest.TestCase):
41307db96d56Sopenharmony_ci    def setUp(self):
41317db96d56Sopenharmony_ci        self.path = os.path.realpath(os_helper.TESTFN)
41327db96d56Sopenharmony_ci        self.addCleanup(os_helper.rmtree, self.path)
41337db96d56Sopenharmony_ci        os.mkdir(self.path)
41347db96d56Sopenharmony_ci
41357db96d56Sopenharmony_ci    def test_uninstantiable(self):
41367db96d56Sopenharmony_ci        self.assertRaises(TypeError, os.DirEntry)
41377db96d56Sopenharmony_ci
41387db96d56Sopenharmony_ci    def test_unpickable(self):
41397db96d56Sopenharmony_ci        filename = create_file(os.path.join(self.path, "file.txt"), b'python')
41407db96d56Sopenharmony_ci        entry = [entry for entry in os.scandir(self.path)].pop()
41417db96d56Sopenharmony_ci        self.assertIsInstance(entry, os.DirEntry)
41427db96d56Sopenharmony_ci        self.assertEqual(entry.name, "file.txt")
41437db96d56Sopenharmony_ci        import pickle
41447db96d56Sopenharmony_ci        self.assertRaises(TypeError, pickle.dumps, entry, filename)
41457db96d56Sopenharmony_ci
41467db96d56Sopenharmony_ci
41477db96d56Sopenharmony_ciclass TestScandir(unittest.TestCase):
41487db96d56Sopenharmony_ci    check_no_resource_warning = warnings_helper.check_no_resource_warning
41497db96d56Sopenharmony_ci
41507db96d56Sopenharmony_ci    def setUp(self):
41517db96d56Sopenharmony_ci        self.path = os.path.realpath(os_helper.TESTFN)
41527db96d56Sopenharmony_ci        self.bytes_path = os.fsencode(self.path)
41537db96d56Sopenharmony_ci        self.addCleanup(os_helper.rmtree, self.path)
41547db96d56Sopenharmony_ci        os.mkdir(self.path)
41557db96d56Sopenharmony_ci
41567db96d56Sopenharmony_ci    def create_file(self, name="file.txt"):
41577db96d56Sopenharmony_ci        path = self.bytes_path if isinstance(name, bytes) else self.path
41587db96d56Sopenharmony_ci        filename = os.path.join(path, name)
41597db96d56Sopenharmony_ci        create_file(filename, b'python')
41607db96d56Sopenharmony_ci        return filename
41617db96d56Sopenharmony_ci
41627db96d56Sopenharmony_ci    def get_entries(self, names):
41637db96d56Sopenharmony_ci        entries = dict((entry.name, entry)
41647db96d56Sopenharmony_ci                       for entry in os.scandir(self.path))
41657db96d56Sopenharmony_ci        self.assertEqual(sorted(entries.keys()), names)
41667db96d56Sopenharmony_ci        return entries
41677db96d56Sopenharmony_ci
41687db96d56Sopenharmony_ci    def assert_stat_equal(self, stat1, stat2, skip_fields):
41697db96d56Sopenharmony_ci        if skip_fields:
41707db96d56Sopenharmony_ci            for attr in dir(stat1):
41717db96d56Sopenharmony_ci                if not attr.startswith("st_"):
41727db96d56Sopenharmony_ci                    continue
41737db96d56Sopenharmony_ci                if attr in ("st_dev", "st_ino", "st_nlink"):
41747db96d56Sopenharmony_ci                    continue
41757db96d56Sopenharmony_ci                self.assertEqual(getattr(stat1, attr),
41767db96d56Sopenharmony_ci                                 getattr(stat2, attr),
41777db96d56Sopenharmony_ci                                 (stat1, stat2, attr))
41787db96d56Sopenharmony_ci        else:
41797db96d56Sopenharmony_ci            self.assertEqual(stat1, stat2)
41807db96d56Sopenharmony_ci
41817db96d56Sopenharmony_ci    def test_uninstantiable(self):
41827db96d56Sopenharmony_ci        scandir_iter = os.scandir(self.path)
41837db96d56Sopenharmony_ci        self.assertRaises(TypeError, type(scandir_iter))
41847db96d56Sopenharmony_ci        scandir_iter.close()
41857db96d56Sopenharmony_ci
41867db96d56Sopenharmony_ci    def test_unpickable(self):
41877db96d56Sopenharmony_ci        filename = self.create_file("file.txt")
41887db96d56Sopenharmony_ci        scandir_iter = os.scandir(self.path)
41897db96d56Sopenharmony_ci        import pickle
41907db96d56Sopenharmony_ci        self.assertRaises(TypeError, pickle.dumps, scandir_iter, filename)
41917db96d56Sopenharmony_ci        scandir_iter.close()
41927db96d56Sopenharmony_ci
41937db96d56Sopenharmony_ci    def check_entry(self, entry, name, is_dir, is_file, is_symlink):
41947db96d56Sopenharmony_ci        self.assertIsInstance(entry, os.DirEntry)
41957db96d56Sopenharmony_ci        self.assertEqual(entry.name, name)
41967db96d56Sopenharmony_ci        self.assertEqual(entry.path, os.path.join(self.path, name))
41977db96d56Sopenharmony_ci        self.assertEqual(entry.inode(),
41987db96d56Sopenharmony_ci                         os.stat(entry.path, follow_symlinks=False).st_ino)
41997db96d56Sopenharmony_ci
42007db96d56Sopenharmony_ci        entry_stat = os.stat(entry.path)
42017db96d56Sopenharmony_ci        self.assertEqual(entry.is_dir(),
42027db96d56Sopenharmony_ci                         stat.S_ISDIR(entry_stat.st_mode))
42037db96d56Sopenharmony_ci        self.assertEqual(entry.is_file(),
42047db96d56Sopenharmony_ci                         stat.S_ISREG(entry_stat.st_mode))
42057db96d56Sopenharmony_ci        self.assertEqual(entry.is_symlink(),
42067db96d56Sopenharmony_ci                         os.path.islink(entry.path))
42077db96d56Sopenharmony_ci
42087db96d56Sopenharmony_ci        entry_lstat = os.stat(entry.path, follow_symlinks=False)
42097db96d56Sopenharmony_ci        self.assertEqual(entry.is_dir(follow_symlinks=False),
42107db96d56Sopenharmony_ci                         stat.S_ISDIR(entry_lstat.st_mode))
42117db96d56Sopenharmony_ci        self.assertEqual(entry.is_file(follow_symlinks=False),
42127db96d56Sopenharmony_ci                         stat.S_ISREG(entry_lstat.st_mode))
42137db96d56Sopenharmony_ci
42147db96d56Sopenharmony_ci        self.assert_stat_equal(entry.stat(),
42157db96d56Sopenharmony_ci                               entry_stat,
42167db96d56Sopenharmony_ci                               os.name == 'nt' and not is_symlink)
42177db96d56Sopenharmony_ci        self.assert_stat_equal(entry.stat(follow_symlinks=False),
42187db96d56Sopenharmony_ci                               entry_lstat,
42197db96d56Sopenharmony_ci                               os.name == 'nt')
42207db96d56Sopenharmony_ci
42217db96d56Sopenharmony_ci    def test_attributes(self):
42227db96d56Sopenharmony_ci        link = hasattr(os, 'link')
42237db96d56Sopenharmony_ci        symlink = os_helper.can_symlink()
42247db96d56Sopenharmony_ci
42257db96d56Sopenharmony_ci        dirname = os.path.join(self.path, "dir")
42267db96d56Sopenharmony_ci        os.mkdir(dirname)
42277db96d56Sopenharmony_ci        filename = self.create_file("file.txt")
42287db96d56Sopenharmony_ci        if link:
42297db96d56Sopenharmony_ci            try:
42307db96d56Sopenharmony_ci                os.link(filename, os.path.join(self.path, "link_file.txt"))
42317db96d56Sopenharmony_ci            except PermissionError as e:
42327db96d56Sopenharmony_ci                self.skipTest('os.link(): %s' % e)
42337db96d56Sopenharmony_ci        if symlink:
42347db96d56Sopenharmony_ci            os.symlink(dirname, os.path.join(self.path, "symlink_dir"),
42357db96d56Sopenharmony_ci                       target_is_directory=True)
42367db96d56Sopenharmony_ci            os.symlink(filename, os.path.join(self.path, "symlink_file.txt"))
42377db96d56Sopenharmony_ci
42387db96d56Sopenharmony_ci        names = ['dir', 'file.txt']
42397db96d56Sopenharmony_ci        if link:
42407db96d56Sopenharmony_ci            names.append('link_file.txt')
42417db96d56Sopenharmony_ci        if symlink:
42427db96d56Sopenharmony_ci            names.extend(('symlink_dir', 'symlink_file.txt'))
42437db96d56Sopenharmony_ci        entries = self.get_entries(names)
42447db96d56Sopenharmony_ci
42457db96d56Sopenharmony_ci        entry = entries['dir']
42467db96d56Sopenharmony_ci        self.check_entry(entry, 'dir', True, False, False)
42477db96d56Sopenharmony_ci
42487db96d56Sopenharmony_ci        entry = entries['file.txt']
42497db96d56Sopenharmony_ci        self.check_entry(entry, 'file.txt', False, True, False)
42507db96d56Sopenharmony_ci
42517db96d56Sopenharmony_ci        if link:
42527db96d56Sopenharmony_ci            entry = entries['link_file.txt']
42537db96d56Sopenharmony_ci            self.check_entry(entry, 'link_file.txt', False, True, False)
42547db96d56Sopenharmony_ci
42557db96d56Sopenharmony_ci        if symlink:
42567db96d56Sopenharmony_ci            entry = entries['symlink_dir']
42577db96d56Sopenharmony_ci            self.check_entry(entry, 'symlink_dir', True, False, True)
42587db96d56Sopenharmony_ci
42597db96d56Sopenharmony_ci            entry = entries['symlink_file.txt']
42607db96d56Sopenharmony_ci            self.check_entry(entry, 'symlink_file.txt', False, True, True)
42617db96d56Sopenharmony_ci
42627db96d56Sopenharmony_ci    def get_entry(self, name):
42637db96d56Sopenharmony_ci        path = self.bytes_path if isinstance(name, bytes) else self.path
42647db96d56Sopenharmony_ci        entries = list(os.scandir(path))
42657db96d56Sopenharmony_ci        self.assertEqual(len(entries), 1)
42667db96d56Sopenharmony_ci
42677db96d56Sopenharmony_ci        entry = entries[0]
42687db96d56Sopenharmony_ci        self.assertEqual(entry.name, name)
42697db96d56Sopenharmony_ci        return entry
42707db96d56Sopenharmony_ci
42717db96d56Sopenharmony_ci    def create_file_entry(self, name='file.txt'):
42727db96d56Sopenharmony_ci        filename = self.create_file(name=name)
42737db96d56Sopenharmony_ci        return self.get_entry(os.path.basename(filename))
42747db96d56Sopenharmony_ci
42757db96d56Sopenharmony_ci    def test_current_directory(self):
42767db96d56Sopenharmony_ci        filename = self.create_file()
42777db96d56Sopenharmony_ci        old_dir = os.getcwd()
42787db96d56Sopenharmony_ci        try:
42797db96d56Sopenharmony_ci            os.chdir(self.path)
42807db96d56Sopenharmony_ci
42817db96d56Sopenharmony_ci            # call scandir() without parameter: it must list the content
42827db96d56Sopenharmony_ci            # of the current directory
42837db96d56Sopenharmony_ci            entries = dict((entry.name, entry) for entry in os.scandir())
42847db96d56Sopenharmony_ci            self.assertEqual(sorted(entries.keys()),
42857db96d56Sopenharmony_ci                             [os.path.basename(filename)])
42867db96d56Sopenharmony_ci        finally:
42877db96d56Sopenharmony_ci            os.chdir(old_dir)
42887db96d56Sopenharmony_ci
42897db96d56Sopenharmony_ci    def test_repr(self):
42907db96d56Sopenharmony_ci        entry = self.create_file_entry()
42917db96d56Sopenharmony_ci        self.assertEqual(repr(entry), "<DirEntry 'file.txt'>")
42927db96d56Sopenharmony_ci
42937db96d56Sopenharmony_ci    def test_fspath_protocol(self):
42947db96d56Sopenharmony_ci        entry = self.create_file_entry()
42957db96d56Sopenharmony_ci        self.assertEqual(os.fspath(entry), os.path.join(self.path, 'file.txt'))
42967db96d56Sopenharmony_ci
42977db96d56Sopenharmony_ci    def test_fspath_protocol_bytes(self):
42987db96d56Sopenharmony_ci        bytes_filename = os.fsencode('bytesfile.txt')
42997db96d56Sopenharmony_ci        bytes_entry = self.create_file_entry(name=bytes_filename)
43007db96d56Sopenharmony_ci        fspath = os.fspath(bytes_entry)
43017db96d56Sopenharmony_ci        self.assertIsInstance(fspath, bytes)
43027db96d56Sopenharmony_ci        self.assertEqual(fspath,
43037db96d56Sopenharmony_ci                         os.path.join(os.fsencode(self.path),bytes_filename))
43047db96d56Sopenharmony_ci
43057db96d56Sopenharmony_ci    def test_removed_dir(self):
43067db96d56Sopenharmony_ci        path = os.path.join(self.path, 'dir')
43077db96d56Sopenharmony_ci
43087db96d56Sopenharmony_ci        os.mkdir(path)
43097db96d56Sopenharmony_ci        entry = self.get_entry('dir')
43107db96d56Sopenharmony_ci        os.rmdir(path)
43117db96d56Sopenharmony_ci
43127db96d56Sopenharmony_ci        # On POSIX, is_dir() result depends if scandir() filled d_type or not
43137db96d56Sopenharmony_ci        if os.name == 'nt':
43147db96d56Sopenharmony_ci            self.assertTrue(entry.is_dir())
43157db96d56Sopenharmony_ci        self.assertFalse(entry.is_file())
43167db96d56Sopenharmony_ci        self.assertFalse(entry.is_symlink())
43177db96d56Sopenharmony_ci        if os.name == 'nt':
43187db96d56Sopenharmony_ci            self.assertRaises(FileNotFoundError, entry.inode)
43197db96d56Sopenharmony_ci            # don't fail
43207db96d56Sopenharmony_ci            entry.stat()
43217db96d56Sopenharmony_ci            entry.stat(follow_symlinks=False)
43227db96d56Sopenharmony_ci        else:
43237db96d56Sopenharmony_ci            self.assertGreater(entry.inode(), 0)
43247db96d56Sopenharmony_ci            self.assertRaises(FileNotFoundError, entry.stat)
43257db96d56Sopenharmony_ci            self.assertRaises(FileNotFoundError, entry.stat, follow_symlinks=False)
43267db96d56Sopenharmony_ci
43277db96d56Sopenharmony_ci    def test_removed_file(self):
43287db96d56Sopenharmony_ci        entry = self.create_file_entry()
43297db96d56Sopenharmony_ci        os.unlink(entry.path)
43307db96d56Sopenharmony_ci
43317db96d56Sopenharmony_ci        self.assertFalse(entry.is_dir())
43327db96d56Sopenharmony_ci        # On POSIX, is_dir() result depends if scandir() filled d_type or not
43337db96d56Sopenharmony_ci        if os.name == 'nt':
43347db96d56Sopenharmony_ci            self.assertTrue(entry.is_file())
43357db96d56Sopenharmony_ci        self.assertFalse(entry.is_symlink())
43367db96d56Sopenharmony_ci        if os.name == 'nt':
43377db96d56Sopenharmony_ci            self.assertRaises(FileNotFoundError, entry.inode)
43387db96d56Sopenharmony_ci            # don't fail
43397db96d56Sopenharmony_ci            entry.stat()
43407db96d56Sopenharmony_ci            entry.stat(follow_symlinks=False)
43417db96d56Sopenharmony_ci        else:
43427db96d56Sopenharmony_ci            self.assertGreater(entry.inode(), 0)
43437db96d56Sopenharmony_ci            self.assertRaises(FileNotFoundError, entry.stat)
43447db96d56Sopenharmony_ci            self.assertRaises(FileNotFoundError, entry.stat, follow_symlinks=False)
43457db96d56Sopenharmony_ci
43467db96d56Sopenharmony_ci    def test_broken_symlink(self):
43477db96d56Sopenharmony_ci        if not os_helper.can_symlink():
43487db96d56Sopenharmony_ci            return self.skipTest('cannot create symbolic link')
43497db96d56Sopenharmony_ci
43507db96d56Sopenharmony_ci        filename = self.create_file("file.txt")
43517db96d56Sopenharmony_ci        os.symlink(filename,
43527db96d56Sopenharmony_ci                   os.path.join(self.path, "symlink.txt"))
43537db96d56Sopenharmony_ci        entries = self.get_entries(['file.txt', 'symlink.txt'])
43547db96d56Sopenharmony_ci        entry = entries['symlink.txt']
43557db96d56Sopenharmony_ci        os.unlink(filename)
43567db96d56Sopenharmony_ci
43577db96d56Sopenharmony_ci        self.assertGreater(entry.inode(), 0)
43587db96d56Sopenharmony_ci        self.assertFalse(entry.is_dir())
43597db96d56Sopenharmony_ci        self.assertFalse(entry.is_file())  # broken symlink returns False
43607db96d56Sopenharmony_ci        self.assertFalse(entry.is_dir(follow_symlinks=False))
43617db96d56Sopenharmony_ci        self.assertFalse(entry.is_file(follow_symlinks=False))
43627db96d56Sopenharmony_ci        self.assertTrue(entry.is_symlink())
43637db96d56Sopenharmony_ci        self.assertRaises(FileNotFoundError, entry.stat)
43647db96d56Sopenharmony_ci        # don't fail
43657db96d56Sopenharmony_ci        entry.stat(follow_symlinks=False)
43667db96d56Sopenharmony_ci
43677db96d56Sopenharmony_ci    def test_bytes(self):
43687db96d56Sopenharmony_ci        self.create_file("file.txt")
43697db96d56Sopenharmony_ci
43707db96d56Sopenharmony_ci        path_bytes = os.fsencode(self.path)
43717db96d56Sopenharmony_ci        entries = list(os.scandir(path_bytes))
43727db96d56Sopenharmony_ci        self.assertEqual(len(entries), 1, entries)
43737db96d56Sopenharmony_ci        entry = entries[0]
43747db96d56Sopenharmony_ci
43757db96d56Sopenharmony_ci        self.assertEqual(entry.name, b'file.txt')
43767db96d56Sopenharmony_ci        self.assertEqual(entry.path,
43777db96d56Sopenharmony_ci                         os.fsencode(os.path.join(self.path, 'file.txt')))
43787db96d56Sopenharmony_ci
43797db96d56Sopenharmony_ci    def test_bytes_like(self):
43807db96d56Sopenharmony_ci        self.create_file("file.txt")
43817db96d56Sopenharmony_ci
43827db96d56Sopenharmony_ci        for cls in bytearray, memoryview:
43837db96d56Sopenharmony_ci            path_bytes = cls(os.fsencode(self.path))
43847db96d56Sopenharmony_ci            with self.assertWarns(DeprecationWarning):
43857db96d56Sopenharmony_ci                entries = list(os.scandir(path_bytes))
43867db96d56Sopenharmony_ci            self.assertEqual(len(entries), 1, entries)
43877db96d56Sopenharmony_ci            entry = entries[0]
43887db96d56Sopenharmony_ci
43897db96d56Sopenharmony_ci            self.assertEqual(entry.name, b'file.txt')
43907db96d56Sopenharmony_ci            self.assertEqual(entry.path,
43917db96d56Sopenharmony_ci                             os.fsencode(os.path.join(self.path, 'file.txt')))
43927db96d56Sopenharmony_ci            self.assertIs(type(entry.name), bytes)
43937db96d56Sopenharmony_ci            self.assertIs(type(entry.path), bytes)
43947db96d56Sopenharmony_ci
43957db96d56Sopenharmony_ci    @unittest.skipUnless(os.listdir in os.supports_fd,
43967db96d56Sopenharmony_ci                         'fd support for listdir required for this test.')
43977db96d56Sopenharmony_ci    def test_fd(self):
43987db96d56Sopenharmony_ci        self.assertIn(os.scandir, os.supports_fd)
43997db96d56Sopenharmony_ci        self.create_file('file.txt')
44007db96d56Sopenharmony_ci        expected_names = ['file.txt']
44017db96d56Sopenharmony_ci        if os_helper.can_symlink():
44027db96d56Sopenharmony_ci            os.symlink('file.txt', os.path.join(self.path, 'link'))
44037db96d56Sopenharmony_ci            expected_names.append('link')
44047db96d56Sopenharmony_ci
44057db96d56Sopenharmony_ci        with os_helper.open_dir_fd(self.path) as fd:
44067db96d56Sopenharmony_ci            with os.scandir(fd) as it:
44077db96d56Sopenharmony_ci                entries = list(it)
44087db96d56Sopenharmony_ci            names = [entry.name for entry in entries]
44097db96d56Sopenharmony_ci            self.assertEqual(sorted(names), expected_names)
44107db96d56Sopenharmony_ci            self.assertEqual(names, os.listdir(fd))
44117db96d56Sopenharmony_ci            for entry in entries:
44127db96d56Sopenharmony_ci                self.assertEqual(entry.path, entry.name)
44137db96d56Sopenharmony_ci                self.assertEqual(os.fspath(entry), entry.name)
44147db96d56Sopenharmony_ci                self.assertEqual(entry.is_symlink(), entry.name == 'link')
44157db96d56Sopenharmony_ci                if os.stat in os.supports_dir_fd:
44167db96d56Sopenharmony_ci                    st = os.stat(entry.name, dir_fd=fd)
44177db96d56Sopenharmony_ci                    self.assertEqual(entry.stat(), st)
44187db96d56Sopenharmony_ci                    st = os.stat(entry.name, dir_fd=fd, follow_symlinks=False)
44197db96d56Sopenharmony_ci                    self.assertEqual(entry.stat(follow_symlinks=False), st)
44207db96d56Sopenharmony_ci
44217db96d56Sopenharmony_ci    @unittest.skipIf(support.is_wasi, "WASI maps '' to cwd")
44227db96d56Sopenharmony_ci    def test_empty_path(self):
44237db96d56Sopenharmony_ci        self.assertRaises(FileNotFoundError, os.scandir, '')
44247db96d56Sopenharmony_ci
44257db96d56Sopenharmony_ci    def test_consume_iterator_twice(self):
44267db96d56Sopenharmony_ci        self.create_file("file.txt")
44277db96d56Sopenharmony_ci        iterator = os.scandir(self.path)
44287db96d56Sopenharmony_ci
44297db96d56Sopenharmony_ci        entries = list(iterator)
44307db96d56Sopenharmony_ci        self.assertEqual(len(entries), 1, entries)
44317db96d56Sopenharmony_ci
44327db96d56Sopenharmony_ci        # check than consuming the iterator twice doesn't raise exception
44337db96d56Sopenharmony_ci        entries2 = list(iterator)
44347db96d56Sopenharmony_ci        self.assertEqual(len(entries2), 0, entries2)
44357db96d56Sopenharmony_ci
44367db96d56Sopenharmony_ci    def test_bad_path_type(self):
44377db96d56Sopenharmony_ci        for obj in [1.234, {}, []]:
44387db96d56Sopenharmony_ci            self.assertRaises(TypeError, os.scandir, obj)
44397db96d56Sopenharmony_ci
44407db96d56Sopenharmony_ci    def test_close(self):
44417db96d56Sopenharmony_ci        self.create_file("file.txt")
44427db96d56Sopenharmony_ci        self.create_file("file2.txt")
44437db96d56Sopenharmony_ci        iterator = os.scandir(self.path)
44447db96d56Sopenharmony_ci        next(iterator)
44457db96d56Sopenharmony_ci        iterator.close()
44467db96d56Sopenharmony_ci        # multiple closes
44477db96d56Sopenharmony_ci        iterator.close()
44487db96d56Sopenharmony_ci        with self.check_no_resource_warning():
44497db96d56Sopenharmony_ci            del iterator
44507db96d56Sopenharmony_ci
44517db96d56Sopenharmony_ci    def test_context_manager(self):
44527db96d56Sopenharmony_ci        self.create_file("file.txt")
44537db96d56Sopenharmony_ci        self.create_file("file2.txt")
44547db96d56Sopenharmony_ci        with os.scandir(self.path) as iterator:
44557db96d56Sopenharmony_ci            next(iterator)
44567db96d56Sopenharmony_ci        with self.check_no_resource_warning():
44577db96d56Sopenharmony_ci            del iterator
44587db96d56Sopenharmony_ci
44597db96d56Sopenharmony_ci    def test_context_manager_close(self):
44607db96d56Sopenharmony_ci        self.create_file("file.txt")
44617db96d56Sopenharmony_ci        self.create_file("file2.txt")
44627db96d56Sopenharmony_ci        with os.scandir(self.path) as iterator:
44637db96d56Sopenharmony_ci            next(iterator)
44647db96d56Sopenharmony_ci            iterator.close()
44657db96d56Sopenharmony_ci
44667db96d56Sopenharmony_ci    def test_context_manager_exception(self):
44677db96d56Sopenharmony_ci        self.create_file("file.txt")
44687db96d56Sopenharmony_ci        self.create_file("file2.txt")
44697db96d56Sopenharmony_ci        with self.assertRaises(ZeroDivisionError):
44707db96d56Sopenharmony_ci            with os.scandir(self.path) as iterator:
44717db96d56Sopenharmony_ci                next(iterator)
44727db96d56Sopenharmony_ci                1/0
44737db96d56Sopenharmony_ci        with self.check_no_resource_warning():
44747db96d56Sopenharmony_ci            del iterator
44757db96d56Sopenharmony_ci
44767db96d56Sopenharmony_ci    def test_resource_warning(self):
44777db96d56Sopenharmony_ci        self.create_file("file.txt")
44787db96d56Sopenharmony_ci        self.create_file("file2.txt")
44797db96d56Sopenharmony_ci        iterator = os.scandir(self.path)
44807db96d56Sopenharmony_ci        next(iterator)
44817db96d56Sopenharmony_ci        with self.assertWarns(ResourceWarning):
44827db96d56Sopenharmony_ci            del iterator
44837db96d56Sopenharmony_ci            support.gc_collect()
44847db96d56Sopenharmony_ci        # exhausted iterator
44857db96d56Sopenharmony_ci        iterator = os.scandir(self.path)
44867db96d56Sopenharmony_ci        list(iterator)
44877db96d56Sopenharmony_ci        with self.check_no_resource_warning():
44887db96d56Sopenharmony_ci            del iterator
44897db96d56Sopenharmony_ci
44907db96d56Sopenharmony_ci
44917db96d56Sopenharmony_ciclass TestPEP519(unittest.TestCase):
44927db96d56Sopenharmony_ci
44937db96d56Sopenharmony_ci    # Abstracted so it can be overridden to test pure Python implementation
44947db96d56Sopenharmony_ci    # if a C version is provided.
44957db96d56Sopenharmony_ci    fspath = staticmethod(os.fspath)
44967db96d56Sopenharmony_ci
44977db96d56Sopenharmony_ci    def test_return_bytes(self):
44987db96d56Sopenharmony_ci        for b in b'hello', b'goodbye', b'some/path/and/file':
44997db96d56Sopenharmony_ci            self.assertEqual(b, self.fspath(b))
45007db96d56Sopenharmony_ci
45017db96d56Sopenharmony_ci    def test_return_string(self):
45027db96d56Sopenharmony_ci        for s in 'hello', 'goodbye', 'some/path/and/file':
45037db96d56Sopenharmony_ci            self.assertEqual(s, self.fspath(s))
45047db96d56Sopenharmony_ci
45057db96d56Sopenharmony_ci    def test_fsencode_fsdecode(self):
45067db96d56Sopenharmony_ci        for p in "path/like/object", b"path/like/object":
45077db96d56Sopenharmony_ci            pathlike = FakePath(p)
45087db96d56Sopenharmony_ci
45097db96d56Sopenharmony_ci            self.assertEqual(p, self.fspath(pathlike))
45107db96d56Sopenharmony_ci            self.assertEqual(b"path/like/object", os.fsencode(pathlike))
45117db96d56Sopenharmony_ci            self.assertEqual("path/like/object", os.fsdecode(pathlike))
45127db96d56Sopenharmony_ci
45137db96d56Sopenharmony_ci    def test_pathlike(self):
45147db96d56Sopenharmony_ci        self.assertEqual('#feelthegil', self.fspath(FakePath('#feelthegil')))
45157db96d56Sopenharmony_ci        self.assertTrue(issubclass(FakePath, os.PathLike))
45167db96d56Sopenharmony_ci        self.assertTrue(isinstance(FakePath('x'), os.PathLike))
45177db96d56Sopenharmony_ci
45187db96d56Sopenharmony_ci    def test_garbage_in_exception_out(self):
45197db96d56Sopenharmony_ci        vapor = type('blah', (), {})
45207db96d56Sopenharmony_ci        for o in int, type, os, vapor():
45217db96d56Sopenharmony_ci            self.assertRaises(TypeError, self.fspath, o)
45227db96d56Sopenharmony_ci
45237db96d56Sopenharmony_ci    def test_argument_required(self):
45247db96d56Sopenharmony_ci        self.assertRaises(TypeError, self.fspath)
45257db96d56Sopenharmony_ci
45267db96d56Sopenharmony_ci    def test_bad_pathlike(self):
45277db96d56Sopenharmony_ci        # __fspath__ returns a value other than str or bytes.
45287db96d56Sopenharmony_ci        self.assertRaises(TypeError, self.fspath, FakePath(42))
45297db96d56Sopenharmony_ci        # __fspath__ attribute that is not callable.
45307db96d56Sopenharmony_ci        c = type('foo', (), {})
45317db96d56Sopenharmony_ci        c.__fspath__ = 1
45327db96d56Sopenharmony_ci        self.assertRaises(TypeError, self.fspath, c())
45337db96d56Sopenharmony_ci        # __fspath__ raises an exception.
45347db96d56Sopenharmony_ci        self.assertRaises(ZeroDivisionError, self.fspath,
45357db96d56Sopenharmony_ci                          FakePath(ZeroDivisionError()))
45367db96d56Sopenharmony_ci
45377db96d56Sopenharmony_ci    def test_pathlike_subclasshook(self):
45387db96d56Sopenharmony_ci        # bpo-38878: subclasshook causes subclass checks
45397db96d56Sopenharmony_ci        # true on abstract implementation.
45407db96d56Sopenharmony_ci        class A(os.PathLike):
45417db96d56Sopenharmony_ci            pass
45427db96d56Sopenharmony_ci        self.assertFalse(issubclass(FakePath, A))
45437db96d56Sopenharmony_ci        self.assertTrue(issubclass(FakePath, os.PathLike))
45447db96d56Sopenharmony_ci
45457db96d56Sopenharmony_ci    def test_pathlike_class_getitem(self):
45467db96d56Sopenharmony_ci        self.assertIsInstance(os.PathLike[bytes], types.GenericAlias)
45477db96d56Sopenharmony_ci
45487db96d56Sopenharmony_ci
45497db96d56Sopenharmony_ciclass TimesTests(unittest.TestCase):
45507db96d56Sopenharmony_ci    def test_times(self):
45517db96d56Sopenharmony_ci        times = os.times()
45527db96d56Sopenharmony_ci        self.assertIsInstance(times, os.times_result)
45537db96d56Sopenharmony_ci
45547db96d56Sopenharmony_ci        for field in ('user', 'system', 'children_user', 'children_system',
45557db96d56Sopenharmony_ci                      'elapsed'):
45567db96d56Sopenharmony_ci            value = getattr(times, field)
45577db96d56Sopenharmony_ci            self.assertIsInstance(value, float)
45587db96d56Sopenharmony_ci
45597db96d56Sopenharmony_ci        if os.name == 'nt':
45607db96d56Sopenharmony_ci            self.assertEqual(times.children_user, 0)
45617db96d56Sopenharmony_ci            self.assertEqual(times.children_system, 0)
45627db96d56Sopenharmony_ci            self.assertEqual(times.elapsed, 0)
45637db96d56Sopenharmony_ci
45647db96d56Sopenharmony_ci
45657db96d56Sopenharmony_ci@support.requires_fork()
45667db96d56Sopenharmony_ciclass ForkTests(unittest.TestCase):
45677db96d56Sopenharmony_ci    def test_fork(self):
45687db96d56Sopenharmony_ci        # bpo-42540: ensure os.fork() with non-default memory allocator does
45697db96d56Sopenharmony_ci        # not crash on exit.
45707db96d56Sopenharmony_ci        code = """if 1:
45717db96d56Sopenharmony_ci            import os
45727db96d56Sopenharmony_ci            from test import support
45737db96d56Sopenharmony_ci            pid = os.fork()
45747db96d56Sopenharmony_ci            if pid != 0:
45757db96d56Sopenharmony_ci                support.wait_process(pid, exitcode=0)
45767db96d56Sopenharmony_ci        """
45777db96d56Sopenharmony_ci        assert_python_ok("-c", code)
45787db96d56Sopenharmony_ci        assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug")
45797db96d56Sopenharmony_ci
45807db96d56Sopenharmony_ci
45817db96d56Sopenharmony_ci# Only test if the C version is provided, otherwise TestPEP519 already tested
45827db96d56Sopenharmony_ci# the pure Python implementation.
45837db96d56Sopenharmony_ciif hasattr(os, "_fspath"):
45847db96d56Sopenharmony_ci    class TestPEP519PurePython(TestPEP519):
45857db96d56Sopenharmony_ci
45867db96d56Sopenharmony_ci        """Explicitly test the pure Python implementation of os.fspath()."""
45877db96d56Sopenharmony_ci
45887db96d56Sopenharmony_ci        fspath = staticmethod(os._fspath)
45897db96d56Sopenharmony_ci
45907db96d56Sopenharmony_ci
45917db96d56Sopenharmony_ciif __name__ == "__main__":
45927db96d56Sopenharmony_ci    unittest.main()
4593