Skip to content

Commit 85eedf0

Browse files
authored
Add serving integration test for updated feature type (#1112)
* Add serving integration test for updated feature type Signed-off-by: Terence <terencelimxp@gmail.com> * Make cache refresh configurable Signed-off-by: Terence <terencelimxp@gmail.com> * Update refresh interval name Signed-off-by: Terence <terencelimxp@gmail.com>
1 parent 663daec commit 85eedf0

4 files changed

Lines changed: 104 additions & 6 deletions

File tree

serving/src/main/java/feast/serving/config/FeastProperties.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ public void setCoreAuthentication(CoreAuthenticationProperties coreAuthenticatio
8686
this.coreAuthentication = coreAuthentication;
8787
}
8888

89+
/* Feast Core port to connect to. */
90+
@Positive private int coreCacheRefreshInterval;
91+
8992
private SecurityProperties security;
9093

9194
@Bean
@@ -220,6 +223,24 @@ public void setCoreGrpcPort(int coreGrpcPort) {
220223
this.coreGrpcPort = coreGrpcPort;
221224
}
222225

226+
/**
227+
* Gets CachedSpecService refresh interval.
228+
*
229+
* @return CachedSpecService refresh interval
230+
*/
231+
public int getCoreCacheRefreshInterval() {
232+
return coreCacheRefreshInterval;
233+
}
234+
235+
/**
236+
* Sets CachedSpecService refresh interval.
237+
*
238+
* @param coreCacheRefreshInterval CachedSpecService refresh interval
239+
*/
240+
public void setCoreCacheRefreshInterval(int coreCacheRefreshInterval) {
241+
this.coreCacheRefreshInterval = coreCacheRefreshInterval;
242+
}
243+
223244
/**
224245
* Sets the collection of configured stores.
225246
*

serving/src/main/java/feast/serving/config/SpecServiceConfig.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,13 @@ public class SpecServiceConfig {
3737
private static final Logger log = org.slf4j.LoggerFactory.getLogger(SpecServiceConfig.class);
3838
private String feastCoreHost;
3939
private int feastCorePort;
40-
private static final int CACHE_REFRESH_RATE_SECONDS = 10;
40+
private int feastCachedSpecServiceRefreshInterval;
4141

4242
@Autowired
4343
public SpecServiceConfig(FeastProperties feastProperties) {
44-
feastCoreHost = feastProperties.getCoreHost();
45-
feastCorePort = feastProperties.getCoreGrpcPort();
44+
this.feastCoreHost = feastProperties.getCoreHost();
45+
this.feastCorePort = feastProperties.getCoreGrpcPort();
46+
this.feastCachedSpecServiceRefreshInterval = feastProperties.getCoreCacheRefreshInterval();
4647
}
4748

4849
@Bean
@@ -53,8 +54,8 @@ public ScheduledExecutorService cachedSpecServiceScheduledExecutorService(
5354
// reload all specs including new ones periodically
5455
scheduledExecutorService.scheduleAtFixedRate(
5556
cachedSpecStorage::scheduledPopulateCache,
56-
CACHE_REFRESH_RATE_SECONDS,
57-
CACHE_REFRESH_RATE_SECONDS,
57+
feastCachedSpecServiceRefreshInterval,
58+
feastCachedSpecServiceRefreshInterval,
5859
TimeUnit.SECONDS);
5960
return scheduledExecutorService;
6061
}

serving/src/main/resources/application.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ feast:
1717
audience: https://localhost #token audience.
1818
jwkEndpointURI: <jwkEndpointURI> #jwk enpoint uri, used for caching token till expiry.
1919

20+
core-cache-refresh-interval: 10
2021

2122
# Indicates the active store. Only a single store in the last can be active at one time. In the future this key
2223
# will be deprecated in order to allow multiple stores to be served from a single serving instance

serving/src/test/java/feast/serving/it/ServingServiceIT.java

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@
6060
import org.testcontainers.junit.jupiter.Testcontainers;
6161

6262
@ActiveProfiles("it")
63-
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
63+
@SpringBootTest(
64+
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
65+
properties = {
66+
"feast.core-cache-refresh-interval=1",
67+
})
6468
@Testcontainers
6569
public class ServingServiceIT extends BaseAuthIT {
6670

@@ -419,4 +423,75 @@ public void shouldReturnNotFoundForDiffType() {
419423

420424
assertEquals(expectedFieldValuesList, featureResponse.getFieldValuesList());
421425
}
426+
427+
@Test
428+
public void shouldReturnNotFoundForUpdatedType() {
429+
String projectName = "default";
430+
String entityName = "driver_id";
431+
String featureTableName = "rides";
432+
433+
ImmutableList<String> entities = ImmutableList.of(entityName);
434+
ImmutableMap<String, ValueProto.ValueType.Enum> features =
435+
ImmutableMap.of(
436+
"trip_cost",
437+
ValueProto.ValueType.Enum.INT64,
438+
"trip_distance",
439+
ValueProto.ValueType.Enum.STRING,
440+
"trip_empty",
441+
ValueProto.ValueType.Enum.DOUBLE,
442+
"trip_wrong_type",
443+
ValueProto.ValueType.Enum.STRING);
444+
445+
TestUtils.applyFeatureTable(
446+
coreClient, projectName, featureTableName, entities, features, 7200);
447+
448+
// Sleep is necessary to ensure caching (every 1s) of updated FeatureTable is done
449+
try {
450+
Thread.sleep(2000);
451+
} catch (InterruptedException e) {
452+
}
453+
454+
ValueProto.Value entityValue = ValueProto.Value.newBuilder().setInt64Val(1).build();
455+
// Instantiate EntityRows
456+
GetOnlineFeaturesRequestV2.EntityRow entityRow1 =
457+
DataGenerator.createEntityRow(entityName, DataGenerator.createInt64Value(1), 100);
458+
ImmutableList<GetOnlineFeaturesRequestV2.EntityRow> entityRows = ImmutableList.of(entityRow1);
459+
460+
// Instantiate FeatureReferences
461+
ServingAPIProto.FeatureReferenceV2 featureReference =
462+
DataGenerator.createFeatureReference("rides", "trip_distance");
463+
464+
ImmutableList<ServingAPIProto.FeatureReferenceV2> featureReferences =
465+
ImmutableList.of(featureReference);
466+
467+
// Build GetOnlineFeaturesRequestV2
468+
GetOnlineFeaturesRequestV2 onlineFeatureRequest =
469+
TestUtils.createOnlineFeatureRequest(projectName, featureReferences, entityRows);
470+
GetOnlineFeaturesResponse featureResponse =
471+
servingStub.getOnlineFeaturesV2(onlineFeatureRequest);
472+
473+
ImmutableMap<String, ValueProto.Value> expectedValueMap =
474+
ImmutableMap.of(
475+
entityName,
476+
entityValue,
477+
FeatureV2.getFeatureStringRef(featureReference),
478+
DataGenerator.createEmptyValue());
479+
480+
ImmutableMap<String, GetOnlineFeaturesResponse.FieldStatus> expectedStatusMap =
481+
ImmutableMap.of(
482+
entityName,
483+
GetOnlineFeaturesResponse.FieldStatus.PRESENT,
484+
FeatureV2.getFeatureStringRef(featureReference),
485+
GetOnlineFeaturesResponse.FieldStatus.NOT_FOUND);
486+
487+
GetOnlineFeaturesResponse.FieldValues expectedFieldValues =
488+
GetOnlineFeaturesResponse.FieldValues.newBuilder()
489+
.putAllFields(expectedValueMap)
490+
.putAllStatuses(expectedStatusMap)
491+
.build();
492+
ImmutableList<GetOnlineFeaturesResponse.FieldValues> expectedFieldValuesList =
493+
ImmutableList.of(expectedFieldValues);
494+
495+
assertEquals(expectedFieldValuesList, featureResponse.getFieldValuesList());
496+
}
422497
}

0 commit comments

Comments
 (0)