1111# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212# See the License for the specific language governing permissions and
1313# limitations under the License.
14+ import importlib
1415import logging
1516import multiprocessing
1617import os
2021from multiprocessing import Process
2122from sys import platform
2223from textwrap import dedent
23- from typing import Any , Dict , List , Tuple , no_type_check
24+ from typing import Any , Dict , List , Optional , Tuple , no_type_check
2425from unittest import mock
2526
2627import pandas as pd
3637 create_document_dataset ,
3738 create_image_dataset ,
3839)
39- from tests .universal .feature_repos .integration_test_repo_config import ( # noqa: E402
40- IntegrationTestRepoConfig ,
41- )
42- from tests .universal .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 .universal .feature_repos .universal .data_sources .file import ( # noqa: E402
53- FileDataSourceCreator ,
54- )
55- from tests .universal .feature_repos .universal .entities import ( # noqa: E402
56- customer ,
57- driver ,
58- location ,
59- )
60- from tests .utils .auth_permissions_util import default_store
6140from tests .utils .http_server import check_port_open , free_port # noqa: E402
62- from tests .utils .ssl_certifcates_util import (
63- combine_trust_stores ,
64- create_ca_trust_store ,
65- generate_self_signed_cert ,
66- )
41+
42+ IntegrationTestRepoConfig : Any = None
43+ Environment = Any
44+ TestData = Any
45+ AVAILABLE_OFFLINE_STORES : Any = None
46+ AVAILABLE_ONLINE_STORES : Any = None
47+ OFFLINE_STORE_TO_PROVIDER_CONFIG : Any = None
48+ construct_test_environment : Any = None
49+ construct_universal_feature_views : Any = None
50+ construct_universal_test_data : Any = None
51+ FileDataSourceCreator : Any = None
52+ customer : Any = None
53+ driver : Any = None
54+ location : Any = None
55+ _universal_deps_missing_reason : Optional [str ] = None
56+
57+
58+ def _load_universal_feature_repo_deps () -> bool :
59+ global IntegrationTestRepoConfig
60+ global Environment
61+ global TestData
62+ global AVAILABLE_OFFLINE_STORES
63+ global AVAILABLE_ONLINE_STORES
64+ global OFFLINE_STORE_TO_PROVIDER_CONFIG
65+ global construct_test_environment
66+ global construct_universal_feature_views
67+ global construct_universal_test_data
68+ global FileDataSourceCreator
69+ global customer
70+ global driver
71+ global location
72+ global _universal_deps_missing_reason
73+
74+ if IntegrationTestRepoConfig is not None :
75+ return True
76+
77+ try :
78+ integration_config = importlib .import_module (
79+ "tests.universal.feature_repos.integration_test_repo_config"
80+ )
81+ repo_configuration = importlib .import_module (
82+ "tests.universal.feature_repos.repo_configuration"
83+ )
84+ file_data_sources = importlib .import_module (
85+ "tests.universal.feature_repos.universal.data_sources.file"
86+ )
87+ entities = importlib .import_module (
88+ "tests.universal.feature_repos.universal.entities"
89+ )
90+ except ModuleNotFoundError as e :
91+ _universal_deps_missing_reason = (
92+ f"Optional integration test dependency is not installed: { e .name } "
93+ )
94+ return False
95+
96+ IntegrationTestRepoConfig = integration_config .IntegrationTestRepoConfig
97+ Environment = repo_configuration .Environment
98+ TestData = repo_configuration .TestData
99+ AVAILABLE_OFFLINE_STORES = repo_configuration .AVAILABLE_OFFLINE_STORES
100+ AVAILABLE_ONLINE_STORES = repo_configuration .AVAILABLE_ONLINE_STORES
101+ OFFLINE_STORE_TO_PROVIDER_CONFIG = (
102+ repo_configuration .OFFLINE_STORE_TO_PROVIDER_CONFIG
103+ )
104+ construct_test_environment = repo_configuration .construct_test_environment
105+ construct_universal_feature_views = (
106+ repo_configuration .construct_universal_feature_views
107+ )
108+ construct_universal_test_data = repo_configuration .construct_universal_test_data
109+ FileDataSourceCreator = file_data_sources .FileDataSourceCreator
110+ customer = entities .customer
111+ driver = entities .driver
112+ location = entities .location
113+ _universal_deps_missing_reason = None
114+ return True
115+
116+
117+ def _skip_missing_universal_feature_repo_deps () -> None :
118+ if not _load_universal_feature_repo_deps ():
119+ pytest .skip (
120+ _universal_deps_missing_reason
121+ or "Optional integration test dependencies are not installed"
122+ )
123+
67124
68125logger = logging .getLogger (__name__ )
69126
85142
86143
87144def pytest_configure (config ):
88- if platform in [ "darwin" , "windows" ] :
145+ if platform == "darwin" or platform . startswith ( "win" ) :
89146 multiprocessing .set_start_method ("spawn" , force = True )
90147 else :
91148 multiprocessing .set_start_method ("fork" )
@@ -192,6 +249,7 @@ def start_test_local_server(repo_path: str, port: int):
192249
193250@pytest .fixture
194251def environment (request , worker_id ):
252+ _skip_missing_universal_feature_repo_deps ()
195253 e = construct_test_environment (
196254 request .param ,
197255 worker_id = worker_id ,
@@ -211,6 +269,7 @@ def environment(request, worker_id):
211269
212270@pytest .fixture
213271def vectordb_environment (request , worker_id ):
272+ _skip_missing_universal_feature_repo_deps ()
214273 e = construct_test_environment (
215274 request .param ,
216275 worker_id = worker_id ,
@@ -251,6 +310,23 @@ def pytest_generate_tests(metafunc: pytest.Metafunc):
251310 parameter should point to the same Python object (hence, we use _config_cache dict to store those objects).
252311 """
253312 if "environment" in metafunc .fixturenames :
313+ if not _load_universal_feature_repo_deps ():
314+ metafunc .parametrize (
315+ "environment" ,
316+ [
317+ pytest .param (
318+ None ,
319+ marks = pytest .mark .skip (
320+ reason = _universal_deps_missing_reason
321+ or "Optional integration test dependencies are not installed"
322+ ),
323+ )
324+ ],
325+ indirect = True ,
326+ ids = ["missing_optional_integration_deps" ],
327+ )
328+ return
329+
254330 markers = {m .name : m for m in metafunc .definition .own_markers }
255331 offline_stores = None
256332 if "universal_offline_stores" in markers :
@@ -371,6 +447,7 @@ def feature_server_endpoint(environment):
371447
372448@pytest .fixture
373449def universal_data_sources (environment ) -> TestData :
450+ _skip_missing_universal_feature_repo_deps ()
374451 return construct_universal_test_data (environment )
375452
376453
@@ -394,6 +471,7 @@ def feature_store_for_online_retrieval(
394471 Returns a feature store that is ready for online retrieval, along with entity rows and feature
395472 refs that can be used to query for online features.
396473 """
474+ _skip_missing_universal_feature_repo_deps ()
397475 fs = environment .feature_store
398476 entities , datasets , data_sources = universal_data_sources
399477 feature_views = construct_universal_feature_views (data_sources )
@@ -478,6 +556,11 @@ def server_port():
478556
479557@pytest .fixture
480558def feature_store (temp_dir , auth_config , applied_permissions ):
559+ try :
560+ from tests .utils .auth_permissions_util import default_store
561+ except ModuleNotFoundError as e :
562+ pytest .skip (f"Optional auth test dependency is not installed: { e .name } " )
563+
481564 print (f"Creating store at { temp_dir } " )
482565 return default_store (str (temp_dir ), auth_config , applied_permissions )
483566
@@ -542,6 +625,15 @@ def auth_config(request, is_integration_test):
542625
543626@pytest .fixture (scope = "module" )
544627def tls_mode (request ):
628+ try :
629+ from tests .utils .ssl_certifcates_util import (
630+ combine_trust_stores ,
631+ create_ca_trust_store ,
632+ generate_self_signed_cert ,
633+ )
634+ except ModuleNotFoundError as e :
635+ pytest .skip (f"Optional TLS test dependency is not installed: { e .name } " )
636+
545637 is_tls_mode = request .param [0 ]
546638 output_combined_truststore_path = ""
547639
0 commit comments