Skip to content

Commit e455922

Browse files
Plugin repo universal tests (feast-dev#1946)
* Add universal pytest marker Signed-off-by: Felix Wang <wangfelix98@gmail.com> * Allow plugin repos to overwrite FULL_REPO_CONFIGS through environment variable Signed-off-by: Felix Wang <wangfelix98@gmail.com>
1 parent 0212728 commit e455922

9 files changed

Lines changed: 50 additions & 1 deletion

File tree

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ test-python:
6161
test-python-integration:
6262
FEAST_USAGE=False IS_TEST=True python -m pytest -n 8 --integration sdk/python/tests
6363

64+
test-python-universal:
65+
FEAST_USAGE=False IS_TEST=True python -m pytest -n 8 --integration --universal sdk/python/tests
66+
6467
format-python:
6568
# Sort
6669
cd ${ROOT_DIR}/sdk/python; python -m isort feast/ tests/

sdk/python/feast/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@
2424

2525
# Environment variable for toggling usage
2626
FEAST_USAGE = "FEAST_USAGE"
27+
28+
# Environment variable for the path for overwriting universal test configs
29+
FULL_REPO_CONFIGS_MODULE_ENV_NAME: str = "FULL_REPO_CONFIGS_MODULE"

sdk/python/tests/conftest.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ def pytest_configure(config):
4040
"markers", "integration: mark test that has external dependencies"
4141
)
4242
config.addinivalue_line("markers", "benchmark: mark benchmarking tests")
43+
config.addinivalue_line(
44+
"markers", "universal: mark tests that use the universal feature repo"
45+
)
4346

4447

4548
def pytest_addoption(parser):
@@ -52,11 +55,15 @@ def pytest_addoption(parser):
5255
parser.addoption(
5356
"--benchmark", action="store_true", default=False, help="Run benchmark tests",
5457
)
58+
parser.addoption(
59+
"--universal", action="store_true", default=False, help="Run universal tests",
60+
)
5561

5662

5763
def pytest_collection_modifyitems(config, items: List[Item]):
5864
should_run_integration = config.getoption("--integration") is True
5965
should_run_benchmark = config.getoption("--benchmark") is True
66+
should_run_universal = config.getoption("--universal") is True
6067

6168
integration_tests = [t for t in items if "integration" in t.keywords]
6269
if not should_run_integration:
@@ -76,6 +83,12 @@ def pytest_collection_modifyitems(config, items: List[Item]):
7683
for t in benchmark_tests:
7784
items.append(t)
7885

86+
universal_tests = [t for t in items if "universal" in t.keywords]
87+
if should_run_universal:
88+
items.clear()
89+
for t in universal_tests:
90+
items.append(t)
91+
7992

8093
@pytest.fixture
8194
def simple_dataset_1() -> pd.DataFrame:

sdk/python/tests/integration/e2e/test_universal_e2e.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313

1414
@pytest.mark.integration
15+
@pytest.mark.universal
1516
@pytest.mark.parametrize("infer_features", [True, False])
1617
def test_e2e_consistency(environment, e2e_data_sources, infer_features):
1718
fs = environment.feature_store

sdk/python/tests/integration/feature_repos/repo_configuration.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import importlib
2+
import os
13
import tempfile
24
import uuid
35
from contextlib import contextmanager
@@ -9,6 +11,7 @@
911
import pandas as pd
1012

