Skip to content

Commit 62e83c7

Browse files
committed
Improve test concurrency
1 parent a6f1787 commit 62e83c7

1 file changed

Lines changed: 45 additions & 17 deletions

File tree

tests/cli/test_integration_cli.py

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from sqlmesh.utils import yaml
77
import shutil
88
import site
9+
import uuid
910

1011
pytestmark = pytest.mark.slow
1112

@@ -16,6 +17,10 @@ def __call__(
1617
) -> subprocess.CompletedProcess: ...
1718

1819

20+
class CreateSitePackageType(t.Protocol):
21+
def __call__(self, name: str) -> t.Tuple[str, Path]: ...
22+
23+
1924
@pytest.fixture
2025
def invoke_cli(tmp_path: Path) -> InvokeCliType:
2126
# Fetch the full path to the SQLMesh binary so that when we use `cwd` to run in the context of a test dir, the correct SQLMesh binary is executed
@@ -65,10 +70,36 @@ def _fetch() -> str:
6570
return _fetch
6671

6772

73+
@pytest.fixture
74+
def create_site_package() -> t.Iterator[CreateSitePackageType]:
75+
created_package_path = None
76+
77+
def _create(name: str) -> t.Tuple[str, Path]:
78+
nonlocal created_package_path
79+
80+
unique_id = str(uuid.uuid4())[0:8]
81+
package_name = f"{name}_{unique_id}" # so that multiple tests using the same name dont clobber each other
82+
83+
site_packages = site.getsitepackages()[0]
84+
package_path = Path(site_packages) / package_name
85+
package_path.mkdir()
86+
87+
created_package_path = package_path
88+
89+
return package_name, package_path
90+
91+
yield _create
92+
93+
if created_package_path:
94+
# cleanup
95+
shutil.rmtree(created_package_path, ignore_errors=True)
96+
97+
6898
def test_load_snapshots_that_reference_nonexistent_python_libraries(
6999
invoke_cli: InvokeCliType,
70100
duckdb_example_project: Path,
71101
last_log_file_contents: t.Callable[[], str],
102+
create_site_package: CreateSitePackageType,
72103
) -> None:
73104
"""
74105
Scenario:
@@ -84,10 +115,8 @@ def test_load_snapshots_that_reference_nonexistent_python_libraries(
84115
project_path = duckdb_example_project
85116

86117
# simulate a 3rd party library that provides a macro
87-
site_packages = site.getsitepackages()[0]
88-
sqlmesh_test_macros_package_path = Path(site_packages) / "sqlmesh_test_macros"
89-
sqlmesh_test_macros_package_path.mkdir()
90-
(sqlmesh_test_macros_package_path / "macros.py").write_text("""
118+
package_name, package_path = create_site_package("sqlmesh_test_macros")
119+
(package_path / "macros.py").write_text("""
91120
from sqlmesh import macro
92121
93122
@macro()
@@ -96,8 +125,8 @@ def do_something(evaluator):
96125
""")
97126

98127
# reference the macro from site-packages
99-
(project_path / "macros" / "__init__.py").write_text("""
100-
from sqlmesh_test_macros.macros import do_something
128+
(project_path / "macros" / "__init__.py").write_text(f"""
129+
from {package_name}.macros import do_something
101130
""")
102131

103132
(project_path / "models" / "example.sql").write_text("""
@@ -125,7 +154,7 @@ def do_something(evaluator):
125154

126155
# deleting this removes the 'do_something()' macro used by the version of the snapshot stored in state
127156
# when loading the old snapshot from state in the local python env, this will create an ImportError
128-
shutil.rmtree(sqlmesh_test_macros_package_path)
157+
shutil.rmtree(package_path)
129158

130159
# Move the macro inline so its no longer being loaded from a library but still exists with the same signature
131160
(project_path / "macros" / "__init__.py").write_text("""
@@ -150,7 +179,7 @@ def do_something(evaluator):
150179
assert "Virtual layer updated" in result.stdout
151180

152181
log_file_contents = last_log_file_contents()
153-
assert "ModuleNotFoundError: No module named 'sqlmesh_test_macros'" in log_file_contents
182+
assert f"ModuleNotFoundError: No module named '{package_name}'" in log_file_contents
154183
assert (
155184
"ERROR - Failed to cache optimized query for model 'example.test_model'"
156185
in log_file_contents
@@ -165,6 +194,7 @@ def test_model_selector_snapshot_references_nonexistent_python_libraries(
165194
invoke_cli: InvokeCliType,
166195
duckdb_example_project: Path,
167196
last_log_file_contents: t.Callable[[], str],
197+
create_site_package: CreateSitePackageType,
168198
) -> None:
169199
"""
170200
Scenario:
@@ -180,10 +210,8 @@ def test_model_selector_snapshot_references_nonexistent_python_libraries(
180210
project_path = duckdb_example_project
181211

182212
# simulate a 3rd party library that provides a macro
183-
site_packages = site.getsitepackages()[0]
184-
sqlmesh_test_macros_package_path = Path(site_packages) / "sqlmesh_test_macros"
185-
sqlmesh_test_macros_package_path.mkdir()
186-
(sqlmesh_test_macros_package_path / "macros.py").write_text("""
213+
package_name, package_path = create_site_package("sqlmesh_test_macros")
214+
(package_path / "macros.py").write_text("""
187215
from sqlmesh import macro
188216
189217
@macro()
@@ -192,8 +220,8 @@ def do_something(evaluator):
192220
""")
193221

194222
# reference the macro from site-packages
195-
(project_path / "macros" / "__init__.py").write_text("""
196-
from sqlmesh_test_macros.macros import do_something
223+
(project_path / "macros" / "__init__.py").write_text(f"""
224+
from {package_name}.macros import do_something
197225
""")
198226

199227
(project_path / "models" / "example.sql").write_text("""
@@ -216,7 +244,7 @@ def do_something(evaluator):
216244

217245
# deleting this removes the 'do_something()' macro used by the version of the snapshot stored in state
218246
# when loading the old snapshot from state in the local python env, this will create an ImportError
219-
shutil.rmtree(sqlmesh_test_macros_package_path)
247+
shutil.rmtree(package_path)
220248

221249
# Move the macro inline so its no longer being loaded from a library but still exists with the same signature
222250
(project_path / "macros" / "__init__.py").write_text("""
@@ -267,15 +295,15 @@ def do_something(evaluator):
267295
"Model 'sqlmesh_example.test_model' sourced from state cannot be rendered in the local environment"
268296
in result.stdout
269297
)
270-
assert "No module named 'sqlmesh_test_macros'" in result.stdout
298+
assert f"No module named '{package_name}'" in result.stdout
271299
assert (
272300
"If the model has been fixed locally, please ensure that the --select-model expression includes it"
273301
in result.stdout
274302
)
275303

276304
# verify the full stack trace was logged
277305
log_file_contents = last_log_file_contents()
278-
assert "ModuleNotFoundError: No module named 'sqlmesh_test_macros'" in log_file_contents
306+
assert f"ModuleNotFoundError: No module named '{package_name}'" in log_file_contents
279307
assert (
280308
"The above exception was the direct cause of the following exception:" in log_file_contents
281309
)

0 commit comments

Comments
 (0)