16
16
#
17
17
18
18
import logging
19
+ import pytest
19
20
20
21
from google .cloud import aiplatform
21
22
from tests .system .aiplatform import e2e_base
29
30
"gs://cloud-samples-data-us-central1/vertex-ai/feature-store/datasets/movies.avro"
30
31
)
31
32
33
+ _TEST_READ_INSTANCE_SRC = "gs://cloud-samples-data-us-central1/vertex-ai/feature-store/datasets/movie_prediction.csv"
34
+
32
35
_TEST_FEATURESTORE_ID = "movie_prediction"
33
36
_TEST_USER_ENTITY_TYPE_ID = "users"
34
37
_TEST_MOVIE_ENTITY_TYPE_ID = "movies"
42
45
_TEST_MOVIE_AVERAGE_RATING_FEATURE_ID = "average_rating"
43
46
44
47
48
+ @pytest .mark .usefixtures (
49
+ "prepare_staging_bucket" ,
50
+ "delete_staging_bucket" ,
51
+ "prepare_bigquery_dataset" ,
52
+ "delete_bigquery_dataset" ,
53
+ )
45
54
class TestFeaturestore (e2e_base .TestEndToEnd ):
46
55
47
56
_temp_prefix = "temp_vertex_sdk_e2e_featurestore_test"
@@ -131,7 +140,7 @@ def test_create_get_list_features(self, shared_state):
131
140
user_age_feature = user_entity_type .create_feature (
132
141
feature_id = _TEST_USER_AGE_FEATURE_ID , value_type = "INT64"
133
142
)
134
-
143
+ shared_state [ "user_age_feature_resource_name" ] = user_age_feature . resource_name
135
144
get_user_age_feature = user_entity_type .get_feature (
136
145
feature_id = _TEST_USER_AGE_FEATURE_ID
137
146
)
@@ -142,6 +151,9 @@ def test_create_get_list_features(self, shared_state):
142
151
value_type = "STRING" ,
143
152
entity_type_name = user_entity_type_name ,
144
153
)
154
+ shared_state [
155
+ "user_gender_feature_resource_name"
156
+ ] = user_gender_feature .resource_name
145
157
146
158
get_user_gender_feature = aiplatform .Feature (
147
159
feature_name = user_gender_feature .resource_name
@@ -153,6 +165,9 @@ def test_create_get_list_features(self, shared_state):
153
165
user_liked_genres_feature = user_entity_type .create_feature (
154
166
feature_id = _TEST_USER_LIKED_GENRES_FEATURE_ID , value_type = "STRING_ARRAY" ,
155
167
)
168
+ shared_state [
169
+ "user_liked_genres_feature_resource_name"
170
+ ] = user_liked_genres_feature .resource_name
156
171
157
172
get_user_liked_genres_feature = aiplatform .Feature (
158
173
feature_name = user_liked_genres_feature .resource_name
@@ -250,6 +265,105 @@ def test_search_features(self, shared_state):
250
265
len (list_searched_features ) - shared_state ["base_list_searched_features" ]
251
266
) == 6
252
267
268
+ def test_batch_serve_to_gcs (self , shared_state , caplog ):
269
+
270
+ assert shared_state ["featurestore" ]
271
+ assert shared_state ["bucket" ]
272
+ assert shared_state ["user_age_feature_resource_name" ]
273
+ assert shared_state ["user_gender_feature_resource_name" ]
274
+ assert shared_state ["user_liked_genres_feature_resource_name" ]
275
+
276
+ featurestore = shared_state ["featurestore" ]
277
+ bucket_name = shared_state ["staging_bucket_name" ]
278
+ user_age_feature_resource_name = shared_state ["user_age_feature_resource_name" ]
279
+ user_gender_feature_resource_name = shared_state [
280
+ "user_gender_feature_resource_name"
281
+ ]
282
+ user_liked_genres_feature_resource_name = shared_state [
283
+ "user_liked_genres_feature_resource_name"
284
+ ]
285
+
286
+ aiplatform .init (
287
+ project = e2e_base ._PROJECT , location = e2e_base ._LOCATION ,
288
+ )
289
+
290
+ caplog .set_level (logging .INFO )
291
+
292
+ featurestore .batch_serve_to_gcs (
293
+ serving_feature_ids = {
294
+ _TEST_USER_ENTITY_TYPE_ID : [
295
+ _TEST_USER_AGE_FEATURE_ID ,
296
+ _TEST_USER_GENDER_FEATURE_ID ,
297
+ _TEST_USER_LIKED_GENRES_FEATURE_ID ,
298
+ ],
299
+ _TEST_MOVIE_ENTITY_TYPE_ID : [
300
+ _TEST_MOVIE_TITLE_FEATURE_ID ,
301
+ _TEST_MOVIE_GENRES_FEATURE_ID ,
302
+ _TEST_MOVIE_AVERAGE_RATING_FEATURE_ID ,
303
+ ],
304
+ },
305
+ feature_destination_fields = {
306
+ user_age_feature_resource_name : "user_age_dest" ,
307
+ user_gender_feature_resource_name : "user_gender_dest" ,
308
+ user_liked_genres_feature_resource_name : "user_liked_genres_dest" ,
309
+ },
310
+ read_instances = _TEST_READ_INSTANCE_SRC ,
311
+ gcs_destination_output_uri_prefix = f"gs://{ bucket_name } /featurestore_test/tfrecord" ,
312
+ gcs_destination_type = "tfrecord" ,
313
+ )
314
+ assert "Featurestore feature values served." in caplog .text
315
+
316
+ caplog .clear ()
317
+
318
+ def test_batch_serve_to_bq (self , shared_state , caplog ):
319
+
320
+ assert shared_state ["featurestore" ]
321
+ assert shared_state ["bigquery_dataset" ]
322
+ assert shared_state ["user_age_feature_resource_name" ]
323
+ assert shared_state ["user_gender_feature_resource_name" ]
324
+ assert shared_state ["user_liked_genres_feature_resource_name" ]
325
+
326
+ featurestore = shared_state ["featurestore" ]
327
+ bigquery_dataset_id = shared_state ["bigquery_dataset_id" ]
328
+ user_age_feature_resource_name = shared_state ["user_age_feature_resource_name" ]
329
+ user_gender_feature_resource_name = shared_state [
330
+ "user_gender_feature_resource_name"
331
+ ]
332
+ user_liked_genres_feature_resource_name = shared_state [
333
+ "user_liked_genres_feature_resource_name"
334
+ ]
335
+
336
+ aiplatform .init (
337
+ project = e2e_base ._PROJECT , location = e2e_base ._LOCATION ,
338
+ )
339
+
340
+ caplog .set_level (logging .INFO )
341
+
342
+ featurestore .batch_serve_to_bq (
343
+ serving_feature_ids = {
344
+ _TEST_USER_ENTITY_TYPE_ID : [
345
+ _TEST_USER_AGE_FEATURE_ID ,
346
+ _TEST_USER_GENDER_FEATURE_ID ,
347
+ _TEST_USER_LIKED_GENRES_FEATURE_ID ,
348
+ ],
349
+ _TEST_MOVIE_ENTITY_TYPE_ID : [
350
+ _TEST_MOVIE_TITLE_FEATURE_ID ,
351
+ _TEST_MOVIE_GENRES_FEATURE_ID ,
352
+ _TEST_MOVIE_AVERAGE_RATING_FEATURE_ID ,
353
+ ],
354
+ },
355
+ feature_destination_fields = {
356
+ user_age_feature_resource_name : "user_age_dest" ,
357
+ user_gender_feature_resource_name : "user_gender_dest" ,
358
+ user_liked_genres_feature_resource_name : "user_liked_genres_dest" ,
359
+ },
360
+ read_instances = _TEST_READ_INSTANCE_SRC ,
361
+ bq_destination_output_uri = f"bq://{ bigquery_dataset_id } .test_table" ,
362
+ )
363
+
364
+ assert "Featurestore feature values served." in caplog .text
365
+ caplog .clear ()
366
+
253
367
def test_online_reads (self , shared_state ):
254
368
assert shared_state ["user_entity_type" ]
255
369
assert shared_state ["movie_entity_type" ]
0 commit comments