2025-04-03 10:39:47 +05:30

161 lines
6.0 KiB
Python

# Copyright 2025 Collate
# Licensed under the Collate Community License, Version 1.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# https://github.com/open-metadata/OpenMetadata/blob/main/ingestion/LICENSE
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Test FQN build behavior
"""
from unittest import TestCase
from unittest.mock import MagicMock
import pytest
from metadata.generated.schema.entity.data.table import Table
from metadata.generated.schema.type.basic import FullyQualifiedEntityName
from metadata.ingestion.ometa.utils import quote
from metadata.utils import fqn
class TestFqn(TestCase):
"""
Validate FQN building
"""
def test_split(self):
this = self
class FQNTest:
"""
Test helper class
"""
def __init__(self, parts, fqn):
self.parts = parts
self.fqn = fqn
def validate(self, actual_parts, actual_fqn):
this.assertEqual(self.fqn, actual_fqn)
this.assertEqual(len(self.parts), len(actual_parts))
for i in range(len(self.parts)):
if "." in self.parts[i]:
this.assertEqual(fqn.quote_name(self.parts[i]), actual_parts[i])
else:
this.assertEqual(self.parts[i], actual_parts[i])
xs = [
FQNTest(["a", "b", "c", "d"], "a.b.c.d"),
FQNTest(["a.1", "b", "c", "d"], '"a.1".b.c.d'),
FQNTest(["a", "b.2", "c", "d"], 'a."b.2".c.d'),
FQNTest(["a", "b", "c.3", "d"], 'a.b."c.3".d'),
FQNTest(["a", "b", "c", "d.4"], 'a.b.c."d.4"'),
FQNTest(["a.1", "b.2", "c", "d"], '"a.1"."b.2".c.d'),
FQNTest(["a.1", "b.2", "c.3", "d"], '"a.1"."b.2"."c.3".d'),
FQNTest(["a.1", "b.2", "c.3", "d.4"], '"a.1"."b.2"."c.3"."d.4"'),
FQNTest(["fqn", "test.test.test"], 'fqn."test.test.test"'),
FQNTest(["fqn", "testtesttest"], "fqn.testtesttest"),
FQNTest(["fqn", "testtes ttest"], "fqn.testtes ttest"),
]
for x in xs:
x.validate(fqn.split(x.fqn), fqn._build(*x.parts))
def test_quote_name(self):
"""
Make sure that fqns are properly quoted
"""
# Unquote_named name remains unquote_named
self.assertEqual("a", fqn.quote_name("a"))
# Add quote_names when "." exists in the name
self.assertEqual('"a.b"', fqn.quote_name("a.b"))
# Leave existing valid quote_names
self.assertEqual('"a.b"', fqn.quote_name('"a.b"'))
# Remove quote_names when not needed
self.assertEqual("a", fqn.quote_name('"a"'))
with self.assertRaises(Exception) as context:
fqn.quote_name('"a')
self.assertEqual('Invalid name "a', str(context.exception))
with self.assertRaises(Exception) as context:
fqn.quote_name('a"')
self.assertEqual('Invalid name a"', str(context.exception))
with self.assertRaises(Exception) as context:
fqn.quote_name('a"b')
self.assertEqual('Invalid name a"b', str(context.exception))
def test_invalid(self):
with self.assertRaises(Exception):
fqn.split('a.."')
def test_build_table(self):
"""
Validate Table FQN building
"""
mocked_metadata = MagicMock()
mocked_metadata.es_search_from_fqn.return_value = None
table_fqn = fqn.build(
metadata=mocked_metadata,
entity_type=Table,
service_name="service",
database_name="db",
schema_name="schema",
table_name="table",
)
self.assertEqual(table_fqn, "service.db.schema.table")
table_fqn_dots = fqn.build(
metadata=mocked_metadata,
entity_type=Table,
service_name="service",
database_name="data.base",
schema_name="schema",
table_name="table",
)
self.assertEqual(table_fqn_dots, 'service."data.base".schema.table')
table_fqn_space = fqn.build(
metadata=mocked_metadata,
entity_type=Table,
service_name="service",
database_name="data base",
schema_name="schema",
table_name="table",
)
self.assertEqual(table_fqn_space, "service.data base.schema.table")
def test_split_test_case_fqn(self):
"""test for split test case"""
split_fqn = fqn.split_test_case_fqn(
"local_redshift.dev.dbt_jaffle.customers.customer_id.expect_column_max_to_be_between"
)
assert split_fqn.service == "local_redshift"
assert split_fqn.database == "dev"
assert split_fqn.schema_ == "dbt_jaffle"
assert split_fqn.table == "customers"
assert split_fqn.column == "customer_id"
assert split_fqn.test_case == "expect_column_max_to_be_between"
split_fqn = fqn.split_test_case_fqn(
"local_redshift.dev.dbt_jaffle.customers.expect_table_column_to_be_between"
)
assert not split_fqn.column
assert split_fqn.test_case == "expect_table_column_to_be_between"
with pytest.raises(ValueError):
fqn.split_test_case_fqn("local_redshift.dev.dbt_jaffle.customers")
def test_quote_fqns(self):
"""We can properly quote FQNs for URL usage"""
assert quote(FullyQualifiedEntityName("a.b.c")) == "a.b.c"
# Works with strings directly
assert quote("a.b.c") == "a.b.c"
assert quote(FullyQualifiedEntityName('"foo.bar".baz')) == "%22foo.bar%22.baz"
assert quote('"foo.bar/baz".hello') == "%22foo.bar%2Fbaz%22.hello"