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        # embedded null character
54        self.assertRaises(ValueError, grp.getgrnam, 'a\x00b')
55
56        # try to get some errors
57        bynames = {}
58        bygids = {}
59        for (n, p, g, mem) in grp.getgrall():
60            if not n or n == '+':
61                continue # skip NIS entries etc.
62            bynames[n] = g
63            bygids[g] = n
64
65        allnames = list(bynames.keys())
66        namei = 0
67        fakename = allnames[namei]
68        while fakename in bynames:
69            chars = list(fakename)
70            for i in range(len(chars)):
71                if chars[i] == 'z':
72                    chars[i] = 'A'
73                    break
74                elif chars[i] == 'Z':
75                    continue
76                else:
77                    chars[i] = chr(ord(chars[i]) + 1)
78                    break
79            else:
80                namei = namei + 1
81                try:
82                    fakename = allnames[namei]
83                except IndexError:
84                    # should never happen... if so, just forget it
85                    break
86            fakename = ''.join(chars)
87
88        self.assertRaises(KeyError, grp.getgrnam, fakename)
89
90        # Choose a non-existent gid.
91        fakegid = 4127
92        while fakegid in bygids:
93            fakegid = (fakegid * 3) % 0x10000
94
95        self.assertRaises(KeyError, grp.getgrgid, fakegid)
96
97    def test_noninteger_gid(self):
98        entries = grp.getgrall()
99        if not entries:
100            self.skipTest('no groups')
101        # Choose an existent gid.
102        gid = entries[0][2]
103        self.assertWarns(DeprecationWarning, grp.getgrgid, float(gid))
104        self.assertWarns(DeprecationWarning, grp.getgrgid, str(gid))
105
106
107if __name__ == "__main__":
108    unittest.main()
109