1import os
2import unittest
3from test import support
4
5spwd = support.import_module('spwd')
6
7
8@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0,
9                     'root privileges required')
10class TestSpwdRoot(unittest.TestCase):
11
12    def test_getspall(self):
13        entries = spwd.getspall()
14        self.assertIsInstance(entries, list)
15        for entry in entries:
16            self.assertIsInstance(entry, spwd.struct_spwd)
17
18    def test_getspnam(self):
19        entries = spwd.getspall()
20        if not entries:
21            self.skipTest('empty shadow password database')
22        random_name = entries[0].sp_namp
23        entry = spwd.getspnam(random_name)
24        self.assertIsInstance(entry, spwd.struct_spwd)
25        self.assertEqual(entry.sp_namp, random_name)
26        self.assertEqual(entry.sp_namp, entry[0])
27        self.assertEqual(entry.sp_namp, entry.sp_nam)
28        self.assertIsInstance(entry.sp_pwdp, str)
29        self.assertEqual(entry.sp_pwdp, entry[1])
30        self.assertEqual(entry.sp_pwdp, entry.sp_pwd)
31        self.assertIsInstance(entry.sp_lstchg, int)
32        self.assertEqual(entry.sp_lstchg, entry[2])
33        self.assertIsInstance(entry.sp_min, int)
34        self.assertEqual(entry.sp_min, entry[3])
35        self.assertIsInstance(entry.sp_max, int)
36        self.assertEqual(entry.sp_max, entry[4])
37        self.assertIsInstance(entry.sp_warn, int)
38        self.assertEqual(entry.sp_warn, entry[5])
39        self.assertIsInstance(entry.sp_inact, int)
40        self.assertEqual(entry.sp_inact, entry[6])
41        self.assertIsInstance(entry.sp_expire, int)
42        self.assertEqual(entry.sp_expire, entry[7])
43        self.assertIsInstance(entry.sp_flag, int)
44        self.assertEqual(entry.sp_flag, entry[8])
45        with self.assertRaises(KeyError) as cx:
46            spwd.getspnam('invalid user name')
47        self.assertEqual(str(cx.exception), "'getspnam(): name not found'")
48        self.assertRaises(TypeError, spwd.getspnam)
49        self.assertRaises(TypeError, spwd.getspnam, 0)
50        self.assertRaises(TypeError, spwd.getspnam, random_name, 0)
51        try:
52            bytes_name = os.fsencode(random_name)
53        except UnicodeEncodeError:
54            pass
55        else:
56            self.assertRaises(TypeError, spwd.getspnam, bytes_name)
57
58
59@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() != 0,
60                     'non-root user required')
61class TestSpwdNonRoot(unittest.TestCase):
62
63    def test_getspnam_exception(self):
64        name = 'bin'
65        try:
66            with self.assertRaises(PermissionError) as cm:
67                spwd.getspnam(name)
68        except KeyError as exc:
69            self.skipTest("spwd entry %r doesn't exist: %s" % (name, exc))
70        else:
71            self.assertEqual(str(cm.exception), '[Errno 13] Permission denied')
72
73
74if __name__ == "__main__":
75    unittest.main()
76