Skip to content

Improve FileSystem tests on FAT32 temp volumes#130369

Open
Sahithbasani wants to merge 1 commit into
dotnet:mainfrom
Sahithbasani:sahit/issue-66544-fat32-filesystem-tests
Open

Improve FileSystem tests on FAT32 temp volumes#130369
Sahithbasani wants to merge 1 commit into
dotnet:mainfrom
Sahithbasani:sahit/issue-66544-fat32-filesystem-tests

Conversation

@Sahithbasani

Copy link
Copy Markdown

Fixes #66544

Summary

  • Add shared temp-volume capability helpers for FAT32, large-file support, alternate data streams, and delete-open-file behavior.
  • Adjust System.IO.FileSystem tests so FAT32 temp volumes use safer timestamp expectations and skip capabilities the volume cannot support.
  • Reuse the shared helpers across File, FileStream, Directory, and LargeFile test cases instead of scattered local detection.

Impact

This should reduce false failures when the test temp path is on FAT32, while keeping the existing assertions active on file systems that support the required capabilities.

Validation

  • git diff --check
  • Roslyn syntax sanity check over the edited C# files using the repo-local compiler package
  • Attempted targeted System.IO.FileSystem.Tests project builds, but the builds did not finish within the local time budget on this machine

@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Jul 8, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

@Sahithbasani

Copy link
Copy Markdown
Author

@dotnet-policy-service agree

@Sahithbasani
Sahithbasani marked this pull request as ready for review July 9, 2026 23:16

@jeffhandley jeffhandley left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Note

This review was generated by the holistic code review workflow being iterated on as part of #130339. Please treat its findings as assistive input for human review.

Holistic Review

Motivation: The linked issue is a real test-infrastructure gap: System.IO.FileSystem.Tests has explicit FAT32 coverage intent, and the existing tests assume NTFS-like ADS, large-file, delete-pending, and timestamp behavior. Improving these tests is justified as long as the changes preserve coverage on capable file systems.

Approach: Centralizing temp-volume capability probes in FileSystemTest is a good direction, and the ADS / large-file / delete-open-file adjustments are narrowly targeted to the temp volume actually used by FileCleanupTestBase. I have one unresolved FAT timestamp concern that needs someone with a FAT32 run (or area expertise) to confirm.

Summary: ⚠️ Needs Human Review. The change looks mostly well-scoped, but a human should focus on whether the timestamp tests still assert exact last-access times on FAT/FAT32 even though Windows documents FAT access time as date-only. Please also sanity-check whether symlink tests remain appropriately skipped on FAT32 when MountHelper.CanCreateSymbolicLinks is evaluated in elevated Windows environments.


Detailed Findings

⚠️ Test Quality — FAT32 last-access timestamp granularity may still be over-asserted

BaseGetSetTimes<T>.SettingUpdatesPropertiesCore now chooses an even second on FAT32 (Base/BaseGetSetTimes.cs:20-24, :78), which addresses FAT write-time's 2-second resolution, and File/GetSetTimes.cs:116-127 still includes both local and UTC last-access time setters/getters in the exact round-trip assertions. However, the Win32 file-time documentation says FAT write time has 2-second resolution while access time has 1-day resolution (it is really the access date): https://learn.microsoft.com/windows/win32/sysinfo/file-times.

If FAT32 returns last-access times with the time-of-day truncated, SettingUpdatesProperties, SettingUpdatesPropertiesAfterAnother, and the symlink variants will still fail on FAT32 despite the new MilliSecondTemporalResolution/even-second handling. I did not run against a FAT32 temp volume, so this is a human-review item rather than a firm blocker, but the central FAT32 timestamp assumption should be verified before relying on this PR to make the test suite pass there.

⚠️ Test Scope — symlink capability may still be filesystem-sensitive on FAT32

The changed timestamp base class still runs SettingPropertiesOnSymlink under [ConditionalTheory(typeof(MountHelper), nameof(MountHelper.CanCreateSymbolicLinks))] (Base/BaseGetSetTimes.cs:119-123). MountHelper.CanCreateSymbolicLinks probes by attempting to create links under Path.GetTempPath(), but its Windows failure path asserts that a privileged process should not fail (src/libraries/Common/tests/System/IO/ReparsePointUtilities.cs:62-80), while the linked issue discussion notes FAT32 itself does not support symlinks.

This may already skip correctly for normal unelevated FAT32 runs, but it is worth a human check for elevated Windows / Developer Mode scenarios: unsupported filesystem capability should ideally skip tests, not fail during condition evaluation.

✅ Test Quality — capability skips are mostly narrow and preserve existing coverage elsewhere

