Skip to content

Commit b251fe2

Browse files
tokokontkathole
authored andcommitted
chore: add workflow for ray offline tests
Signed-off-by: tokoko <togurgenidze@gmail.com>
1 parent d482727 commit b251fe2

11 files changed

Lines changed: 1315 additions & 187 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: pr-ray-integration-tests
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- synchronize
8+
- labeled
9+
10+
jobs:
11+
integration-test-ray-offline:
12+
if:
13+
((github.event.action == 'labeled' && (github.event.label.name == 'approved' || github.event.label.name == 'lgtm' || github.event.label.name == 'ok-to-test')) ||
14+
(github.event.action != 'labeled' && (contains(github.event.pull_request.labels.*.name, 'ok-to-test') || contains(github.event.pull_request.labels.*.name, 'approved') || contains(github.event.pull_request.labels.*.name, 'lgtm')))) &&
15+
github.event.pull_request.base.repo.full_name == 'feast-dev/feast'
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
with:
20+
repository: ${{ github.event.repository.full_name }}
21+
ref: ${{ github.ref }}
22+
token: ${{ secrets.GITHUB_TOKEN }}
23+
submodules: recursive
24+
- name: Setup pixi
25+
uses: prefix-dev/setup-pixi@v0.8.1
26+
with:
27+
pixi-version: v0.63.1
28+
environments: ray-tests
29+
cache: true
30+
- name: Run Ray offline store integration tests
31+
run: make test-python-universal-ray-offline

.secrets.baseline

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,14 +1333,14 @@
13331333
"filename": "sdk/python/tests/integration/feature_repos/universal/data_sources/file.py",
13341334
"hashed_secret": "d70eab08607a4d05faa2d0d6647206599e9abc65",
13351335
"is_verified": false,
1336-
"line_number": 258
1336+
"line_number": 257
13371337
},
13381338
{
13391339
"type": "Secret Keyword",
13401340
"filename": "sdk/python/tests/integration/feature_repos/universal/data_sources/file.py",
13411341
"hashed_secret": "d70eab08607a4d05faa2d0d6647206599e9abc65",
13421342
"is_verified": false,
1343-
"line_number": 258
1343+
"line_number": 257
13441344
}
13451345
],
13461346
"sdk/python/tests/integration/feature_repos/universal/online_store/couchbase.py": [
@@ -1539,5 +1539,5 @@
15391539
}
15401540
]
15411541
},
1542-
"generated_at": "2026-03-01T13:20:18Z"
1542+
"generated_at": "2026-03-01T19:07:31Z"
15431543
}

Makefile

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -395,22 +395,7 @@ test-python-universal-postgres-offline: ## Run Python Postgres integration tests
395395
sdk/python/tests
396396

397397
test-python-universal-ray-offline: ## Run Python Ray offline store integration tests
398-
PYTHONPATH='.' \
399-
FULL_REPO_CONFIGS_MODULE=sdk.python.feast.infra.offline_stores.contrib.ray_repo_configuration \
400-
PYTEST_PLUGINS=sdk.python.feast.infra.offline_stores.contrib.ray_offline_store.tests \
401-
python -m pytest -n 8 --integration \
402-
-m "not universal_online_stores and not benchmark" \
403-
-k "not test_historical_retrieval_with_validation and \
404-
not test_universal_cli and \
405-
not test_go_feature_server and \
406-
not test_feature_logging and \
407-
not test_logged_features_validation and \
408-
not test_lambda_materialization_consistency and \
409-
not gcs_registry and \
410-
not s3_registry and \
411-
not test_snowflake and \
412-
not test_spark" \
413-
sdk/python/tests
398+
pixi run -e ray-tests test
414399

415400
test-python-ray-compute-engine: ## Run Python Ray compute engine tests
416401
PYTHONPATH='.' \

pixi.lock

Lines changed: 1226 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,17 @@ python = "~=3.10.0"
282282
feast = { path = ".", editable = true, extras = ["duckdb", "delta", "grpcio", "test"] }
283283

284284
[tool.pixi.feature.duckdb-tests.tasks]
285-
test = { cmd = "python -m pytest -n 8 --integration --ignore=sdk/python/tests/integration/offline_store/test_dqm_validation.py sdk/python/tests/integration/offline_store", env = { PYTHONPATH = ".", FULL_REPO_CONFIGS_MODULE = "sdk.python.tests.integration.feature_repos.duckdb_repo_configuration", FEAST_IS_LOCAL_TEST = "True" } }
285+
test = { cmd = "python -m pytest -n 8 --integration -m 'not ray_offline_stores_only' --ignore=sdk/python/tests/integration/offline_store/test_dqm_validation.py sdk/python/tests/integration/offline_store", env = { PYTHONPATH = ".", FULL_REPO_CONFIGS_MODULE = "sdk.python.tests.integration.feature_repos.duckdb_repo_configuration", FEAST_IS_LOCAL_TEST = "True" } }
286+
287+
[tool.pixi.feature.ray-tests.dependencies]
288+
python = "~=3.10.0"
289+
290+
[tool.pixi.feature.ray-tests.pypi-dependencies]
291+
feast = { path = ".", editable = true, extras = ["ray", "grpcio", "test"] }
292+
293+
[tool.pixi.feature.ray-tests.tasks]
294+
test = { cmd = "python -m pytest -n 8 --integration --ignore=sdk/python/tests/integration/offline_store/test_dqm_validation.py sdk/python/tests/integration/offline_store", env = { PYTHONPATH = ".", FULL_REPO_CONFIGS_MODULE = "sdk.python.tests.integration.feature_repos.ray_repo_configuration", FEAST_IS_LOCAL_TEST = "True" } }
286295

