Skip to content

Commit 5d5a42a

Browse files
committed
test: require blocking Windows compatibility coverage
1 parent 99bda44 commit 5d5a42a

2 files changed

Lines changed: 86 additions & 2 deletions

File tree

tests/test_release_artifacts.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ def test_builder_rejects_missing_file_and_incomplete_mit_notice(
619619
release_builder.build_release(TAG, license_repo, tmp_path / "license-assets")
620620

621621

622-
def test_ci_uses_full_tag_checkout_and_only_claims_supported_platforms():
622+
def test_ci_uses_full_tag_checkout_and_blocking_windows_matrix():
623623
workflow = (REPO_ROOT / ".github" / "workflows" / "tests.yml").read_text(
624624
encoding="utf-8"
625625
)
@@ -633,9 +633,15 @@ def test_ci_uses_full_tag_checkout_and_only_claims_supported_platforms():
633633
assert '"pytest==8.4.2"' in workflow
634634
assert 'python-version == \'3.9\'' in workflow
635635
assert 'python-version == \'3.8\'' not in workflow
636-
assert "windows-2025" not in workflow
636+
assert "windows-2025" in workflow
637+
assert '"3.10"' in workflow
638+
assert '"3.14"' in workflow
637639
assert "continue-on-error" not in workflow
638640
assert "Windows experimental atomic no-replace probe passed" not in workflow
641+
windows_job = workflow.split("\n windows:", 1)[1].split("\n quality:", 1)[0]
642+
assert "runs-on: windows-2025" in windows_job
643+
assert "python -m py_compile codex-instruct.py" in windows_job
644+
assert "python -m pytest -p no:cacheprovider -q tests" in windows_job
639645
quality_job = workflow.split("\n quality:", 1)[1]
640646
assert "fetch-depth: 0" in quality_job
641647
assert "fetch-tags: true" in quality_job

tests/test_windows_filesystem.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,15 @@ def test_operation_directories_are_identity_deduplicated_and_stably_sorted(tmp_p
176176
assert {item.path for item in normalized} == {first.resolve(), second.resolve()}
177177

178178

179+
@pytest.mark.parametrize(
180+
"name",
181+
["CON", "prn.md", "AUX", "nul.txt", "COM1", "lpt9.md"],
182+
)
183+
def test_windows_reserved_device_names_are_rejected(name):
184+
with pytest.raises(ValueError, match="reserved"):
185+
codex_instruct.normalize_md_name(name)
186+
187+
179188
def test_directory_lock_excludes_second_process_without_sleep(tmp_path):
180189
codex_dir = _make_codex_dir(tmp_path, "lock target")
181190
worker = """
@@ -220,6 +229,75 @@ def checkpoint(name):
220229
assert stdout == "directory-lock-acquired\n"
221230

222231

232+
def test_process_termination_releases_directory_lock(tmp_path):
233+
codex_dir = _make_codex_dir(tmp_path, "terminated lock")
234+
holder = """
235+
import importlib.util
236+
import sys
237+
from pathlib import Path
238+
239+
module_path = Path(sys.argv[1])
240+
target = sys.argv[2]
241+
spec = importlib.util.spec_from_file_location("keysmith_lock_holder", module_path)
242+
module = importlib.util.module_from_spec(spec)
243+
sys.modules[spec.name] = module
244+
spec.loader.exec_module(module)
245+
246+
def checkpoint(name):
247+
if name == "directory-lock-acquired":
248+
print(name, flush=True)
249+
250+
module._FILESYSTEM_CHECKPOINT_HOOK = checkpoint
251+
with module._DirectoryLockSet([target]):
252+
sys.stdin.buffer.read(1)
253+
"""
254+
process = subprocess.Popen(
255+
[sys.executable, "-c", holder, str(MODULE_PATH), str(codex_dir)],
256+
stdin=subprocess.PIPE,
257+
stdout=subprocess.PIPE,
258+
stderr=subprocess.PIPE,
259+
text=True,
260+
)
261+
assert process.stdout is not None
262+
assert process.stdout.readline() == "directory-lock-acquired\n"
263+
process.kill()
264+
process.communicate(timeout=10)
265+
266+
worker = subprocess.run(
267+
[
268+
sys.executable,
269+
"-c",
270+
(
271+
"import importlib.util,sys; from pathlib import Path; "
272+
"p=Path(sys.argv[1]); s=importlib.util.spec_from_file_location('m',p); "
273+
"m=importlib.util.module_from_spec(s); sys.modules[s.name]=m; "
274+
"s.loader.exec_module(m); "
275+
"lock=m._DirectoryLockSet([sys.argv[2]]); lock.__enter__(); "
276+
"print('acquired'); lock.__exit__(None,None,None)"
277+
),
278+
str(MODULE_PATH),
279+
str(codex_dir),
280+
],
281+
text=True,
282+
capture_output=True,
283+
timeout=10,
284+
)
285+
assert worker.returncode == 0, worker.stderr
286+
assert worker.stdout == "acquired\n"
287+
288+
289+
@pytest.mark.skipif(os.name != "nt", reason="Windows case-insensitive identity contract")
290+
def test_windows_case_aliases_are_identity_deduplicated(tmp_path):
291+
directory = _make_codex_dir(tmp_path, "CaseAlias")
292+
alias = Path(str(directory).swapcase())
293+
294+
normalized = codex_instruct._normalize_operation_directories(
295+
[str(directory), str(alias)]
296+
)
297+
298+
assert len(normalized) == 1
299+
300+
223301
@pytest.mark.skipif(os.name != "nt", reason="Windows native ACL contract")
224302
def test_windows_private_file_and_directory_acl(tmp_path):
225303
directory = tmp_path / "private 中文"

0 commit comments

Comments
 (0)