1010
1111from feast import FeatureStore , FeatureView , RepoConfig , driver_test_data , importer
1212from feast .data_source import DataSource
13+ from feast .value_type import ValueType
1314from tests .data .data_creator import create_dataset
1415from tests .integration .feature_repos .universal .data_source_creator import (
1516 DataSourceCreator ,
@@ -70,7 +71,6 @@ def ds_creator_path(cls: str):
7071 ),
7172]
7273
73-
7474OFFLINE_STORES : List [str ] = []
7575ONLINE_STORES : List [str ] = []
7676PROVIDERS : List [str ] = []
@@ -83,6 +83,9 @@ class Environment:
8383 feature_store : FeatureStore
8484 data_source : DataSource
8585 data_source_creator : DataSourceCreator
86+ entity_type : ValueType
87+ feature_dtype : str
88+ feature_is_list : bool
8689
8790 end_date = datetime .now ().replace (microsecond = 0 , second = 0 , minute = 0 )
8891 start_date = end_date - timedelta (days = 7 )
@@ -199,6 +202,9 @@ def construct_test_environment(
199202 test_repo_config : TestRepoConfig ,
200203 create_and_apply : bool = False ,
201204 materialize : bool = False ,
205+ entity_type : ValueType = ValueType .INT32 ,
206+ feature_dtype : str = None ,
207+ feature_is_list : bool = False ,
202208) -> Environment :
203209 """
204210 This method should take in the parameters from the test repo config and created a feature repo, apply it,
@@ -208,9 +214,14 @@ def construct_test_environment(
208214 The user is *not* expected to perform any clean up actions.
209215
210216 :param test_repo_config: configuration
217+ :param create_and_apply: whether to create and apply the repo config
218+ :param materialize: whether to materialize features to online store
219+ :param entity_type: the data type for the entity column (i.e. id)
220+ :param feature_dtype: the data type for the feature column (i.e. value)
221+ :param feature_is_list: whether the feature column (i.e. value) should be a list feature
211222 :return: A feature store built using the supplied configuration.
212223 """
213- df = create_dataset ()
224+ df = create_dataset (entity_type , feature_dtype , feature_is_list )
214225
215226 project = f"test_correctness_{ str (uuid .uuid4 ()).replace ('-' , '' )[:8 ]} "
216227
@@ -221,9 +232,7 @@ def construct_test_environment(
221232 offline_creator : DataSourceCreator = importer .get_class_from_type (
222233 module_name , config_class_name , "DataSourceCreator"
223234 )(project )
224- ds = offline_creator .create_data_source (
225- project , df , field_mapping = {"ts_1" : "ts" , "id" : "driver_id" }
226- )
235+ ds = offline_creator .create_data_source (project , df , field_mapping = {"ts_1" : "ts" })
227236 offline_store = offline_creator .create_offline_store_config ()
228237 online_store = test_repo_config .online_store
229238
@@ -243,6 +252,9 @@ def construct_test_environment(
243252 feature_store = fs ,
244253 data_source = ds ,
245254 data_source_creator = offline_creator ,
255+ entity_type = entity_type ,
256+ feature_dtype = feature_dtype ,
257+ feature_is_list = feature_is_list ,
246258 )
247259
248260 fvs = []
@@ -341,3 +353,80 @@ def inner_test(config):
341353 online_test (environment )
342354
343355 return inner_test
356+
357+
358+ def parametrize_types_no_materialize_test (types_test ):
359+ """
360+ This decorator should be used by tests that want to parametrize by different kinds of entity + feature types and
361+ not materialize said features
362+ """
363+ return _parametrize_types_test_internal (types_test , create_apply_materialize = False )
364+
365+
366+ def parametrize_types_materialize_test (types_test ):
367+ """
368+ This decorator should be used by tests that want to parametrize by different kinds of entity + feature types and
369+ materialize said features
370+ """
371+ return _parametrize_types_test_internal (types_test , create_apply_materialize = True )
372+
373+
374+ def parametrize_types_no_materialize_test_no_list (types_test ):
375+ """
376+ This decorator should be used by tests that want to parametrize by different kinds of entity + feature types, but
377+ not materializing and not allowing for feature list types
378+ """
379+ return _parametrize_types_test_internal (
380+ types_test , create_apply_materialize = False , vary_feature_is_list = False
381+ )
382+
383+
384+ def _parametrize_types_test_internal (
385+ types_test , create_apply_materialize : bool , vary_feature_is_list : bool = True
386+ ):
387+ def entity_feature_types_ids (entity_type : ValueType , feature_dtype : str ):
388+ return f"entity_type:{ str (entity_type )} -feature_dtype:{ feature_dtype } "
389+
390+ # TODO(adchia): consider adding timestamp / bytes for feature_dtypes
391+ # TODO(adchia): test materializing float entity types and ensure we throw an error before querying BQ
392+ entity_type_feature_dtypes = [
393+ (ValueType .INT32 , "int32" ),
394+ (ValueType .INT64 , "int64" ),
395+ (ValueType .STRING , "float" ),
396+ (ValueType .STRING , "bool" ),
397+ ]
398+
399+ # TODO(adchia): fix conversion to allow for lists in materialization
400+ feature_is_list = [True , False ] if vary_feature_is_list else [False ]
401+
402+ @pytest .mark .integration
403+ @pytest .mark .parametrize (
404+ "entity_type,feature_dtype" ,
405+ entity_type_feature_dtypes ,
406+ ids = [
407+ entity_feature_types_ids (entity_type , feature_dtype )
408+ for entity_type , feature_dtype in entity_type_feature_dtypes
409+ ],
410+ )
411+ @pytest .mark .parametrize (
412+ "feature_is_list" , feature_is_list , ids = lambda v : f"feature_is_list:{ str (v )} "
413+ )
414+ def inner_test (entity_type : ValueType , feature_dtype : str , feature_is_list : bool ):
415+ # TODO: parametrize config
416+ with construct_test_environment (
417+ TestRepoConfig (
418+ provider = "gcp" ,
419+ offline_store_creator = ds_creator_path (
420+ "bigquery.BigQueryDataSourceCreator"
421+ ),
422+ online_store = "datastore" ,
423+ ),
424+ create_and_apply = create_apply_materialize ,
425+ materialize = create_apply_materialize ,
426+ entity_type = entity_type ,
427+ feature_dtype = feature_dtype ,
428+ feature_is_list = feature_is_list ,
429+ ) as environment :
430+ types_test (environment )
431+
432+ return inner_test
0 commit comments