blob: ededbdba421949ed2a85d1e45712942897fba4bb [file] [log] [blame]
Victor Stinner620c48b2013-12-09 00:01:27 +01001from unittest import mock
Benjamin Peterson856ff5f2008-05-29 21:22:40 +00002import os
Walter Dörwaldc69d1c42005-11-21 17:48:12 +00003import platform
Hirokazu Yamamotoe6748402008-10-06 04:51:11 +00004import subprocess
Victor Stinner3a38a6d2011-06-10 13:59:59 +02005import sys
Victor Stinner620c48b2013-12-09 00:01:27 +01006import tempfile
Victor Stinner3a38a6d2011-06-10 13:59:59 +02007import unittest
8import warnings
Walter Dörwaldc69d1c42005-11-21 17:48:12 +00009
Benjamin Petersonee8712c2008-05-20 21:35:26 +000010from test import support
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +000011
Walter Dörwaldc69d1c42005-11-21 17:48:12 +000012class PlatformTest(unittest.TestCase):
13 def test_architecture(self):
14 res = platform.architecture()
15
Brian Curtin3b4499c2010-12-28 14:31:47 +000016 @support.skip_unless_symlink
Brian Curtind40e6f72010-07-08 21:39:08 +000017 def test_architecture_via_symlink(self): # issue3762
18 # On Windows, the EXE needs to know where pythonXY.dll is at so we have
19 # to add the directory to the path.
20 if sys.platform == "win32":
Brian Curtin74e45612010-07-09 15:58:59 +000021 os.environ["Path"] = "{};{}".format(
22 os.path.dirname(sys.executable), os.environ["Path"])
Brian Curtind40e6f72010-07-08 21:39:08 +000023
24 def get(python):
25 cmd = [python, '-c',
26 'import platform; print(platform.architecture())']
27 p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
28 return p.communicate()
29 real = os.path.realpath(sys.executable)
30 link = os.path.abspath(support.TESTFN)
31 os.symlink(real, link)
32 try:
33 self.assertEqual(get(real), get(link))
34 finally:
35 os.remove(link)
Hirokazu Yamamotoe6748402008-10-06 04:51:11 +000036
Walter Dörwaldc69d1c42005-11-21 17:48:12 +000037 def test_platform(self):
38 for aliased in (False, True):
39 for terse in (False, True):
40 res = platform.platform(aliased, terse)
41
Benjamin Peterson5f28b7b2009-03-26 21:49:58 +000042 def test_system(self):
43 res = platform.system()
44
45 def test_node(self):
46 res = platform.node()
47
48 def test_release(self):
49 res = platform.release()
50
51 def test_version(self):
52 res = platform.version()
53
54 def test_machine(self):
55 res = platform.machine()
56
Walter Dörwaldc69d1c42005-11-21 17:48:12 +000057 def test_processor(self):
58 res = platform.processor()
59
Benjamin Petersone549ead2009-03-28 21:42:05 +000060 def setUp(self):
61 self.save_version = sys.version
Georg Brandl82562422011-03-05 21:09:22 +010062 self.save_mercurial = sys._mercurial
Benjamin Petersone549ead2009-03-28 21:42:05 +000063 self.save_platform = sys.platform
Benjamin Peterson5f28b7b2009-03-26 21:49:58 +000064
Benjamin Petersone549ead2009-03-28 21:42:05 +000065 def tearDown(self):
66 sys.version = self.save_version
Georg Brandl82562422011-03-05 21:09:22 +010067 sys._mercurial = self.save_mercurial
Benjamin Petersone549ead2009-03-28 21:42:05 +000068 sys.platform = self.save_platform
Benjamin Peterson5f28b7b2009-03-26 21:49:58 +000069
Benjamin Petersone549ead2009-03-28 21:42:05 +000070 def test_sys_version(self):
71 # Old test.
72 for input, output in (
73 ('2.4.3 (#1, Jun 21 2006, 13:54:21) \n[GCC 3.3.4 (pre 3.3.5 20040809)]',
74 ('CPython', '2.4.3', '', '', '1', 'Jun 21 2006 13:54:21', 'GCC 3.3.4 (pre 3.3.5 20040809)')),
75 ('IronPython 1.0.60816 on .NET 2.0.50727.42',
76 ('IronPython', '1.0.60816', '', '', '', '', '.NET 2.0.50727.42')),
77 ('IronPython 1.0 (1.0.61005.1977) on .NET 2.0.50727.42',
78 ('IronPython', '1.0.0', '', '', '', '', '.NET 2.0.50727.42')),
79 ):
80 # branch and revision are not "parsed", but fetched
Georg Brandl776e5862011-03-06 10:35:42 +010081 # from sys._mercurial. Ignore them
Benjamin Petersone549ead2009-03-28 21:42:05 +000082 (name, version, branch, revision, buildno, builddate, compiler) \
83 = platform._sys_version(input)
84 self.assertEqual(
85 (name, version, '', '', buildno, builddate, compiler), output)
Benjamin Peterson5f28b7b2009-03-26 21:49:58 +000086
Benjamin Petersone549ead2009-03-28 21:42:05 +000087 # Tests for python_implementation(), python_version(), python_branch(),
88 # python_revision(), python_build(), and python_compiler().
89 sys_versions = {
90 ("2.6.1 (r261:67515, Dec 6 2008, 15:26:00) \n[GCC 4.0.1 (Apple Computer, Inc. build 5370)]",
91 ('CPython', 'tags/r261', '67515'), self.save_platform)
92 :
93 ("CPython", "2.6.1", "tags/r261", "67515",
94 ('r261:67515', 'Dec 6 2008 15:26:00'),
95 'GCC 4.0.1 (Apple Computer, Inc. build 5370)'),
Ezio Melottif076f532013-10-21 03:03:32 +030096
Benjamin Petersone549ead2009-03-28 21:42:05 +000097 ("IronPython 2.0 (2.0.0.0) on .NET 2.0.50727.3053", None, "cli")
98 :
99 ("IronPython", "2.0.0", "", "", ("", ""),
100 ".NET 2.0.50727.3053"),
Ezio Melottif076f532013-10-21 03:03:32 +0300101
102 ("2.6.1 (IronPython 2.6.1 (2.6.10920.0) on .NET 2.0.50727.1433)", None, "cli")
103 :
104 ("IronPython", "2.6.1", "", "", ("", ""),
105 ".NET 2.0.50727.1433"),
106
107 ("2.7.4 (IronPython 2.7.4 (2.7.0.40) on Mono 4.0.30319.1 (32-bit))", None, "cli")
108 :
109 ("IronPython", "2.7.4", "", "", ("", ""),
110 "Mono 4.0.30319.1 (32-bit)"),
111
Benjamin Petersone549ead2009-03-28 21:42:05 +0000112 ("2.5 (trunk:6107, Mar 26 2009, 13:02:18) \n[Java HotSpot(TM) Client VM (\"Apple Computer, Inc.\")]",
113 ('Jython', 'trunk', '6107'), "java1.5.0_16")
114 :
115 ("Jython", "2.5.0", "trunk", "6107",
116 ('trunk:6107', 'Mar 26 2009'), "java1.5.0_16"),
Ezio Melottif076f532013-10-21 03:03:32 +0300117
Benjamin Petersone549ead2009-03-28 21:42:05 +0000118 ("2.5.2 (63378, Mar 26 2009, 18:03:29)\n[PyPy 1.0.0]",
119 ('PyPy', 'trunk', '63378'), self.save_platform)
120 :
121 ("PyPy", "2.5.2", "trunk", "63378", ('63378', 'Mar 26 2009'),
122 "")
123 }
124 for (version_tag, subversion, sys_platform), info in \
125 sys_versions.items():
126 sys.version = version_tag
127 if subversion is None:
Georg Brandl82562422011-03-05 21:09:22 +0100128 if hasattr(sys, "_mercurial"):
129 del sys._mercurial
Benjamin Petersone549ead2009-03-28 21:42:05 +0000130 else:
Georg Brandl82562422011-03-05 21:09:22 +0100131 sys._mercurial = subversion
Benjamin Petersone549ead2009-03-28 21:42:05 +0000132 if sys_platform is not None:
133 sys.platform = sys_platform
134 self.assertEqual(platform.python_implementation(), info[0])
135 self.assertEqual(platform.python_version(), info[1])
136 self.assertEqual(platform.python_branch(), info[2])
137 self.assertEqual(platform.python_revision(), info[3])
138 self.assertEqual(platform.python_build(), info[4])
139 self.assertEqual(platform.python_compiler(), info[5])
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000140
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000141 def test_system_alias(self):
142 res = platform.system_alias(
143 platform.system(),
144 platform.release(),
145 platform.version(),
146 )
147
148 def test_uname(self):
149 res = platform.uname()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000150 self.assertTrue(any(res))
Larry Hastings68386bc2012-06-24 14:30:41 -0700151 self.assertEqual(res[0], res.system)
152 self.assertEqual(res[1], res.node)
153 self.assertEqual(res[2], res.release)
154 self.assertEqual(res[3], res.version)
155 self.assertEqual(res[4], res.machine)
156 self.assertEqual(res[5], res.processor)
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000157
R. David Murrayca2edce2010-03-22 17:48:48 +0000158 @unittest.skipUnless(sys.platform.startswith('win'), "windows only test")
159 def test_uname_win32_ARCHITEW6432(self):
160 # Issue 7860: make sure we get architecture from the correct variable
161 # on 64 bit Windows: if PROCESSOR_ARCHITEW6432 exists we should be
162 # using it, per
163 # http://blogs.msdn.com/david.wang/archive/2006/03/26/HOWTO-Detect-Process-Bitness.aspx
164 try:
R. David Murraya1135542010-03-24 00:29:21 +0000165 with support.EnvironmentVarGuard() as environ:
R. David Murrayca2edce2010-03-22 17:48:48 +0000166 if 'PROCESSOR_ARCHITEW6432' in environ:
167 del environ['PROCESSOR_ARCHITEW6432']
168 environ['PROCESSOR_ARCHITECTURE'] = 'foo'
169 platform._uname_cache = None
170 system, node, release, version, machine, processor = platform.uname()
171 self.assertEqual(machine, 'foo')
172 environ['PROCESSOR_ARCHITEW6432'] = 'bar'
173 platform._uname_cache = None
174 system, node, release, version, machine, processor = platform.uname()
175 self.assertEqual(machine, 'bar')
176 finally:
177 platform._uname_cache = None
178
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000179 def test_java_ver(self):
180 res = platform.java_ver()
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000181 if sys.platform == 'java':
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000182 self.assertTrue(all(res))
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000183
184 def test_win32_ver(self):
185 res = platform.win32_ver()
186
187 def test_mac_ver(self):
188 res = platform.mac_ver()
Benjamin Peterson856ff5f2008-05-29 21:22:40 +0000189
Larry Hastings68386bc2012-06-24 14:30:41 -0700190 if platform.uname().system == 'Darwin':
Benjamin Peterson856ff5f2008-05-29 21:22:40 +0000191 # We're on a MacOSX system, check that
192 # the right version information is returned
193 fd = os.popen('sw_vers', 'r')
194 real_ver = None
195 for ln in fd:
196 if ln.startswith('ProductVersion:'):
197 real_ver = ln.strip().split()[-1]
198 break
199 fd.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000200 self.assertFalse(real_ver is None)
Brett Cannon353411d2009-09-03 21:29:20 +0000201 result_list = res[0].split('.')
202 expect_list = real_ver.split('.')
203 len_diff = len(result_list) - len(expect_list)
204 # On Snow Leopard, sw_vers reports 10.6.0 as 10.6
205 if len_diff > 0:
206 expect_list.extend(['0'] * len_diff)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000207 self.assertEqual(result_list, expect_list)
Benjamin Peterson856ff5f2008-05-29 21:22:40 +0000208
209 # res[1] claims to contain
210 # (version, dev_stage, non_release_version)
211 # That information is no longer available
Ezio Melottib3aedd42010-11-20 19:04:17 +0000212 self.assertEqual(res[1], ('', '', ''))
Benjamin Peterson856ff5f2008-05-29 21:22:40 +0000213
214 if sys.byteorder == 'little':
Ned Deily58e33502011-07-13 15:07:04 -0700215 self.assertIn(res[2], ('i386', 'x86_64'))
Benjamin Peterson856ff5f2008-05-29 21:22:40 +0000216 else:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000217 self.assertEqual(res[2], 'PowerPC')
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000218
Ronald Oussorene186e382010-07-23 11:54:59 +0000219
220 @unittest.skipUnless(sys.platform == 'darwin', "OSX only test")
221 def test_mac_ver_with_fork(self):
222 # Issue7895: platform.mac_ver() crashes when using fork without exec
223 #
224 # This test checks that the fix for that issue works.
225 #
226 pid = os.fork()
227 if pid == 0:
228 # child
229 info = platform.mac_ver()
230 os._exit(0)
231
232 else:
233 # parent
234 cpid, sts = os.waitpid(pid, 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000235 self.assertEqual(cpid, pid)
236 self.assertEqual(sts, 0)
Ronald Oussorene186e382010-07-23 11:54:59 +0000237
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000238 def test_dist(self):
239 res = platform.dist()
240
241 def test_libc_ver(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000242 import os
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000243 if os.path.isdir(sys.executable) and \
244 os.path.exists(sys.executable+'.exe'):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000245 # Cygwin horror
Georg Brandl89fad142010-03-14 10:23:39 +0000246 executable = sys.executable + '.exe'
247 else:
248 executable = sys.executable
249 res = platform.libc_ver(executable)
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000250
Benjamin Peterson1a6e0d02008-10-25 15:49:17 +0000251 def test_parse_release_file(self):
252
253 for input, output in (
254 # Examples of release file contents:
255 ('SuSE Linux 9.3 (x86-64)', ('SuSE Linux ', '9.3', 'x86-64')),
256 ('SUSE LINUX 10.1 (X86-64)', ('SUSE LINUX ', '10.1', 'X86-64')),
257 ('SUSE LINUX 10.1 (i586)', ('SUSE LINUX ', '10.1', 'i586')),
258 ('Fedora Core release 5 (Bordeaux)', ('Fedora Core', '5', 'Bordeaux')),
259 ('Red Hat Linux release 8.0 (Psyche)', ('Red Hat Linux', '8.0', 'Psyche')),
260 ('Red Hat Linux release 9 (Shrike)', ('Red Hat Linux', '9', 'Shrike')),
261 ('Red Hat Enterprise Linux release 4 (Nahant)', ('Red Hat Enterprise Linux', '4', 'Nahant')),
262 ('CentOS release 4', ('CentOS', '4', None)),
263 ('Rocks release 4.2.1 (Cydonia)', ('Rocks', '4.2.1', 'Cydonia')),
Benjamin Peterson25001472010-01-25 03:37:42 +0000264 ('', ('', '', '')), # If there's nothing there.
Benjamin Peterson1a6e0d02008-10-25 15:49:17 +0000265 ):
266 self.assertEqual(platform._parse_release_file(input), output)
267
Victor Stinner1dfd3802011-03-03 12:54:07 +0000268 def test_popen(self):
Victor Stinnerff45fed2011-03-03 14:07:21 +0000269 mswindows = (sys.platform == "win32")
270
271 if mswindows:
272 command = '"{}" -c "print(\'Hello\')"'.format(sys.executable)
273 else:
274 command = "'{}' -c 'print(\"Hello\")'".format(sys.executable)
Victor Stinner3a38a6d2011-06-10 13:59:59 +0200275 with warnings.catch_warnings():
276 warnings.simplefilter("ignore", DeprecationWarning)
277 with platform.popen(command) as stdout:
278 hello = stdout.read().strip()
279 stdout.close()
280 self.assertEqual(hello, "Hello")
Victor Stinner1dfd3802011-03-03 12:54:07 +0000281
Victor Stinner1dfd3802011-03-03 12:54:07 +0000282 data = 'plop'
Victor Stinnerff45fed2011-03-03 14:07:21 +0000283 if mswindows:
284 command = '"{}" -c "import sys; data=sys.stdin.read(); exit(len(data))"'
285 else:
286 command = "'{}' -c 'import sys; data=sys.stdin.read(); exit(len(data))'"
287 command = command.format(sys.executable)
Victor Stinner3a38a6d2011-06-10 13:59:59 +0200288 with warnings.catch_warnings():
289 warnings.simplefilter("ignore", DeprecationWarning)
290 with platform.popen(command, 'w') as stdin:
291 stdout = stdin.write(data)
292 ret = stdin.close()
293 self.assertIsNotNone(ret)
294 if os.name == 'nt':
295 returncode = ret
296 else:
297 returncode = ret >> 8
298 self.assertEqual(returncode, len(data))
Victor Stinner1dfd3802011-03-03 12:54:07 +0000299
Victor Stinner620c48b2013-12-09 00:01:27 +0100300 def test_linux_distribution_encoding(self):
301 # Issue #17429
302 with tempfile.TemporaryDirectory() as tempdir:
303 filename = os.path.join(tempdir, 'fedora-release')
304 with open(filename, 'w', encoding='utf-8') as f:
305 f.write('Fedora release 19 (Schr\xf6dinger\u2019s Cat)\n')
306
307 with mock.patch('platform._UNIXCONFDIR', tempdir):
308 distname, version, distid = platform.linux_distribution()
309
Barry Warsaw7c549c42014-08-05 11:28:12 -0400310 self.assertEqual(distname, 'Fedora')
Victor Stinner620c48b2013-12-09 00:01:27 +0100311 self.assertEqual(version, '19')
312 self.assertEqual(distid, 'Schr\xf6dinger\u2019s Cat')
Benjamin Peterson1a6e0d02008-10-25 15:49:17 +0000313
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000314def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000315 support.run_unittest(
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000316 PlatformTest
317 )
318
319if __name__ == '__main__':
320 test_main()