test_platform.py 12.1 KB
Newer Older
1
from unittest import mock
2
import os
3
import platform
4
import subprocess
5
import sys
6
import tempfile
7 8
import unittest
import warnings
9

10
from test import support
11

12 13 14 15
class PlatformTest(unittest.TestCase):
    def test_architecture(self):
        res = platform.architecture()

16
    @support.skip_unless_symlink
17 18 19 20
    def test_architecture_via_symlink(self): # issue3762
        # On Windows, the EXE needs to know where pythonXY.dll is at so we have
        # to add the directory to the path.
        if sys.platform == "win32":
21 22
            os.environ["Path"] = "{};{}".format(
                os.path.dirname(sys.executable), os.environ["Path"])
23 24 25 26 27 28 29 30 31 32 33 34 35

        def get(python):
            cmd = [python, '-c',
                'import platform; print(platform.architecture())']
            p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
            return p.communicate()
        real = os.path.realpath(sys.executable)
        link = os.path.abspath(support.TESTFN)
        os.symlink(real, link)
        try:
            self.assertEqual(get(real), get(link))
        finally:
            os.remove(link)
36

37 38 39 40 41
    def test_platform(self):
        for aliased in (False, True):
            for terse in (False, True):
                res = platform.platform(aliased, terse)

42 43
    def test_system(self):
        res = platform.system()
44

45 46
    def test_node(self):
        res = platform.node()
47

48 49
    def test_release(self):
        res = platform.release()
50 51

    def test_version(self):
52 53 54 55 56 57 58 59
        res = platform.version()

    def test_machine(self):
        res = platform.machine()

    def test_processor(self):
        res = platform.processor()

Benjamin Peterson's avatar
Benjamin Peterson committed
60 61
    def setUp(self):
        self.save_version = sys.version
62
        self.save_mercurial = sys._mercurial
Benjamin Peterson's avatar
Benjamin Peterson committed
63
        self.save_platform = sys.platform
64

Benjamin Peterson's avatar
Benjamin Peterson committed
65 66
    def tearDown(self):
        sys.version = self.save_version
67
        sys._mercurial = self.save_mercurial
Benjamin Peterson's avatar
Benjamin Peterson committed
68
        sys.platform = self.save_platform
69

Benjamin Peterson's avatar
Benjamin Peterson committed
70 71 72 73 74 75 76 77 78 79 80
    def test_sys_version(self):
        # Old test.
        for input, output in (
            ('2.4.3 (#1, Jun 21 2006, 13:54:21) \n[GCC 3.3.4 (pre 3.3.5 20040809)]',
             ('CPython', '2.4.3', '', '', '1', 'Jun 21 2006 13:54:21', 'GCC 3.3.4 (pre 3.3.5 20040809)')),
            ('IronPython 1.0.60816 on .NET 2.0.50727.42',
             ('IronPython', '1.0.60816', '', '', '', '', '.NET 2.0.50727.42')),
            ('IronPython 1.0 (1.0.61005.1977) on .NET 2.0.50727.42',
             ('IronPython', '1.0.0', '', '', '', '', '.NET 2.0.50727.42')),
            ):
            # branch and revision are not "parsed", but fetched
81
            # from sys._mercurial.  Ignore them
Benjamin Peterson's avatar
Benjamin Peterson committed
82 83 84 85
            (name, version, branch, revision, buildno, builddate, compiler) \
                   = platform._sys_version(input)
            self.assertEqual(
                (name, version, '', '', buildno, builddate, compiler), output)
86

Benjamin Peterson's avatar
Benjamin Peterson committed
87 88 89 90 91 92 93 94 95
        # Tests for python_implementation(), python_version(), python_branch(),
        # python_revision(), python_build(), and python_compiler().
        sys_versions = {
            ("2.6.1 (r261:67515, Dec  6 2008, 15:26:00) \n[GCC 4.0.1 (Apple Computer, Inc. build 5370)]",
             ('CPython', 'tags/r261', '67515'), self.save_platform)
            :
                ("CPython", "2.6.1", "tags/r261", "67515",
                 ('r261:67515', 'Dec  6 2008 15:26:00'),
                 'GCC 4.0.1 (Apple Computer, Inc. build 5370)'),
96

Benjamin Peterson's avatar
Benjamin Peterson committed
97 98 99 100
            ("IronPython 2.0 (2.0.0.0) on .NET 2.0.50727.3053", None, "cli")
            :
                ("IronPython", "2.0.0", "", "", ("", ""),
                 ".NET 2.0.50727.3053"),
101 102 103 104 105 106 107 108 109 110 111

            ("2.6.1 (IronPython 2.6.1 (2.6.10920.0) on .NET 2.0.50727.1433)", None, "cli")
            :
                ("IronPython", "2.6.1", "", "", ("", ""),
                 ".NET 2.0.50727.1433"),

            ("2.7.4 (IronPython 2.7.4 (2.7.0.40) on Mono 4.0.30319.1 (32-bit))", None, "cli")
            :
                ("IronPython", "2.7.4", "", "", ("", ""),
                 "Mono 4.0.30319.1 (32-bit)"),

Benjamin Peterson's avatar
Benjamin Peterson committed
112 113 114 115 116
            ("2.5 (trunk:6107, Mar 26 2009, 13:02:18) \n[Java HotSpot(TM) Client VM (\"Apple Computer, Inc.\")]",
            ('Jython', 'trunk', '6107'), "java1.5.0_16")
            :
                ("Jython", "2.5.0", "trunk", "6107",
                 ('trunk:6107', 'Mar 26 2009'), "java1.5.0_16"),
117

Benjamin Peterson's avatar
Benjamin Peterson committed
118 119 120 121 122 123 124 125 126 127
            ("2.5.2 (63378, Mar 26 2009, 18:03:29)\n[PyPy 1.0.0]",
             ('PyPy', 'trunk', '63378'), self.save_platform)
            :
                ("PyPy", "2.5.2", "trunk", "63378", ('63378', 'Mar 26 2009'),
                 "")
            }
        for (version_tag, subversion, sys_platform), info in \
                sys_versions.items():
            sys.version = version_tag
            if subversion is None:
