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