Test: pin filename edge cases in the shared artifact-service conformance suite - #765
Open
AmaadMartin wants to merge 1 commit into
Open
Test: pin filename edge cases in the shared artifact-service conformance suite#765AmaadMartin wants to merge 1 commit into
AmaadMartin wants to merge 1 commit into
Conversation
…ce suite The shared conformance suite only exercised plain filenames, so the three BaseArtifactService backends could diverge on legal-but-unusual names without any test noticing. Add a 'filename edge cases' block covering a leading dot, an interior space, a trailing dot and a nested path. Test-only change. No file under core/src is touched.
This was referenced Aug 7, 2026
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.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
Closes: #issue_number
Related: #issue_number
Problem:
runArtifactServiceTests()is the conformance suite that everyBaseArtifactServicebackend must satisfy, but it only exercises plain filenames. The three backends store a filename very differently:InMemoryArtifactServiceescapes it into aRecordkey,GcsArtifactServicemakes it a segment of an object name, andFileArtifactServicemaps it onto a real directory. They can therefore diverge on a legal-but-unusual name and no test notices.Solution: I added one
filename edge casesblock to the shared suite. It pins a save -> load round trip and the exactlistArtifactKeysstring for four names, plus an exact-set assertion that the four stay distinct in one session. This is a test-only change; no file undercore/src/is touched.The four names and why each was chosen:
.hidden.txt..prefix the file backend's containment guard rejectsmy report.txtencodeURIComponentin memory and become a real directory name on disktrailing.dot.nested/dir/report.txt%2Fin memoryTwo cases are deliberately excluded because the backends genuinely disagree on them today, so a shared test cannot pin them:
..-prefixed names such as..hidden.txt.FileArtifactService.getArtifactDir()rejects them while the other two accept them. That over-rejection is a source fix, tracked separately.cleanFilename.trim()collapses'a.txt',' a.txt'and'a.txt 'onto one artifact directory, while the other two backends keep them apart. That needs a product decision, not a test.The set assertion sorts both sides (
[...keys].sort()).GcsArtifactServicesorts withlocaleCompareand the other two use the default sort, so collation is not part of the contract, but the exact set is.Collision check: I listed every open PR on the fork and diffed the artifact-adjacent ones (#760, #658, #661, #520). None touches
core/test/artifacts/artifact_service_test_utils.ts, so there is no overlap and this branch is based onmain.Testing Plan
Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes.
Unit Tests:
[x] I have added or updated unit tests for my change.
[x] All unit tests pass locally.
The new block runs three times, once per backend: 15 new test cases in total.
Proof the tests can fail. There is no source fix to revert here, so I broke each backend in turn, confirmed the new block went red, then reverted. Every backend is caught by at least one case.
InMemoryArtifactServicedecodeURIComponentinlistArtifactKeysexpected [ 'my%20report.txt' ] to include 'my report.txt'(4 failed)GcsArtifactServicegetFileNameFromPathreturnsparts[0]expected [ 'nested' ] to include 'nested/dir/report.txt'(3 failed)FileArtifactServicerelative.startsWith('.')Error: Artifact filename .hidden.txt escapes storage directory.(2 failed)The
FileArtifactServicemutation is the sharpest signal: it fails only the new block, and every pre-existing test in that file still passes.Other gates, run on the pushed commit:
npm run ts:checkreports 287 errors in 42 files both with and without this change. Those errors are pre-existing and unrelated.CI. The three artifact suites are green on all three runner platforms. Every leg of every attempt reports
core/test/artifacts/file_artifact_service_test.ts (47 tests),gcs_artifact_service_test.ts (38 tests)andin_memory_artifact_service_test.ts (32 tests)passing. The trailing-dot case therefore passes on Windows, which is where it had platform exposure.The
run-testsmatrix is nonetheless red, on a test this change does not touch.tests/integration/app_loader/app_loader_test.ts:82times out at its 40000ms budget. It is the only failing test in every red run. I re-ran the matrix twice: it failed on macOS, then on macOS again, then on Windows while macOS passed.ubuntu-latestpassed every time.This flake is pre-existing. The identical test fails the same way on upstream
mainwith no PR changes, in the macOS leg of validation run 31061656732 (commit13f9995c). ItsbeforeAllrunsnpm installin a fixture and the test body then compiles TypeScript throughAgentLoader.listApps(), which is much slower on the Windows and macOS runners. I did not change it, because it is unrelated breakage. It is filed as separate work.Manual End-to-End (E2E) Tests:
Not applicable. This change adds no runtime behaviour a user can exercise. To see the new cases, run
npx vitest run --project unit:core core/test/artifacts --reporter=verboseand look forfilename edge casesunder each of the three backends.Cross-platform note: CI runs this suite on Linux, Windows and macOS. The trailing-dot case is the one with platform exposure, because Win32 strips a trailing dot from an on-disk path component. The round trip still holds, since the write and the read share the same normalization and
listArtifactKeysreturns the originalmetadata.fileName. The four base names stay distinct after stripping, so no Windows collision is possible between them.Checklist
[x] I have read the CONTRIBUTING.md document.
[x] I have performed a self-review of my own code.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] I have added tests that prove my fix is effective or that my feature works.
[x] New and existing unit tests pass locally with my changes.