Skip to content

Commit a170511

Browse files
committed
Increase coverage but with a number of tests requiring tweaks to the underlying
`userdb` module and in particular the locking from `fileio`.
1 parent 6fa9e88 commit a170511

File tree

1 file changed

+104
-13
lines changed

1 file changed

+104
-13
lines changed

tests/test_mig_shared_userdb.py

Lines changed: 104 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def test_lock_unlock_user_db(self):
114114
flock = lock_user_db(self.user_db_path, exclusive=False)
115115
self.assertTrue(flock is not None)
116116
self.assertTrue(flock.readable)
117-
# TODO: expose this attribue in the backend and enable next
117+
# TODO: expose this attribue in the backend and enable next?
118118
# self.assertFalse(flock.writable)
119119

120120
# Unlock shared
@@ -127,15 +127,15 @@ def test_load_user_db(self):
127127
save_user_db(empty_db, self.user_db_path)
128128
try:
129129
loaded = load_user_db(self.user_db_path)
130-
except Exception as exc:
130+
except Exception:
131131
loaded = None
132132
self.assertEqual(loaded, empty_db)
133133

134134
# Verify proper loading
135135
sample_db = self._create_sample_db()
136136
try:
137137
loaded = load_user_db(self.user_db_path)
138-
except Exception as exc:
138+
except Exception:
139139
loaded = None
140140
self.assertEqual(loaded, sample_db)
141141

@@ -144,7 +144,7 @@ def test_load_user_db(self):
144144
self.configuration.user_db_home, "no-such-db.db")
145145
try:
146146
loaded = load_user_db(db_path)
147-
except Exception as exc:
147+
except Exception:
148148
loaded = None
149149
self.assertEqual(loaded, None)
150150

@@ -153,7 +153,7 @@ def test_save_user_db(self):
153153
sample_db = self._create_sample_db()
154154
try:
155155
loaded = load_user_db(self.user_db_path)
156-
except Exception as exc:
156+
except Exception:
157157
loaded = None
158158
self.assertEqual(sample_db, loaded)
159159

@@ -162,7 +162,7 @@ def test_save_user_db(self):
162162
save_user_db(sample_db, self.user_db_path)
163163
try:
164164
reloaded = load_user_db(self.user_db_path)
165-
except Exception as exc:
165+
except Exception:
166166
reloaded = None
167167
self.assertEqual(reloaded, sample_db)
168168

@@ -172,7 +172,7 @@ def test_load_user_dict_missing(self):
172172
try:
173173
loaded = load_user_dict(self.logger, "no-such-user",
174174
self.user_db_path)
175-
except Exception as exc:
175+
except Exception:
176176
loaded = None
177177
self.assertIsNone(loaded)
178178

@@ -182,7 +182,7 @@ def test_load_user_dict_existing(self):
182182
try:
183183
test_user_data = load_user_dict(self.logger, TEST_USER_ID,
184184
self.user_db_path)
185-
except Exception as exc:
185+
except Exception:
186186
test_user_data = None
187187
self.assertEqual(test_user_data, sample_db[TEST_USER_ID])
188188

@@ -195,7 +195,7 @@ def test_save_user_dict_new_user(self):
195195

196196
try:
197197
loaded = load_user_db(self.user_db_path)
198-
except Exception as exc:
198+
except Exception:
199199
loaded = None
200200
self.assertEqual(loaded[OTHER_USER_ID], other_user)
201201

@@ -210,7 +210,7 @@ def test_save_user_dict_update(self):
210210

211211
try:
212212
loaded = load_user_db(self.user_db_path)
213-
except Exception as exc:
213+
except Exception:
214214
loaded = None
215215
self.assertEqual(loaded[THIS_USER_ID], changed)
216216

@@ -224,7 +224,7 @@ def test_update_user_dict(self):
224224

225225
try:
226226
full_db = load_user_db(self.user_db_path)
227-
except Exception as exc:
227+
except Exception:
228228
full_db = None
229229
self.assertEqual(full_db[THIS_USER_ID]["Organization"], "CHANGED")
230230

@@ -234,7 +234,7 @@ def test_update_user_dict_requirements(self):
234234
try:
235235
result = update_user_dict(self.logger, "no-such-user",
236236
{"field": "test"}, self.user_db_path)
237-
except Exception as exc:
237+
except Exception:
238238
result = None
239239
self.assertIsNone(result)
240240

