test script for the grp module import unittest from test support import importhelper grp importhelper importmodule grp class groupdatabasetestcaseunittest testcase def checkvalueself value check that a grp tuple has the entries and attributes promised by the docs self assertequallenvalue 4 self assertequalvalue0 value grname self assertisinstancevalue grname str self assertequalvalue1 value grpasswd self assertisinstancevalue grpasswd str self assertequalvalue2 value grgid self assertisinstancevalue grgid int self assertequalvalue3 value grmem self assertisinstancevalue grmem list def testvaluesself entries grp getgrall for e in entries self checkvaluee def testvaluesextendedself entries grp getgrall if lenentries 1000 huge group file nis skip the rest self skiptest huge group file extended test skipped for e in entries e2 grp getgrgide grgid self checkvaluee2 self assertequale2 grgid e grgid name e grname if name startswith or name startswith nisrelated entry continue e2 grp getgrnamname self checkvaluee2 there are instances where getgrall returns group names in lowercase while getgrgid returns proper casing discovered on ubuntu 5 04 custom self assertequale2 grname lower name lower def testerrorsself self assertraisestypeerror grp getgrgid self assertraisestypeerror grp getgrgid 3 14 self assertraisestypeerror grp getgrnam self assertraisestypeerror grp getgrnam 42 self assertraisestypeerror grp getgrall 42 embedded null character self assertraisesregexvalueerror null grp getgrnam ax00b try to get some errors bynames bygids for n p g mem in grp getgrall if not n or n continue skip nis entries etc bynamesn g bygidsg n allnames listbynames keys namei 0 fakename allnamesnamei while fakename in bynames chars listfakename for i in rangelenchars if charsi z charsi a break elif charsi z continue else charsi chrordcharsi 1 break else namei namei 1 try fakename allnamesnamei except indexerror should never happen if so just forget it break fakename joinchars self assertraiseskeyerror grp getgrnam fakename choose a nonexistent gid fakegid 4127 while fakegid in bygids fakegid fakegid 3 0x10000 self assertraiseskeyerror grp getgrgid fakegid def testnonintegergidself entries grp getgrall if not entries self skiptest no groups choose an existent gid gid entries02 self assertraisestypeerror grp getgrgid floatgid self assertraisestypeerror grp getgrgid strgid if name main unittest main check that a grp tuple has the entries and attributes promised by the docs huge group file nis skip the rest nis related entry there are instances where getgrall returns group names in lowercase while getgrgid returns proper casing discovered on ubuntu 5 04 custom embedded null character try to get some errors skip nis entries etc should never happen if so just forget it choose a non existent gid choose an existent gid
import unittest
from test.support import import_helper


grp = import_helper.import_module('grp')

class GroupDatabaseTestCase(unittest.TestCase):

    def check_value(self, value):
        
        
        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:  
            self.skipTest('huge group file, extended test skipped')

        for e in entries:
            e2 = grp.getgrgid(e.gr_gid)
            self.check_value(e2)
            self.assertEqual(e2.gr_gid, e.gr_gid)
            name = e.gr_name
            if name.startswith('+') or name.startswith('-'):
                
                continue
            e2 = grp.getgrnam(name)
            self.check_value(e2)
            
            
            
            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.getgrnam)
        self.assertRaises(TypeError, grp.getgrnam, 42)
        self.assertRaises(TypeError, grp.getgrall, 42)
        
        self.assertRaisesRegex(ValueError, 'null', grp.getgrnam, 'a\x00b')

        
        bynames = {}
        bygids = {}
        for (n, p, g, mem) in grp.getgrall():
            if not n or n == '+':
                continue 
            bynames[n] = g
            bygids[g] = n

        allnames = list(bynames.keys())
        namei = 0
        fakename = allnames[namei]
        while fakename in bynames:
            chars = list(fakename)
            for i in range(len(chars)):
                if chars[i] == 'z':
                    chars[i] = 'A'
                    break
                elif chars[i] == 'Z':
                    continue
                else:
                    chars[i] = chr(ord(chars[i]) + 1)
                    break
            else:
                namei = namei + 1
                try:
                    fakename = allnames[namei]
                except IndexError:
                    
                    break
            fakename = ''.join(chars)

        self.assertRaises(KeyError, grp.getgrnam, fakename)

        
        fakegid = 4127
        while fakegid in bygids:
            fakegid = (fakegid * 3) % 0x10000

        self.assertRaises(KeyError, grp.getgrgid, fakegid)

    def test_noninteger_gid(self):
        entries = grp.getgrall()
        if not entries:
            self.skipTest('no groups')
        
        gid = entries[0][2]
        self.assertRaises(TypeError, grp.getgrgid, float(gid))
        self.assertRaises(TypeError, grp.getgrgid, str(gid))


if __name__ == "__main__":
    unittest.main()