1
# Copyright (c) 2009 Twisted Matrix Laboratories.
2
# See LICENSE for details.
5
Tests for L{twisted.python.fakepwd}.
14
from operator import getitem
16
from twisted.trial.unittest import TestCase
17
from twisted.python.fakepwd import UserDatabase
18
from twisted.python.compat import set
21
class UserDatabaseTestsMixin:
23
L{UserDatabaseTestsMixin} defines tests which apply to any user database
24
implementation. Subclasses should mix it in, implement C{setUp} to create
25
C{self.database} bound to a user database instance, and implement
26
C{getExistingUserInfo} to return information about a user (such information
27
should be unique per test method).
29
def test_getpwuid(self):
31
I{getpwuid} accepts a uid and returns the user record associated with
35
# Get some user which exists in the database.
36
username, password, uid, gid, gecos, dir, shell = self.getExistingUserInfo()
38
# Now try to look it up and make sure the result is correct.
39
entry = self.database.getpwuid(uid)
40
self.assertEquals(entry.pw_name, username)
41
self.assertEquals(entry.pw_passwd, password)
42
self.assertEquals(entry.pw_uid, uid)
43
self.assertEquals(entry.pw_gid, gid)
44
self.assertEquals(entry.pw_gecos, gecos)
45
self.assertEquals(entry.pw_dir, dir)
46
self.assertEquals(entry.pw_shell, shell)
49
def test_noSuchUID(self):
51
I{getpwuid} raises L{KeyError} when passed a uid which does not exist
54
self.assertRaises(KeyError, self.database.getpwuid, -13)
57
def test_getpwnam(self):
59
I{getpwnam} accepts a username and returns the user record associated
63
# Get some user which exists in the database.
64
username, password, uid, gid, gecos, dir, shell = self.getExistingUserInfo()
66
# Now try to look it up and make sure the result is correct.
67
entry = self.database.getpwnam(username)
68
self.assertEquals(entry.pw_name, username)
69
self.assertEquals(entry.pw_passwd, password)
70
self.assertEquals(entry.pw_uid, uid)
71
self.assertEquals(entry.pw_gid, gid)
72
self.assertEquals(entry.pw_gecos, gecos)
73
self.assertEquals(entry.pw_dir, dir)
74
self.assertEquals(entry.pw_shell, shell)
77
def test_noSuchName(self):
79
I{getpwnam} raises L{KeyError} when passed a username which does not
80
exist in the user database.
83
KeyError, self.database.getpwnam,
84
'no' 'such' 'user' 'exists' 'the' 'name' 'is' 'too' 'long' 'and' 'has'
88
def test_recordLength(self):
90
The user record returned by I{getpwuid}, I{getpwnam}, and I{getpwall}
94
username, password, uid, gid, gecos, dir, shell = self.getExistingUserInfo()
95
for entry in [db.getpwuid(uid), db.getpwnam(username), db.getpwall()[0]]:
96
self.assertIsInstance(len(entry), int)
99
def test_recordIndexable(self):
101
The user record returned by I{getpwuid}, I{getpwnam}, and I{getpwall}
102
is indexable, with successive indexes starting from 0 corresponding to
103
the values of the C{pw_name}, C{pw_passwd}, C{pw_uid}, C{pw_gid},
104
C{pw_gecos}, C{pw_dir}, and C{pw_shell} attributes, respectively.
107
username, password, uid, gid, gecos, dir, shell = self.getExistingUserInfo()
108
for entry in [db.getpwuid(uid), db.getpwnam(username), db.getpwall()[0]]:
109
self.assertEquals(entry[0], username)
110
self.assertEquals(entry[1], password)
111
self.assertEquals(entry[2], uid)
112
self.assertEquals(entry[3], gid)
113
self.assertEquals(entry[4], gecos)
114
self.assertEquals(entry[5], dir)
115
self.assertEquals(entry[6], shell)
117
self.assertEquals(len(entry), len(list(entry)))
118
self.assertRaises(IndexError, getitem, entry, 7)
122
class UserDatabaseTests(TestCase, UserDatabaseTestsMixin):
124
Tests for L{UserDatabase}.
128
Create a L{UserDatabase} with no user data in it.
130
self.database = UserDatabase()
134
def getExistingUserInfo(self):
136
Add a new user to C{self.database} and return its information.
139
suffix = '_' + str(self._counter)
140
username = 'username' + suffix
141
password = 'password' + suffix
143
gid = self._counter + 1000
144
gecos = 'gecos' + suffix
146
shell = 'shell' + suffix
148
self.database.addUser(username, password, uid, gid, gecos, dir, shell)
149
return (username, password, uid, gid, gecos, dir, shell)
152
def test_addUser(self):
154
L{UserDatabase.addUser} accepts seven arguments, one for each field of
155
a L{pwd.struct_passwd}, and makes the new record available via
156
L{UserDatabase.getpwuid}, L{UserDatabase.getpwnam}, and
157
L{UserDatabase.getpwall}.
164
home = '/users/alice'
165
shell = '/usr/bin/foosh'
168
db.addUser(username, password, uid, gid, gecos, home, shell)
170
for entry in [db.getpwuid(uid), db.getpwnam(username)]:
171
self.assertEquals(entry.pw_name, username)
172
self.assertEquals(entry.pw_passwd, password)
173
self.assertEquals(entry.pw_uid, uid)
174
self.assertEquals(entry.pw_gid, gid)
175
self.assertEquals(entry.pw_gecos, gecos)
176
self.assertEquals(entry.pw_dir, home)
177
self.assertEquals(entry.pw_shell, shell)
179
[entry] = db.getpwall()
180
self.assertEquals(entry.pw_name, username)
181
self.assertEquals(entry.pw_passwd, password)
182
self.assertEquals(entry.pw_uid, uid)
183
self.assertEquals(entry.pw_gid, gid)
184
self.assertEquals(entry.pw_gecos, gecos)
185
self.assertEquals(entry.pw_dir, home)
186
self.assertEquals(entry.pw_shell, shell)
190
class PwdModuleTests(TestCase, UserDatabaseTestsMixin):
192
L{PwdModuleTests} runs the tests defined by L{UserDatabaseTestsMixin}
193
against the built-in C{pwd} module. This serves to verify that
194
L{UserDatabase} is really a fake of that API.
197
skip = "Cannot verify UserDatabase against pwd without pwd"
202
self._users = iter(self.database.getpwall())
206
def getExistingUserInfo(self):
208
Read and return the next record from C{self._users}, filtering out
209
any records with previously seen uid values (as these cannot be
210
found with C{getpwuid} and only cause trouble).
213
entry = self._users.next()
214
if entry.pw_uid not in self._uids:
215
self._uids.add(entry.pw_uid)