@@ -252,7 +252,7 @@ def test_concurrent_load_save(self):
252252
def delayed_load():
253253
try:
254254
loaded = load_user_db(self.user_db_path)
255-
except Exception as exc:
255+
except Exception:
256256
loaded = None
257257
return loaded
258258

@@ -275,6 +275,97 @@ def test_pickle_roundtrip(self):
275275
loaded = loads(pickled)
276276
self.assertEqual(orig_db, loaded)
277277

278+
# TODO: adjust API to allow enabling the next test
279+
@unittest.skipIf(True, "requires locking fix")
280+
def test_lock_user_db_invalid_path(self):
281+
"""Test locking on non-existent database path"""
282+
invalid_path = os.path.join(
283+
self.configuration.user_db_home, "missing", "MiG-users.db")
284+
flock = lock_user_db(invalid_path)
285+
self.assertIsNone(flock)
286+
287+
# TODO: adjust API to allow enabling the next test
288+
@unittest.skipIf(True, "requires locking fix")
289+
def test_unlock_user_db_invalid(self):
290+
"""Test unlocking with None and invalid lock objects"""
291+
# Should handle without exceptions
292+
unlock_user_db(None)
293+
unlock_user_db("not a lock object")
294+
295+
def test_load_user_db_corrupted(self):
296+
"""Test loading corrupted user database"""
297+
with open(self.user_db_path, 'w') as fh:
298+
fh.write("invalid pickle content")
299+
with self.assertRaises(Exception):
300+
load_user_db(self.user_db_path)
301+
302+
# TODO: adjust API to allow enabling the next test
303+
@unittest.skipIf(True, "requires error handling fix")
304+
def test_save_user_db_readonly(self):
305+
"""Test saving to read-only database path"""
306+
sample_db = self._create_sample_db()
307+
try:
308+
os.chmod(self.user_db_path, 0o444) # Read-only
309+
except Exception:
310+
self.skipTest("Read-only test not supported")
311+
try:
312+
with self.assertRaises(PermissionError):
313+
save_user_db({"test": "data"}, self.user_db_path)
314+
finally:
315+
os.chmod(self.user_db_path, 0o644)
316+
317+
def test_load_user_dict_empty_db(self):
318+
"""Test loading user from empty database"""
319+
self._create_sample_db(content={})
320+
loaded = load_user_dict(self.logger, TEST_USER_ID, self.user_db_path)
321+
self.assertIsNone(loaded)
322+
323+
# TODO: adjust API to allow enabling the next test
324+
@unittest.skipIf(True, "requires ID validation fix")
325+
def test_save_user_dict_invalid_id(self):
326+
"""Test saving user with invalid characters in ID"""
327+
invalid_id = "../../invalid.user"
328+
user_dict = distinguished_name_to_user(TEST_USER_ID)
329+
save_status = save_user_dict(self.logger, invalid_id,
330+
user_dict, self.user_db_path)
331+
self.assertFalse(save_status)
332+
333+
def test_update_user_dict_empty_changes(self):
334+
"""Test update_user_dict with empty changes dictionary"""
335+
# Let log error about o changes pass
336+
self.logger.forgive_errors()
337+
sample_db = self._create_sample_db()
338+
original = sample_db[THIS_USER_ID].copy()
339+
updated = update_user_dict(self.logger, THIS_USER_ID, {},
340+
self.user_db_path)
341+
self.assertEqual(updated, original)
342+
343+
# TODO: adjust API to allow enabling the next test
344+
@unittest.skipIf(True, "requires error handling fix")
345+
def test_default_db_path_no_valid_paths(self):
346+
"""Test default_db_path with no valid locations"""
347+
self.configuration.user_db_home = None
348+
self.configuration.mig_server_home = None
349+
with self.assertRaises(ValueError):
350+
default_db_path(self.configuration)
351+
352+
# TODO: adjust API to allow enabling the next test
353+
@unittest.skipIf(True, "requires validation fix")
354+
def test_save_user_db_datatypes(self):
355+
"""Test saving non-dictionary database content"""
356+
with self.assertRaises(TypeError):
357+
save_user_db("invalid content", self.user_db_path)
358+
359+
def test_load_user_db_thread_safety(self):
360+
"""Test thread-safe loading with shared lock"""
361+
flock = lock_user_db(self.user_db_path, exclusive=False)
362+
try:
363+
# Should allow concurrent reads
364+
loaded = load_user_db(self.user_db_path)
365+
self.assertIsInstance(loaded, dict)
366+
finally:
367+
unlock_user_db(flock)
368+
278369

279370
if __name__ == '__main__':
280371
testmain()

0 commit comments

Comments
 (0)