| """Test script for the grp module.""" | |
| import random | |
| import string | |
| import sys | |
| import unittest | |
| from test.support import import_helper | |
| grp = import_helper.import_module('grp') | |
| class GroupDatabaseTestCase(unittest.TestCase): | |
| def check_value(self, value): | |
| # check that a grp tuple has the entries and | |
| # attributes promised by the docs | |
| self.assertEqual(len(value), 4) | |
| self.assertEqual(value[0], value.gr_name) | |
| self.assertIsInstance(value.gr_name, str) | |
| self.assertEqual(value[1], value.gr_passwd) | |
| self.assertIsInstance(value.gr_passwd, str) | |
| self.assertEqual(value[2], value.gr_gid) | |
| self.assertIsInstance(value.gr_gid, int) | |
| self.assertEqual(value[3], value.gr_mem) | |
| self.assertIsInstance(value.gr_mem, list) | |
| def test_values(self): | |
| entries = grp.getgrall() | |
| for e in entries: | |
| self.check_value(e) | |
| def test_values_extended(self): | |
| entries = grp.getgrall() | |
| if len(entries) > 1000: # Huge group file (NIS?) -- skip the rest | |
| self.skipTest('huge group file, extended test skipped') | |
| for e in entries: | |
| try: | |
| e2 = grp.getgrgid(e.gr_gid) | |
| except KeyError: | |
| # On Cygwin, some groups returned by getgrall() cannot be | |
| # retrieved by getgrgid() | |
| if sys.platform == 'cygwin': | |
| continue | |
| raise | |
| self.check_value(e2) | |
| self.assertEqual(e2.gr_gid, e.gr_gid) | |
| name = e.gr_name | |
| if name.startswith('+') or name.startswith('-'): | |
| # NIS-related entry | |
| continue | |
| e2 = grp.getgrnam(name) | |
| self.check_value(e2) | |
| # There are instances where getgrall() returns group names in | |
| # lowercase while getgrgid() returns proper casing. | |
| # Discovered on Ubuntu 5.04 (custom). | |
| self.assertEqual(e2.gr_name.lower(), name.lower()) | |
| def test_errors(self): | |
| self.assertRaises(TypeError, grp.getgrgid) | |
| self.assertRaises(TypeError, grp.getgrgid, 3.14) | |
| self.assertRaises(TypeError, grp.getgrgid, 0.0) | |
| self.assertRaises(TypeError, grp.getgrgid, 0, 0) | |
| # should be out of gid_t range | |
| self.assertRaises(OverflowError, grp.getgrgid, 2**128) | |
| self.assertRaises(OverflowError, grp.getgrgid, -2**128) | |
| self.assertRaises(TypeError, grp.getgrnam) | |
| self.assertRaises(TypeError, grp.getgrnam, 42) | |
| self.assertRaises(TypeError, grp.getgrnam, b'root') | |
| self.assertRaises(TypeError, grp.getgrnam, 'root', 0) | |
| # embedded null character | |
| self.assertRaisesRegex(ValueError, 'null', grp.getgrnam, 'a\x00b') | |
| self.assertRaisesRegex(ValueError, 'null', grp.getgrnam, 'root\x00') | |
| self.assertRaises(UnicodeEncodeError, grp.getgrnam, 'roo\udc74') | |
| self.assertRaises(KeyError, grp.getgrnam, '') | |
| self.assertRaises(TypeError, grp.getgrall, 42) | |
| # Find a non-existent group name. | |
| # getgrall() will not necessarily report all existing groups | |
| # (typical for LDAP based directories in big organizations). | |
| for _ in range(30): | |
| fakename = ''.join(random.choices(string.ascii_lowercase, k=6)) | |
| try: | |
| grp.getgrnam(fakename) | |
| except KeyError: | |
| break | |
| else: | |
| self.fail('Cannot find non-existent group name') | |
| # Find a non-existent gid. | |
| maxgid = 2**31 | |
| for _ in range(30): | |
| fakegid = random.randrange(maxgid) | |
| try: | |
| grp.getgrgid(fakegid) | |
| except KeyError: | |
| break | |
| except OverflowError: | |
| if maxgid == 2**31: | |
| maxgid = 2**16-1 | |
| elif maxgid == 2**16-1: | |
| maxgid = 2**15 | |
| else: | |
| raise | |
| else: | |
| self.fail('Cannot find non-existent gid') | |
| if __name__ == "__main__": | |
| unittest.main() |