22
33from collections .abc import Callable , Coroutine
44from typing import Any
5+ from unittest .mock import AsyncMock , MagicMock
56
67import pytest
78
1819 UpdateQuotaResponse ,
1920)
2021from ai .backend .common .types import QuotaScopeID , QuotaScopeType
22+ from ai .backend .manager .clients .storage_proxy .session_manager import StorageSessionManager
2123
2224VFolderFixtureData = dict [str , Any ]
2325VFolderFactory = Callable [..., Coroutine [Any , Any , VFolderFixtureData ]]
2426
2527
28+ @pytest .fixture ()
29+ def storage_manager () -> StorageSessionManager :
30+ """Mock StorageSessionManager with configured storage proxy client methods.
31+
32+ Overrides the parent conftest mock so that quota and usage endpoints work
33+ without a live storage-proxy connection.
34+ """
35+ mock = MagicMock (spec = StorageSessionManager )
36+ mock_client = AsyncMock ()
37+ mock_client .get_volume_quota .return_value = {"used_bytes" : 0 , "limit_bytes" : 0 }
38+ mock_client .update_volume_quota .return_value = None
39+ mock_client .get_folder_usage .return_value = {"used_bytes" : 0 , "file_count" : 0 }
40+ mock_client .get_used_bytes .return_value = {"used_bytes" : 0 }
41+ mock .get_proxy_and_volume .return_value = ("local" , "volume" )
42+ mock .get_manager_facing_client .return_value = mock_client
43+ return mock
44+
45+
2646class TestStorageQuotaScope :
2747 """Storage quota CRUD and access control via the quota scope API.
28- All tests are xfail because they require a live storage-proxy connection
29- that is not available in the CI environment."""
48+ Storage-proxy calls are mocked via the storage_manager fixture in conftest."""
3049
31- @pytest .mark .xfail (strict = False , reason = "Requires live storage-proxy" )
3250 async def test_get_quota (
3351 self ,
3452 admin_registry : BackendAIClientRegistry ,
@@ -46,7 +64,6 @@ async def test_get_quota(
4664 assert isinstance (result , GetQuotaResponse )
4765 assert isinstance (result .data , dict )
4866
49- @pytest .mark .xfail (strict = False , reason = "Requires live storage-proxy" )
5067 async def test_update_quota (
5168 self ,
5269 admin_registry : BackendAIClientRegistry ,
@@ -64,7 +81,6 @@ async def test_update_quota(
6481 )
6582 assert isinstance (result , UpdateQuotaResponse )
6683
67- @pytest .mark .xfail (strict = False , reason = "Requires live storage-proxy" )
6884 async def test_get_usage (
6985 self ,
7086 admin_registry : BackendAIClientRegistry ,
@@ -82,7 +98,6 @@ async def test_get_usage(
8298 assert isinstance (result , GetUsageResponse )
8399 assert isinstance (result .data , dict )
84100
85- @pytest .mark .xfail (strict = False , reason = "Requires live storage-proxy" )
86101 async def test_get_used_bytes (
87102 self ,
88103 admin_registry : BackendAIClientRegistry ,
@@ -100,7 +115,6 @@ async def test_get_used_bytes(
100115 assert isinstance (result , GetUsedBytesResponse )
101116 assert isinstance (result .data , dict )
102117
103- @pytest .mark .xfail (strict = False , reason = "Requires live storage-proxy" )
104118 async def test_regular_user_can_get_own_quota (
105119 self ,
106120 user_registry : BackendAIClientRegistry ,
@@ -121,7 +135,6 @@ async def test_regular_user_can_get_own_quota(
121135 )
122136 assert isinstance (result , GetQuotaResponse )
123137
124- @pytest .mark .xfail (strict = False , reason = "Requires live storage-proxy" )
125138 async def test_regular_user_cannot_update_others_quota (
126139 self ,
127140 user_registry : BackendAIClientRegistry ,
0 commit comments