128 129
                if hasattr(sys, "_mercurial"):
                    del sys._mercurial
Benjamin Peterson's avatar
Benjamin Peterson committed
130
            else:
131
                sys._mercurial = subversion
Benjamin Peterson's avatar
Benjamin Peterson committed
132 133 134 135 136 137 138 139
            if sys_platform is not None:
                sys.platform = sys_platform
            self.assertEqual(platform.python_implementation(), info[0])
            self.assertEqual(platform.python_version(), info[1])
            self.assertEqual(platform.python_branch(), info[2])
            self.assertEqual(platform.python_revision(), info[3])
            self.assertEqual(platform.python_build(), info[4])
            self.assertEqual(platform.python_compiler(), info[5])
140 141 142 143 144 145 146 147 148 149

    def test_system_alias(self):
        res = platform.system_alias(
            platform.system(),
            platform.release(),
            platform.version(),
        )

    def test_uname(self):
        res = platform.uname()
150
        self.assertTrue(any(res))
151 152 153 154 155 156
        self.assertEqual(res[0], res.system)
        self.assertEqual(res[1], res.node)
        self.assertEqual(res[2], res.release)
        self.assertEqual(res[3], res.version)
        self.assertEqual(res[4], res.machine)
        self.assertEqual(res[5], res.processor)
157

158 159 160 161 162 163 164
    @unittest.skipUnless(sys.platform.startswith('win'), "windows only test")
    def test_uname_win32_ARCHITEW6432(self):
        # Issue 7860: make sure we get architecture from the correct variable
        # on 64 bit Windows: if PROCESSOR_ARCHITEW6432 exists we should be
        # using it, per
        # http://blogs.msdn.com/david.wang/archive/2006/03/26/HOWTO-Detect-Process-Bitness.aspx
        try:
165
            with support.EnvironmentVarGuard() as environ:
166 167 168 169 170 171 172 173 174 175 176 177 178
                if 'PROCESSOR_ARCHITEW6432' in environ:
                    del environ['PROCESSOR_ARCHITEW6432']
                environ['PROCESSOR_ARCHITECTURE'] = 'foo'
                platform._uname_cache = None
                system, node, release, version, machine, processor = platform.uname()
                self.assertEqual(machine, 'foo')
                environ['PROCESSOR_ARCHITEW6432'] = 'bar'
                platform._uname_cache = None
                system, node, release, version, machine, processor = platform.uname()
                self.assertEqual(machine, 'bar')
        finally:
            platform._uname_cache = None

179 180
    def test_java_ver(self):
        res = platform.java_ver()
181
        if sys.platform == 'java':
182
            self.assertTrue(all(res))
183 184 185 186 187 188

    def test_win32_ver(self):
        res = platform.win32_ver()

    def test_mac_ver(self):
        res = platform.mac_ver()
189

190
        if platform.uname().system == 'Darwin':
191 192 193 194 195 196 197 198 199
            # We're on a MacOSX system, check that
            # the right version information is returned
            fd = os.popen('sw_vers', 'r')
            real_ver = None
            for ln in fd:
                if ln.startswith('ProductVersion:'):
                    real_ver = ln.strip().split()[-1]
                    break
            fd.close()
200
            self.assertFalse(real_ver is None)
201 202 203 204 205 206
            result_list = res[0].split('.')
            expect_list = real_ver.split('.')
            len_diff = len(result_list) - len(expect_list)
            # On Snow Leopard, sw_vers reports 10.6.0 as 10.6
            if len_diff > 0:
                expect_list.extend(['0'] * len_diff)
207
            self.assertEqual(result_list, expect_list)
