11import logging
22import os
3+ from abc import ABC , abstractmethod
34from io import BytesIO , RawIOBase , UnsupportedOperation
45from typing import BinaryIO , Callable , Optional
6+
57import pytest
6- from abc import ABC , abstractmethod
78
8- from databricks .sdk .mixins .files_utils import _ConcatenatedInputStream , _PresignedUrlDistributor
9+ from databricks .sdk .mixins .files_utils import (_ConcatenatedInputStream ,
10+ _PresignedUrlDistributor )
911
1012logger = logging .getLogger (__name__ )
1113
14+
1215class Utils :
1316 @staticmethod
14- def parse_range_header (range_header : str , content_length : Optional [int ]= None ) -> tuple [int , int ]:
17+ def parse_range_header (range_header : str , content_length : Optional [int ] = None ) -> tuple [int , int ]:
1518 """
1619 Parses a Range header string and returns the start and end byte positions.
1720 Example input: "bytes=0-499"
1821 Example output: (0, 499)
1922 """
2023 if not range_header .startswith ("bytes=" ):
2124 raise ValueError ("Invalid Range header format" )
22- byte_range = range_header [len ("bytes=" ):]
25+ byte_range = range_header [len ("bytes=" ) :]
2326 start_str , end_str = byte_range .split ("-" )
2427 start = int (start_str ) if start_str else 0
2528 end = int (end_str ) if end_str else None
@@ -34,6 +37,7 @@ def parse_range_header(range_header: str, content_length: Optional[int]=None) ->
3437
3538 return start , end
3639
40+
3741class NonSeekableBuffer (RawIOBase , BinaryIO ):
3842 """
3943 A non-seekable buffer that wraps a bytes object. Used for unit tests only.
@@ -268,17 +272,20 @@ def safe_call(buf: BinaryIO, call: Callable[[BinaryIO], any]) -> (any, bool):
268272 assert buffer .tell () == native_buffer .tell ()
269273 assert read_and_restore (buffer ) == read_and_restore (native_buffer )
270274
275+
271276class DummyResponse :
272277 def __init__ (self , value ):
273278 self .value = value
274279
280+
275281def test_get_url_returns_url_and_version ():
276282 distributor = _PresignedUrlDistributor (lambda : DummyResponse ("url1" ))
277283 url , version = distributor .get_url ()
278284 assert isinstance (url , DummyResponse )
279285 assert url .value == "url1"
280286 assert version == 0
281287
288+
282289def test_get_url_caches_url ():
283290 calls = []
284291 distributor = _PresignedUrlDistributor (lambda : calls .append (1 ) or DummyResponse ("url2" ))
@@ -288,6 +295,7 @@ def test_get_url_caches_url():
288295 assert version1 == version2
289296 assert calls .count (1 ) == 1 # Only called once
290297
298+
291299def test_invalidate_url_changes_url_and_version ():
292300 responses = [DummyResponse ("urlA" ), DummyResponse ("urlB" )]
293301 distributor = _PresignedUrlDistributor (lambda : responses .pop (0 ))
@@ -298,10 +306,11 @@ def test_invalidate_url_changes_url_and_version():
298306 assert url2 .value == "urlB"
299307 assert version2 == version1 + 1
300308
309+
301310def test_invalidate_url_wrong_version_does_not_invalidate ():
302311 distributor = _PresignedUrlDistributor (lambda : DummyResponse ("urlX" ))
303312 url1 , version1 = distributor .get_url ()
304313 distributor .invalidate_url (version1 + 1 ) # Wrong version
305314 url2 , version2 = distributor .get_url ()
306315 assert url1 is url2
307- assert version2 == version1
316+ assert version2 == version1
0 commit comments