@@ -1212,6 +1212,78 @@ def mock_func():
12121212 core .delete_stale_entries (timedelta (hours = 1 ))
12131213
12141214
1215+ @pytest .mark .pickle
1216+ def test_clear_all_cache_files_retries_on_permission_error (tmp_path ):
1217+ """Test _clear_all_cache_files retries on PermissionError then succeeds."""
1218+ core = _PickleCore (
1219+ hash_func = None ,
1220+ cache_dir = tmp_path ,
1221+ pickle_reload = False ,
1222+ wait_for_calc_timeout = 10 ,
1223+ separate_files = True ,
1224+ )
1225+
1226+ def mock_func ():
1227+ pass
1228+
1229+ core .set_func (mock_func )
1230+
1231+ # Create a cache file that matches the name pattern
1232+ cache_fpath = core .cache_fpath
1233+ dummy_file = cache_fpath + "_dummykey"
1234+ with open (dummy_file , "wb" ) as f :
1235+ f .write (b"" )
1236+
1237+ # os.remove fails twice then succeeds on the third call
1238+ real_remove = os .remove
1239+ call_count = 0
1240+
1241+ def flaky_remove (path ):
1242+ nonlocal call_count
1243+ call_count += 1
1244+ if call_count < 3 :
1245+ raise PermissionError ("locked" )
1246+ real_remove (path )
1247+
1248+ with patch ("cachier.cores.pickle.os.remove" , side_effect = flaky_remove ), patch (
1249+ "cachier.cores.pickle.time.sleep"
1250+ ) as mock_sleep :
1251+ core ._clear_all_cache_files ()
1252+ assert mock_sleep .call_count == 2
1253+ mock_sleep .assert_any_call (0.1 )
1254+ mock_sleep .assert_any_call (0.2 )
1255+
1256+ assert not os .path .exists (dummy_file )
1257+
1258+
1259+ @pytest .mark .pickle
1260+ def test_clear_all_cache_files_raises_on_persistent_permission_error (tmp_path ):
1261+ """Test _clear_all_cache_files re-raises PermissionError after all retries."""
1262+ core = _PickleCore (
1263+ hash_func = None ,
1264+ cache_dir = tmp_path ,
1265+ pickle_reload = False ,
1266+ wait_for_calc_timeout = 10 ,
1267+ separate_files = True ,
1268+ )
1269+
1270+ def mock_func ():
1271+ pass
1272+
1273+ core .set_func (mock_func )
1274+
1275+ # Create a cache file that matches the name pattern
1276+ cache_fpath = core .cache_fpath
1277+ dummy_file = cache_fpath + "_dummykey"
1278+ with open (dummy_file , "wb" ) as f :
1279+ f .write (b"" )
1280+
1281+ with patch ("cachier.cores.pickle.os.remove" , side_effect = PermissionError ("locked" )), patch (
1282+ "cachier.cores.pickle.time.sleep"
1283+ ), pytest .raises (PermissionError ):
1284+ core ._clear_all_cache_files ()
1285+
1286+
12151287# Redis core static method tests
12161288@pytest .mark .parametrize (
12171289 ("test_input" , "expected" ),
0 commit comments