This is an automated email from the ASF dual-hosted git repository.
jerryshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new d6de18f474 [#10759] test(client-python): add unit tests for
GenericFileset tag operations (#10760)
d6de18f474 is described below
commit d6de18f474793f08e18ccab95cd5efdb4462c237
Author: Sun Yuhan <[email protected]>
AuthorDate: Thu Apr 23 21:05:28 2026 +0800
[#10759] test(client-python): add unit tests for GenericFileset tag
operations (#10760)
Add unit tests for tag operations on `GenericFileset`, covering all
`SupportsTags` methods.
The implementation was merged in #10670. This PR adds comprehensive test
coverage for the fileset-specific tag operations.
### What changes were proposed in this pull request?
6 new unit tests in `TestObjectTagAPI`:
- `test_fileset_supports_tags` — verify GenericFileset is a SupportsTags
instance
- `test_fileset_list_tags` — list tag names on a fileset
- `test_fileset_list_tags_info` — list tags with full details
- `test_fileset_get_tag` — get a specific tag by name
- `test_fileset_get_tag_with_empty_name` — validate empty name raises
IllegalArgumentException
- `test_fileset_associate_tags` — associate and remove tags
### Why are the changes needed?
The fileset tag implementation merged in #10670 lacks test coverage.
These tests ensure the tag operations on GenericFileset work correctly.
Fix: #10759
### Does this PR introduce _any_ user-facing change?
No. Test-only change.
### How was this patch tested?
All 6 new tests pass. Existing tests remain unaffected.
Co-authored-by: Sun Yuhan <[email protected]>
---
.../client-python/tests/unittests/test_tag_api.py | 122 +++++++++++++++++++++
1 file changed, 122 insertions(+)
diff --git a/clients/client-python/tests/unittests/test_tag_api.py
b/clients/client-python/tests/unittests/test_tag_api.py
index 6ced9e0464..0163ba7c3a 100644
--- a/clients/client-python/tests/unittests/test_tag_api.py
+++ b/clients/client-python/tests/unittests/test_tag_api.py
@@ -22,8 +22,12 @@ from unittest.mock import patch
from gravitino import GravitinoClient
from gravitino.api.tag import Tag
+from gravitino.api.tag.supports_tags import SupportsTags
from gravitino.api.tag.tag_change import TagChange
+from gravitino.client.generic_tag import GenericTag
+from gravitino.exceptions.base import IllegalArgumentException
from gravitino.dto.responses.drop_response import DropResponse
+from gravitino.name_identifier import NameIdentifier
from gravitino.dto.responses.tag_response import (
TagListResponse,
TagNamesListResponse,
@@ -480,3 +484,121 @@ class TestTagAPI(unittest.TestCase):
self.assertEqual(left.name(), right.name())
self.assertEqual(left.comment(), right.comment())
self.assertEqual(left.properties(), right.properties())
+
+
+@mock_base.mock_data
+class TestObjectTagAPI(unittest.TestCase):
+ """Tests for object-level tag operations on GenericFileset.""" # pylint:
disable=protected-access
+
+ _metalake_name: str = "metalake_demo"
+
+ def _load_fileset(self, client):
+ """Helper to load a test fileset."""
+ catalog = client.load_catalog("fileset_catalog")
+ return catalog.as_fileset_catalog().load_fileset(
+ NameIdentifier.of("tmp", "fileset")
+ )
+
+ def test_fileset_supports_tags(self, *mock_method) -> None:
+ """Test that GenericFileset is an instance of SupportsTags."""
+ client = GravitinoClient(
+ uri="http://localhost:8090",
+ metalake_name=self._metalake_name,
+ check_version=False,
+ )
+ fileset = self._load_fileset(client)
+ self.assertIsInstance(fileset, SupportsTags)
+
+ def test_fileset_list_tags(self, *mock_method) -> None:
+ """Test listing tags on a fileset via REST API."""
+ client = GravitinoClient(
+ uri="http://localhost:8090",
+ metalake_name=self._metalake_name,
+ check_version=False,
+ )
+ fileset = self._load_fileset(client)
+
+ with patch.object(
+ fileset._object_tag_operations,
+ "list_tags",
+ return_value=["tagA", "tagB"],
+ ):
+ tags = fileset.list_tags()
+ self.assertEqual(2, len(tags))
+ self.assertIn("tagA", tags)
+ self.assertIn("tagB", tags)
+
+ def test_fileset_list_tags_info(self, *mock_method) -> None:
+ """Test listing tags with details on a fileset via REST API."""
+ tag_dto = mock_base.build_tag_dto("tagA", "comment A")
+ mock_tag = GenericTag("metalake_demo", tag_dto, None)
+
+ client = GravitinoClient(
+ uri="http://localhost:8090",
+ metalake_name=self._metalake_name,
+ check_version=False,
+ )
+ fileset = self._load_fileset(client)
+
+ with patch.object(
+ fileset._object_tag_operations,
+ "list_tags_info",
+ return_value=[mock_tag],
+ ):
+ tags = fileset.list_tags_info()
+ self.assertEqual(1, len(tags))
+ self.assertEqual("tagA", tags[0].name())
+ self.assertEqual("comment A", tags[0].comment())
+
+ def test_fileset_get_tag(self, *mock_method) -> None:
+ """Test getting a specific tag on a fileset via REST API."""
+ tag_dto = mock_base.build_tag_dto("tagA", "comment A")
+ mock_tag = GenericTag("metalake_demo", tag_dto, None)
+
+ client = GravitinoClient(
+ uri="http://localhost:8090",
+ metalake_name=self._metalake_name,
+ check_version=False,
+ )
+ fileset = self._load_fileset(client)
+
+ with patch.object(
+ fileset._object_tag_operations,
+ "get_tag",
+ return_value=mock_tag,
+ ):
+ tag = fileset.get_tag("tagA")
+ self.assertEqual("tagA", tag.name())
+ self.assertEqual("comment A", tag.comment())
+
+ def test_fileset_get_tag_with_empty_name(self, *mock_method) -> None:
+ """Test that get_tag raises ValueError for empty tag name."""
+ client = GravitinoClient(
+ uri="http://localhost:8090",
+ metalake_name=self._metalake_name,
+ check_version=False,
+ )
+ fileset = self._load_fileset(client)
+
+ with self.assertRaises(IllegalArgumentException):
+ fileset.get_tag(" ")
+
+ def test_fileset_associate_tags(self, *mock_method) -> None:
+ """Test associating and removing tags on a fileset via REST API."""
+ client = GravitinoClient(
+ uri="http://localhost:8090",
+ metalake_name=self._metalake_name,
+ check_version=False,
+ )
+ fileset = self._load_fileset(client)
+
+ with patch.object(
+ fileset._object_tag_operations,
+ "associate_tags",
+ return_value=["tagA", "tagB"],
+ ) as mock_assoc:
+ result = fileset.associate_tags(["tagA", "tagB"], [])
+ self.assertEqual(2, len(result))
+ self.assertIn("tagA", result)
+ self.assertIn("tagB", result)
+ mock_assoc.assert_called_once_with(["tagA", "tagB"], [])