Home | History | Annotate | Download | only in test
      1 from unittest import mock
      2 import os
      3 import platform
      4 import subprocess
      5 import sys
      6 import tempfile
      7 import unittest
      8 import warnings
      9 
     10 from test import support
     11 
     12 class PlatformTest(unittest.TestCase):
     13     def test_architecture(self):
     14         res = platform.architecture()
     15 
     16     @support.skip_unless_symlink
     17     def test_architecture_via_symlink(self): # issue3762
     18         # On Windows, the EXE needs to know where pythonXY.dll and *.pyd is at
     19         # so we add the directory to the path and PYTHONPATH.
     20         if sys.platform == "win32":
     21             def restore_environ(old_env):
     22                 os.environ.clear()
     23                 os.environ.update(old_env)
     24 
     25             self.addCleanup(restore_environ, dict(os.environ))
     26 
     27             os.environ["Path"] = "{};{}".format(
     28                 os.path.dirname(sys.executable), os.environ["Path"])
     29             os.environ["PYTHONPATH"] = os.path.dirname(sys.executable)
     30 
     31         def get(python):
     32             cmd = [python, '-c',
     33                 'import platform; print(platform.architecture())']
     34             p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
     35             return p.communicate()
     36 
     37         real = os.path.realpath(sys.executable)
     38         link = os.path.abspath(support.TESTFN)
     39         os.symlink(real, link)
     40         try:
     41             self.assertEqual(get(real), get(link))
     42         finally:
     43             os.remove(link)
     44 
     45     def test_platform(self):
     46         for aliased in (False, True):
     47             for terse in (False, True):
     48                 res = platform.platform(aliased, terse)
     49 
     50     def test_system(self):
     51         res = platform.system()
     52 
     53     def test_node(self):
     54         res = platform.node()
     55 
     56     def test_release(self):
     57         res = platform.release()
     58 
     59     def test_version(self):
     60         res = platform.version()
     61 
     62     def test_machine(self):
     63         res = platform.machine()
     64 
     65     def test_processor(self):
     66         res = platform.processor()
     67 
     68     def setUp(self):
     69         self.save_version = sys.version
     70         self.save_git = sys._git
     71         self.save_platform = sys.platform
     72 
     73     def tearDown(self):
     74         sys.version = self.save_version
     75         sys._git = self.save_git
     76         sys.platform = self.save_platform
     77 
     78     def test_sys_version(self):
     79         # Old test.
     80         for input, output in (
     81             ('2.4.3 (#1, Jun 21 2006, 13:54:21) \n[GCC 3.3.4 (pre 3.3.5 20040809)]',
     82              ('CPython', '2.4.3', '', '', '1', 'Jun 21 2006 13:54:21', 'GCC 3.3.4 (pre 3.3.5 20040809)')),
     83             ('IronPython 1.0.60816 on .NET 2.0.50727.42',
     84              ('IronPython', '1.0.60816', '', '', '', '', '.NET 2.0.50727.42')),
     85             ('IronPython 1.0 (1.0.61005.1977) on .NET 2.0.50727.42',
     86              ('IronPython', '1.0.0', '', '', '', '', '.NET 2.0.50727.42')),
     87             ('2.4.3 (truncation, date, t) \n[GCC]',
     88              ('CPython', '2.4.3', '', '', 'truncation', 'date t', 'GCC')),
     89             ('2.4.3 (truncation, date, ) \n[GCC]',
     90              ('CPython', '2.4.3', '', '', 'truncation', 'date', 'GCC')),
     91             ('2.4.3 (truncation, date,) \n[GCC]',
     92              ('CPython', '2.4.3', '', '', 'truncation', 'date', 'GCC')),
     93             ('2.4.3 (truncation, date) \n[GCC]',
     94              ('CPython', '2.4.3', '', '', 'truncation', 'date', 'GCC')),
     95             ('2.4.3 (truncation, d) \n[GCC]',
     96              ('CPython', '2.4.3', '', '', 'truncation', 'd', 'GCC')),
     97             ('2.4.3 (truncation, ) \n[GCC]',
     98              ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')),
     99             ('2.4.3 (truncation,) \n[GCC]',
    100              ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')),
    101             ('2.4.3 (truncation) \n[GCC]',
    102              ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')),
    103             ):
    104             # branch and revision are not "parsed", but fetched
    105             # from sys._git.  Ignore them
    106             (name, version, branch, revision, buildno, builddate, compiler) \
    107                    = platform._sys_version(input)
    108             self.assertEqual(
    109                 (name, version, '', '', buildno, builddate, compiler), output)
    110 
    111         # Tests for python_implementation(), python_version(), python_branch(),
    112         # python_revision(), python_build(), and python_compiler().
    113         sys_versions = {
    114             ("2.6.1 (r261:67515, Dec  6 2008, 15:26:00) \n[GCC 4.0.1 (Apple Computer, Inc. build 5370)]",
    115              ('CPython', 'tags/r261', '67515'), self.save_platform)
    116             :
    117                 ("CPython", "2.6.1", "tags/r261", "67515",
    118                  ('r261:67515', 'Dec  6 2008 15:26:00'),
    119                  'GCC 4.0.1 (Apple Computer, Inc. build 5370)'),
    120 
    121             ("IronPython 2.0 (2.0.0.0) on .NET 2.0.50727.3053", None, "cli")
    122             :
    123                 ("IronPython", "2.0.0", "", "", ("", ""),
    124                  ".NET 2.0.50727.3053"),
    125 
    126             ("2.6.1 (IronPython 2.6.1 (2.6.10920.0) on .NET 2.0.50727.1433)", None, "cli")
    127             :
    128                 ("IronPython", "2.6.1", "", "", ("", ""),
    129                  ".NET 2.0.50727.1433"),
    130 
    131             ("2.7.4 (IronPython 2.7.4 (2.7.0.40) on Mono 4.0.30319.1 (32-bit))", None, "cli")
    132             :
    133                 ("IronPython", "2.7.4", "", "", ("", ""),
    134                  "Mono 4.0.30319.1 (32-bit)"),
    135 
    136             ("2.5 (trunk:6107, Mar 26 2009, 13:02:18) \n[Java HotSpot(TM) Client VM (\"Apple Computer, Inc.\")]",
    137             ('Jython', 'trunk', '6107'), "java1.5.0_16")
    138             :
    139                 ("Jython", "2.5.0", "trunk", "6107",
    140                  ('trunk:6107', 'Mar 26 2009'), "java1.5.0_16"),
    141 
    142             ("2.5.2 (63378, Mar 26 2009, 18:03:29)\n[PyPy 1.0.0]",
    143              ('PyPy', 'trunk', '63378'), self.save_platform)
    144             :
    145                 ("PyPy", "2.5.2", "trunk", "63378", ('63378', 'Mar 26 2009'),
    146                  "")
    147             }
    148         for (version_tag, subversion, sys_platform), info in \
    149                 sys_versions.items():
    150             sys.version = version_tag
    151             if subversion is None:
    152                 if hasattr(sys, "_git"):
    153                     del sys._git
    154             else:
    155                 sys._git = subversion
    156             if sys_platform is not None:
    157                 sys.platform = sys_platform
    158             self.assertEqual(platform.python_implementation(), info[0])
    159             self.assertEqual(platform.python_version(), info[1])
    160             self.assertEqual(platform.python_branch(), info[2])
    161             self.assertEqual(platform.python_revision(), info[3])
    162             self.assertEqual(platform.python_build(), info[4])
    163             self.assertEqual(platform.python_compiler(), info[5])
    164 
    165     def test_system_alias(self):
    166         res = platform.system_alias(
    167             platform.system(),
    168             platform.release(),
    169             platform.version(),
    170         )
    171 
    172     def test_uname(self):
    173         res = platform.uname()
    174         self.assertTrue(any(res))
    175         self.assertEqual(res[0], res.system)
    176         self.assertEqual(res[1], res.node)
    177         self.assertEqual(res[2], res.release)
    178         self.assertEqual(res[3], res.version)
    179         self.assertEqual(res[4], res.machine)
    180         self.assertEqual(res[5], res.processor)
    181 
    182     @unittest.skipUnless(sys.platform.startswith('win'), "windows only test")
    183     def test_uname_win32_ARCHITEW6432(self):
    184         # Issue 7860: make sure we get architecture from the correct variable
    185         # on 64 bit Windows: if PROCESSOR_ARCHITEW6432 exists we should be
    186         # using it, per
    187         # http://blogs.msdn.com/david.wang/archive/2006/03/26/HOWTO-Detect-Process-Bitness.aspx
    188         try:
    189             with support.EnvironmentVarGuard() as environ:
    190                 if 'PROCESSOR_ARCHITEW6432' in environ:
    191                     del environ['PROCESSOR_ARCHITEW6432']
    192                 environ['PROCESSOR_ARCHITECTURE'] = 'foo'
    193                 platform._uname_cache = None
    194                 system, node, release, version, machine, processor = platform.uname()
    195                 self.assertEqual(machine, 'foo')
    196                 environ['PROCESSOR_ARCHITEW6432'] = 'bar'
    197                 platform._uname_cache = None
    198                 system, node, release, version, machine, processor = platform.uname()
    199                 self.assertEqual(machine, 'bar')
    200         finally:
    201             platform._uname_cache = None
    202 
    203     def test_java_ver(self):
    204         res = platform.java_ver()
    205         if sys.platform == 'java':
    206             self.assertTrue(all(res))
    207 
    208     def test_win32_ver(self):
    209         res = platform.win32_ver()
    210 
    211     def test_mac_ver(self):
    212         res = platform.mac_ver()
    213 
    214         if platform.uname().system == 'Darwin':
    215             # We're on a MacOSX system, check that
    216             # the right version information is returned
    217             fd = os.popen('sw_vers', 'r')
    218             real_ver = None
    219             for ln in fd:
    220                 if ln.startswith('ProductVersion:'):
    221                     real_ver = ln.strip().split()[-1]
    222                     break
    223             fd.close()
    224             self.assertFalse(real_ver is None)
    225             result_list = res[0].split('.')
    226             expect_list = real_ver.split('.')
    227             len_diff = len(result_list) - len(expect_list)
    228             # On Snow Leopard, sw_vers reports 10.6.0 as 10.6
    229             if len_diff > 0:
    230                 expect_list.extend(['0'] * len_diff)
    231             self.assertEqual(result_list, expect_list)
    232 
    233             # res[1] claims to contain
    234             # (version, dev_stage, non_release_version)
    235             # That information is no longer available
    236             self.assertEqual(res[1], ('', '', ''))
    237 
    238             if sys.byteorder == 'little':
    239                 self.assertIn(res[2], ('i386', 'x86_64'))
    240             else:
    241                 self.assertEqual(res[2], 'PowerPC')
    242 
    243 
    244     @unittest.skipUnless(sys.platform == 'darwin', "OSX only test")
    245     def test_mac_ver_with_fork(self):
    246         # Issue7895: platform.mac_ver() crashes when using fork without exec
    247         #
    248         # This test checks that the fix for that issue works.
    249         #
    250         pid = os.fork()
    251         if pid == 0:
    252             # child
    253             info = platform.mac_ver()
    254             os._exit(0)
    255 
    256         else:
    257             # parent
    258             cpid, sts = os.waitpid(pid, 0)
    259             self.assertEqual(cpid, pid)
    260             self.assertEqual(sts, 0)
    261 
    262     def test_dist(self):
    263         with warnings.catch_warnings():
    264             warnings.filterwarnings(
    265                 'ignore',
    266                 r'dist\(\) and linux_distribution\(\) '
    267                 'functions are deprecated .*',
    268                 PendingDeprecationWarning,
    269             )
    270             res = platform.dist()
    271 
    272     def test_libc_ver(self):
    273         import os
    274         if os.path.isdir(sys.executable) and \
    275            os.path.exists(sys.executable+'.exe'):
    276             # Cygwin horror
    277             executable = sys.executable + '.exe'
    278         else:
    279             executable = sys.executable
    280         res = platform.libc_ver(executable)
    281 
    282     def test_parse_release_file(self):
    283 
    284         for input, output in (
    285             # Examples of release file contents:
    286             ('SuSE Linux 9.3 (x86-64)', ('SuSE Linux ', '9.3', 'x86-64')),
    287             ('SUSE LINUX 10.1 (X86-64)', ('SUSE LINUX ', '10.1', 'X86-64')),
    288             ('SUSE LINUX 10.1 (i586)', ('SUSE LINUX ', '10.1', 'i586')),
    289             ('Fedora Core release 5 (Bordeaux)', ('Fedora Core', '5', 'Bordeaux')),
    290             ('Red Hat Linux release 8.0 (Psyche)', ('Red Hat Linux', '8.0', 'Psyche')),
    291             ('Red Hat Linux release 9 (Shrike)', ('Red Hat Linux', '9', 'Shrike')),
    292             ('Red Hat Enterprise Linux release 4 (Nahant)', ('Red Hat Enterprise Linux', '4', 'Nahant')),
    293             ('CentOS release 4', ('CentOS', '4', None)),
    294             ('Rocks release 4.2.1 (Cydonia)', ('Rocks', '4.2.1', 'Cydonia')),
    295             ('', ('', '', '')), # If there's nothing there.
    296             ):
    297             self.assertEqual(platform._parse_release_file(input), output)
    298 
    299     def test_popen(self):
    300         mswindows = (sys.platform == "win32")
    301 
    302         if mswindows:
    303             command = '"{}" -c "print(\'Hello\')"'.format(sys.executable)
    304         else:
    305             command = "'{}' -c 'print(\"Hello\")'".format(sys.executable)
    306         with warnings.catch_warnings():
    307             warnings.simplefilter("ignore", DeprecationWarning)
    308             with platform.popen(command) as stdout:
    309                 hello = stdout.read().strip()
    310                 stdout.close()
    311                 self.assertEqual(hello, "Hello")
    312 
    313         data = 'plop'
    314         if mswindows:
    315             command = '"{}" -c "import sys; data=sys.stdin.read(); exit(len(data))"'
    316         else:
    317             command = "'{}' -c 'import sys; data=sys.stdin.read(); exit(len(data))'"
    318         command = command.format(sys.executable)
    319         with warnings.catch_warnings():
    320             warnings.simplefilter("ignore", DeprecationWarning)
    321             with platform.popen(command, 'w') as stdin:
    322                 stdout = stdin.write(data)
    323                 ret = stdin.close()
    324                 self.assertIsNotNone(ret)
    325                 if os.name == 'nt':
    326                     returncode = ret
    327                 else:
    328                     returncode = ret >> 8
    329                 self.assertEqual(returncode, len(data))
    330 
    331     def test_linux_distribution_encoding(self):
    332         # Issue #17429
    333         with tempfile.TemporaryDirectory() as tempdir:
    334             filename = os.path.join(tempdir, 'fedora-release')
    335             with open(filename, 'w', encoding='utf-8') as f:
    336                 f.write('Fedora release 19 (Schr\xf6dinger\u2019s Cat)\n')
    337 
    338             with mock.patch('platform._UNIXCONFDIR', tempdir):
    339                 with warnings.catch_warnings():
    340                     warnings.filterwarnings(
    341                         'ignore',
    342                         r'dist\(\) and linux_distribution\(\) '
    343                         'functions are deprecated .*',
    344                         PendingDeprecationWarning,
    345                     )
    346                     distname, version, distid = platform.linux_distribution()
    347 
    348                 self.assertEqual(distname, 'Fedora')
    349             self.assertEqual(version, '19')
    350             self.assertEqual(distid, 'Schr\xf6dinger\u2019s Cat')
    351 
    352 
    353 class DeprecationTest(unittest.TestCase):
    354 
    355     def test_dist_deprecation(self):
    356         with self.assertWarns(PendingDeprecationWarning) as cm:
    357             platform.dist()
    358         self.assertEqual(str(cm.warning),
    359                          'dist() and linux_distribution() functions are '
    360                          'deprecated in Python 3.5')
    361 
    362     def test_linux_distribution_deprecation(self):
    363         with self.assertWarns(PendingDeprecationWarning) as cm:
    364             platform.linux_distribution()
    365         self.assertEqual(str(cm.warning),
    366                          'dist() and linux_distribution() functions are '
    367                          'deprecated in Python 3.5')
    368 
    369 if __name__ == '__main__':
    370     unittest.main()
    371