mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
test(acceptance): count a purge of a listed trash entry that then vanishes
The reaper found an abandoned root in the trash and sent the delete. The reply did not confirm it, and the next listing no longer had the node, but the retry loop only counted deletes it sent itself. It waited for a node that was already gone, reported it as never trashed, and the leftover check stopped the run before any case ran. Callers that just found the node in the trash now say so, and the error of the first delete is kept for the warning.
This commit is contained in:
1 parent
97277d41dd
commit
2775f0681d
1 file changed
+13
-7
@@ -4014,30 +4014,36 @@ class Janitor:
|
||||
return [
|
||||
f"{name} ({entry['uid']}) is still in the trash"
|
||||
for entry in matches
|
||||
if not self.purge(entry["uid"], name)
|
||||
if not self.purge(entry["uid"], name, listed=True)
|
||||
]
|
||||
|
||||
def purge(self, uid: str, name: str) -> bool:
|
||||
def purge(self, uid: str, name: str, listed: bool = False) -> bool:
|
||||
"""Permanently delete one trashed node the run owns, by uid.
|
||||
|
||||
By uid and never by name: a name can match something of the user's, a
|
||||
uid cannot. The node has to show up in the trash first, which is also
|
||||
what proves the trash step before it worked, and it has to be gone from
|
||||
a fresh listing afterwards.
|
||||
a fresh listing afterwards. `listed` says the caller just found it in
|
||||
the trash.
|
||||
|
||||
The server's own answer comes first, though: it only deletes a node
|
||||
that is in the trash, and it answers per uid. A listing is a whole-trash
|
||||
enumeration, which on a large trash can time out on every attempt and
|
||||
would otherwise keep a folder the server would delete on request.
|
||||
"""
|
||||
with contextlib.suppress(Exception):
|
||||
last_error = ""
|
||||
try:
|
||||
reply = self.daemon.command("delete-forever", uid, stdin="yes\n")
|
||||
if re.search(r"\bpermanently deleted 1 item", reply):
|
||||
print(f"[cleanup] permanently deleted {name}")
|
||||
return True
|
||||
except Exception as error: # noqa: BLE001 - retried, then reported
|
||||
last_error = f": {error}"
|
||||
deadline = time.monotonic() + self.daemon.timeout
|
||||
attempted = False
|
||||
last_error = ""
|
||||
# A node seen in the trash before that delete and gone after it was
|
||||
# deleted by it, whatever it answered. Counting it as never sent kept
|
||||
# waiting for a node that was already gone, and failed the run.
|
||||
attempted = listed
|
||||
while True:
|
||||
try:
|
||||
if self.daemon.trashed(uid):
|
||||
@@ -4149,7 +4155,7 @@ class Janitor:
|
||||
for entry in trashed:
|
||||
if STALE_ROOT.match(entry["name"]) and entry["name"] not in live_names:
|
||||
print(f"[reap] permanently deleting an abandoned root from the trash: {entry['name']}")
|
||||
if not orphan.purge(entry["uid"], entry["name"]):
|
||||
if not orphan.purge(entry["uid"], entry["name"], listed=True):
|
||||
leftovers.append(f"{entry['name']} ({entry['uid']}) is still in the trash")
|
||||
return leftovers
|
||||
|
||||
|
||||
Reference in new issue
Block a user