test: make path-handling tests pass on Windows runners#88
Merged
Conversation
Three tests fail when the suite is run on Windows even though the
underlying behaviour is correct on both platforms — the failures are
test-side platform assumptions, not application bugs. Linux CI is
unaffected; this is purely a quality-of-life fix for contributors who
run pytest on Windows.
1. test_backtest_runner_security.py — rce path interpolation
----------------------------------------------------------
Both ``test_signal_engine_rejects_top_level_execution`` and
``test_signal_engine_rejects_class_level_execution`` write a
``signal_engine.py`` whose source contains the pytest tmp_path
formatted into an ``os.system('touch ...')`` call. On Windows,
tmp_path looks like ``C:\Users\teera\AppData\Local\Temp\...``;
interpolated into a single-quoted Python string literal, the leading
``\U`` is interpreted as a (truncated) unicode escape and ``ast.parse``
raises ``SyntaxError`` before the security scrubber under test ever
runs. Switching to ``Path.as_posix()`` produces forward-slash paths
that survive Python source escaping intact while pointing at the same
filesystem location on every OS.
2. test_loop_helpers.py — absolute-path preservation
--------------------------------------------------
``test_preserves_absolute_run_dir`` passed the literal
``/var/tmp/custom_run`` and expected it back unchanged.
``_normalize_tool_run_dir`` calls ``Path.is_absolute()``, which on
Windows returns False for a bare drive-less path — so the function
correctly treats the input as relative and joins it with
``memory_run_dir``. The test was wrong, not the function: it asserted
POSIX semantics on a cross-platform helper. Resolving the input
through ``os.path.abspath`` before handing it to the function
produces the platform's actual absolute form (``/var/tmp/custom_run``
on POSIX, ``C:\var\tmp\custom_run`` on Windows) and the assertion now
holds on both.
Verified locally: the targeted three now pass; the full pytest sweep
goes from "3 failed, 863 passed" on main to "866 passed, 0 failed".
No production code is touched.
This was referenced May 10, 2026
Collaborator
|
Thanks for the focused Windows compatibility fix. I verified the targeted path-handling tests locally in a combined merge gate, and CI was already green, so this is now merged. |
7 tasks
ykykj
pushed a commit
to ykykj/Vibe-Trading
that referenced
this pull request
May 23, 2026
Empirical end-to-end verification on a real run revealed the dispatch
in fetch_grounding_data was wrong:
loader_cls = resolve_loader(code) # resolve_loader takes a market key
loader = loader_cls() # resolve_loader already returns
# a ready instance, not a class
So a real call with code="NVDA.US" produced
"No available data source for market 'NVDA.US'. Tried: []." — the
fallback chain table is keyed by market type ("us_equity",
"hk_equity", "crypto", ...), not by raw symbol shape.
The unit tests passed only because they monkey-patched resolve_loader
to a `lambda code: lambda: _StubLoader(...)` that happened to satisfy
both the wrong call site and the wrong return-type expectation. A
useful reminder that mock-shaped tests can hide real interface bugs.
Fix
---
- Import the same `_detect_market` runner.py uses for source routing
and feed its output to `resolve_loader`. The private import is a
reasonable pragmatic choice — there is no public equivalent today,
and replicating the regex table in two places would invite drift.
- Drop the `loader_cls()` instantiation step; `resolve_loader` already
returns a ready loader instance.
Test
----
Updated `test_fetch_returns_normalized_bars` to assert the call is
routed through `"us_equity"` (captured via a stub `resolve_loader`).
This pins the contract: a regression that passes the raw code as the
market key, or rewrites the helper so dispatch goes elsewhere, will
fire here instead of waiting for someone to actually run a swarm.
Verified with the local pipeline:
NVDA.US latest close = $215.20 on 2026-05-08 (7 bars, yfinance)
i.e. the same number this PR was supposed to make available to the
worker prompt, instead of the empty block the original commit
silently produced.
`pytest agent/tests/test_swarm_grounding.py -v` -> 12/12 pass.
Full sweep at the same baseline (877 passed, 3 pre-existing Windows-
specific failures untouched, separately addressed in HKUDS#88).
longmfe
pushed a commit
to longmfe/Vibe-Trading-Mars
that referenced
this pull request
Jul 14, 2026
…ompat test: make path-handling tests pass on Windows runners
longmfe
pushed a commit
to longmfe/Vibe-Trading-Mars
that referenced
this pull request
Jul 14, 2026
Empirical end-to-end verification on a real run revealed the dispatch
in fetch_grounding_data was wrong:
loader_cls = resolve_loader(code) # resolve_loader takes a market key
loader = loader_cls() # resolve_loader already returns
# a ready instance, not a class
So a real call with code="NVDA.US" produced
"No available data source for market 'NVDA.US'. Tried: []." — the
fallback chain table is keyed by market type ("us_equity",
"hk_equity", "crypto", ...), not by raw symbol shape.
The unit tests passed only because they monkey-patched resolve_loader
to a `lambda code: lambda: _StubLoader(...)` that happened to satisfy
both the wrong call site and the wrong return-type expectation. A
useful reminder that mock-shaped tests can hide real interface bugs.
Fix
---
- Import the same `_detect_market` runner.py uses for source routing
and feed its output to `resolve_loader`. The private import is a
reasonable pragmatic choice — there is no public equivalent today,
and replicating the regex table in two places would invite drift.
- Drop the `loader_cls()` instantiation step; `resolve_loader` already
returns a ready loader instance.
Test
----
Updated `test_fetch_returns_normalized_bars` to assert the call is
routed through `"us_equity"` (captured via a stub `resolve_loader`).
This pins the contract: a regression that passes the raw code as the
market key, or rewrites the helper so dispatch goes elsewhere, will
fire here instead of waiting for someone to actually run a swarm.
Verified with the local pipeline:
NVDA.US latest close = $215.20 on 2026-05-08 (7 bars, yfinance)
i.e. the same number this PR was supposed to make available to the
worker prompt, instead of the empty block the original commit
silently produced.
`pytest agent/tests/test_swarm_grounding.py -v` -> 12/12 pass.
Full sweep at the same baseline (877 passed, 3 pre-existing Windows-
specific failures untouched, separately addressed in HKUDS#88).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
agent/tests/— no production code changes.3 failed, 863 passedto866 passed, 0 failed.Why
A Windows contributor running
pytest --ignore=agent/tests/e2e_backtest --tb=short -qagainstmainhits these three failures:Linux CI is unaffected, so the failures didn't surface in #80 / #82 / etc. The behaviour the tests exercise is correct on both platforms; only the test inputs make POSIX-specific assumptions.
What was actually wrong
1.
test_backtest_runner_security.py— RCE path interpolationBoth failing tests build a
signal_engine.pywhose source containspytest'stmp_pathformatted into anos.system('touch ...')call. On Windowstmp_pathresolves to e.g.C:\Users\teera\AppData\Local\Temp\pytest-25\.... Interpolated into a single-quoted Python string literal, the leading\Uis interpreted as a (truncated) unicode escape:ast.parseraisesSyntaxErrorbefore the security scrubber under test ever runs — so the test fails for the wrong reason on Windows, while passing on Linux because the path uses forward slashes there.Fix: switch the interpolation to
Path.as_posix(). Forward-slash paths survive Python source escaping intact while still pointing at the same filesystem location on every OS, so the scrubber gets a chance to see the actual class- / top-level statement and reject it as the test originally intended.2.
test_loop_helpers.py::TestNormalizeToolRunDir::test_preserves_absolute_run_dirThe test passed the literal
"/var/tmp/custom_run"and expected it back unchanged from_normalize_tool_run_dir:_normalize_tool_run_dircallsPath.is_absolute(), which on Windows returnsFalsefor a bare drive-less path. The function then correctly treats the input as relative and joins it withmemory_run_dir, yieldingC:\var\tmp\custom_run. The function is doing the right thing — the test asserted POSIX semantics on a cross-platform helper.Fix: resolve the test input through
os.path.abspathbefore handing it to the function, so the input is the platform's actual absolute form (/var/tmp/custom_runon POSIX,C:\var\tmp\custom_runon Windows). The assertion then holds on both.Verification
Before (on Windows / Python 3.12):
After (same machine):
The three previously-failing tests now pass without changing any production code. Linux CI continues to pass (the patches are no-ops on POSIX where forward slashes are already the path separator and
/var/tmp/custom_runis already an absolute path).Test plan
pytest agent/tests/test_backtest_runner_security.py::test_signal_engine_rejects_top_level_execution agent/tests/test_backtest_runner_security.py::test_signal_engine_rejects_class_level_execution agent/tests/test_loop_helpers.py::TestNormalizeToolRunDir::test_preserves_absolute_run_dir -v→ 3 passed.pytest --ignore=agent/tests/e2e_backtest --tb=line -q→866 passed, 0 failed.Path.as_posix()on POSIX is a no-op, andos.path.abspath('/var/tmp/custom_run')returns/var/tmp/custom_rununchanged.Checklist
agent/src/agent/,agent/src/session/,agent/src/providers/) — onlyagent/tests/.CONTRIBUTING.md(Conventional Commit prefixtest:, Google-style docstrings via comments).