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