287296
[tool.pixi.environments]
288297
duckdb-tests = ["duckdb-tests"]
298+
ray-tests = ["ray-tests"]

sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/tests/__init__.py

Whitespace-only changes.

sdk/python/tests/conftest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ def pytest_configure(config):
101101
"markers",
102102
"universal_offline_stores: mark tests that can be run against different offline stores",
103103
)
104+
config.addinivalue_line(
105+
"markers",
106+
"ray_offline_stores_only: mark tests that currently only work with Ray offline store",
107+
)
104108

105109

106110
def pytest_addoption(parser):

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,32 @@
1+
from feast.infra.offline_stores.duckdb import DuckDBOfflineStoreConfig
12
from tests.integration.feature_repos.universal.data_sources.file import (
2-
DuckDBDataSourceCreator,
3-
DuckDBDeltaDataSourceCreator,
3+
DeltaFileSourceCreator,
4+
DeltaS3FileSourceCreator,
5+
FileDataSourceCreator,
46
)
57

8+
9+
class DuckDBDataSourceCreator(FileDataSourceCreator):
10+
def create_offline_store_config(self):
11+
self.duckdb_offline_store_config = DuckDBOfflineStoreConfig()
12+
return self.duckdb_offline_store_config
13+
14+
15+
class DuckDBDeltaDataSourceCreator(DeltaFileSourceCreator):
16+
def create_offline_store_config(self):
17+
self.duckdb_offline_store_config = DuckDBOfflineStoreConfig()
18+
return self.duckdb_offline_store_config
19+
20+
21+
class DuckDBDeltaS3DataSourceCreator(DeltaS3FileSourceCreator):
22+
def create_offline_store_config(self):
23+
self.duckdb_offline_store_config = DuckDBOfflineStoreConfig(
24+
staging_location="s3://test/staging",
25+
staging_location_endpoint_override=self.endpoint_url,
26+
)
27+
return self.duckdb_offline_store_config
28+
29+
630
AVAILABLE_OFFLINE_STORES = [
731
("local", DuckDBDataSourceCreator),
832
("local", DuckDBDeltaDataSourceCreator),
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from feast.infra.offline_stores.contrib.ray_repo_configuration import (
2+
RayDataSourceCreator,
3+
)
4+
5+
AVAILABLE_OFFLINE_STORES = [("local", RayDataSourceCreator)]
6+
AVAILABLE_ONLINE_STORES = {"sqlite": ({"type": "sqlite"}, None)}

sdk/python/tests/integration/feature_repos/universal/data_sources/file.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
from feast.data_source import DataSource
2525
from feast.feature_logging import LoggingDestination
2626
from feast.infra.offline_stores.dask import DaskOfflineStoreConfig
27-
from feast.infra.offline_stores.duckdb import DuckDBOfflineStoreConfig
2827
from feast.infra.offline_stores.file_source import (
2928
FileLoggingDestination,
3029
SavedDatasetFileStorage,
@@ -346,28 +345,6 @@ def teardown(self):
346345
self.f.close()
347346

348347

349-
# TODO split up DataSourceCreator and OfflineStoreCreator
350-
class DuckDBDataSourceCreator(FileDataSourceCreator):
351-
def create_offline_store_config(self):
352-
self.duckdb_offline_store_config = DuckDBOfflineStoreConfig()
353-
return self.duckdb_offline_store_config
354-
355-
356-
class DuckDBDeltaDataSourceCreator(DeltaFileSourceCreator):
357-
def create_offline_store_config(self):
358-
self.duckdb_offline_store_config = DuckDBOfflineStoreConfig()
359-
return self.duckdb_offline_store_config
360-
361-
362-
class DuckDBDeltaS3DataSourceCreator(DeltaS3FileSourceCreator):
363-
def create_offline_store_config(self):
364-
self.duckdb_offline_store_config = DuckDBOfflineStoreConfig(
365-
staging_location="s3://test/staging",
366-
staging_location_endpoint_override=self.endpoint_url,
367-
)
368-
return self.duckdb_offline_store_config
369-
370-
371348
class RemoteOfflineStoreDataSourceCreator(FileDataSourceCreator):
372349
def __init__(self, project_name: str, *args, **kwargs):
373350
super().__init__(project_name)

0 commit comments

Comments
 (0)