Skip to content

Commit 61f061a

Browse files
committed
Update the tests
1 parent e074113 commit 61f061a

File tree

9 files changed

+216
-161
lines changed

9 files changed

+216
-161
lines changed

app/backend/app.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
SpeechSynthesisResult,
1717
SpeechSynthesizer,
1818
)
19-
from azure.core.exceptions import ResourceNotFoundError
2019
from azure.identity.aio import (
2120
AzureDeveloperCliCredential,
2221
ManagedIdentityCredential,
@@ -155,16 +154,12 @@ async def content_file(path: str, auth_claims: dict[str, Any]):
155154
if blob is None:
156155
current_app.logger.info("Path not found in general Blob container: %s", path)
157156
if current_app.config[CONFIG_USER_UPLOAD_ENABLED]:
158-
try:
159-
user_oid = auth_claims["oid"]
160-
user_blob_manager: AdlsBlobManager = current_app.config[CONFIG_USER_BLOB_MANAGER]
161-
blob = await user_blob_manager.download_blob(path, user_oid=user_oid)
162-
except ResourceNotFoundError:
157+
user_oid = auth_claims["oid"]
158+
user_blob_manager: AdlsBlobManager = current_app.config[CONFIG_USER_BLOB_MANAGER]
159+
blob = await user_blob_manager.download_blob(path, user_oid=user_oid)
160+
if blob is None:
163161
current_app.logger.exception("Path not found in DataLake: %s", path)
164-
abort(404)
165-
else:
166-
abort(404)
167-
if not blob.properties or not blob.properties.has_key("content_settings"):
162+
if not blob or not blob.properties or not blob.properties.has_key("content_settings"):
168163
abort(404)
169164
mime_type = blob.properties["content_settings"]["content_type"]
170165
if mime_type == "application/octet-stream":

app/backend/prepdocslib/blobmanager.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ async def download_blob(
287287
filename = path_parts[-1]
288288

289289
try:
290-
user_directory_client = self._ensure_directory(directory_path=directory_path, user_oid=user_oid)
290+
user_directory_client = await self._ensure_directory(directory_path=directory_path, user_oid=user_oid)
291291
file_client = user_directory_client.get_file_client(filename)
292292
blob = await file_client.download_file()
293293
return blob
@@ -343,10 +343,10 @@ async def list_blobs(self, user_oid: str) -> list[str]:
343343
Returns:
344344
list[str]: List of filenames that belong to the user
345345
"""
346-
user_directory_client = await self._ensure_directory(directory_path=user_oid, user_oid=user_oid)
346+
await self._ensure_directory(directory_path=user_oid, user_oid=user_oid)
347347
files = []
348348
try:
349-
all_paths = user_directory_client.get_paths()
349+
all_paths = self.file_system_client.get_paths(path=user_oid, recursive=True)
350350
async for path in all_paths:
351351
# Split path into parts (user_oid/filename or user_oid/directory/files)
352352
path_parts = path.name.split("/", 1)

tests/conftest.py

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
SearchField,
1919
SearchIndex,
2020
)
21-
from azure.storage.blob.aio import ContainerClient
21+
from azure.storage.blob.aio import BlobServiceClient, ContainerClient
2222
from openai.types import CompletionUsage, CreateEmbeddingResponse, Embedding
2323
from openai.types.chat import ChatCompletion, ChatCompletionChunk
2424
from openai.types.chat.chat_completion import (
@@ -43,6 +43,7 @@
4343
MockAzureCredentialExpired,
4444
MockBlobClient,
4545
MockResponse,
46+
MockTransport,
4647
mock_retrieval_response,
4748
mock_speak_text_cancelled,
4849
mock_speak_text_failed,
@@ -299,6 +300,14 @@ def mock_blob_container_client(monkeypatch):
299300
monkeypatch.setattr(ContainerClient, "get_blob_client", lambda *args, **kwargs: MockBlobClient())
300301

301302

303+
@pytest.fixture
304+
def mock_blob_container_client_exists(monkeypatch):
305+
async def mock_exists(*args, **kwargs):
306+
return True
307+
308+
monkeypatch.setattr("azure.storage.blob.aio.ContainerClient.exists", mock_exists)
309+
310+
302311
envs = [
303312
{
304313
"OPENAI_HOST": "openai",
@@ -731,7 +740,7 @@ async def vision_client(
731740
mock_openai_chatcompletion,
732741
mock_openai_embedding,
733742
mock_acs_search,
734-
mock_blob_container_client,
743+
mock_blob_container_client_exists,
735744
mock_azurehttp_calls,
736745
):
737746
quart_app = app.create_app()
@@ -740,6 +749,15 @@ async def vision_client(
740749
test_app.app.config.update({"TESTING": True})
741750
mock_openai_chatcompletion(test_app.app.config[app.CONFIG_OPENAI_CLIENT])
742751
mock_openai_embedding(test_app.app.config[app.CONFIG_OPENAI_CLIENT])
752+
# need to mock app.CONFIG_GLOBAL_BLOB_MANAGER to
753+
mock_blob_service_client = BlobServiceClient(
754+
f"https://{os.environ['AZURE_STORAGE_ACCOUNT']}.blob.core.windows.net",
755+
credential=MockAzureCredential(),
756+
transport=MockTransport(),
757+
retry_total=0, # Necessary to avoid unnecessary network requests during tests
758+
)
759+
test_app.app.config[app.CONFIG_GLOBAL_BLOB_MANAGER].blob_service_client = mock_blob_service_client
760+
743761
yield test_app.test_client()
744762

745763

@@ -939,13 +957,14 @@ def mock_get_paths(self, *args, **kwargs):
939957
monkeypatch.setattr(azure.storage.filedatalake.aio.FileSystemClient, "__init__", mock_init_filesystem_aio)
940958
monkeypatch.setattr(azure.storage.filedatalake.aio.FileSystemClient, "__aenter__", mock_aenter)
941959
monkeypatch.setattr(azure.storage.filedatalake.aio.FileSystemClient, "__aexit__", mock_aexit)
942-
monkeypatch.setattr(azure.storage.filedatalake.aio.FileSystemClient, "get_paths", mock_get_paths)
960+
943961
monkeypatch.setattr(azure.storage.filedatalake.aio.FileSystemClient, "exists", mock_exists_aio)
944-
monkeypatch.setattr(azure.storage.filedatalake.aio.FileSystemClient, "get_paths", mock_get_paths)
945962
monkeypatch.setattr(azure.storage.filedatalake.aio.FileSystemClient, "get_file_client", mock_get_file_client)
946963
monkeypatch.setattr(
947964
azure.storage.filedatalake.aio.FileSystemClient, "create_file_system", mock_create_filesystem_aio
948965
)
966+
monkeypatch.setattr(azure.storage.filedatalake.aio.FileSystemClient, "get_paths", mock_get_paths)
967+
949968
monkeypatch.setattr(azure.storage.filedatalake.aio.FileSystemClient, "create_directory", mock_create_directory_aio)
950969
monkeypatch.setattr(
951970
azure.storage.filedatalake.aio.FileSystemClient,
@@ -985,7 +1004,6 @@ async def mock_upload_data_aio(self, *args, **kwargs):
9851004
monkeypatch.setattr(
9861005
azure.storage.filedatalake.aio.DataLakeFileClient, "get_access_control", mock_get_access_control
9871006
)
988-
9891007
monkeypatch.setattr(azure.storage.filedatalake.aio.DataLakeFileClient, "__init__", mock_init_file)
9901008
monkeypatch.setattr(azure.storage.filedatalake.aio.DataLakeFileClient, "url", property(mock_url))
9911009
monkeypatch.setattr(azure.storage.filedatalake.aio.DataLakeFileClient, "__aenter__", mock_aenter)
@@ -1000,6 +1018,12 @@ def mock_init_directory(self, path, *args, **kwargs):
10001018
self.path = path
10011019
self.files = {}
10021020

1021+
async def mock_get_directory_properties(self, *args, **kwargs):
1022+
return azure.storage.filedatalake.DirectoryProperties()
1023+
1024+
async def mock_get_access_control(self, *args, **kwargs):
1025+
return {"owner": "OID_X"}
1026+
10031027
def mock_directory_get_file_client(self, *args, **kwargs):
10041028
path = kwargs.get("file")
10051029
if path in self.files:
@@ -1030,6 +1054,14 @@ async def mock_close_aio(self, *args, **kwargs):
10301054
"update_access_control_recursive",
10311055
mock_update_access_control_recursive_aio,
10321056
)
1057+
monkeypatch.setattr(
1058+
azure.storage.filedatalake.aio.DataLakeDirectoryClient,
1059+
"get_directory_properties",
1060+
mock_get_directory_properties,
1061+
)
1062+
monkeypatch.setattr(
1063+
azure.storage.filedatalake.aio.DataLakeDirectoryClient, "get_access_control", mock_get_access_control
1064+
)
10331065
monkeypatch.setattr(azure.storage.filedatalake.aio.DataLakeDirectoryClient, "close", mock_close_aio)
10341066

10351067
def mock_readinto(self, stream: IO[bytes]):

tests/mocks.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,16 @@
33
from io import BytesIO
44
from typing import Optional
55

6+
import aiohttp
67
import openai.types
78
from azure.cognitiveservices.speech import ResultReason
89
from azure.core.credentials_async import AsyncTokenCredential
10+
from azure.core.exceptions import ResourceNotFoundError
11+
from azure.core.pipeline.transport import (
12+
AioHttpTransportResponse,
13+
AsyncHttpTransport,
14+
HttpRequest,
15+
)
916
from azure.search.documents.agent.models import (
1017
KnowledgeAgentAzureSearchDocReference,
1118
KnowledgeAgentMessage,
@@ -63,6 +70,57 @@ async def readinto(self, buffer: BytesIO):
6370
buffer.write(b"test")
6471

6572

73+
class MockAiohttpClientResponse404(aiohttp.ClientResponse):
74+
def __init__(self, url, body_bytes, headers=None):
75+
self._body = body_bytes
76+
self._headers = headers
77+
self._cache = {}
78+
self.status = 404
79+
self.reason = "Not Found"
80+
self._url = url
81+
82+
83+
class MockAiohttpClientResponse(aiohttp.ClientResponse):
84+
def __init__(self, url, body_bytes, headers=None):
85+
self._body = body_bytes
86+
self._headers = headers
87+
self._cache = {}
88+
self.status = 200
89+
self.reason = "OK"
90+
self._url = url
91+
92+
93+
class MockTransport(AsyncHttpTransport):
94+
async def send(self, request: HttpRequest, **kwargs) -> AioHttpTransportResponse:
95+
if request.url.endswith("notfound.png"):
96+
raise ResourceNotFoundError(MockAiohttpClientResponse404(request.url, b""))
97+
else:
98+
return AioHttpTransportResponse(
99+
request,
100+
MockAiohttpClientResponse(
101+
request.url,
102+
b"test content",
103+
{
104+
"Content-Type": "application/octet-stream",
105+
"Content-Range": "bytes 0-27/28",
106+
"Content-Length": "28",
107+
},
108+
),
109+
)
110+
111+
async def __aenter__(self):
112+
return self
113+
114+
async def __aexit__(self, *args):
115+
pass
116+
117+
async def open(self):
118+
pass
119+
120+
async def close(self):
121+
pass
122+
123+
66124
class MockAsyncPageIterator:
67125
def __init__(self, data):
68126
self.data = data

tests/snapshots/test_app/test_ask_vision/client0/result.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"Financial Market Analysis Report 2023.pdf#page=2"
99
],
1010
"images": [
11-
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg=="
11+
"data:image/png;base64,dGVzdCBjb250ZW50"
1212
],
1313
"text": [
1414
"Financial Market Analysis Report 2023.pdf#page=7: This section examines the correlations between stock indices, cryptocurrency prices, and commodity prices, revealing how changes in one market can have ripple effects across the financial ecosystem.### Impact of Macroeconomic Factors <figure><figcaption>Impact of Interest Rates, Inflation, and GDP Growth on Financial Markets<br>The image is a line graph titled \"on Financial Markets\" displaying data from 2018 to 2023. It tracks three variables: Interest Rates %, Inflation Data %, and GDP Growth %, each represented by a different colored line (blue for Interest Rates, orange for Inflation Data, and gray for GDP Growth). Interest Rates % start around 2% in 2018, dip to about 0.25% in 2021, then rise to 1.5% in 2023. Inflation Data % begin at approximately 1.9% in 2018, rise to a peak near 3.4% in 2022, and then decrease to 2.5% in 2023. GDP Growth % shows significant fluctuations, starting at 3% in 2018, plunging to almost -4% in 2020, then rebounding to around 4.5% in 2021 before gradually declining to around 2.8% in 2023.</figcaption></figure> Macroeconomic factors such as interest rates, inflation, and GDP growth play a pivotal role in shaping financial markets.",
@@ -124,7 +124,7 @@
124124
},
125125
{
126126
"image_url": {
127-
"url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg=="
127+
"url": "data:image/png;base64,dGVzdCBjb250ZW50"
128128
},
129129
"type": "image_url"
130130
},

tests/snapshots/test_app/test_chat_stream_vision/client0/result.jsonlines

Lines changed: 4 additions & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)