Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
"""Transaction-boundary regression for Windows venv recreation (#83149).
|
||||
|
||||
Review finding on PR #83194 (egilewski): the rollback source (the parked
|
||||
previous venv) was deleted as soon as ``Install-Venv`` saw a working
|
||||
interpreter in the replacement — but ``Install-Dependencies`` is a separate,
|
||||
later stage (a separate *process* under the stage-per-process bootstrap) and
|
||||
every dependency tier or the baseline-import gate can still fail after that
|
||||
point. Deleting the backup early re-creates exactly the availability failure
|
||||
the transactional recreate exists to prevent.
|
||||
|
||||
The contract locked here:
|
||||
|
||||
* ``Install-Venv`` records the parked backup in ``venv.pending-backup``
|
||||
instead of deleting it, and its stale-tree sweep excludes that backup.
|
||||
* ``Install-Dependencies`` restores the previous venv on failure
|
||||
(``Restore-VenvBackup``) and commits the cleanup only after the
|
||||
baseline-import gate passes (``Complete-VenvTransaction``).
|
||||
|
||||
The script only runs on Windows, so Linux CI locks the contract at the
|
||||
source level, same approach as tests/test_install_ps1_venv_recreate_safety.py.
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
INSTALL_PS1 = Path(__file__).resolve().parents[1] / "scripts" / "install.ps1"
|
||||
|
||||
|
||||
def _function_body(source: str, function_name: str) -> str:
|
||||
start = source.index(f"function {function_name}")
|
||||
opening_brace = source.index("{", start)
|
||||
depth = 0
|
||||
for index in range(opening_brace, len(source)):
|
||||
if source[index] == "{":
|
||||
depth += 1
|
||||
elif source[index] == "}":
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
return source[opening_brace : index + 1]
|
||||
raise AssertionError(f"unterminated function: {function_name}")
|
||||
|
||||
|
||||
def _source() -> str:
|
||||
return INSTALL_PS1.read_text(encoding="ascii")
|
||||
|
||||
|
||||
def test_install_venv_does_not_delete_backup_before_dependency_stage() -> None:
|
||||
"""The parked previous venv must survive Install-Venv's success path."""
|
||||
body = _function_body(_source(), "Install-Venv")
|
||||
|
||||
# The success path records the rollback source instead of deleting it.
|
||||
assert "venv.pending-backup" in body
|
||||
# The only backup deletion allowed inside Install-Venv is the *rollback*
|
||||
# rename in the catch block; a Remove-Item of the backup must not appear.
|
||||
assert "Remove-Item -LiteralPath $venvBackupName" not in body
|
||||
|
||||
|
||||
def test_install_venv_stale_sweep_excludes_current_backup() -> None:
|
||||
"""The venv.stale.* sweep must not delete this run's rollback source."""
|
||||
body = _function_body(_source(), "Install-Venv")
|
||||
|
||||
sweep_at = body.index('Get-ChildItem -Directory -Filter "venv.stale.*"')
|
||||
window = body[sweep_at : sweep_at + 400]
|
||||
assert "$_.Name -ne $venvBackupName" in window, (
|
||||
"the stale-tree sweep must exclude the backup parked by this run"
|
||||
)
|
||||
|
||||
|
||||
def test_install_dependencies_restores_backup_on_failure() -> None:
|
||||
"""A failed dependency tier or import gate must restore the parked venv."""
|
||||
body = _function_body(_source(), "Install-Dependencies")
|
||||
|
||||
assert "Restore-VenvBackup" in body
|
||||
catch_at = body.index("Restore-VenvBackup")
|
||||
assert "throw" in body[catch_at : catch_at + 400], (
|
||||
"rollback must rethrow the original failure after restoring"
|
||||
)
|
||||
|
||||
|
||||
def test_install_dependencies_commits_only_after_import_gate() -> None:
|
||||
"""Backup cleanup must come after the baseline-import verification."""
|
||||
body = _function_body(_source(), "Install-Dependencies")
|
||||
|
||||
import_gate = body.index("Baseline imports verified in venv")
|
||||
commit = body.index("Complete-VenvTransaction")
|
||||
assert import_gate < commit, (
|
||||
"the venv transaction must commit only after imports prove the "
|
||||
"replacement usable"
|
||||
)
|
||||
|
||||
|
||||
def test_restore_helper_parks_failed_replacement_and_restores_previous() -> None:
|
||||
body = _function_body(_source(), "Restore-VenvBackup")
|
||||
|
||||
park = body.index("venv.failed.")
|
||||
restore = body.index('-NewName "venv"')
|
||||
assert park < restore, (
|
||||
"the failed replacement must be parked before the previous venv is "
|
||||
"renamed back into place"
|
||||
)
|
||||
|
||||
|
||||
def test_commit_helper_deletes_backup_and_clears_marker() -> None:
|
||||
body = _function_body(_source(), "Complete-VenvTransaction")
|
||||
|
||||
assert "Remove-Item" in body
|
||||
assert "venv.pending-backup" in body
|
||||
Reference in New Issue
Block a user