diff --git a/Makefile b/Makefile index aed58ed465..8ec4aa3bd0 100644 --- a/Makefile +++ b/Makefile @@ -80,19 +80,16 @@ test-python-unit: python -m pytest -n 8 --color=yes sdk/python/tests test-python-integration: - python -m pytest -n 8 --integration -k "(not snowflake or not test_historical_features_main) and not minio_registry" --color=yes --durations=5 --timeout=1200 --timeout_method=thread sdk/python/tests + python -m pytest -n 8 --integration --color=yes --durations=10 --timeout=1200 --timeout_method=thread \ + -k "(not snowflake or not test_historical_features_main)" \ + sdk/python/tests test-python-integration-local: - @(docker info > /dev/null 2>&1 && \ - FEAST_IS_LOCAL_TEST=True \ - FEAST_LOCAL_ONLINE_CONTAINER=True \ - python -m pytest -n 8 --color=yes --integration \ - -k "not gcs_registry and \ - not s3_registry and \ - not test_lambda_materialization and \ - not test_snowflake_materialization" \ - sdk/python/tests \ - ) || echo "This script uses Docker, and it isn't running - please start the Docker Daemon and try again!"; + FEAST_IS_LOCAL_TEST=True \ + FEAST_LOCAL_ONLINE_CONTAINER=True \ + python -m pytest -n 8 --color=yes --integration --durations=5 --dist loadgroup \ + -k "not test_lambda_materialization and not test_snowflake_materialization" \ + sdk/python/tests test-python-integration-container: @(docker info > /dev/null 2>&1 && \ diff --git a/sdk/python/tests/integration/feature_repos/universal/data_sources/file.py b/sdk/python/tests/integration/feature_repos/universal/data_sources/file.py index 6f0ac02a00..18094b723f 100644 --- a/sdk/python/tests/integration/feature_repos/universal/data_sources/file.py +++ b/sdk/python/tests/integration/feature_repos/universal/data_sources/file.py @@ -141,7 +141,8 @@ def __init__(self, project_name: str, *args, **kwargs): self.minio = MinioContainer() self.minio.start() client = self.minio.get_client() - client.make_bucket("test") + if not client.bucket_exists("test"): + client.make_bucket("test") host_ip = self.minio.get_container_host_ip() exposed_port = self.minio.get_exposed_port(self.minio.port) self.endpoint_url = f"http://{host_ip}:{exposed_port}" diff --git a/sdk/python/tests/integration/registration/test_feature_store.py b/sdk/python/tests/integration/registration/test_feature_store.py index bf0c2fb61f..d7ffb83059 100644 --- a/sdk/python/tests/integration/registration/test_feature_store.py +++ b/sdk/python/tests/integration/registration/test_feature_store.py @@ -11,68 +11,21 @@ # 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 os -import time from datetime import timedelta from tempfile import mkstemp import pytest from pytest_lazyfixture import lazy_fixture -from feast import FileSource -from feast.data_format import ParquetFormat from feast.entity import Entity from feast.feature_store import FeatureStore from feast.feature_view import FeatureView -from feast.field import Field -from feast.infra.offline_stores.file import FileOfflineStoreConfig -from feast.infra.online_stores.dynamodb import DynamoDBOnlineStoreConfig from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig from feast.repo_config import RepoConfig -from feast.types import Array, Bytes, Float64, Int64, String +from feast.types import Float64, Int64, String from tests.utils.data_source_test_creator import prep_file_source -@pytest.mark.integration -@pytest.mark.parametrize( - "test_feature_store", - [ - lazy_fixture("feature_store_with_gcs_registry"), - lazy_fixture("feature_store_with_s3_registry"), - ], -) -def test_apply_entity_integration(test_feature_store): - entity = Entity( - name="driver_car_id", - description="Car driver id", - tags={"team": "matchmaking"}, - ) - - # Register Entity - test_feature_store.apply([entity]) - - entities = test_feature_store.list_entities() - - entity = entities[0] - assert ( - len(entities) == 1 - and entity.name == "driver_car_id" - and entity.description == "Car driver id" - and "team" in entity.tags - and entity.tags["team"] == "matchmaking" - ) - - entity = test_feature_store.get_entity("driver_car_id") - assert ( - entity.name == "driver_car_id" - and entity.description == "Car driver id" - and "team" in entity.tags - and entity.tags["team"] == "matchmaking" - ) - - test_feature_store.teardown() - - @pytest.mark.integration @pytest.mark.parametrize( "test_feature_store", @@ -109,81 +62,6 @@ def test_feature_view_inference_success(test_feature_store, dataframe_source): test_feature_store.teardown() -@pytest.mark.integration -@pytest.mark.parametrize( - "test_feature_store", - [ - lazy_fixture("feature_store_with_gcs_registry"), - lazy_fixture("feature_store_with_s3_registry"), - ], -) -def test_apply_feature_view_integration(test_feature_store): - # Create Feature Views - batch_source = FileSource( - file_format=ParquetFormat(), - path="file://feast/*", - timestamp_field="ts_col", - created_timestamp_column="timestamp", - ) - - entity = Entity(name="fs1_my_entity_1", join_keys=["test"]) - - fv1 = FeatureView( - name="my_feature_view_1", - schema=[ - Field(name="fs1_my_feature_1", dtype=Int64), - Field(name="fs1_my_feature_2", dtype=String), - Field(name="fs1_my_feature_3", dtype=Array(String)), - Field(name="fs1_my_feature_4", dtype=Array(Bytes)), - Field(name="test", dtype=Int64), - ], - entities=[entity], - tags={"team": "matchmaking"}, - source=batch_source, - ttl=timedelta(minutes=5), - ) - - # Register Feature View - test_feature_store.apply([fv1, entity]) - - feature_views = test_feature_store.list_feature_views() - - # List Feature Views - assert ( - len(feature_views) == 1 - and feature_views[0].name == "my_feature_view_1" - and feature_views[0].features[0].name == "fs1_my_feature_1" - and feature_views[0].features[0].dtype == Int64 - and feature_views[0].features[1].name == "fs1_my_feature_2" - and feature_views[0].features[1].dtype == String - and feature_views[0].features[2].name == "fs1_my_feature_3" - and feature_views[0].features[2].dtype == Array(String) - and feature_views[0].features[3].name == "fs1_my_feature_4" - and feature_views[0].features[3].dtype == Array(Bytes) - and feature_views[0].entities[0] == "fs1_my_entity_1" - ) - - feature_view = test_feature_store.get_feature_view("my_feature_view_1") - assert ( - feature_view.name == "my_feature_view_1" - and feature_view.features[0].name == "fs1_my_feature_1" - and feature_view.features[0].dtype == Int64 - and feature_view.features[1].name == "fs1_my_feature_2" - and feature_view.features[1].dtype == String - and feature_view.features[2].name == "fs1_my_feature_3" - and feature_view.features[2].dtype == Array(String) - and feature_view.features[3].name == "fs1_my_feature_4" - and feature_view.features[3].dtype == Array(Bytes) - and feature_view.entities[0] == "fs1_my_entity_1" - ) - - test_feature_store.delete_feature_view("my_feature_view_1") - feature_views = test_feature_store.list_feature_views() - assert len(feature_views) == 0 - - test_feature_store.teardown() - - @pytest.fixture def feature_store_with_local_registry(): fd, registry_path = mkstemp() @@ -197,46 +75,3 @@ def feature_store_with_local_registry(): entity_key_serialization_version=2, ) ) - - -@pytest.fixture -def feature_store_with_gcs_registry(): - from google.cloud import storage - - storage_client = storage.Client() - bucket_name = f"feast-registry-test-{int(time.time() * 1000)}" - bucket = storage_client.bucket(bucket_name) - bucket = storage_client.create_bucket(bucket) - bucket.add_lifecycle_delete_rule( - age=14 - ) # delete buckets automatically after 14 days - bucket.patch() - bucket.blob("registry.db") - - return FeatureStore( - config=RepoConfig( - registry=f"gs://{bucket_name}/registry.db", - project="default", - provider="gcp", - entity_key_serialization_version=2, - ) - ) - - -@pytest.fixture -def feature_store_with_s3_registry(): - aws_registry_path = os.getenv( - "AWS_REGISTRY_PATH", "s3://feast-int-bucket/registries" - ) - return FeatureStore( - config=RepoConfig( - registry=f"{aws_registry_path}/{int(time.time() * 1000)}/registry.db", - project="default", - provider="aws", - online_store=DynamoDBOnlineStoreConfig( - region=os.getenv("AWS_REGION", "us-west-2") - ), - offline_store=FileOfflineStoreConfig(), - entity_key_serialization_version=2, - ) - ) diff --git a/sdk/python/tests/integration/registration/test_universal_cli.py b/sdk/python/tests/integration/registration/test_universal_cli.py index e7331a0789..c16b26fee6 100644 --- a/sdk/python/tests/integration/registration/test_universal_cli.py +++ b/sdk/python/tests/integration/registration/test_universal_cli.py @@ -7,7 +7,9 @@ from assertpy import assertpy from feast.feature_store import FeatureStore -from tests.integration.feature_repos.repo_configuration import Environment +from tests.integration.feature_repos.universal.data_sources.file import ( + FileDataSourceCreator, +) from tests.utils.basic_read_write_test import basic_rw_test from tests.utils.cli_repo_creator import CliRunner, get_example_repo from tests.utils.e2e_test_validation import ( @@ -17,8 +19,7 @@ @pytest.mark.integration -@pytest.mark.universal_offline_stores -def test_universal_cli(environment: Environment): +def test_universal_cli(): project = f"test_universal_cli_{str(uuid.uuid4()).replace('-', '')[:8]}" runner = CliRunner() @@ -28,9 +29,9 @@ def test_universal_cli(environment: Environment): feature_store_yaml = make_feature_store_yaml( project, repo_path, - environment.data_source_creator, - environment.provider, - environment.online_store, + FileDataSourceCreator("project"), + "local", + {"type": "sqlite"}, ) repo_config = repo_path / "feature_store.yaml" @@ -115,8 +116,7 @@ def test_universal_cli(environment: Environment): @pytest.mark.integration -@pytest.mark.universal_offline_stores -def test_odfv_apply(environment) -> None: +def test_odfv_apply() -> None: project = f"test_odfv_apply{str(uuid.uuid4()).replace('-', '')[:8]}" runner = CliRunner() @@ -126,9 +126,9 @@ def test_odfv_apply(environment) -> None: feature_store_yaml = make_feature_store_yaml( project, repo_path, - environment.data_source_creator, - environment.provider, - environment.online_store, + FileDataSourceCreator("project"), + "local", + {"type": "sqlite"}, ) repo_config = repo_path / "feature_store.yaml" diff --git a/sdk/python/tests/integration/registration/test_universal_registry.py b/sdk/python/tests/integration/registration/test_universal_registry.py index 18274ae5e1..65d07aca45 100644 --- a/sdk/python/tests/integration/registration/test_universal_registry.py +++ b/sdk/python/tests/integration/registration/test_universal_registry.py @@ -234,27 +234,40 @@ def mock_remote_registry(): if os.getenv("FEAST_IS_LOCAL_TEST", "False") == "False": - all_fixtures = ["s3_registry", "gcs_registry"] + all_fixtures = [lazy_fixture("s3_registry"), lazy_fixture("gcs_registry")] else: all_fixtures = [ - "local_registry", - "minio_registry", - "pg_registry", - "mysql_registry", - "sqlite_registry", - "mock_remote_registry", + lazy_fixture("local_registry"), + pytest.param( + lazy_fixture("minio_registry"), + marks=pytest.mark.xdist_group(name="minio_registry"), + ), + pytest.param( + lazy_fixture("pg_registry"), + marks=pytest.mark.xdist_group(name="pg_registry"), + ), + pytest.param( + lazy_fixture("mysql_registry"), + marks=pytest.mark.xdist_group(name="mysql_registry"), + ), + lazy_fixture("sqlite_registry"), + lazy_fixture("mock_remote_registry"), ] - -# sql_fixtures = [ -# "pg_registry", -# "mysql_registry", -# "sqlite_registry", -# ] +sql_fixtures = [ + pytest.param( + lazy_fixture("pg_registry"), marks=pytest.mark.xdist_group(name="pg_registry") + ), + pytest.param( + lazy_fixture("mysql_registry"), + marks=pytest.mark.xdist_group(name="mysql_registry"), + ), + lazy_fixture("sqlite_registry"), +] @pytest.mark.integration -@pytest.mark.parametrize("test_registry", [lazy_fixture(f) for f in all_fixtures]) +@pytest.mark.parametrize("test_registry", all_fixtures) def test_apply_entity_success(test_registry): entity = Entity( name="driver_car_id", @@ -313,7 +326,7 @@ def assert_project_uuid(project, project_uuid, test_registry): @pytest.mark.integration @pytest.mark.parametrize( "test_registry", - [lazy_fixture(f) for f in all_fixtures], + all_fixtures, ) def test_apply_feature_view_success(test_registry): # Create Feature Views @@ -400,16 +413,7 @@ def test_apply_feature_view_success(test_registry): @pytest.mark.integration @pytest.mark.parametrize( "test_registry", - [ - # lazy_fixture("local_registry"), - # lazy_fixture("gcs_registry"), - # lazy_fixture("s3_registry"), - # lazy_fixture("minio_registry"), - lazy_fixture("pg_registry"), - lazy_fixture("mysql_registry"), - lazy_fixture("sqlite_registry"), - # lazy_fixture("mock_remote_registry"), - ], + sql_fixtures, ) def test_apply_on_demand_feature_view_success(test_registry): # Create Feature Views @@ -491,7 +495,7 @@ def location_features_from_push(inputs: pd.DataFrame) -> pd.DataFrame: @pytest.mark.integration @pytest.mark.parametrize( "test_registry", - [lazy_fixture(f) for f in all_fixtures], + all_fixtures, ) def test_apply_data_source(test_registry): # Create Feature Views @@ -554,7 +558,7 @@ def test_apply_data_source(test_registry): @pytest.mark.integration @pytest.mark.parametrize( "test_registry", - [lazy_fixture(f) for f in all_fixtures], + all_fixtures, ) def test_modify_feature_views_success(test_registry): # Create Feature Views @@ -677,16 +681,7 @@ def odfv1(feature_df: pd.DataFrame) -> pd.DataFrame: @pytest.mark.integration @pytest.mark.parametrize( "test_registry", - [ - # lazy_fixture("local_registry"), - # lazy_fixture("gcs_registry"), - # lazy_fixture("s3_registry"), - # lazy_fixture("minio_registry"), - lazy_fixture("pg_registry"), - lazy_fixture("mysql_registry"), - lazy_fixture("sqlite_registry"), - # lazy_fixture("mock_remote_registry"), - ], + sql_fixtures, ) def test_update_infra(test_registry): # Create infra object @@ -717,16 +712,7 @@ def test_update_infra(test_registry): @pytest.mark.integration @pytest.mark.parametrize( "test_registry", - [ - # lazy_fixture("local_registry"), - # lazy_fixture("gcs_registry"), - # lazy_fixture("s3_registry"), - # lazy_fixture("minio_registry"), - lazy_fixture("pg_registry"), - lazy_fixture("mysql_registry"), - lazy_fixture("sqlite_registry"), - # lazy_fixture("mock_remote_registry"), - ], + sql_fixtures, ) def test_registry_cache(test_registry): # Create Feature Views @@ -790,7 +776,7 @@ def test_registry_cache(test_registry): @pytest.mark.integration @pytest.mark.parametrize( "test_registry", - [lazy_fixture(f) for f in all_fixtures], + all_fixtures, ) def test_apply_stream_feature_view_success(test_registry): # Create Feature Views @@ -852,3 +838,94 @@ def simple_udf(x: int): assert len(stream_feature_views) == 0 test_registry.teardown() + + +@pytest.mark.integration +def test_commit(): + fd, registry_path = mkstemp() + registry_config = RegistryConfig(path=registry_path, cache_ttl_seconds=600) + test_registry = Registry("project", registry_config, None) + + entity = Entity( + name="driver_car_id", + description="Car driver id", + tags={"team": "matchmaking"}, + ) + + project = "project" + + # Register Entity without commiting + test_registry.apply_entity(entity, project, commit=False) + assert test_registry.cached_registry_proto + assert len(test_registry.cached_registry_proto.project_metadata) == 1 + project_metadata = test_registry.cached_registry_proto.project_metadata[0] + project_uuid = project_metadata.project_uuid + assert len(project_uuid) == 36 + validate_project_uuid(project_uuid, test_registry) + + # Retrieving the entity should still succeed + entities = test_registry.list_entities(project, allow_cache=True) + entity = entities[0] + assert ( + len(entities) == 1 + and entity.name == "driver_car_id" + and entity.description == "Car driver id" + and "team" in entity.tags + and entity.tags["team"] == "matchmaking" + ) + validate_project_uuid(project_uuid, test_registry) + + entity = test_registry.get_entity("driver_car_id", project, allow_cache=True) + assert ( + entity.name == "driver_car_id" + and entity.description == "Car driver id" + and "team" in entity.tags + and entity.tags["team"] == "matchmaking" + ) + validate_project_uuid(project_uuid, test_registry) + + # Create new registry that points to the same store + registry_with_same_store = Registry("project", registry_config, None) + + # Retrieving the entity should fail since the store is empty + entities = registry_with_same_store.list_entities(project) + assert len(entities) == 0 + validate_project_uuid(project_uuid, registry_with_same_store) + + # commit from the original registry + test_registry.commit() + + # Reconstruct the new registry in order to read the newly written store + registry_with_same_store = Registry("project", registry_config, None) + + # Retrieving the entity should now succeed + entities = registry_with_same_store.list_entities(project) + entity = entities[0] + assert ( + len(entities) == 1 + and entity.name == "driver_car_id" + and entity.description == "Car driver id" + and "team" in entity.tags + and entity.tags["team"] == "matchmaking" + ) + validate_project_uuid(project_uuid, registry_with_same_store) + + entity = test_registry.get_entity("driver_car_id", project) + assert ( + entity.name == "driver_car_id" + and entity.description == "Car driver id" + and "team" in entity.tags + and entity.tags["team"] == "matchmaking" + ) + + test_registry.teardown() + + # Will try to reload registry, which will fail because the file has been deleted + with pytest.raises(FileNotFoundError): + test_registry._get_registry_proto(project=project) + + +def validate_project_uuid(project_uuid, test_registry): + assert len(test_registry.cached_registry_proto.project_metadata) == 1 + project_metadata = test_registry.cached_registry_proto.project_metadata[0] + assert project_metadata.project_uuid == project_uuid diff --git a/sdk/python/tests/unit/infra/registry/test_remote.py b/sdk/python/tests/unit/infra/registry/test_remote.py deleted file mode 100644 index 8b15f0d507..0000000000 --- a/sdk/python/tests/unit/infra/registry/test_remote.py +++ /dev/null @@ -1,69 +0,0 @@ -import assertpy -import grpc_testing -import pytest - -from feast import Entity, FeatureStore -from feast.infra.registry.remote import RemoteRegistry, RemoteRegistryConfig -from feast.protos.feast.registry import RegistryServer_pb2, RegistryServer_pb2_grpc -from feast.registry_server import RegistryServer - - -class GrpcMockChannel: - def __init__(self, service, servicer): - self.service = service - self.test_server = grpc_testing.server_from_dictionary( - {service: servicer}, - grpc_testing.strict_real_time(), - ) - - def unary_unary( - self, method: str, request_serializer=None, response_deserializer=None - ): - method_name = method.split("/")[-1] - method_descriptor = self.service.methods_by_name[method_name] - - def handler(request): - rpc = self.test_server.invoke_unary_unary( - method_descriptor, (), request, None - ) - - response, trailing_metadata, code, details = rpc.termination() - return response - - return handler - - -@pytest.fixture -def mock_remote_registry(environment): - store: FeatureStore = environment.feature_store - registry = RemoteRegistry( - registry_config=RemoteRegistryConfig(path=""), project=None, repo_path=None - ) - mock_channel = GrpcMockChannel( - RegistryServer_pb2.DESCRIPTOR.services_by_name["RegistryServer"], - RegistryServer(registry=store._registry), - ) - registry.stub = RegistryServer_pb2_grpc.RegistryServerStub(mock_channel) - return registry - - -def test_registry_server_get_entity(environment, mock_remote_registry): - store: FeatureStore = environment.feature_store - entity = Entity(name="driver", join_keys=["driver_id"]) - store.apply(entity) - - expected = store.get_entity(entity.name) - response_entity = mock_remote_registry.get_entity(entity.name, store.project) - - assertpy.assert_that(response_entity).is_equal_to(expected) - - -def test_registry_server_proto(environment, mock_remote_registry): - store: FeatureStore = environment.feature_store - entity = Entity(name="driver", join_keys=["driver_id"]) - store.apply(entity) - - expected = store.registry.proto() - response = mock_remote_registry.proto() - - assertpy.assert_that(response).is_equal_to(expected) diff --git a/sdk/python/tests/unit/infra/test_local_registry.py b/sdk/python/tests/unit/infra/test_local_registry.py deleted file mode 100644 index c86a616c40..0000000000 --- a/sdk/python/tests/unit/infra/test_local_registry.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright 2022 The Feast 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 -# -# https://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. -from tempfile import mkstemp - -import pytest - -from feast.entity import Entity -from feast.infra.registry.registry import Registry -from feast.repo_config import RegistryConfig - - -def test_commit(): - fd, registry_path = mkstemp() - registry_config = RegistryConfig(path=registry_path, cache_ttl_seconds=600) - test_registry = Registry("project", registry_config, None) - - entity = Entity( - name="driver_car_id", - description="Car driver id", - tags={"team": "matchmaking"}, - ) - - project = "project" - - # Register Entity without commiting - test_registry.apply_entity(entity, project, commit=False) - assert test_registry.cached_registry_proto - assert len(test_registry.cached_registry_proto.project_metadata) == 1 - project_metadata = test_registry.cached_registry_proto.project_metadata[0] - project_uuid = project_metadata.project_uuid - assert len(project_uuid) == 36 - validate_project_uuid(project_uuid, test_registry) - - # Retrieving the entity should still succeed - entities = test_registry.list_entities(project, allow_cache=True) - entity = entities[0] - assert ( - len(entities) == 1 - and entity.name == "driver_car_id" - and entity.description == "Car driver id" - and "team" in entity.tags - and entity.tags["team"] == "matchmaking" - ) - validate_project_uuid(project_uuid, test_registry) - - entity = test_registry.get_entity("driver_car_id", project, allow_cache=True) - assert ( - entity.name == "driver_car_id" - and entity.description == "Car driver id" - and "team" in entity.tags - and entity.tags["team"] == "matchmaking" - ) - validate_project_uuid(project_uuid, test_registry) - - # Create new registry that points to the same store - registry_with_same_store = Registry("project", registry_config, None) - - # Retrieving the entity should fail since the store is empty - entities = registry_with_same_store.list_entities(project) - assert len(entities) == 0 - validate_project_uuid(project_uuid, registry_with_same_store) - - # commit from the original registry - test_registry.commit() - - # Reconstruct the new registry in order to read the newly written store - registry_with_same_store = Registry("project", registry_config, None) - - # Retrieving the entity should now succeed - entities = registry_with_same_store.list_entities(project) - entity = entities[0] - assert ( - len(entities) == 1 - and entity.name == "driver_car_id" - and entity.description == "Car driver id" - and "team" in entity.tags - and entity.tags["team"] == "matchmaking" - ) - validate_project_uuid(project_uuid, registry_with_same_store) - - entity = test_registry.get_entity("driver_car_id", project) - assert ( - entity.name == "driver_car_id" - and entity.description == "Car driver id" - and "team" in entity.tags - and entity.tags["team"] == "matchmaking" - ) - - test_registry.teardown() - - # Will try to reload registry, which will fail because the file has been deleted - with pytest.raises(FileNotFoundError): - test_registry._get_registry_proto(project=project) - - -def validate_project_uuid(project_uuid, test_registry): - assert len(test_registry.cached_registry_proto.project_metadata) == 1 - project_metadata = test_registry.cached_registry_proto.project_metadata[0] - assert project_metadata.project_uuid == project_uuid diff --git a/sdk/python/tests/unit/test_registry_server.py b/sdk/python/tests/unit/test_registry_server.py deleted file mode 100644 index 462983d898..0000000000 --- a/sdk/python/tests/unit/test_registry_server.py +++ /dev/null @@ -1,60 +0,0 @@ -import assertpy -import grpc_testing -import pytest -from google.protobuf.empty_pb2 import Empty - -from feast import Entity, FeatureStore -from feast.protos.feast.registry import RegistryServer_pb2 -from feast.registry_server import RegistryServer - - -def call_registry_server(server, method: str, request=None): - service = RegistryServer_pb2.DESCRIPTOR.services_by_name["RegistryServer"] - rpc = server.invoke_unary_unary( - service.methods_by_name[method], (), request if request else Empty(), None - ) - - return rpc.termination() - - -@pytest.fixture -def registry_server(environment): - store: FeatureStore = environment.feature_store - - servicer = RegistryServer(registry=store._registry) - - return grpc_testing.server_from_dictionary( - {RegistryServer_pb2.DESCRIPTOR.services_by_name["RegistryServer"]: servicer}, - grpc_testing.strict_real_time(), - ) - - -def test_registry_server_get_entity(environment, registry_server): - store: FeatureStore = environment.feature_store - entity = Entity(name="driver", join_keys=["driver_id"]) - store.apply(entity) - - expected = store.get_entity(entity.name) - - get_entity_request = RegistryServer_pb2.GetEntityRequest( - name=entity.name, project=store.project, allow_cache=False - ) - response, trailing_metadata, code, details = call_registry_server( - registry_server, "GetEntity", get_entity_request - ) - response_entity = Entity.from_proto(response) - - assertpy.assert_that(response_entity).is_equal_to(expected) - - -def test_registry_server_proto(environment, registry_server): - store: FeatureStore = environment.feature_store - entity = Entity(name="driver", join_keys=["driver_id"]) - store.apply(entity) - - expected = store.registry.proto() - response, trailing_metadata, code, details = call_registry_server( - registry_server, "Proto" - ) - - assertpy.assert_that(response).is_equal_to(expected)