mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-12-24 05:20:48 +08:00
rework + add test for concurrent AssetInfo delete
This commit is contained in:
parent
cdd8d16075
commit
47f7c7ee8c
@ -379,11 +379,12 @@ async def touch_asset_info_by_id(
|
||||
|
||||
|
||||
async def delete_asset_info_by_id(session: AsyncSession, *, asset_info_id: str, owner_id: str) -> bool:
|
||||
res = await session.execute(delete(AssetInfo).where(
|
||||
AssetInfo.id == asset_info_id,
|
||||
visible_owner_clause(owner_id),
|
||||
))
|
||||
return bool(res.rowcount)
|
||||
return (
|
||||
await session.execute(delete(AssetInfo).where(
|
||||
AssetInfo.id == asset_info_id,
|
||||
visible_owner_clause(owner_id),
|
||||
).returning(AssetInfo.id))
|
||||
).scalar_one_or_none() is not None
|
||||
|
||||
|
||||
async def add_tags_to_asset_info(
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import asyncio
|
||||
import uuid
|
||||
|
||||
import aiohttp
|
||||
@ -177,3 +178,43 @@ async def test_update_requires_at_least_one_field(http: aiohttp.ClientSession, a
|
||||
body = await r.json()
|
||||
assert r.status == 400
|
||||
assert body["error"]["code"] == "INVALID_BODY"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("root", ["input", "output"])
|
||||
async def test_concurrent_delete_same_asset_info_single_204(
|
||||
root: str,
|
||||
http: aiohttp.ClientSession,
|
||||
api_base: str,
|
||||
asset_factory,
|
||||
make_asset_bytes,
|
||||
):
|
||||
"""
|
||||
Many concurrent DELETE for the same AssetInfo should result in:
|
||||
- exactly one 204 No Content (the one that actually deleted)
|
||||
- all others 404 Not Found (row already gone)
|
||||
"""
|
||||
scope = f"conc-del-{uuid.uuid4().hex[:6]}"
|
||||
name = "to_delete.bin"
|
||||
data = make_asset_bytes(name, 1536)
|
||||
|
||||
created = await asset_factory(name, [root, "unit-tests", scope], {}, data)
|
||||
aid = created["id"]
|
||||
|
||||
# Hit the same endpoint N times in parallel.
|
||||
n_tests = 4
|
||||
url = f"{api_base}/api/assets/{aid}?delete_content=false"
|
||||
tasks = [asyncio.create_task(http.delete(url)) for _ in range(n_tests)]
|
||||
responses = await asyncio.gather(*tasks)
|
||||
|
||||
statuses = [r.status for r in responses]
|
||||
# Drain bodies to close connections (optional but avoids warnings).
|
||||
await asyncio.gather(*[r.read() for r in responses])
|
||||
|
||||
# Exactly one actual delete, the rest must be 404
|
||||
assert statuses.count(204) == 1, f"Expected exactly one 204; got: {statuses}"
|
||||
assert statuses.count(404) == n_tests - 1, f"Expected {n_tests-1} 404; got: {statuses}"
|
||||
|
||||
# The resource must be gone.
|
||||
async with http.get(f"{api_base}/api/assets/{aid}") as rg:
|
||||
assert rg.status == 404
|
||||
|
||||
Loading…
Reference in New Issue
Block a user