Collin Winter | b24ef19 | 2010-03-18 00:23:44 +0000 | [diff] [blame] | 1 | import sys |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 2 | import unittest |
Benjamin Peterson | ee8712c | 2008-05-20 21:35:26 +0000 | [diff] [blame] | 3 | from test import support |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 4 | |
R. David Murray | a21e4ca | 2009-03-31 23:16:50 +0000 | [diff] [blame] | 5 | pwd = support.import_module('pwd') |
Barry Warsaw | 3d070fb | 1996-12-11 16:53:51 +0000 | [diff] [blame] | 6 | |
Xavier de Gaye | fb24eea | 2016-12-13 09:11:38 +0100 | [diff] [blame] | 7 | def _getpwall(): |
| 8 | # Android does not have getpwall. |
| 9 | if hasattr(pwd, 'getpwall'): |
| 10 | return pwd.getpwall() |
| 11 | elif hasattr(pwd, 'getpwuid'): |
| 12 | return [pwd.getpwuid(0)] |
| 13 | else: |
| 14 | return [] |
| 15 | |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 16 | class PwdTest(unittest.TestCase): |
Barry Warsaw | 3d070fb | 1996-12-11 16:53:51 +0000 | [diff] [blame] | 17 | |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 18 | def test_values(self): |
Xavier de Gaye | fb24eea | 2016-12-13 09:11:38 +0100 | [diff] [blame] | 19 | entries = _getpwall() |
Barry Warsaw | 3d070fb | 1996-12-11 16:53:51 +0000 | [diff] [blame] | 20 | |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 21 | for e in entries: |
| 22 | self.assertEqual(len(e), 7) |
| 23 | self.assertEqual(e[0], e.pw_name) |
Ezio Melotti | e961593 | 2010-01-24 19:26:24 +0000 | [diff] [blame] | 24 | self.assertIsInstance(e.pw_name, str) |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 25 | self.assertEqual(e[1], e.pw_passwd) |
Ezio Melotti | e961593 | 2010-01-24 19:26:24 +0000 | [diff] [blame] | 26 | self.assertIsInstance(e.pw_passwd, str) |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 27 | self.assertEqual(e[2], e.pw_uid) |
Ezio Melotti | e961593 | 2010-01-24 19:26:24 +0000 | [diff] [blame] | 28 | self.assertIsInstance(e.pw_uid, int) |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 29 | self.assertEqual(e[3], e.pw_gid) |
Ezio Melotti | e961593 | 2010-01-24 19:26:24 +0000 | [diff] [blame] | 30 | self.assertIsInstance(e.pw_gid, int) |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 31 | self.assertEqual(e[4], e.pw_gecos) |
Ezio Melotti | e961593 | 2010-01-24 19:26:24 +0000 | [diff] [blame] | 32 | self.assertIsInstance(e.pw_gecos, str) |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 33 | self.assertEqual(e[5], e.pw_dir) |
Ezio Melotti | e961593 | 2010-01-24 19:26:24 +0000 | [diff] [blame] | 34 | self.assertIsInstance(e.pw_dir, str) |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 35 | self.assertEqual(e[6], e.pw_shell) |
Ezio Melotti | e961593 | 2010-01-24 19:26:24 +0000 | [diff] [blame] | 36 | self.assertIsInstance(e.pw_shell, str) |
Barry Warsaw | 3d070fb | 1996-12-11 16:53:51 +0000 | [diff] [blame] | 37 | |
Walter Dörwald | 66e1e50 | 2003-04-15 15:39:08 +0000 | [diff] [blame] | 38 | # The following won't work, because of duplicate entries |
| 39 | # for one uid |
| 40 | # self.assertEqual(pwd.getpwuid(e.pw_uid), e) |
| 41 | # instead of this collect all entries for one uid |
Zachary Ware | 9fe6d86 | 2013-12-08 00:20:35 -0600 | [diff] [blame] | 42 | # and check afterwards (done in test_values_extended) |
| 43 | |
| 44 | def test_values_extended(self): |
Xavier de Gaye | fb24eea | 2016-12-13 09:11:38 +0100 | [diff] [blame] | 45 | entries = _getpwall() |
Zachary Ware | 9fe6d86 | 2013-12-08 00:20:35 -0600 | [diff] [blame] | 46 | entriesbyname = {} |
| 47 | entriesbyuid = {} |
| 48 | |
| 49 | if len(entries) > 1000: # Huge passwd file (NIS?) -- skip this test |
| 50 | self.skipTest('passwd file is huge; extended test skipped') |
| 51 | |
| 52 | for e in entries: |
Walter Dörwald | ecd2fdc | 2003-04-22 11:05:57 +0000 | [diff] [blame] | 53 | entriesbyname.setdefault(e.pw_name, []).append(e) |
Walter Dörwald | 66e1e50 | 2003-04-15 15:39:08 +0000 | [diff] [blame] | 54 | entriesbyuid.setdefault(e.pw_uid, []).append(e) |
| 55 | |
| 56 | # check whether the entry returned by getpwuid() |
| 57 | # for each uid is among those from getpwall() for this uid |
| 58 | for e in entries: |
Fredrik Lundh | 0e664e1 | 2005-12-12 20:53:40 +0000 | [diff] [blame] | 59 | if not e[0] or e[0] == '+': |
| 60 | continue # skip NIS entries etc. |
Benjamin Peterson | 577473f | 2010-01-19 00:09:57 +0000 | [diff] [blame] | 61 | self.assertIn(pwd.getpwnam(e.pw_name), entriesbyname[e.pw_name]) |
| 62 | self.assertIn(pwd.getpwuid(e.pw_uid), entriesbyuid[e.pw_uid]) |
Fred Drake | 004d5e6 | 2000-10-23 17:22:08 +0000 | [diff] [blame] | 63 | |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 64 | def test_errors(self): |
| 65 | self.assertRaises(TypeError, pwd.getpwuid) |
Serhiy Storchaka | 55e2238 | 2013-02-11 20:32:47 +0200 | [diff] [blame] | 66 | self.assertRaises(TypeError, pwd.getpwuid, 3.14) |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 67 | self.assertRaises(TypeError, pwd.getpwnam) |
Serhiy Storchaka | 55e2238 | 2013-02-11 20:32:47 +0200 | [diff] [blame] | 68 | self.assertRaises(TypeError, pwd.getpwnam, 42) |
Xavier de Gaye | fb24eea | 2016-12-13 09:11:38 +0100 | [diff] [blame] | 69 | if hasattr(pwd, 'getpwall'): |
| 70 | self.assertRaises(TypeError, pwd.getpwall, 42) |
Barry Warsaw | 3d070fb | 1996-12-11 16:53:51 +0000 | [diff] [blame] | 71 | |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 72 | # try to get some errors |
| 73 | bynames = {} |
| 74 | byuids = {} |
Xavier de Gaye | fb24eea | 2016-12-13 09:11:38 +0100 | [diff] [blame] | 75 | for (n, p, u, g, gecos, d, s) in _getpwall(): |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 76 | bynames[n] = u |
| 77 | byuids[u] = n |
Barry Warsaw | 3d070fb | 1996-12-11 16:53:51 +0000 | [diff] [blame] | 78 | |
Guido van Rossum | 9afbb4e | 2007-02-11 18:54:18 +0000 | [diff] [blame] | 79 | allnames = list(bynames.keys()) |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 80 | namei = 0 |
| 81 | fakename = allnames[namei] |
| 82 | while fakename in bynames: |
Guido van Rossum | c1f779c | 2007-07-03 08:25:58 +0000 | [diff] [blame] | 83 | chars = list(fakename) |
Guido van Rossum | 805365e | 2007-05-07 22:24:25 +0000 | [diff] [blame] | 84 | for i in range(len(chars)): |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 85 | if chars[i] == 'z': |
| 86 | chars[i] = 'A' |
| 87 | break |
| 88 | elif chars[i] == 'Z': |
| 89 | continue |
| 90 | else: |
| 91 | chars[i] = chr(ord(chars[i]) + 1) |
| 92 | break |
| 93 | else: |
| 94 | namei = namei + 1 |
| 95 | try: |
| 96 | fakename = allnames[namei] |
| 97 | except IndexError: |
| 98 | # should never happen... if so, just forget it |
| 99 | break |
Guido van Rossum | c1f779c | 2007-07-03 08:25:58 +0000 | [diff] [blame] | 100 | fakename = ''.join(chars) |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 101 | |
| 102 | self.assertRaises(KeyError, pwd.getpwnam, fakename) |
| 103 | |
Collin Winter | b24ef19 | 2010-03-18 00:23:44 +0000 | [diff] [blame] | 104 | # In some cases, byuids isn't a complete list of all users in the |
| 105 | # system, so if we try to pick a value not in byuids (via a perturbing |
| 106 | # loop, say), pwd.getpwuid() might still be able to find data for that |
| 107 | # uid. Using sys.maxint may provoke the same problems, but hopefully |
| 108 | # it will be a more repeatable failure. |
Xavier de Gaye | fb24eea | 2016-12-13 09:11:38 +0100 | [diff] [blame] | 109 | # Android accepts a very large span of uids including sys.maxsize and |
| 110 | # -1; it raises KeyError with 1 or 2 for example. |
Collin Winter | b24ef19 | 2010-03-18 00:23:44 +0000 | [diff] [blame] | 111 | fakeuid = sys.maxsize |
| 112 | self.assertNotIn(fakeuid, byuids) |
Xavier de Gaye | fb24eea | 2016-12-13 09:11:38 +0100 | [diff] [blame] | 113 | if not support.is_android: |
| 114 | self.assertRaises(KeyError, pwd.getpwuid, fakeuid) |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 115 | |
Serhiy Storchaka | 55e2238 | 2013-02-11 20:32:47 +0200 | [diff] [blame] | 116 | # -1 shouldn't be a valid uid because it has a special meaning in many |
| 117 | # uid-related functions |
Xavier de Gaye | fb24eea | 2016-12-13 09:11:38 +0100 | [diff] [blame] | 118 | if not support.is_android: |
| 119 | self.assertRaises(KeyError, pwd.getpwuid, -1) |
Serhiy Storchaka | 55e2238 | 2013-02-11 20:32:47 +0200 | [diff] [blame] | 120 | # should be out of uid_t range |
| 121 | self.assertRaises(KeyError, pwd.getpwuid, 2**128) |
| 122 | self.assertRaises(KeyError, pwd.getpwuid, -2**128) |
| 123 | |
Walter Dörwald | b1ded1e | 2003-04-15 11:10:33 +0000 | [diff] [blame] | 124 | if __name__ == "__main__": |
Zachary Ware | 38c707e | 2015-04-13 15:00:43 -0500 | [diff] [blame] | 125 | unittest.main() |