Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions tests/lib/test_bedrock.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import re
import json
import base64
Expand Down Expand Up @@ -66,12 +67,18 @@ def mock_aws_config(
profiles: t.List[AwsConfigProfile],
monkeypatch: t.Any,
) -> t.Iterable[None]:
with tempfile.NamedTemporaryFile(mode="w+", delete=True) as temp_file:
# `delete=True` keeps the handle open, and a second open of that file fails
# on Windows while botocore reads it; close and unlink explicitly instead.
temp_file = tempfile.NamedTemporaryFile(mode="w+", delete=False)
try:
for profile in profiles:
temp_file.write(profile_to_ini(profile))
temp_file.flush()
monkeypatch.setenv("AWS_CONFIG_FILE", str(temp_file.name))
temp_file.close()
monkeypatch.setenv("AWS_CONFIG_FILE", temp_file.name)
yield
finally:
os.unlink(temp_file.name)


@pytest.mark.respx()
Expand Down
5 changes: 4 additions & 1 deletion tests/lib/tools/memory_sync/test_delete_discipline.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
import pytest

import anthropic.lib.tools._memories as memories_mod

pytestmark = pytest.mark.skipif(os.name != "posix", reason="FileStore-backed sync suites refuse non-POSIX platforms")

from anthropic.lib.tools._memories import MemoryDeleteMode, SessionMemoryStores

