@@ -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
279370if __name__ == '__main__' :
280371 testmain ()
0 commit comments