Skip to content

test(sandbox): add per-user isolation regression tests for virtual path contract#3087

Open
64johnlee wants to merge 2 commits into
bytedance:mainfrom
64johnlee:fix/sandbox-vpath-contract-tests
Open

test(sandbox): add per-user isolation regression tests for virtual path contract#3087
64johnlee wants to merge 2 commits into
bytedance:mainfrom
64johnlee:fix/sandbox-vpath-contract-tests

Conversation

@64johnlee
Copy link
Copy Markdown
Contributor

@64johnlee 64johnlee commented May 20, 2026

Closes #3024

Problem

The virtual path contract (/mnt/user-data/{workspace,uploads,outputs} → per-user/per-thread host directories) had no regression tests covering per-user isolation. Refactors to LocalSandboxProvider could silently break the contract by merging host directories across users sharing the same thread_id.

Fix

Extended tests/test_local_sandbox_virtual_path_contract.py with 3 regression tests (new section 7) covering per-user path isolation:

  • test_per_user_isolation_different_users_same_thread — two different user_ids acquiring the same thread_id must get distinct host paths
  • test_per_user_workspace_maps_to_user_scoped_directory — resolved workspace path must contain both user_id and thread_id components
  • test_user_a_writes_invisible_to_user_b_on_same_thread_id — a file written by user A must not appear in user B's sandbox view of the same thread_id

🤖 Generated with Claude Code

…th contract (bytedance#3024)

The existing virtual-path contract tests verified that LocalSandbox
honours /mnt/user-data/... paths for per-thread sandboxes, but none of
them exercised user-id scoping: two users sharing the same thread_id
must map that virtual path to distinct host directories under
users/{user_id}/threads/{thread_id}/user-data/.

Add three new tests to the existing suite:

- test_per_user_isolation_different_users_same_thread: acquires the same
  thread_id as alice and then bob; verifies their workspace host paths
  differ and each contains the correct user_id component.
- test_per_user_workspace_maps_to_user_scoped_directory: verifies the
  workspace virtual path resolves under users/carol/threads/t-carol/.
- test_user_a_writes_invisible_to_user_b_on_same_thread_id: writes a
  file as user-a and confirms it is not readable in user-b's view.

These tests answer the question in bytedance#3024 ("Does the new sandbox
architecture still need the virtual path contract tests?") and pin down
the per-user isolation invariant that bytedance#2873 originally introduced.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds regression coverage to ensure LocalSandboxProvider continues to honor the public /mnt/user-data/* virtual path contract with per-user isolation, preventing refactors from accidentally merging host directories across users sharing the same thread_id.

Changes:

  • Adds tests asserting /mnt/user-data/workspace host mappings differ by user_id even when thread_id is the same.
  • Adds a test asserting the resolved workspace path reflects both user_id and thread_id scoping.
  • Adds a test intended to ensure user A’s workspace writes are not visible to user B (but currently has an issue noted in comments).

Comment on lines +434 to +438
try:
content = sandbox_b.read_file("/mnt/user-data/workspace/secret.txt")
assert "user-a-data" not in content
except Exception:
pass # expected: user-b has no such file


# ──────────────────────────────────────────────────────────────────────────
# 6. User-id scoping: per-user path isolation contract (#3024 / #2873)
Comment on lines +385 to +390
def test_per_user_isolation_different_users_same_thread(provider, isolated_paths, monkeypatch):
"""Two different users acquiring the same thread_id must get distinct host paths."""
monkeypatch.setattr("deerflow.runtime.user_context.get_effective_user_id", lambda: "alice")
provider.acquire("thread-shared")
alice_path = _get_workspace_local_path(provider, "thread-shared")

- Rename duplicate section header # 6 → # 7 (User-id scoping)
- Fix test_user_a_writes_invisible_to_user_b: use try/except FileNotFoundError/else
  so AssertionError is no longer swallowed — isolation failures now propagate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Verify Issue #2873 regression test coverage after sandbox refactoring

2 participants