1113
from feast import FeatureStore, FeatureView, RepoConfig, driver_test_data
14+
from feast.constants import FULL_REPO_CONFIGS_MODULE_ENV_NAME
1215
from feast.data_source import DataSource
1316
from tests.integration.feature_repos.universal.data_source_creator import (
1417
DataSourceCreator,
@@ -61,7 +64,15 @@ def __repr__(self) -> str:
6164

6265
DYNAMO_CONFIG = {"type": "dynamodb", "region": "us-west-2"}
6366
REDIS_CONFIG = {"type": "redis", "connection_string": "localhost:6379,db=0"}
64-
FULL_REPO_CONFIGS: List[IntegrationTestRepoConfig] = [
67+
68+
# FULL_REPO_CONFIGS contains the repo configurations (e.g. provider, offline store,
69+
# online store, test data, and more parameters) that most integration tests will test
70+
# against. By default, FULL_REPO_CONFIGS uses the three providers (local, GCP, and AWS)
71+
# with their default offline and online stores; it also tests the providers with the
72+
# Redis online store. It can be overwritten by specifying a Python module through the
73+
# FULL_REPO_CONFIGS_MODULE_ENV_NAME environment variable. In this case, that Python
74+
# module will be imported and FULL_REPO_CONFIGS will be extracted from the file.
75+
DEFAULT_FULL_REPO_CONFIGS: List[IntegrationTestRepoConfig] = [
6576
# Local configurations
6677
IntegrationTestRepoConfig(),
6778
IntegrationTestRepoConfig(online_store=REDIS_CONFIG),
@@ -88,6 +99,17 @@ def __repr__(self) -> str:
8899
online_store=REDIS_CONFIG,
89100
),
90101
]
102+
full_repo_configs_module = os.environ.get(FULL_REPO_CONFIGS_MODULE_ENV_NAME)
103+
if full_repo_configs_module is not None:
104+
try:
105+
module = importlib.import_module(full_repo_configs_module)
106+
FULL_REPO_CONFIGS = getattr(module, "FULL_REPO_CONFIGS")
107+
except Exception:
108+
pass
109+
finally:
110+
FULL_REPO_CONFIGS = DEFAULT_FULL_REPO_CONFIGS
111+
else:
112+
FULL_REPO_CONFIGS = DEFAULT_FULL_REPO_CONFIGS
91113

92114

93115
def construct_universal_entities() -> Dict[str, List[Any]]:

sdk/python/tests/integration/offline_store/test_universal_historical_retrieval.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ def get_expected_training_df(
231231

232232

233233
@pytest.mark.integration
234+
@pytest.mark.universal
234235
@pytest.mark.parametrize("full_feature_names", [True, False], ids=lambda v: str(v))
235236
def test_historical_features(environment, universal_data_sources, full_feature_names):
236237
store = environment.feature_store

sdk/python/tests/integration/online_store/test_universal_online.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323

2424
@pytest.mark.integration
25+
@pytest.mark.universal
2526
@pytest.mark.parametrize("full_feature_names", [True, False], ids=lambda v: str(v))
2627
def test_online_retrieval(environment, universal_data_sources, full_feature_names):
2728

sdk/python/tests/integration/registration/test_universal_odfv_feature_inference.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212

1313
@pytest.mark.integration
14+
@pytest.mark.universal
1415
@pytest.mark.parametrize("infer_features", [True, False], ids=lambda v: str(v))
1516
def test_infer_odfv_features(environment, universal_data_sources, infer_features):
1617
store = environment.feature_store
@@ -33,6 +34,7 @@ def test_infer_odfv_features(environment, universal_data_sources, infer_features
3334

3435

3536
@pytest.mark.integration
37+
@pytest.mark.universal
3638
def test_infer_odfv_features_with_error(environment, universal_data_sources):
3739
store = environment.feature_store
3840

sdk/python/tests/integration/registration/test_universal_types.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ def get_fixtures(request):
116116

117117

118118
@pytest.mark.integration
119+
@pytest.mark.universal
119120
def test_entity_inference_types_match(offline_types_test_fixtures):
120121
environment, config, data_source, fv = offline_types_test_fixtures
121122
fs = environment.feature_store
@@ -139,6 +140,7 @@ def test_entity_inference_types_match(offline_types_test_fixtures):
139140

140141

141142
@pytest.mark.integration
143+
@pytest.mark.universal
142144
def test_feature_get_historical_features_types_match(offline_types_test_fixtures):
143145
environment, config, data_source, fv = offline_types_test_fixtures
144146
fs = environment.feature_store
@@ -185,6 +187,7 @@ def test_feature_get_historical_features_types_match(offline_types_test_fixtures
185187

186188

187189
@pytest.mark.integration
190+
@pytest.mark.universal
188191
def test_feature_get_online_features_types_match(online_types_test_fixtures):
189192
environment, config, data_source, fv = online_types_test_fixtures
190193
fv = create_feature_view(

0 commit comments

Comments
 (0)