"""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()
