Skip to content

Commit 81fb1ba

Browse files
smadarasmifeast-ci-bot
authored andcommitted
Add unit test in Redis to return values with no max age set (#329)
* fix path in serving application.yml for redis serving config * add test to RedisServingService for checking values are returned when max age is default
1 parent 8e6bbd4 commit 81fb1ba

2 files changed

Lines changed: 88 additions & 10 deletions

File tree

serving/src/main/resources/application.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ feast:
1919

2020
store:
2121
# Path containing the store configuration for this serving store.
22-
config-path: ${FEAST_STORE_CONFIG_PATH:./sample_redis_config.yml}
22+
config-path: ${FEAST_STORE_CONFIG_PATH:serving/sample_redis_config.yml}
2323
# If serving redis, the redis pool max size
2424
redis-pool-max-size: ${FEAST_REDIS_POOL_MAX_SIZE:128}
2525
# If serving redis, the redis pool max idle conns

serving/src/test/java/feast/serving/service/RedisServingServiceTest.java

Lines changed: 87 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
import com.google.protobuf.Timestamp;
1212
import feast.core.FeatureSetProto.EntitySpec;
1313
import feast.core.FeatureSetProto.FeatureSetSpec;
14+
import feast.serving.ServingAPIProto.FeatureSetRequest;
1415
import feast.serving.ServingAPIProto.GetOnlineFeaturesRequest;
1516
import feast.serving.ServingAPIProto.GetOnlineFeaturesRequest.EntityRow;
16-
import feast.serving.ServingAPIProto.FeatureSetRequest;
1717
import feast.serving.ServingAPIProto.GetOnlineFeaturesResponse;
1818
import feast.serving.ServingAPIProto.GetOnlineFeaturesResponse.FieldValues;
1919
import feast.storage.RedisProto.RedisKey;
@@ -53,14 +53,6 @@ public class RedisServingServiceTest {
5353
@Before
5454
public void setUp() {
5555
initMocks(this);
56-
FeatureSetSpec featureSetSpec = FeatureSetSpec.newBuilder()
57-
.addEntities(EntitySpec.newBuilder().setName("entity1"))
58-
.addEntities(EntitySpec.newBuilder().setName("entity2"))
59-
.setMaxAge(Duration.newBuilder().setSeconds(30)) // default
60-
.build();
61-
62-
when(specService.getFeatureSet("featureSet", 1))
63-
.thenReturn(featureSetSpec);
6456

6557
redisServingService = new RedisServingService(jedisPool, specService, tracer);
6658
redisKeyList = Lists.newArrayList(
@@ -124,6 +116,72 @@ public void shouldReturnResponseWithValuesIfKeysPresent() {
124116
List<byte[]> featureRowBytes = featureRows.stream()
125117
.map(AbstractMessageLite::toByteArray)
126118
.collect(Collectors.toList());
119+
when(specService.getFeatureSet("featureSet", 1)).thenReturn(getFeatureSetSpec());
120+
when(jedisPool.getResource()).thenReturn(jedis);
121+
when(jedis.mget(redisKeyList)).thenReturn(featureRowBytes);
122+
when(tracer.buildSpan(ArgumentMatchers.any())).thenReturn(Mockito.mock(SpanBuilder.class));
123+
124+
GetOnlineFeaturesResponse expected = GetOnlineFeaturesResponse.newBuilder()
125+
.addFieldValues(FieldValues.newBuilder()
126+
.putFields("entity1", intValue(1))
127+
.putFields("entity2", strValue("a"))
128+
.putFields("featureSet:1:feature1", intValue(1))
129+
.putFields("featureSet:1:feature2", intValue(1)))
130+
.addFieldValues(FieldValues.newBuilder()
131+
.putFields("entity1", intValue(2))
132+
.putFields("entity2", strValue("b"))
133+
.putFields("featureSet:1:feature1", intValue(2))
134+
.putFields("featureSet:1:feature2", intValue(2)))
135+
.build();
136+
GetOnlineFeaturesResponse actual = redisServingService.getOnlineFeatures(request);
137+
assertThat(responseToMapList(actual), containsInAnyOrder(responseToMapList(expected).toArray()));
138+
}
139+
140+
@Test
141+
public void shouldReturnResponseWithValuesWhenFeatureSetSpecHasUnspecifiedMaxAge() {
142+
GetOnlineFeaturesRequest request = GetOnlineFeaturesRequest.newBuilder()
143+
.addFeatureSets(FeatureSetRequest.newBuilder()
144+
.setName("featureSet")
145+
.setVersion(1)
146+
.addAllFeatureNames(Lists.newArrayList("feature1", "feature2"))
147+
.build())
148+
.addEntityRows(EntityRow.newBuilder()
149+
.setEntityTimestamp(Timestamp.newBuilder().setSeconds(100))
150+
.putFields("entity1", intValue(1))
151+
.putFields("entity2", strValue("a")))
152+
.addEntityRows(EntityRow.newBuilder()
153+
.setEntityTimestamp(Timestamp.newBuilder().setSeconds(100))
154+
.putFields("entity1", intValue(2))
155+
.putFields("entity2", strValue("b")))
156+
.build();
157+
158+
List<FeatureRow> featureRows = Lists.newArrayList(
159+
FeatureRow.newBuilder()
160+
.setEventTimestamp(Timestamp.newBuilder().setSeconds(2)) // much older timestamp
161+
.addAllFields(Lists
162+
.newArrayList(
163+
Field.newBuilder().setName("entity1").setValue(intValue(1)).build(),
164+
Field.newBuilder().setName("entity2").setValue(strValue("a")).build(),
165+
Field.newBuilder().setName("feature1").setValue(intValue(1)).build(),
166+
Field.newBuilder().setName("feature2").setValue(intValue(1)).build()))
167+
.setFeatureSet("featureSet:1")
168+
.build(),
169+
FeatureRow.newBuilder()
170+
.setEventTimestamp(Timestamp.newBuilder().setSeconds(15)) // much older timestamp
171+
.addAllFields(Lists
172+
.newArrayList(
173+
Field.newBuilder().setName("entity1").setValue(intValue(2)).build(),
174+
Field.newBuilder().setName("entity2").setValue(strValue("b")).build(),
175+
Field.newBuilder().setName("feature1").setValue(intValue(2)).build(),
176+
Field.newBuilder().setName("feature2").setValue(intValue(2)).build()))
177+
.setFeatureSet("featureSet:1")
178+
.build()
179+
);
180+
181+
List<byte[]> featureRowBytes = featureRows.stream()
182+
.map(AbstractMessageLite::toByteArray)
183+
.collect(Collectors.toList());
184+
when(specService.getFeatureSet("featureSet", 1)).thenReturn(getFeatureSetSpecWithNoMaxAge());
127185
when(jedisPool.getResource()).thenReturn(jedis);
128186
when(jedis.mget(redisKeyList)).thenReturn(featureRowBytes);
129187
when(tracer.buildSpan(ArgumentMatchers.any())).thenReturn(Mockito.mock(SpanBuilder.class));
@@ -187,6 +245,7 @@ public void shouldReturnResponseWithUnsetValuesIfKeysNotPresent() {
187245
);
188246

189247
List<byte[]> featureRowBytes = Lists.newArrayList(featureRows.get(0).toByteArray(), null);
248+
when(specService.getFeatureSet("featureSet", 1)).thenReturn(getFeatureSetSpec());
190249
when(jedisPool.getResource()).thenReturn(jedis);
191250
when(jedis.mget(redisKeyList)).thenReturn(featureRowBytes);
192251
when(tracer.buildSpan(ArgumentMatchers.any())).thenReturn(Mockito.mock(SpanBuilder.class));
@@ -253,6 +312,7 @@ public void shouldReturnResponseWithUnsetValuesIfMaxAgeIsExceeded() {
253312
List<byte[]> featureRowBytes = featureRows.stream()
254313
.map(AbstractMessageLite::toByteArray)
255314
.collect(Collectors.toList());
315+
when(specService.getFeatureSet("featureSet", 1)).thenReturn(getFeatureSetSpec());
256316
when(jedisPool.getResource()).thenReturn(jedis);
257317
when(jedis.mget(redisKeyList)).thenReturn(featureRowBytes);
258318
when(tracer.buildSpan(ArgumentMatchers.any())).thenReturn(Mockito.mock(SpanBuilder.class));
@@ -319,6 +379,7 @@ public void shouldReturnResponseWithUnsetValuesIfDefaultMaxAgeIsExceeded() {
319379
List<byte[]> featureRowBytes = featureRows.stream()
320380
.map(AbstractMessageLite::toByteArray)
321381
.collect(Collectors.toList());
382+
when(specService.getFeatureSet("featureSet", 1)).thenReturn(getFeatureSetSpec());
322383
when(jedisPool.getResource()).thenReturn(jedis);
323384
when(jedis.mget(redisKeyList)).thenReturn(featureRowBytes);
324385
when(tracer.buildSpan(ArgumentMatchers.any())).thenReturn(Mockito.mock(SpanBuilder.class));
@@ -385,6 +446,7 @@ public void shouldFilterOutUndesiredRows() {
385446
List<byte[]> featureRowBytes = featureRows.stream()
386447
.map(AbstractMessageLite::toByteArray)
387448
.collect(Collectors.toList());
449+
when(specService.getFeatureSet("featureSet", 1)).thenReturn(getFeatureSetSpec());
388450
when(jedisPool.getResource()).thenReturn(jedis);
389451
when(jedis.mget(redisKeyList)).thenReturn(featureRowBytes);
390452
when(tracer.buildSpan(ArgumentMatchers.any())).thenReturn(Mockito.mock(SpanBuilder.class));
@@ -414,4 +476,20 @@ private Value intValue(int val) {
414476
private Value strValue(String val) {
415477
return Value.newBuilder().setStringVal(val).build();
416478
}
479+
private FeatureSetSpec getFeatureSetSpec() {
480+
return FeatureSetSpec.newBuilder()
481+
.addEntities(EntitySpec.newBuilder().setName("entity1"))
482+
.addEntities(EntitySpec.newBuilder().setName("entity2"))
483+
.setMaxAge(Duration.newBuilder().setSeconds(30)) // default
484+
.build();
485+
}
486+
487+
private FeatureSetSpec getFeatureSetSpecWithNoMaxAge() {
488+
return FeatureSetSpec.newBuilder()
489+
.addEntities(EntitySpec.newBuilder().setName("entity1"))
490+
.addEntities(EntitySpec.newBuilder().setName("entity2"))
491+
.setMaxAge(Duration.newBuilder().setSeconds(0).setNanos(0).build())
492+
.build();
493+
}
494+
417495
}

0 commit comments

Comments
 (0)