from .conftest import Clock, run_sync, listing_interrupted_by
Expand Down Expand Up @@ -165,7 +168,7 @@ async def test_a_folder_destroyed_mid_sync_sends_no_deletes(tmp_path: Path, cloc
assert server.files == {"a.md": "v1", "keep.md": "v1"}


@pytest.mark.skipif(os.geteuid() == 0, reason="permission checks do not bind root")
@pytest.mark.skipif(os.name == "posix" and os.geteuid() == 0, reason="permission checks do not bind root")
@pytest.mark.asyncio()
async def test_an_unreadable_subdirectory_fails_the_pass_instead_of_reading_as_deletions(
tmp_path: Path, clock: Clock, caplog: pytest.LogCaptureFixture
Expand Down
4 changes: 4 additions & 0 deletions tests/lib/tools/memory_sync/test_e2e_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from __future__ import annotations

import os
import json
import time
import base64
Expand All @@ -24,6 +25,9 @@

import anthropic.lib.tools._memories as memories_mod
import anthropic.lib.environments._worker as worker_mod

pytestmark = pytest.mark.skipif(os.name != "posix", reason="FileStore-backed sync suites refuse non-POSIX platforms")

from anthropic.lib.tools._memories import MemoryDeleteMode
from anthropic.lib.environments._worker import EnvironmentWorker

Expand Down
4 changes: 4 additions & 0 deletions tests/lib/tools/memory_sync/test_final_flush.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@

from __future__ import annotations

import os
from typing import Any
from pathlib import Path

import anyio
import pytest

import anthropic.lib.tools._memories as memories_mod

pytestmark = pytest.mark.skipif(os.name != "posix", reason="FileStore-backed sync suites refuse non-POSIX platforms")

from anthropic.lib.tools._memories import MARKER_PATH, SessionMemoryStores

from .conftest import run_sync
Expand Down
4 changes: 4 additions & 0 deletions tests/lib/tools/memory_sync/test_folder_trust.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@

from __future__ import annotations

import os
import shutil
from pathlib import Path

import pytest

import anthropic.lib.tools._memories as memories_mod

pytestmark = pytest.mark.skipif(os.name != "posix", reason="FileStore-backed sync suites refuse non-POSIX platforms")

from anthropic.lib.tools._memories import MARKER_PATH, SessionMemoryStores

from .conftest import Clock, run_sync, listing_interrupted_by
Expand Down
3 changes: 3 additions & 0 deletions tests/lib/tools/memory_sync/test_keep_only_copy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

from __future__ import annotations

import os
from pathlib import Path

import pytest

pytestmark = pytest.mark.skipif(os.name != "posix", reason="FileStore-backed sync suites refuse non-POSIX platforms")

from anthropic.lib.tools._memories import SessionMemoryStores

from .conftest import run_sync, listing_interrupted_by
Expand Down
3 changes: 3 additions & 0 deletions tests/lib/tools/memory_sync/test_lost_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from __future__ import annotations

import os
from typing import Any
from pathlib import Path
from contextlib import contextmanager
Expand All @@ -16,6 +17,8 @@
import httpx2
import pytest

pytestmark = pytest.mark.skipif(os.name != "posix", reason="FileStore-backed sync suites refuse non-POSIX platforms")

from anthropic import APIConnectionError
from anthropic.lib.tools._memories import SessionMemoryStores

Expand Down
2 changes: 2 additions & 0 deletions tests/lib/tools/memory_sync/test_memory_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import pytest

pytestmark = pytest.mark.skipif(os.name != "posix", reason="FileStore-backed sync suites refuse non-POSIX platforms")

from anthropic._compat import PYDANTIC_V1
from anthropic.lib.tools import _memories as memories_mod
from anthropic.lib.tools._memories import SessionMemoryError, SessionMemoryStores
Expand Down
3 changes: 3 additions & 0 deletions tests/lib/tools/memory_sync/test_two_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@

from __future__ import annotations

import os
from typing import Any
from pathlib import Path

import pytest

pytestmark = pytest.mark.skipif(os.name != "posix", reason="FileStore-backed sync suites refuse non-POSIX platforms")

from anthropic.lib.tools._memories import SessionMemoryStores

from .conftest import run_sync
Expand Down
3 changes: 3 additions & 0 deletions tests/lib/tools/test_agent_toolset.py
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,7 @@ async def test_bash_outer_cancel_closes_subprocess_no_stale_state(tmp_path: Path


@needs_pydantic_v2
@needs_symlinks
async def test_read_through_symlink_escape_is_rejected(tmp_path: Path) -> None:
"""resolve_path realpaths, so a symlink that escapes the workdir is caught."""
outside = tmp_path / "outside"
Expand Down Expand Up @@ -886,6 +887,7 @@ async def test_glob_rejects_dotdot_pattern(tmp_path: Path) -> None:


@needs_pydantic_v2
@needs_symlinks
async def test_glob_post_filters_symlink_escape(tmp_path: Path) -> None:
"""A symlink traversed mid-pattern must not let a glob result escape the workdir."""
outside = tmp_path / "outside"
Expand All @@ -911,6 +913,7 @@ async def test_glob_drops_matches_that_cannot_be_canonicalised(tmp_path: Path) -


@needs_pydantic_v2
@needs_symlinks
async def test_grep_skips_symlinked_files(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
"""The fallback walker must not read through a symlink that escapes the workdir."""
secret = tmp_path / "secret.txt"
Expand Down
4 changes: 2 additions & 2 deletions tests/lib/tools/test_file_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ async def test_filestore_hashtree_hashes_regular_files_and_skips_symlinks(tmp_pa
assert await store.hashtree("sub/") == {"sub/b.md": _sha("bravo")}


@pytest.mark.skipif(os.geteuid() == 0, reason="permission checks do not bind root")
@pytest.mark.skipif(os.name == "posix" and os.geteuid() == 0, reason="permission checks do not bind root")
@pytest.mark.asyncio()
async def test_filestore_listings_raise_on_an_unreadable_subdirectory(store: FileStore) -> None:
"""An unreadable subdirectory fails the listing rather than dropping out of it."""
Expand Down Expand Up @@ -314,7 +314,7 @@ async def test_filestore_remove_unlinks_a_dangling_symlink(store: FileStore) ->
assert not (store.root().path / "dangling.md").is_symlink()


@pytest.mark.skipif(os.geteuid() == 0, reason="permission checks do not bind root")
@pytest.mark.skipif(os.name == "posix" and os.geteuid() == 0, reason="permission checks do not bind root")
@pytest.mark.asyncio()
async def test_filestore_open_raises_on_an_unreadable_mount_path(tmp_path: Path) -> None:
"""A mount path the process cannot stat raises at open — it is never read
Expand Down