1"""Test script for the grp module."""
2
3import unittest
4from test import support
5
6grp = support.import_module('grp')
7
8class GroupDatabaseTestCase(unittest.TestCase):
9
10    def check_value(self, value):
11        # check that a grp tuple has the entries and
12        # attributes promised by the docs
13        self.assertEqual(len(value), 4)
14        self.assertEqual(value[0], value.gr_name)
15        self.assertIsInstance(value.gr_name, str)
16        self.assertEqual(value[1], value.gr_passwd)
17        self.assertIsInstance(value.gr_passwd, str)
18        self.assertEqual(value[2], value.gr_gid)
19        self.assertIsInstance(value.gr_gid, int)
20        self.assertEqual(value[3], value.gr_mem)
21        self.assertIsInstance(value.gr_mem, list)
22
23    def test_values(self):
24        entries = grp.getgrall()
25
26        for e in entries:
27            self.check_value(e)
28
29    def test_values_extended(self):
30        entries = grp.getgrall()
31        if len(entries) > 1000:  # Huge group file (NIS?) -- skip the rest
32            self.skipTest('huge group file, extended test skipped')
33
34        for e in entries:
35            e2 = grp.getgrgid(e.gr_gid)
36            self.check_value(e2)
37            self.assertEqual(e2.gr_gid, e.gr_gid)
38            name = e.gr_name
39            if name.startswith('+') or name.startswith('-'):
40                # NIS-related entry
41                continue
42            e2 = grp.getgrnam(name)
43            self.check_value(e2)
44            # There are instances where getgrall() returns group names in
45            # lowercase while getgrgid() returns proper casing.
46            # Discovered on Ubuntu 5.04 (custom).
47            self.assertEqual(e2.gr_name.lower(), name.lower())
48
49    def test_errors(self):
50        self.assertRaises(TypeError, grp.getgrgid)
51        self.assertRaises(TypeError, grp.getgrnam)
52        self.assertRaises(TypeError, grp.getgrall, 42)
53
54        # try to get some errors
55        bynames = {}
56        bygids = {}
57        for (n, p, g, mem) in grp.getgrall():
58            if not n or n == '+':
59                continue # skip NIS entries etc.
60            bynames[n] = g
61            bygids[g] = n
62
63        allnames = list(bynames.keys())
64        namei = 0
65        fakename = allnames[namei]
66        while fakename in bynames:
67            chars = list(fakename)
68            for i in range(len(chars)):
69                if chars[i] == 'z':
70                    chars[i] = 'A'
71                    break
72                elif chars[i] == 'Z':
73                    continue
74                else:
75                    chars[i] = chr(ord(chars[i]) + 1)
76                    break
77            else:
78                namei = namei + 1
79                try:
80                    fakename = allnames[namei]
81                except IndexError:
82                    # should never happen... if so, just forget it
83                    break
84            fakename = ''.join(chars)
85
86        self.assertRaises(KeyError, grp.getgrnam, fakename)
87
88        # Choose a non-existent gid.
89        fakegid = 4127
90        while fakegid in bygids:
91            fakegid = (fakegid * 3) % 0x10000
92
93        self.assertRaises(KeyError, grp.getgrgid, fakegid)
94
95    def test_noninteger_gid(self):
96        entries = grp.getgrall()
97        if not entries:
98            self.skipTest('no groups')
99        # Choose an existent gid.
100        gid = entries[0][2]
101        self.assertWarns(DeprecationWarning, grp.getgrgid, float(gid))
102        self.assertWarns(DeprecationWarning, grp.getgrgid, str(gid))
103
104
105if __name__ == "__main__":
106    unittest.main()
107