|
36 | 36 | create_document_dataset, |
37 | 37 | create_image_dataset, |
38 | 38 | ) |
39 | | -from tests.integration.feature_repos.integration_test_repo_config import ( # noqa: E402 |
40 | | - IntegrationTestRepoConfig, |
41 | | -) |
42 | | -from tests.integration.feature_repos.repo_configuration import ( # noqa: E402 |
43 | | - AVAILABLE_OFFLINE_STORES, |
44 | | - AVAILABLE_ONLINE_STORES, |
45 | | - OFFLINE_STORE_TO_PROVIDER_CONFIG, |
46 | | - Environment, |
47 | | - TestData, |
48 | | - construct_test_environment, |
49 | | - construct_universal_feature_views, |
50 | | - construct_universal_test_data, |
51 | | -) |
52 | | -from tests.integration.feature_repos.universal.data_sources.file import ( # noqa: E402 |
53 | | - FileDataSourceCreator, |
54 | | -) |
55 | | -from tests.integration.feature_repos.universal.entities import ( # noqa: E402 |
56 | | - customer, |
57 | | - driver, |
58 | | - location, |
59 | | -) |
60 | | -from tests.utils.auth_permissions_util import default_store |
| 39 | +try: |
| 40 | + from tests.integration.feature_repos.integration_test_repo_config import ( # noqa: E402 |
| 41 | + IntegrationTestRepoConfig, |
| 42 | + ) |
| 43 | + from tests.integration.feature_repos.repo_configuration import ( # noqa: E402 |
| 44 | + AVAILABLE_OFFLINE_STORES, |
| 45 | + AVAILABLE_ONLINE_STORES, |
| 46 | + OFFLINE_STORE_TO_PROVIDER_CONFIG, |
| 47 | + Environment, |
| 48 | + TestData, |
| 49 | + construct_test_environment, |
| 50 | + construct_universal_feature_views, |
| 51 | + construct_universal_test_data, |
| 52 | + ) |
| 53 | + from tests.integration.feature_repos.universal.data_sources.file import ( # noqa: E402 |
| 54 | + FileDataSourceCreator, |
| 55 | + ) |
| 56 | + from tests.integration.feature_repos.universal.entities import ( # noqa: E402 |
| 57 | + customer, |
| 58 | + driver, |
| 59 | + location, |
| 60 | + ) |
| 61 | + |
| 62 | + _integration_test_deps_available = True |
| 63 | +except ModuleNotFoundError: |
| 64 | + _integration_test_deps_available = False |
| 65 | + |
| 66 | + IntegrationTestRepoConfig = None # type: ignore[assignment] |
| 67 | + AVAILABLE_OFFLINE_STORES = [] # type: ignore[assignment] |
| 68 | + AVAILABLE_ONLINE_STORES = {} # type: ignore[assignment] |
| 69 | + OFFLINE_STORE_TO_PROVIDER_CONFIG = {} # type: ignore[assignment] |
| 70 | + Environment = Any # type: ignore[assignment] |
| 71 | + TestData = Any # type: ignore[assignment] |
| 72 | + |
| 73 | + def construct_test_environment(*args, **kwargs): # type: ignore[no-redef] |
| 74 | + raise RuntimeError("Integration test dependencies are not available") |
| 75 | + |
| 76 | + def construct_universal_feature_views(*args, **kwargs): # type: ignore[no-redef] |
| 77 | + raise RuntimeError("Integration test dependencies are not available") |
| 78 | + |
| 79 | + def construct_universal_test_data(*args, **kwargs): # type: ignore[no-redef] |
| 80 | + raise RuntimeError("Integration test dependencies are not available") |
| 81 | + |
| 82 | + class FileDataSourceCreator: # type: ignore[no-redef] |
| 83 | + pass |
| 84 | + |
| 85 | + def customer(*args, **kwargs): # type: ignore[no-redef] |
| 86 | + raise RuntimeError("Integration test dependencies are not available") |
| 87 | + |
| 88 | + def driver(*args, **kwargs): # type: ignore[no-redef] |
| 89 | + raise RuntimeError("Integration test dependencies are not available") |
| 90 | + |
| 91 | + def location(*args, **kwargs): # type: ignore[no-redef] |
| 92 | + raise RuntimeError("Integration test dependencies are not available") |
| 93 | + |
| 94 | +try: |
| 95 | + from tests.utils.auth_permissions_util import default_store |
| 96 | +except ModuleNotFoundError: |
| 97 | + |
| 98 | + def default_store(*args, **kwargs): # type: ignore[no-redef] |
| 99 | + raise RuntimeError("Auth test dependencies are not available") |
61 | 100 | from tests.utils.http_server import check_port_open, free_port # noqa: E402 |
62 | 101 | from tests.utils.ssl_certifcates_util import ( |
63 | 102 | combine_trust_stores, |
|
67 | 106 |
|
68 | 107 | logger = logging.getLogger(__name__) |
69 | 108 |
|
| 109 | +os.environ.setdefault("IS_TEST", "True") |
| 110 | + |
70 | 111 | level = logging.INFO |
71 | 112 | logging.basicConfig( |
72 | 113 | format="%(asctime)s %(name)s %(levelname)s: %(message)s", |
|
85 | 126 |
|
86 | 127 |
|
87 | 128 | def pytest_configure(config): |
88 | | - if platform in ["darwin", "windows"]: |
| 129 | + if platform == "darwin" or platform.startswith("win"): |
89 | 130 | multiprocessing.set_start_method("spawn", force=True) |
90 | 131 | else: |
91 | 132 | multiprocessing.set_start_method("fork") |
@@ -239,92 +280,92 @@ def pytest_generate_tests(metafunc: pytest.Metafunc): |
239 | 280 |
|
240 | 281 | See more examples at https://docs.pytest.org/en/6.2.x/example/parametrize.html#paramexamples |
241 | 282 |
|
242 | | - We also utilize indirect parametrization here. Since `environment` is a fixture, |
243 | | - when we call metafunc.parametrize("environment", ..., indirect=True) we actually |
244 | | - parametrizing this "environment" fixture and not the test itself. |
245 | | - Moreover, by utilizing `_config_cache` we are able to share `environment` fixture between different tests. |
246 | | - In order for pytest to group tests together (and share environment fixture) |
247 | | - parameter should point to the same Python object (hence, we use _config_cache dict to store those objects). |
248 | 283 | """ |
249 | | - if "environment" in metafunc.fixturenames: |
250 | | - markers = {m.name: m for m in metafunc.definition.own_markers} |
251 | | - offline_stores = None |
252 | | - if "universal_offline_stores" in markers: |
253 | | - # Offline stores can be explicitly requested |
254 | | - if "only" in markers["universal_offline_stores"].kwargs: |
255 | | - offline_stores = [ |
256 | | - OFFLINE_STORE_TO_PROVIDER_CONFIG.get(store_name) |
257 | | - for store_name in markers["universal_offline_stores"].kwargs["only"] |
258 | | - if store_name in OFFLINE_STORE_TO_PROVIDER_CONFIG |
259 | | - ] |
260 | | - else: |
261 | | - offline_stores = AVAILABLE_OFFLINE_STORES |
| 284 | + if "environment" not in metafunc.fixturenames: |
| 285 | + return |
| 286 | + |
| 287 | + if not _integration_test_deps_available: |
| 288 | + pytest.skip("Integration test dependencies are not available") |
| 289 | + |
| 290 | + markers = {m.name: m for m in metafunc.definition.iter_markers()} |
| 291 | + |
| 292 | + offline_stores = None |
| 293 | + if "universal_offline_stores" in markers: |
| 294 | + # Offline stores can be explicitly requested |
| 295 | + if "only" in markers["universal_offline_stores"].kwargs: |
| 296 | + offline_stores = [ |
| 297 | + OFFLINE_STORE_TO_PROVIDER_CONFIG.get(store_name) |
| 298 | + for store_name in markers["universal_offline_stores"].kwargs["only"] |
| 299 | + if store_name in OFFLINE_STORE_TO_PROVIDER_CONFIG |
| 300 | + ] |
262 | 301 | else: |
263 | | - # default offline store for testing online store dimension |
264 | | - offline_stores = [("local", FileDataSourceCreator)] |
265 | | - |
266 | | - online_stores = None |
267 | | - if "universal_online_stores" in markers: |
268 | | - # Online stores can be explicitly requested |
269 | | - if "only" in markers["universal_online_stores"].kwargs: |
270 | | - online_stores = [ |
271 | | - AVAILABLE_ONLINE_STORES.get(store_name) |
272 | | - for store_name in markers["universal_online_stores"].kwargs["only"] |
273 | | - if store_name in AVAILABLE_ONLINE_STORES |
274 | | - ] |
275 | | - else: |
276 | | - online_stores = AVAILABLE_ONLINE_STORES.values() |
277 | | - |
278 | | - if online_stores is None: |
279 | | - # No online stores requested -> setting the default or first available |
| 302 | + offline_stores = AVAILABLE_OFFLINE_STORES |
| 303 | + else: |
| 304 | + # default offline store for testing online store dimension |
| 305 | + offline_stores = [("local", FileDataSourceCreator)] |
| 306 | + |
| 307 | + online_stores = None |
| 308 | + if "universal_online_stores" in markers: |
| 309 | + # Online stores can be explicitly requested |
| 310 | + if "only" in markers["universal_online_stores"].kwargs: |
280 | 311 | online_stores = [ |
281 | | - AVAILABLE_ONLINE_STORES.get( |
282 | | - "redis", |
283 | | - AVAILABLE_ONLINE_STORES.get( |
284 | | - "sqlite", next(iter(AVAILABLE_ONLINE_STORES.values())) |
285 | | - ), |
286 | | - ) |
| 312 | + AVAILABLE_ONLINE_STORES.get(store_name) |
| 313 | + for store_name in markers["universal_online_stores"].kwargs["only"] |
| 314 | + if store_name in AVAILABLE_ONLINE_STORES |
287 | 315 | ] |
288 | | - |
289 | | - extra_dimensions: List[Dict[str, Any]] = [{}] |
290 | | - |
291 | | - if "python_server" in metafunc.fixturenames: |
292 | | - extra_dimensions.extend([{"python_feature_server": True}]) |
293 | | - |
294 | | - configs = [] |
295 | | - if offline_stores: |
296 | | - for provider, offline_store_creator in offline_stores: |
297 | | - for online_store, online_store_creator in online_stores: |
298 | | - for dim in extra_dimensions: |
299 | | - config = { |
300 | | - "provider": provider, |
301 | | - "offline_store_creator": offline_store_creator, |
302 | | - "online_store": online_store, |
303 | | - "online_store_creator": online_store_creator, |
304 | | - **dim, |
305 | | - } |
306 | | - |
307 | | - c = IntegrationTestRepoConfig(**config) |
308 | | - |
309 | | - if c not in _config_cache: |
310 | | - marks = [ |
311 | | - pytest.mark.xdist_group(name=m) |
312 | | - for m in c.offline_store_creator.xdist_groups() |
313 | | - ] |
314 | | - # Check if there are any test markers associated with the creator and add them. |
315 | | - if c.offline_store_creator.test_markers(): |
316 | | - marks.extend(c.offline_store_creator.test_markers()) |
317 | | - |
318 | | - _config_cache[c] = pytest.param(c, marks=marks) |
319 | | - |
320 | | - configs.append(_config_cache[c]) |
321 | 316 | else: |
322 | | - # No offline stores requested -> setting the default or first available |
323 | | - offline_stores = [("local", FileDataSourceCreator)] |
| 317 | + online_stores = AVAILABLE_ONLINE_STORES.values() |
324 | 318 |
|
325 | | - metafunc.parametrize( |
326 | | - "environment", configs, indirect=True, ids=[str(c) for c in configs] |
327 | | - ) |
| 319 | + if online_stores is None: |
| 320 | + # No online stores requested -> setting the default or first available |
| 321 | + online_stores = [ |
| 322 | + AVAILABLE_ONLINE_STORES.get( |
| 323 | + "redis", |
| 324 | + AVAILABLE_ONLINE_STORES.get( |
| 325 | + "sqlite", next(iter(AVAILABLE_ONLINE_STORES.values())) |
| 326 | + ), |
| 327 | + ) |
| 328 | + ] |
| 329 | + |
| 330 | + extra_dimensions: List[Dict[str, Any]] = [{}] |
| 331 | + |
| 332 | + if "python_server" in metafunc.fixturenames: |
| 333 | + extra_dimensions.extend([{"python_feature_server": True}]) |
| 334 | + |
| 335 | + configs = [] |
| 336 | + if offline_stores: |
| 337 | + for provider, offline_store_creator in offline_stores: |
| 338 | + for online_store, online_store_creator in online_stores: |
| 339 | + for dim in extra_dimensions: |
| 340 | + config = { |
| 341 | + "provider": provider, |
| 342 | + "offline_store_creator": offline_store_creator, |
| 343 | + "online_store": online_store, |
| 344 | + "online_store_creator": online_store_creator, |
| 345 | + **dim, |
| 346 | + } |
| 347 | + |
| 348 | + c = IntegrationTestRepoConfig(**config) |
| 349 | + |
| 350 | + if c not in _config_cache: |
| 351 | + marks = [ |
| 352 | + pytest.mark.xdist_group(name=m) |
| 353 | + for m in c.offline_store_creator.xdist_groups() |
| 354 | + ] |
| 355 | + # Check if there are any test markers associated with the creator and add them. |
| 356 | + if c.offline_store_creator.test_markers(): |
| 357 | + marks.extend(c.offline_store_creator.test_markers()) |
| 358 | + |
| 359 | + _config_cache[c] = pytest.param(c, marks=marks) |
| 360 | + |
| 361 | + configs.append(_config_cache[c]) |
| 362 | + else: |
| 363 | + # No offline stores requested -> setting the default or first available |
| 364 | + offline_stores = [("local", FileDataSourceCreator)] |
| 365 | + |
| 366 | + metafunc.parametrize( |
| 367 | + "environment", configs, indirect=True, ids=[str(c) for c in configs] |
| 368 | + ) |
328 | 369 |
|
329 | 370 |
|
330 | 371 | @pytest.fixture |
|
0 commit comments