1919import logging
2020import sys
2121import threading
22+ from contextlib import contextmanager
2223from dataclasses import asdict
2324from typing import Any
2425from unittest import TestCase
@@ -85,10 +86,21 @@ def test_fsspec_entry_point_no_fsspec(self):
8586FAKE_SYSTEM_INSTRUCTION = [types .Text (content = "You are a helpful assistant." )]
8687
8788
89+ class ThreadSafeMagicMock (MagicMock ):
90+ def __init__ (self , * args , ** kwargs ) -> None :
91+ self .__dict__ ["_lock" ] = threading .Lock ()
92+ super ().__init__ (* args , ** kwargs )
93+
94+ def _increment_mock_call (self , / , * args , ** kwargs ):
95+ with self .__dict__ ["_lock" ]:
96+ super ()._increment_mock_call (* args , ** kwargs )
97+
98+
8899class TestFsspecUploadHook (TestCase ):
89100 def setUp (self ):
90101 self ._fsspec_patcher = patch (
91- "opentelemetry.util.genai._fsspec_upload.fsspec_hook.fsspec"
102+ "opentelemetry.util.genai._fsspec_upload.fsspec_hook.fsspec" ,
103+ new = ThreadSafeMagicMock (),
92104 )
93105 self .mock_fsspec = self ._fsspec_patcher .start ()
94106 self .hook = FsspecUploadHook (
@@ -100,6 +112,20 @@ def tearDown(self) -> None:
100112 self .hook .shutdown ()
101113 self ._fsspec_patcher .stop ()
102114
115+ @contextmanager
116+ def block_upload (self ):
117+ unblock_upload = threading .Event ()
118+
119+ def blocked_upload (* args : Any ):
120+ unblock_upload .wait ()
121+ return MagicMock ()
122+
123+ try :
124+ self .mock_fsspec .open .side_effect = blocked_upload
125+ yield
126+ finally :
127+ unblock_upload .set ()
128+
103129 def test_shutdown_no_items (self ):
104130 self .hook .shutdown ()
105131
@@ -119,46 +145,45 @@ def test_upload_then_shutdown(self):
119145 )
120146
121147 def test_upload_blocked (self ):
122- unblock_upload = threading .Event ()
123-
124- def blocked_upload (* args : Any ):
125- unblock_upload .wait ()
126- return MagicMock ()
148+ with self .block_upload ():
149+ # fill the queue
150+ for _ in range (MAXSIZE ):
151+ self .hook .upload (
152+ inputs = FAKE_INPUTS ,
153+ outputs = FAKE_OUTPUTS ,
154+ system_instruction = FAKE_SYSTEM_INSTRUCTION ,
155+ )
156+
157+ self .assertLessEqual (
158+ self .mock_fsspec .open .call_count ,
159+ MAXSIZE ,
160+ f"uploader should only be called { MAXSIZE = } times" ,
161+ )
127162
128- self .mock_fsspec .open .side_effect = blocked_upload
163+ with self .assertLogs (level = logging .WARNING ) as logs :
164+ self .hook .upload (
165+ inputs = FAKE_INPUTS ,
166+ outputs = FAKE_OUTPUTS ,
167+ system_instruction = FAKE_SYSTEM_INSTRUCTION ,
168+ )
129169
130- # fill the queue
131- for _ in range (MAXSIZE ):
132- self .hook .upload (
133- inputs = FAKE_INPUTS ,
134- outputs = FAKE_OUTPUTS ,
135- system_instruction = FAKE_SYSTEM_INSTRUCTION ,
170+ self .assertIn (
171+ "fsspec upload queue is full, dropping upload" , logs .output [0 ]
136172 )
137173
138- self .assertLessEqual (
139- self .mock_fsspec .open .call_count ,
140- MAXSIZE ,
141- f"uploader should only be called { MAXSIZE = } times" ,
142- )
143-
144- with self .assertLogs (level = logging .WARNING ) as logs :
174+ def test_shutdown_timeout (self ):
175+ with self .block_upload ():
145176 self .hook .upload (
146177 inputs = FAKE_INPUTS ,
147178 outputs = FAKE_OUTPUTS ,
148179 system_instruction = FAKE_SYSTEM_INSTRUCTION ,
149180 )
150181
151- self .assertIn (
152- "fsspec upload queue is full, dropping upload" , logs .output [0 ]
153- )
154-
155- unblock_upload .set ()
182+ # shutdown should timeout and return even though there are still items in the queue
183+ self .hook .shutdown (timeout_sec = 0.01 )
156184
157185 def test_failed_upload_logs (self ):
158- def failing_upload (* args : Any ) -> None :
159- raise RuntimeError ("failed to upload" )
160-
161- self .mock_fsspec .open = MagicMock (wraps = failing_upload )
186+ self .mock_fsspec .open .side_effect = RuntimeError ("failed to upload" )
162187
163188 with self .assertLogs (level = logging .ERROR ) as logs :
164189 self .hook .upload (
@@ -178,7 +203,7 @@ def test_upload_after_shutdown_logs(self):
178203 outputs = FAKE_OUTPUTS ,
179204 system_instruction = FAKE_SYSTEM_INSTRUCTION ,
180205 )
181- self .assertEqual (len (logs .output ), 1 )
206+ self .assertEqual (len (logs .output ), 3 )
182207 self .assertIn (
183208 "attempting to upload file after FsspecUploadHook.shutdown() was already called" ,
184209 logs .output [0 ],
0 commit comments