import pytest
from pyiceberg.catalog.rest import RestCatalog
from pyiceberg.exceptions import NamespaceAlreadyExistsError, NoSuchNamespaceError
class TestNamespaceOperations:
def test_create_namespace(self, catalog: RestCatalog):
ns = "test_create_ns"
try:
catalog.drop_namespace(ns)
except NoSuchNamespaceError:
pass
try:
catalog.create_namespace(ns)
namespaces = catalog.list_namespaces()
assert (ns,) in namespaces
finally:
catalog.drop_namespace(ns)
def test_create_namespace_with_properties(self, catalog: RestCatalog):
ns = "test_ns_props"
properties = {
"owner": "test-user",
"description": "Test namespace with properties",
"custom.key": "custom-value",
}
try:
catalog.drop_namespace(ns)
except NoSuchNamespaceError:
pass
try:
catalog.create_namespace(ns, properties=properties)
loaded_props = catalog.load_namespace_properties(ns)
assert loaded_props.get("owner") == "test-user"
assert loaded_props.get("description") == "Test namespace with properties"
assert loaded_props.get("custom.key") == "custom-value"
finally:
catalog.drop_namespace(ns)
def test_create_namespace_already_exists(self, catalog: RestCatalog):
ns = "test_dup_ns"
try:
catalog.drop_namespace(ns)
except NoSuchNamespaceError:
pass
try:
catalog.create_namespace(ns)
with pytest.raises(NamespaceAlreadyExistsError):
catalog.create_namespace(ns)
finally:
catalog.drop_namespace(ns)
def test_nested_namespace(self, catalog: RestCatalog):
ns_parent = "parent_ns"
ns_child = "parent_ns.child_ns"
try:
catalog.drop_namespace(ns_child)
except NoSuchNamespaceError:
pass
try:
catalog.drop_namespace(ns_parent)
except NoSuchNamespaceError:
pass
try:
catalog.create_namespace(ns_parent)
catalog.create_namespace(ns_child)
namespaces = catalog.list_namespaces()
assert (ns_parent,) in namespaces or ("parent_ns", "child_ns") in namespaces
finally:
try:
catalog.drop_namespace(ns_child)
except NoSuchNamespaceError:
pass
try:
catalog.drop_namespace(ns_parent)
except NoSuchNamespaceError:
pass
def test_list_namespaces_empty(self, catalog: RestCatalog):
namespaces = catalog.list_namespaces()
assert isinstance(namespaces, list)
def test_update_namespace_properties(self, catalog: RestCatalog):
ns = "test_update_ns"
try:
catalog.drop_namespace(ns)
except NoSuchNamespaceError:
pass
try:
catalog.create_namespace(ns, properties={"key1": "value1"})
catalog.update_namespace_properties(
ns,
updates={"key2": "value2", "key1": "updated"},
)
props = catalog.load_namespace_properties(ns)
assert props.get("key1") == "updated"
assert props.get("key2") == "value2"
finally:
catalog.drop_namespace(ns)
def test_remove_namespace_properties(self, catalog: RestCatalog):
ns = "test_remove_props_ns"
try:
catalog.drop_namespace(ns)
except NoSuchNamespaceError:
pass
try:
catalog.create_namespace(ns, properties={"key1": "value1", "key2": "value2"})
catalog.update_namespace_properties(ns, removals=["key1"])
props = catalog.load_namespace_properties(ns)
assert "key1" not in props
assert props.get("key2") == "value2"
finally:
catalog.drop_namespace(ns)
def test_drop_nonexistent_namespace(self, catalog: RestCatalog):
with pytest.raises(NoSuchNamespaceError):
catalog.drop_namespace("nonexistent_namespace_12345")
def test_load_nonexistent_namespace_properties(self, catalog: RestCatalog):
with pytest.raises(NoSuchNamespaceError):
catalog.load_namespace_properties("nonexistent_namespace_12345")
class TestNamespaceValidation:
def test_namespace_name_special_characters(self, catalog: RestCatalog):
ns = "test_ns_123"
try:
catalog.drop_namespace(ns)
except NoSuchNamespaceError:
pass
try:
catalog.create_namespace(ns)
namespaces = catalog.list_namespaces()
assert (ns,) in namespaces
finally:
catalog.drop_namespace(ns)
def test_namespace_case_sensitivity(self, catalog: RestCatalog):
ns_lower = "testcasens"
ns_upper = "TESTCASENS"
try:
catalog.drop_namespace(ns_lower)
except NoSuchNamespaceError:
pass
try:
catalog.drop_namespace(ns_upper)
except NoSuchNamespaceError:
pass
try:
catalog.create_namespace(ns_lower)
try:
catalog.create_namespace(ns_upper)
assert True
catalog.drop_namespace(ns_upper)
except NamespaceAlreadyExistsError:
assert True
finally:
try:
catalog.drop_namespace(ns_lower)
except NoSuchNamespaceError:
pass