The new SupportsAlternateDataStreams, TempPathSupportsLargeFiles, IsTempPathOnFat32, and DeletesOpenFileNameImmediately helpers are based on the same Path.GetTempPath() root used by FileCleanupTestBase, so the conditions track the volume under test rather than hardcoding a drive. ADS tests remain active when a live probe succeeds, large-file tests are skipped only for FAT32, and delete-open-file expectations remain unchanged for non-FAT32 Windows versions.

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Workflow state for the Holistic Review Orchestrator.

{
  "version": 5,
  "last_dispatched_commit": "346a22802976bfa6c9749850b1329923b2cd1ac2",
  "last_dispatched_base_ref": "main",
  "last_dispatched_base_sha": "7abe5f60c079129a57c358451cfe01ee198fa40f",
  "last_reviewed_commit": "346a22802976bfa6c9749850b1329923b2cd1ac2",
  "last_reviewed_base_ref": "main",
  "last_reviewed_base_sha": "7abe5f60c079129a57c358451cfe01ee198fa40f",
  "last_recorded_worker_run_id": "29686398719",
  "review_attempt_commit": "",
  "review_attempt_base_ref": "",
  "review_attempt_count": 0,
  "max_review_attempts": 5,
  "review_history_format": "holistic-review-disclosure-v1",
  "review_history": [
    {
      "commit": "346a22802976bfa6c9749850b1329923b2cd1ac2",
      "review_id": 4730735805
    }
  ]
}

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Holistic Review

Motivation: Fixes #66544. The System.IO.FileSystem tests generate hundreds of false failures when the temp path resides on a FAT32 volume, because they assume capabilities FAT32 lacks: alternate data streams (ADS), sub-second timestamp resolution, files larger than 4 GB, and immediate deletion of files with open handles. The goal is to make these tests pass on FAT32 while keeping the assertions active on file systems that do support those capabilities.

Approach: The PR centralizes temp-volume capability detection into FileSystemTest via lazily-evaluated static helpers (TempDriveFormat, IsTempPathOnFat32, TempPathSupportsLargeFiles, DeletesOpenFileNameImmediately, SupportsAlternateDataStreams). It then replaces scattered, local FAT32/Windows detection (notably the duplicated P/Invoke GetVolumeInformation block in ctor_options.Windows.cs) with these shared helpers. ADS-dependent theories are converted to ConditionalTheory/ConditionalFact gated on SupportsAlternateDataStreams; timestamp tests widen tolerance and use a FAT32-safe seconds value; large-file tests are gated on TempPathSupportsLargeFiles; and open-handle delete tests use DeletesOpenFileNameImmediately. This is a focused, test-only change with no product code impact.

Summary: This is a well-scoped, correct improvement that directly addresses the four failure categories enumerated in the issue and removes duplicated interop code in favor of a single shared detection point. SupportsAlternateDataStreams is a sound design choice: it probes actual behavior (attempt to write/read an ADS) rather than inferring from the volume format, which is more robust than a pure FAT32 check. The lazy caching avoids repeated DriveInfo/probe cost, and the probe cleans up its temp file in a finally. I have one non-blocking inline note about exception-type exactness in InvalidPath_Core. Overall this looks good to merge; verify via CI that the affected test assemblies still build and pass on the standard (non-FAT32) NTFS/Unix legs, since the change touches many [Theory][ConditionalTheory] attribute conversions.

Detailed Findings

No blocking issues. One minor, non-actionable observation left inline on Directory/GetFileSystemEntries_str.cs regarding Assert.Throws<IOException> matching the exact type rather than derived types when SupportsAlternateDataStreams is false.

Note

This review was generated by this repository's Holistic Review agentic workflow to complement the built-in Copilot review.

Generated by Holistic Review · 92 AIC · ⌖ 10.7 AIC · ⊞ 10K

Assert.Throws<DirectoryNotFoundException>(() => GetEntries(badPath));
}
else
{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Assert.Throws<IOException> matches only the exact IOException type, not derived types like DirectoryNotFoundException. That is fine here given the observed FAT32 behavior (a plain IOException "...syntax is incorrect"), but it makes the assertion sensitive to the exact runtime exception type. Since SupportsAlternateDataStreams is a temp-volume probe rather than a strict "is FAT32" check, a non-FAT32 Windows configuration that happens to lack ADS support would also take this branch and would fail if it threw DirectoryNotFoundException instead. Consider Assert.ThrowsAny<IOException> to be robust to derived types, or gate specifically on IsTempPathOnFat32 to mirror the failure mode described in the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.IO community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.IO.FileSystem tests fail all over with temp on Fat32

2 participants