Skip to content

Commit fb6eacb

Browse files
committed
test: dynamodb online store online_read in batches
Signed-off-by: Miguel Trejo <armando.trejo.marrufo@gmail.com>
1 parent 8bd2a84 commit fb6eacb

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import time
2+
from dataclasses import dataclass
3+
4+
import pytest
5+
6+
from feast.infra.offline_stores.file import FileOfflineStoreConfig
7+
from feast.infra.online_stores.dynamodb import (
8+
DynamoDBOnlineStore,
9+
DynamoDBOnlineStoreConfig,
10+
)
11+
from feast.repo_config import RepoConfig
12+
from tests.utils.online_store_utils import (
13+
_create_n_customer_test_samples,
14+
_create_test_table,
15+
_delete_test_table,
16+
_insert_data_test_table,
17+
)
18+
19+
REGISTRY = "s3://test_registry/registry.db"
20+
PROJECT = "test_aws"
21+
PROVIDER = "aws"
22+
TABLE_NAME = "dynamodb_online_store"
23+
REGION = "us-west-2"
24+
25+
26+
@dataclass
27+
class MockFeatureView:
28+
name: str
29+
30+
31+
@pytest.fixture
32+
def repo_config():
33+
return RepoConfig(
34+
registry=REGISTRY,
35+
project=PROJECT,
36+
provider=PROVIDER,
37+
online_store=DynamoDBOnlineStoreConfig(region=REGION),
38+
offline_store=FileOfflineStoreConfig(),
39+
)
40+
41+
42+
@pytest.mark.parametrize("n_samples", [5, 50, 100])
43+
def test_online_read(repo_config, n_samples):
44+
"""Test DynamoDBOnlineStore online_read method."""
45+
_create_test_table(PROJECT, f"{TABLE_NAME}_{n_samples}", REGION)
46+
time.sleep(10) # Wait for table to be available
47+
data = _create_n_customer_test_samples(n=n_samples)
48+
_insert_data_test_table(data, PROJECT, f"{TABLE_NAME}_{n_samples}", REGION)
49+
50+
entity_keys, features = zip(*data)
51+
dynamodb_store = DynamoDBOnlineStore()
52+
returned_items = dynamodb_store.online_read(
53+
config=repo_config,
54+
table=MockFeatureView(name=f"{TABLE_NAME}_{n_samples}"),
55+
entity_keys=entity_keys,
56+
)
57+
_delete_test_table(PROJECT, f"{TABLE_NAME}_{n_samples}", REGION)
58+
assert len(returned_items) == len(data)
59+
assert [item[1] for item in returned_items] == list(features)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from datetime import datetime
2+
3+
import boto3
4+
5+
from feast import utils
6+
from feast.infra.online_stores.helpers import compute_entity_id
7+
from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto
8+
from feast.protos.feast.types.Value_pb2 import Value as ValueProto
9+
10+
11+
def _create_n_customer_test_samples(n=10):
12+
return [
13+
(
14+
EntityKeyProto(
15+
join_keys=["customer"], entity_values=[ValueProto(string_val=str(i))]
16+
),
17+
{
18+
"avg_orders_day": ValueProto(float_val=1.0),
19+
"name": ValueProto(string_val="John"),
20+
"age": ValueProto(int64_val=3),
21+
},
22+
)
23+
for i in range(n)
24+
]
25+
26+
27+
def _create_test_table(project, tbl_name, region):
28+
client = boto3.client("dynamodb", region_name=region)
29+
client.create_table(
30+
TableName=f"{project}.{tbl_name}",
31+
KeySchema=[{"AttributeName": "entity_id", "KeyType": "HASH"}],
32+
AttributeDefinitions=[{"AttributeName": "entity_id", "AttributeType": "S"}],
33+
BillingMode="PAY_PER_REQUEST",
34+
)
35+
36+
37+
def _delete_test_table(project, tbl_name, region):
38+
client = boto3.client("dynamodb", region_name=region)
39+
client.delete_table(TableName=f"{project}.{tbl_name}")
40+
41+
42+
def _insert_data_test_table(data, project, tbl_name, region):
43+
dynamodb_resource = boto3.resource("dynamodb", region_name=region)
44+
table_instance = dynamodb_resource.Table(f"{project}.{tbl_name}")
45+
for entity_key, features in data:
46+
entity_id = compute_entity_id(entity_key)
47+
with table_instance.batch_writer() as batch:
48+
batch.put_item(
49+
Item={
50+
"entity_id": entity_id,
51+
"event_ts": str(utils.make_tzaware(datetime.utcnow())),
52+
"values": {k: v.SerializeToString() for k, v in features.items()},
53+
}
54+
)

0 commit comments

Comments
 (0)