blob: 0dcfe0504a5e3102d8497d5749493cb4fdd77050 [file] [log] [blame]
Benjamin Peterson856ff5f2008-05-29 21:22:40 +00001import os
Walter Dörwaldc69d1c42005-11-21 17:48:12 +00002import platform
Hirokazu Yamamotoe6748402008-10-06 04:51:11 +00003import subprocess
Victor Stinner3a38a6d2011-06-10 13:59:59 +02004import sys
5import unittest
6import warnings
Walter Dörwaldc69d1c42005-11-21 17:48:12 +00007
Benjamin Petersonee8712c2008-05-20 21:35:26 +00008from test import support
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +00009
Walter Dörwaldc69d1c42005-11-21 17:48:12 +000010class PlatformTest(unittest.TestCase):
11 def test_architecture(self):
12 res = platform.architecture()
13
Brian Curtin3b4499c2010-12-28 14:31:47 +000014 @support.skip_unless_symlink
Brian Curtind40e6f72010-07-08 21:39:08 +000015 def test_architecture_via_symlink(self): # issue3762
16 # On Windows, the EXE needs to know where pythonXY.dll is at so we have
17 # to add the directory to the path.
18 if sys.platform == "win32":
Brian Curtin74e45612010-07-09 15:58:59 +000019 os.environ["Path"] = "{};{}".format(
20 os.path.dirname(sys.executable), os.environ["Path"])
Brian Curtind40e6f72010-07-08 21:39:08 +000021
22 def get(python):
23 cmd = [python, '-c',
24 'import platform; print(platform.architecture())']
25 p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
26 return p.communicate()
27 real = os.path.realpath(sys.executable)
28 link = os.path.abspath(support.TESTFN)
29 os.symlink(real, link)
30 try:
31 self.assertEqual(get(real), get(link))
32 finally:
33 os.remove(link)
Hirokazu Yamamotoe6748402008-10-06 04:51:11 +000034
Walter Dörwaldc69d1c42005-11-21 17:48:12 +000035 def test_platform(self):
36 for aliased in (False, True):
37 for terse in (False, True):
38 res = platform.platform(aliased, terse)
39
Benjamin Peterson5f28b7b2009-03-26 21:49:58 +000040 def test_system(self):
41 res = platform.system()
42
43 def test_node(self):
44 res = platform.node()
45
46 def test_release(self):
47 res = platform.release()
48
49 def test_version(self):
50 res = platform.version()
51
52 def test_machine(self):
53 res = platform.machine()
54
Walter Dörwaldc69d1c42005-11-21 17:48:12 +000055 def test_processor(self):
56 res = platform.processor()
57
Benjamin Petersone549ead2009-03-28 21:42:05 +000058 def setUp(self):
59 self.save_version = sys.version
Georg Brandl82562422011-03-05 21:09:22 +010060 self.save_mercurial = sys._mercurial
Benjamin Petersone549ead2009-03-28 21:42:05 +000061 self.save_platform = sys.platform
Benjamin Peterson5f28b7b2009-03-26 21:49:58 +000062
Benjamin Petersone549ead2009-03-28 21:42:05 +000063 def tearDown(self):
64 sys.version = self.save_version
Georg Brandl82562422011-03-05 21:09:22 +010065 sys._mercurial = self.save_mercurial
Benjamin Petersone549ead2009-03-28 21:42:05 +000066 sys.platform = self.save_platform
Benjamin Peterson5f28b7b2009-03-26 21:49:58 +000067
Benjamin Petersone549ead2009-03-28 21:42:05 +000068 def test_sys_version(self):
69 # Old test.
70 for input, output in (
71 ('2.4.3 (#1, Jun 21 2006, 13:54:21) \n[GCC 3.3.4 (pre 3.3.5 20040809)]',
72 ('CPython', '2.4.3', '', '', '1', 'Jun 21 2006 13:54:21', 'GCC 3.3.4 (pre 3.3.5 20040809)')),
73 ('IronPython 1.0.60816 on .NET 2.0.50727.42',
74 ('IronPython', '1.0.60816', '', '', '', '', '.NET 2.0.50727.42')),
75 ('IronPython 1.0 (1.0.61005.1977) on .NET 2.0.50727.42',
76 ('IronPython', '1.0.0', '', '', '', '', '.NET 2.0.50727.42')),
77 ):
78 # branch and revision are not "parsed", but fetched
Georg Brandl776e5862011-03-06 10:35:42 +010079 # from sys._mercurial. Ignore them
Benjamin Petersone549ead2009-03-28 21:42:05 +000080 (name, version, branch, revision, buildno, builddate, compiler) \
81 = platform._sys_version(input)
82 self.assertEqual(
83 (name, version, '', '', buildno, builddate, compiler), output)
Benjamin Peterson5f28b7b2009-03-26 21:49:58 +000084
Benjamin Petersone549ead2009-03-28 21:42:05 +000085 # Tests for python_implementation(), python_version(), python_branch(),
86 # python_revision(), python_build(), and python_compiler().
87 sys_versions = {
88 ("2.6.1 (r261:67515, Dec 6 2008, 15:26:00) \n[GCC 4.0.1 (Apple Computer, Inc. build 5370)]",
89 ('CPython', 'tags/r261', '67515'), self.save_platform)
90 :
91 ("CPython", "2.6.1", "tags/r261", "67515",
92 ('r261:67515', 'Dec 6 2008 15:26:00'),
93 'GCC 4.0.1 (Apple Computer, Inc. build 5370)'),
Ezio Melottif076f532013-10-21 03:03:32 +030094
Benjamin Petersone549ead2009-03-28 21:42:05 +000095 ("IronPython 2.0 (2.0.0.0) on .NET 2.0.50727.3053", None, "cli")
96 :
97 ("IronPython", "2.0.0", "", "", ("", ""),
98 ".NET 2.0.50727.3053"),
Ezio Melottif076f532013-10-21 03:03:32 +030099
100 ("2.6.1 (IronPython 2.6.1 (2.6.10920.0) on .NET 2.0.50727.1433)", None, "cli")
101 :
102 ("IronPython", "2.6.1", "", "", ("", ""),
103 ".NET 2.0.50727.1433"),
104
105 ("2.7.4 (IronPython 2.7.4 (2.7.0.40) on Mono 4.0.30319.1 (32-bit))", None, "cli")
106 :
107 ("IronPython", "2.7.4", "", "", ("", ""),
108 "Mono 4.0.30319.1 (32-bit)"),
109
Benjamin Petersone549ead2009-03-28 21:42:05 +0000110 ("2.5 (trunk:6107, Mar 26 2009, 13:02:18) \n[Java HotSpot(TM) Client VM (\"Apple Computer, Inc.\")]",
111 ('Jython', 'trunk', '6107'), "java1.5.0_16")
112 :
113 ("Jython", "2.5.0", "trunk", "6107",
114 ('trunk:6107', 'Mar 26 2009'), "java1.5.0_16"),
Ezio Melottif076f532013-10-21 03:03:32 +0300115
Benjamin Petersone549ead2009-03-28 21:42:05 +0000116 ("2.5.2 (63378, Mar 26 2009, 18:03:29)\n[PyPy 1.0.0]",
117 ('PyPy', 'trunk', '63378'), self.save_platform)
118 :
119 ("PyPy", "2.5.2", "trunk", "63378", ('63378', 'Mar 26 2009'),
120 "")
121 }
122 for (version_tag, subversion, sys_platform), info in \
123 sys_versions.items():
124 sys.version = version_tag
125 if subversion is None:
Georg Brandl82562422011-03-05 21:09:22 +0100126 if hasattr(sys, "_mercurial"):
127 del sys._mercurial
Benjamin Petersone549ead2009-03-28 21:42:05 +0000128 else:
Georg Brandl82562422011-03-05 21:09:22 +0100129 sys._mercurial = subversion
Benjamin Petersone549ead2009-03-28 21:42:05 +0000130 if sys_platform is not None:
131 sys.platform = sys_platform
132 self.assertEqual(platform.python_implementation(), info[0])
133 self.assertEqual(platform.python_version(), info[1])
134 self.assertEqual(platform.python_branch(), info[2])
135 self.assertEqual(platform.python_revision(), info[3])
136 self.assertEqual(platform.python_build(), info[4])
137 self.assertEqual(platform.python_compiler(), info[5])
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000138
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000139 def test_system_alias(self):
140 res = platform.system_alias(
141 platform.system(),
142 platform.release(),
143 platform.version(),
144 )
145
146 def test_uname(self):
147 res = platform.uname()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000148 self.assertTrue(any(res))
Larry Hastings68386bc2012-06-24 14:30:41 -0700149 self.assertEqual(res[0], res.system)
150 self.assertEqual(res[1], res.node)
151 self.assertEqual(res[2], res.release)
152 self.assertEqual(res[3], res.version)
153 self.assertEqual(res[4], res.machine)
154 self.assertEqual(res[5], res.processor)
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000155
R. David Murrayca2edce2010-03-22 17:48:48 +0000156 @unittest.skipUnless(sys.platform.startswith('win'), "windows only test")
157 def test_uname_win32_ARCHITEW6432(self):
158 # Issue 7860: make sure we get architecture from the correct variable
159 # on 64 bit Windows: if PROCESSOR_ARCHITEW6432 exists we should be
160 # using it, per
161 # http://blogs.msdn.com/david.wang/archive/2006/03/26/HOWTO-Detect-Process-Bitness.aspx
162 try:
R. David Murraya1135542010-03-24 00:29:21 +0000163 with support.EnvironmentVarGuard() as environ:
R. David Murrayca2edce2010-03-22 17:48:48 +0000164 if 'PROCESSOR_ARCHITEW6432' in environ:
165 del environ['PROCESSOR_ARCHITEW6432']
166 environ['PROCESSOR_ARCHITECTURE'] = 'foo'
167 platform._uname_cache = None
168 system, node, release, version, machine, processor = platform.uname()
169 self.assertEqual(machine, 'foo')
170 environ['PROCESSOR_ARCHITEW6432'] = 'bar'
171 platform._uname_cache = None
172 system, node, release, version, machine, processor = platform.uname()
173 self.assertEqual(machine, 'bar')
174 finally:
175 platform._uname_cache = None
176
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000177 def test_java_ver(self):
178 res = platform.java_ver()
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000179 if sys.platform == 'java':
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000180 self.assertTrue(all(res))
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000181
182 def test_win32_ver(self):
183 res = platform.win32_ver()
184
185 def test_mac_ver(self):
186 res = platform.mac_ver()
Benjamin Peterson856ff5f2008-05-29 21:22:40 +0000187
Larry Hastings68386bc2012-06-24 14:30:41 -0700188 if platform.uname().system == 'Darwin':
Benjamin Peterson856ff5f2008-05-29 21:22:40 +0000189 # We're on a MacOSX system, check that
190 # the right version information is returned
191 fd = os.popen('sw_vers', 'r')
192 real_ver = None
193 for ln in fd:
194 if ln.startswith('ProductVersion:'):
195 real_ver = ln.strip().split()[-1]
196 break
197 fd.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000198 self.assertFalse(real_ver is None)
Brett Cannon353411d2009-09-03 21:29:20 +0000199 result_list = res[0].split('.')
200 expect_list = real_ver.split('.')
201 len_diff = len(result_list) - len(expect_list)
202 # On Snow Leopard, sw_vers reports 10.6.0 as 10.6
203 if len_diff > 0:
204 expect_list.extend(['0'] * len_diff)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000205 self.assertEqual(result_list, expect_list)
Benjamin Peterson856ff5f2008-05-29 21:22:40 +0000206
207 # res[1] claims to contain
208 # (version, dev_stage, non_release_version)
209 # That information is no longer available
Ezio Melottib3aedd42010-11-20 19:04:17 +0000210 self.assertEqual(res[1], ('', '', ''))
Benjamin Peterson856ff5f2008-05-29 21:22:40 +0000211
212 if sys.byteorder == 'little':
Ned Deily58e33502011-07-13 15:07:04 -0700213 self.assertIn(res[2], ('i386', 'x86_64'))
Benjamin Peterson856ff5f2008-05-29 21:22:40 +0000214 else:
Ezio Melottib3aedd42010-11-20 19:04:17 +0000215 self.assertEqual(res[2], 'PowerPC')
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000216
Ronald Oussorene186e382010-07-23 11:54:59 +0000217
218 @unittest.skipUnless(sys.platform == 'darwin', "OSX only test")
219 def test_mac_ver_with_fork(self):
220 # Issue7895: platform.mac_ver() crashes when using fork without exec
221 #
222 # This test checks that the fix for that issue works.
223 #
224 pid = os.fork()
225 if pid == 0:
226 # child
227 info = platform.mac_ver()
228 os._exit(0)
229
230 else:
231 # parent
232 cpid, sts = os.waitpid(pid, 0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000233 self.assertEqual(cpid, pid)
234 self.assertEqual(sts, 0)
Ronald Oussorene186e382010-07-23 11:54:59 +0000235
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000236 def test_dist(self):
237 res = platform.dist()
238
239 def test_libc_ver(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000240 import os
Alexandre Vassalottie9f305f2008-05-16 04:39:54 +0000241 if os.path.isdir(sys.executable) and \
242 os.path.exists(sys.executable+'.exe'):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000243 # Cygwin horror
Georg Brandl89fad142010-03-14 10:23:39 +0000244 executable = sys.executable + '.exe'
245 else:
246 executable = sys.executable
247 res = platform.libc_ver(executable)
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000248
Benjamin Peterson1a6e0d02008-10-25 15:49:17 +0000249 def test_parse_release_file(self):
250
251 for input, output in (
252 # Examples of release file contents:
253 ('SuSE Linux 9.3 (x86-64)', ('SuSE Linux ', '9.3', 'x86-64')),
254 ('SUSE LINUX 10.1 (X86-64)', ('SUSE LINUX ', '10.1', 'X86-64')),
255 ('SUSE LINUX 10.1 (i586)', ('SUSE LINUX ', '10.1', 'i586')),
256 ('Fedora Core release 5 (Bordeaux)', ('Fedora Core', '5', 'Bordeaux')),
257 ('Red Hat Linux release 8.0 (Psyche)', ('Red Hat Linux', '8.0', 'Psyche')),
258 ('Red Hat Linux release 9 (Shrike)', ('Red Hat Linux', '9', 'Shrike')),
259 ('Red Hat Enterprise Linux release 4 (Nahant)', ('Red Hat Enterprise Linux', '4', 'Nahant')),
260 ('CentOS release 4', ('CentOS', '4', None)),
261 ('Rocks release 4.2.1 (Cydonia)', ('Rocks', '4.2.1', 'Cydonia')),
Benjamin Peterson25001472010-01-25 03:37:42 +0000262 ('', ('', '', '')), # If there's nothing there.
Benjamin Peterson1a6e0d02008-10-25 15:49:17 +0000263 ):
264 self.assertEqual(platform._parse_release_file(input), output)
265
Victor Stinner1dfd3802011-03-03 12:54:07 +0000266 def test_popen(self):
Victor Stinnerff45fed2011-03-03 14:07:21 +0000267 mswindows = (sys.platform == "win32")
268
269 if mswindows:
270 command = '"{}" -c "print(\'Hello\')"'.format(sys.executable)
271 else:
272 command = "'{}' -c 'print(\"Hello\")'".format(sys.executable)
Victor Stinner3a38a6d2011-06-10 13:59:59 +0200273 with warnings.catch_warnings():
274 warnings.simplefilter("ignore", DeprecationWarning)
275 with platform.popen(command) as stdout:
276 hello = stdout.read().strip()
277 stdout.close()
278 self.assertEqual(hello, "Hello")
Victor Stinner1dfd3802011-03-03 12:54:07 +0000279
Victor Stinner1dfd3802011-03-03 12:54:07 +0000280 data = 'plop'
Victor Stinnerff45fed2011-03-03 14:07:21 +0000281 if mswindows:
282 command = '"{}" -c "import sys; data=sys.stdin.read(); exit(len(data))"'
283 else:
284 command = "'{}' -c 'import sys; data=sys.stdin.read(); exit(len(data))'"
285 command = command.format(sys.executable)
Victor Stinner3a38a6d2011-06-10 13:59:59 +0200286 with warnings.catch_warnings():
287 warnings.simplefilter("ignore", DeprecationWarning)
288 with platform.popen(command, 'w') as stdin:
289 stdout = stdin.write(data)
290 ret = stdin.close()
291 self.assertIsNotNone(ret)
292 if os.name == 'nt':
293 returncode = ret
294 else:
295 returncode = ret >> 8
296 self.assertEqual(returncode, len(data))
Victor Stinner1dfd3802011-03-03 12:54:07 +0000297
Benjamin Peterson1a6e0d02008-10-25 15:49:17 +0000298
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000299def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000300 support.run_unittest(
Walter Dörwaldc69d1c42005-11-21 17:48:12 +0000301 PlatformTest
302 )
303
304if __name__ == '__main__':
305 test_main()