Skip to content

Commit

Permalink
test: extend python test for object direct get feature
Browse files Browse the repository at this point in the history
Signed-off-by: Tony Chen <[email protected]>
  • Loading branch information
Nahemah1022 committed Jan 31, 2025
1 parent fce0ada commit cb5b64d
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
2 changes: 1 addition & 1 deletion python/aistore/sdk/obj/object_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def _initialize_target_client(self, force: bool = False):
)
self._request_client = new_client

def _retry_with_new_smap(self, method: str, **kwargs):
def _retry_with_new_smap(self, method: str, **kwargs) -> requests.Response:
"""
Retry the request with the latest `smap` if a 404 error is encountered.
Expand Down
35 changes: 35 additions & 0 deletions python/tests/integration/sdk/test_object_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,3 +441,38 @@ def test_get_object_direct(self):
self.assertGreater(
len(obj_from_direct), 0, f"Object data is empty for object: {obj_name}"
)

@unittest.skipIf(not has_enough_targets(), "Test requires more than one target")
def test_get_object_direct_all_targets(self):
"""
Test retrieving an object directly from all targets in the cluster.
This test intentionally provides the client with incorrect target URLs to verify whether it can
self-correct through retries. It simulates real-world scenarios where the smap changes,
and the object may be relocated to a different target. The test ensures that the client can still
successfully identify and connect to the correct target using `_retry_with_new_smap`.
"""
self.bucket = self._create_bucket()
obj = self._create_object()

content = b"content for the object"
bck_name, obj_name = self.bucket.name, obj.name

obj.get_writer().put_content(content)
expected_content = obj.get_reader(direct=True).read_all()
res = obj.get_reader()
self.assertEqual(content, res.read_all())

smap = self.client.cluster().get_info()

for target in smap.tmap.values():
if target.in_maint_or_decomm():
continue
clnt = Client(target.public_net.direct_url)
content = (
clnt.bucket(bck_name)
.object(obj_name)
.get_reader(direct=True)
.read_all()
)
self.assertEqual(content, expected_content)
41 changes: 41 additions & 0 deletions python/tests/unit/sdk/obj/test_object_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from aistore.sdk.const import HTTP_METHOD_HEAD, HTTP_METHOD_GET, HEADER_RANGE
from aistore.sdk.request_client import RequestClient
from aistore.sdk.obj.object_client import ObjectClient
from aistore.sdk.errors import ErrObjNotFound

from tests.utils import cases

Expand Down Expand Up @@ -99,3 +100,43 @@ def test_head(self, mock_attr):
HTTP_METHOD_HEAD, path=self.path, params=self.params
)
mock_attr.assert_called_with(self.response_headers)

@patch("aistore.sdk.obj.object_client.ObjectClient._retry_with_new_smap")
def test_obj_not_found_retry(self, mock_retry_with_new_smap):
"""
Test that the get method retries with a new smap when ErrObjNotFound is raised and catched.
"""
self.request_client.request.side_effect = ErrObjNotFound(
404, "Object not found"
)
# pylint: disable=protected-access
self.object_client._uname = (
"test" # will retry only if ObjectClient._uname is set
)

mock_retry_response = Mock(spec=requests.Response)
mock_retry_with_new_smap.return_value = mock_retry_response

res = self.object_client.get(stream=False)

mock_retry_with_new_smap.assert_called_once_with(
HTTP_METHOD_GET,
path=self.path,
params=self.params,
stream=False,
headers=self.headers,
)

self.assertEqual(res, mock_retry_response)

def test_raises_err_obj_not_found(self):
"""
Test that the get method raises ErrObjNotFound when no uname is provided.
"""
object_client = ObjectClient(self.request_client, self.path, self.params)
self.request_client.request.side_effect = ErrObjNotFound(
404, "Object not found"
)

with self.assertRaises(ErrObjNotFound):
object_client.get(stream=False)

0 comments on commit cb5b64d

Please sign in to comment.