test_pwd.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import sys
  2. import unittest
  3. from test.support import import_helper
  4. pwd = import_helper.import_module('pwd')
  5. @unittest.skipUnless(hasattr(pwd, 'getpwall'), 'Does not have getpwall()')
  6. class PwdTest(unittest.TestCase):
  7. def test_values(self):
  8. entries = pwd.getpwall()
  9. for e in entries:
  10. self.assertEqual(len(e), 7)
  11. self.assertEqual(e[0], e.pw_name)
  12. self.assertIsInstance(e.pw_name, str)
  13. self.assertEqual(e[1], e.pw_passwd)
  14. self.assertIsInstance(e.pw_passwd, str)
  15. self.assertEqual(e[2], e.pw_uid)
  16. self.assertIsInstance(e.pw_uid, int)
  17. self.assertEqual(e[3], e.pw_gid)
  18. self.assertIsInstance(e.pw_gid, int)
  19. self.assertEqual(e[4], e.pw_gecos)
  20. self.assertIn(type(e.pw_gecos), (str, type(None)))
  21. self.assertEqual(e[5], e.pw_dir)
  22. self.assertIsInstance(e.pw_dir, str)
  23. self.assertEqual(e[6], e.pw_shell)
  24. self.assertIsInstance(e.pw_shell, str)
  25. # The following won't work, because of duplicate entries
  26. # for one uid
  27. # self.assertEqual(pwd.getpwuid(e.pw_uid), e)
  28. # instead of this collect all entries for one uid
  29. # and check afterwards (done in test_values_extended)
  30. def test_values_extended(self):
  31. entries = pwd.getpwall()
  32. entriesbyname = {}
  33. entriesbyuid = {}
  34. if len(entries) > 1000: # Huge passwd file (NIS?) -- skip this test
  35. self.skipTest('passwd file is huge; extended test skipped')
  36. for e in entries:
  37. entriesbyname.setdefault(e.pw_name, []).append(e)
  38. entriesbyuid.setdefault(e.pw_uid, []).append(e)
  39. # check whether the entry returned by getpwuid()
  40. # for each uid is among those from getpwall() for this uid
  41. for e in entries:
  42. if not e[0] or e[0] == '+':
  43. continue # skip NIS entries etc.
  44. self.assertIn(pwd.getpwnam(e.pw_name), entriesbyname[e.pw_name])
  45. self.assertIn(pwd.getpwuid(e.pw_uid), entriesbyuid[e.pw_uid])
  46. def test_errors(self):
  47. self.assertRaises(TypeError, pwd.getpwuid)
  48. self.assertRaises(TypeError, pwd.getpwuid, 3.14)
  49. self.assertRaises(TypeError, pwd.getpwnam)
  50. self.assertRaises(TypeError, pwd.getpwnam, 42)
  51. self.assertRaises(TypeError, pwd.getpwall, 42)
  52. # embedded null character
  53. self.assertRaisesRegex(ValueError, 'null', pwd.getpwnam, 'a\x00b')
  54. # try to get some errors
  55. bynames = {}
  56. byuids = {}
  57. for (n, p, u, g, gecos, d, s) in pwd.getpwall():
  58. bynames[n] = u
  59. byuids[u] = n
  60. allnames = list(bynames.keys())
  61. namei = 0
  62. fakename = allnames[namei] if allnames else "invaliduser"
  63. while fakename in bynames:
  64. chars = list(fakename)
  65. for i in range(len(chars)):
  66. if chars[i] == 'z':
  67. chars[i] = 'A'
  68. break
  69. elif chars[i] == 'Z':
  70. continue
  71. else:
  72. chars[i] = chr(ord(chars[i]) + 1)
  73. break
  74. else:
  75. namei = namei + 1
  76. try:
  77. fakename = allnames[namei]
  78. except IndexError:
  79. # should never happen... if so, just forget it
  80. break
  81. fakename = ''.join(chars)
  82. self.assertRaises(KeyError, pwd.getpwnam, fakename)
  83. # In some cases, byuids isn't a complete list of all users in the
  84. # system, so if we try to pick a value not in byuids (via a perturbing
  85. # loop, say), pwd.getpwuid() might still be able to find data for that
  86. # uid. Using sys.maxint may provoke the same problems, but hopefully
  87. # it will be a more repeatable failure.
  88. fakeuid = sys.maxsize
  89. self.assertNotIn(fakeuid, byuids)
  90. self.assertRaises(KeyError, pwd.getpwuid, fakeuid)
  91. # -1 shouldn't be a valid uid because it has a special meaning in many
  92. # uid-related functions
  93. self.assertRaises(KeyError, pwd.getpwuid, -1)
  94. # should be out of uid_t range
  95. self.assertRaises(KeyError, pwd.getpwuid, 2**128)
  96. self.assertRaises(KeyError, pwd.getpwuid, -2**128)
  97. if __name__ == "__main__":
  98. unittest.main()