208 209 210 211

            # res[1] claims to contain
            # (version, dev_stage, non_release_version)
            # That information is no longer available
212
            self.assertEqual(res[1], ('', '', ''))
213 214

            if sys.byteorder == 'little':
215
                self.assertIn(res[2], ('i386', 'x86_64'))
216
            else:
217
                self.assertEqual(res[2], 'PowerPC')
218

219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234

    @unittest.skipUnless(sys.platform == 'darwin', "OSX only test")
    def test_mac_ver_with_fork(self):
        # Issue7895: platform.mac_ver() crashes when using fork without exec
        #
        # This test checks that the fix for that issue works.
        #
        pid = os.fork()
        if pid == 0:
            # child
            info = platform.mac_ver()
            os._exit(0)

        else:
            # parent
            cpid, sts = os.waitpid(pid, 0)
235 236
            self.assertEqual(cpid, pid)
            self.assertEqual(sts, 0)
237

238 239 240 241
    def test_dist(self):
        res = platform.dist()

    def test_libc_ver(self):
242
        import os
243 244
        if os.path.isdir(sys.executable) and \
           os.path.exists(sys.executable+'.exe'):
245
            # Cygwin horror
Georg Brandl's avatar
Georg Brandl committed
246 247 248 249
            executable = sys.executable + '.exe'
        else:
            executable = sys.executable
        res = platform.libc_ver(executable)
250

Benjamin Peterson's avatar
Benjamin Peterson committed
251 252 253 254 255 256 257 258 259 260 261 262 263
    def test_parse_release_file(self):

        for input, output in (
            # Examples of release file contents:
            ('SuSE Linux 9.3 (x86-64)', ('SuSE Linux ', '9.3', 'x86-64')),
            ('SUSE LINUX 10.1 (X86-64)', ('SUSE LINUX ', '10.1', 'X86-64')),
            ('SUSE LINUX 10.1 (i586)', ('SUSE LINUX ', '10.1', 'i586')),
            ('Fedora Core release 5 (Bordeaux)', ('Fedora Core', '5', 'Bordeaux')),
            ('Red Hat Linux release 8.0 (Psyche)', ('Red Hat Linux', '8.0', 'Psyche')),
            ('Red Hat Linux release 9 (Shrike)', ('Red Hat Linux', '9', 'Shrike')),
            ('Red Hat Enterprise Linux release 4 (Nahant)', ('Red Hat Enterprise Linux', '4', 'Nahant')),
            ('CentOS release 4', ('CentOS', '4', None)),
            ('Rocks release 4.2.1 (Cydonia)', ('Rocks', '4.2.1', 'Cydonia')),
264
            ('', ('', '', '')), # If there's nothing there.
Benjamin Peterson's avatar
Benjamin Peterson committed
265 266 267
            ):
            self.assertEqual(platform._parse_release_file(input), output)

268
    def test_popen(self):
269 270 271 272 273 274
        mswindows = (sys.platform == "win32")

        if mswindows:
            command = '"{}" -c "print(\'Hello\')"'.format(sys.executable)
        else:
            command = "'{}' -c 'print(\"Hello\")'".format(sys.executable)
275 276 277 278 279 280
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            with platform.popen(command) as stdout:
                hello = stdout.read().strip()
                stdout.close()
                self.assertEqual(hello, "Hello")
281 282

        data = 'plop'
283 284 285 286 287
        if mswindows:
            command = '"{}" -c "import sys; data=sys.stdin.read(); exit(len(data))"'
        else:
            command = "'{}' -c 'import sys; data=sys.stdin.read(); exit(len(data))'"
        command = command.format(sys.executable)
288 289 290 291 292 293 294 295 296 297 298
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            with platform.popen(command, 'w') as stdin:
                stdout = stdin.write(data)
                ret = stdin.close()
                self.assertIsNotNone(ret)
                if os.name == 'nt':
                    returncode = ret
                else:
                    returncode = ret >> 8
                self.assertEqual(returncode, len(data))
299

300 301 302 303 304 305 306 307 308 309 310 311 312
    def test_linux_distribution_encoding(self):
        # Issue #17429
        with tempfile.TemporaryDirectory() as tempdir:
            filename = os.path.join(tempdir, 'fedora-release')
            with open(filename, 'w', encoding='utf-8') as f:
                f.write('Fedora release 19 (Schr\xf6dinger\u2019s Cat)\n')

            with mock.patch('platform._UNIXCONFDIR', tempdir):
                distname, version, distid = platform.linux_distribution()

            self.assertEqual(distname, 'Fedora')
            self.assertEqual(version, '19')
            self.assertEqual(distid, 'Schr\xf6dinger\u2019s Cat')
Benjamin Peterson's avatar
Benjamin Peterson committed
313

314
def test_main():
315
    support.run_unittest(
316 317 318 319 320
        PlatformTest
    )

if __name__ == '__main__':
    test_main()