55# ------------------------------------
66import csv , os , pytest , re , inspect , sys
77import importlib .util
8- import io
98import unittest .mock as mock
109from azure .core .exceptions import HttpResponseError
1110from devtools_testutils .aio import recorded_by_proxy_async
1211from devtools_testutils import AzureRecordedTestCase , recorded_by_proxy , RecordedTransport
13- from test_base import servicePreparer
12+ from test_base import servicePreparer , patched_open_crlf_to_lf
1413from pytest import MonkeyPatch
1514from azure .ai .projects import AIProjectClient
1615
1716
1817class SampleExecutor :
1918 """Helper class for executing sample files with proper environment setup and credential mocking."""
2019
21- class ConvertedFileWrapper (io .BufferedReader ):
22- """File wrapper that converts CRLF to LF content while preserving original filename."""
23-
24- def __init__ (self , file_path , converted_content ):
25- # Create BytesIO with converted content
26- self ._bytesio = io .BytesIO (converted_content )
27- # Initialize BufferedReader with the BytesIO
28- super ().__init__ (self ._bytesio )
29- # Override name to be the original file path
30- self ._name = file_path
31-
32- @property
33- def name (self ):
34- return self ._name
35-
3620 def __init__ (
3721 self , test_instance : "AzureRecordedTestCase" , sample_path : str , env_var_mapping : dict [str , str ], ** kwargs
3822 ):
@@ -62,43 +46,19 @@ def __init__(
6246
6347 self .module = importlib .util .module_from_spec (spec )
6448 self .spec = spec
65- self ._original_open = open
6649
6750 def _capture_print (self , * args , ** kwargs ):
6851 """Capture print calls while still outputting to console."""
6952 self .print_calls .append (" " .join (str (arg ) for arg in args ))
7053 self ._original_print (* args , ** kwargs )
7154
72- def _patched_open (self , * args , ** kwargs ):
73- """Patch open to convert CRLF to LF for text files."""
74- file_path = args [0 ] if args else kwargs .get ("file" )
75- mode = args [1 ] if len (args ) > 1 else kwargs .get ("mode" , "r" )
76-
77- # Check if this is binary read mode for text-like files
78- if "r" in mode and "b" in mode and file_path and isinstance (file_path , str ):
79- # Check file extension to determine if it's a text file
80- text_extensions = {".txt" , ".json" , ".jsonl" , ".csv" , ".md" , ".yaml" , ".yml" , ".xml" }
81- ext = os .path .splitext (file_path )[1 ].lower ()
82- if ext in text_extensions :
83- # Read the original file
84- with self ._original_open (file_path , "rb" ) as f :
85- content = f .read ()
86-
87- # Convert CRLF to LF
88- converted_content = content .replace (b"\r \n " , b"\n " )
89-
90- # Return wrapped file-like object with converted content
91- return SampleExecutor .ConvertedFileWrapper (file_path , converted_content )
92-
93- return self ._original_open (* args , ** kwargs )
94-
9555 def execute (self ):
9656 """Execute a synchronous sample with proper mocking and environment setup."""
9757
9858 with (
9959 MonkeyPatch .context () as mp ,
10060 mock .patch ("builtins.print" , side_effect = self ._capture_print ),
101- mock .patch ("builtins.open" , side_effect = self . _patched_open ),
61+ mock .patch ("builtins.open" , side_effect = patched_open_crlf_to_lf ),
10262 mock .patch ("azure.identity.DefaultAzureCredential" ) as mock_credential ,
10363 ):
10464 for var_name , var_value in self .env_vars .items ():
@@ -119,7 +79,7 @@ async def execute_async(self):
11979 with (
12080 MonkeyPatch .context () as mp ,
12181 mock .patch ("builtins.print" , side_effect = self ._capture_print ),
122- mock .patch ("builtins.open" , side_effect = self . _patched_open ),
82+ mock .patch ("builtins.open" , side_effect = patched_open_crlf_to_lf ),
12383 mock .patch ("azure.identity.aio.DefaultAzureCredential" ) as mock_credential ,
12484 ):
12585 for var_name , var_value in self .env_vars .items ():
0 commit comments