123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- #
- # Copyright 2018-2022 Elyra Authors
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # 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.
- #
- import copy
- import os
- from typing import List
- from typing import Optional
- from entrypoints import EntryPoint
- import pytest
- from elyra.metadata.schema import METADATA_TEST_SCHEMASPACE_ID
- from elyra.metadata.schema import SchemaManager
- from elyra.metadata.schema import Schemaspace
- from elyra.metadata.schema import SchemasProvider
- from elyra.tests.metadata.test_utils import BYOSchemaspace
- from elyra.tests.metadata.test_utils import NON_EXISTENT_SCHEMASPACE_ID
- """ This file contains tests for testing SchemaManager, Schemaspace and SchemasProvider classes """
- os.environ["METADATA_TESTING"] = "1" # Enable metadata-tests schemaspace
- schemaspace_map = {
- "metadata-tests": ("elyra.tests.metadata.test_utils", "MetadataTestSchemaspace"),
- "byo_schemaspace_bad_id": ("elyra.tests.metadata.test_utils", "BYOSchemaspaceBadId"),
- "byo.schemaspace-bad.name": ("elyra.tests.metadata.test_utils", "BYOSchemaspaceBadName"),
- "byo.schemaspace_CaseSensitiveName": ("elyra.tests.metadata.test_utils", "BYOSchemaspaceCaseSensitiveName"),
- "byo-schemaspace": ("elyra.tests.metadata.test_utils", "BYOSchemaspace"),
- "byo-schemaspace-bad-class": ("elyra.tests.metadata.test_utils", "BYOSchemaspaceBadClass"),
- "byo-schemaspace-throws": ("elyra.tests.metadata.test_utils", "BYOSchemaspaceThrows"),
- }
- schemas_provider_map = {
- "metadata-tests": ("elyra.tests.metadata.test_utils", "MetadataTestSchemasProvider"),
- "byo-schemas-provider-throws": ("elyra.tests.metadata.test_utils", "BYOSchemasProviderThrows"),
- "byo-schemas-provider-bad-class": ("elyra.tests.metadata.test_utils", "BYOSchemasProviderBadClass"),
- "byo-schemas-provider": ("elyra.tests.metadata.test_utils", "BYOSchemasProvider"),
- }
- def mock_get_schemaspaces(ep_map: Optional[dict] = None) -> List[EntryPoint]:
- result = []
- if ep_map is None:
- ep_map = schemaspace_map
- for name, epstr in ep_map.items():
- result.append(EntryPoint(name, epstr[0], epstr[1]))
- return result
- def mock_get_schemas_providers(ep_map: Optional[dict] = None) -> List[EntryPoint]:
- result = []
- if ep_map is None:
- ep_map = schemas_provider_map
- for name, epstr in ep_map.items():
- result.append(EntryPoint(name, epstr[0], epstr[1]))
- return result
- @pytest.fixture
- def byo_schemaspaces(monkeypatch):
- """Setup the BYO Schemaspaces and SchemasProviders, returning the SchemaManager instance."""
- monkeypatch.setattr(SchemaManager, "_get_schemaspaces", mock_get_schemaspaces)
- monkeypatch.setattr(SchemaManager, "_get_schemas_providers", mock_get_schemas_providers)
- yield # We must clear the SchemaManager instance else follow-on tests will be side-effected
- SchemaManager.clear_instance()
- def test_validate_factory_schemas():
- # Test that each of our factory schemas meet the minimum requirements.
- # This is accomplished by merely accessing the schemas of the schemaspace
- # and ensuring their presence.
- schema_mgr = SchemaManager.instance() # validation actually happens here
- schemaspace_names = schema_mgr.get_schemaspace_names()
- for schemaspace_name in schemaspace_names:
- schemaspace = schema_mgr.get_schemaspace(schemaspace_name)
- for name, schema in schemaspace.schemas.items():
- print(f"Schema '{schemaspace_name}/{name}' is valid.")
- # ########################## SchemaManager, Schemaspace and SchemasProvider Tests ###########################
- def test_schemaspace_display_name():
- """Ensures that display_name properly defaults from name (or not when provided itself)."""
- schema_mgr = SchemaManager.instance()
- # Only metadata-tests have matching name and display_name values
- schemaspace = schema_mgr.get_schemaspace("metadata-tests")
- assert schemaspace.name == "metadata-tests"
- assert schemaspace.display_name == schemaspace.name
- # All others have a separate name, we'll check runtime-images
- schemaspace = schema_mgr.get_schemaspace("runtime-images")
- assert schemaspace.name == "runtime-images"
- assert schemaspace.display_name == "Runtime Images"
- def test_schema_no_side_effect():
- """Ensures that schemas returned from get_schema_schemas can be altered and not side-effect the next access."""
- schema_mgr = SchemaManager.instance()
- schemas = schema_mgr.get_schemaspace_schemas(METADATA_TEST_SCHEMASPACE_ID)
- for name, schema in schemas.items():
- if name == "metadata-test":
- orig_schema = copy.deepcopy(schema_mgr.get_schema(METADATA_TEST_SCHEMASPACE_ID, name)) # capture good copy
- schema["metadata_class_name"] = "bad_class"
- assert schema != orig_schema
- fresh_schema = schema_mgr.get_schema(METADATA_TEST_SCHEMASPACE_ID, name)
- assert fresh_schema == orig_schema
- def test_byo_schema(byo_schemaspaces):
- """Validates that the expected number of BYO schemas exist (2 of 4 are valid)"""
- SchemaManager.clear_instance()
- schema_mgr = SchemaManager.instance()
- byo_ss = schema_mgr.get_schemaspace(BYOSchemaspace.BYO_SCHEMASPACE_ID)
- assert len(byo_ss.schemas) == 2
- for name, schema in byo_ss.schemas.items():
- assert schema["name"] in ["byo-test-0", "byo-test-1"]
- def test_schemaspace_case_sensitive_name_id(byo_schemaspaces, caplog):
- """Ensures that a schemaspace with case sensitive name and id has its instance properties unaltered."""
- SchemaManager.clear_instance()
- schema_mgr = SchemaManager.instance()
- byo_ss_name = "byo-schemaspace_CaseSensitiveName"
- byo_ss_id = "1b1e461a-c7fa-40f2-a3a3-bf1f2fd48EEA"
- schema_mgr_ss_names = schema_mgr.get_schemaspace_names()
- # Check schemaspace name is normalized in schema manager reference list
- assert byo_ss_name.lower() in schema_mgr_ss_names
- byo_ss_instance_name = schema_mgr.get_schemaspace_name(byo_ss_name)
- assert byo_ss_instance_name == byo_ss_name
- byo_ss_instance_name = schema_mgr.get_schemaspace_name(byo_ss_id)
- assert byo_ss_instance_name == byo_ss_name
- # Confirm this schemaspace produces an "empty schemaspace warning
- assert "The following schemaspaces have no schemas: ['byo-schemaspace_CaseSensitiveName']" in caplog.text
- def validate_log_output(caplog: pytest.LogCaptureFixture, expected_entry: str) -> Schemaspace:
- """Common negative test pattern that validates expected log output."""
- SchemaManager.clear_instance()
- schema_mgr = SchemaManager.instance()
- assert expected_entry in caplog.text
- byo_ss = schema_mgr.get_schemaspace(BYOSchemaspace.BYO_SCHEMASPACE_ID)
- # Ensure there are two valid schemas and make sure our bad one is not in the list.
- assert len(byo_ss.schemas) == 2
- for name, schema in byo_ss.schemas.items():
- assert schema["name"] in ["byo-test-0", "byo-test-1"]
- return byo_ss # in case caller wants to check other things.
- def test_schemaspace_bad_name(byo_schemaspaces, caplog):
- """Ensure a Schemaspace with a bad name (not alphanumeric, w/ dash, underscore) is handled cleanly."""
- validate_log_output(
- caplog, "The 'name' property (byo.schemaspace-bad.name) must " "be alphanumeric with dash or underscore only!"
- )
- def test_schemaspace_bad_class(byo_schemaspaces, caplog):
- """Ensure a Schemaspace that is registered but not a subclass of Schemaspace is handled cleanly."""
- validate_log_output(caplog, "'byo-schemaspace-bad-class' is not an instance of 'Schemaspace'")
- def test_schemaspace_throws(byo_schemaspaces, caplog):
- """Ensure a schemaspace that throws from its constructor doesn't affect the loads of other schemas."""
- validate_log_output(caplog, "Test that throw from constructor is not harmful.")
- def test_schemasprovider_bad_class(byo_schemaspaces, caplog):
- """Ensure a bad SchemasProvider class doesn't affect the loads of other schemas."""
- validate_log_output(
- caplog,
- "SchemasProvider instance 'byo-schemas-provider-bad-class' is not an "
- f"instance of '{SchemasProvider.__name__}'!",
- )
- def test_schemasprovider_throws(byo_schemaspaces, caplog):
- """Ensure exception thrown by SchemasProvider doesn't affect the loads of other schemas."""
- validate_log_output(caplog, "Error loading schemas for SchemasProvider 'byo-schemas-provider-throws'")
- def test_schemasprovider_no_schemaspace(byo_schemaspaces, caplog):
- """Ensure SchemasProvider that references a non-existent schemaspace doesn't affect the loads of other schemas."""
- byo_ss = validate_log_output(
- caplog,
- "Schema 'byo-test-unknown_schemaspace' references a schemaspace "
- f"'{NON_EXISTENT_SCHEMASPACE_ID}' that is not loaded!",
- )
- assert len(byo_ss.schemas) == 2
- for name, schema in byo_ss.schemas.items():
- assert schema["name"] != "byo-test-unknown_schemaspace"
|