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

Some tests in System.IO.FileSystem are conditionalized on being run on a FAT32 volume (specifically, that temp is on FAT32 – location of the repo or artifacts folder is not relevant here) https://github.com/dotnet/runtime/blob/7db092a6ed68a5fbf47962c45bb0c1bb965d02c6/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_options.Windows.cs#L61

So I’d expect this library to pass when temp is on FAT32. We certainly should test on FAT32 since we support using .NET against FAT32 volumes. I changed TEMP and TMP env variables to a FAT32 volume and ran this test library. Unsurprisingly because this hasn’t been done in a long time and there are many failures, below are the various failure modes. Presumably we want to fix this so that we have some way to confirm that our IO APIs work fine on FAT32. (In an ideal world, all our tests that use the file system would be known to pass on FAT32, but minimally our IO tests would)

The failures below are

  1. Test uses alternate data streams. Skip on FAT32
  2. Test expects sub second timestamps. Modify to not expect that on FAT32
  3. Test makes a file exceeding FAT32 4GB file limit. Skip on FAT32
  4. Test assumes that latest Windows can delete files with open handles, which is not true on FAT32
failures
  <assembly name="System.IO.FileSystem.Tests.dll" environment="64-bit .NET  [collection-per-class, parallel (8 threads)]" test-framework="xUnit.net 2.4.2.0" run-date="2022-03-12" run-time="10:19:01" total="9280" passed="8350" failed="840" skipped="90" time="63.822" errors="0">
...
<failure exception-type="Xunit.Sdk.ThrowsException">
          <message><![CDATA[Assert.Throws() Failure\r\nExpected: typeof(System.IO.DirectoryNotFoundException)\r\nActual:   typeof(System.IO.IOException): The filename, directory name, or volume label syntax is incorrect. : 'd:\\tmp\\Directory_GetFiles_str_str_so_edwrfevw.rtd\\te:st'\r\n---- System.IO.IOException : The filename, directory name, or volume label syntax is incorrect. : 'd:\\tmp\\Directory_GetFiles_str_str_so_edwrfevw.rtd\\te:st']]></message>
          <stack-trace><![CDATA[   at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
   at System.IO.Enumeration.FileSystemEnumerator`1.Init()
   at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
   at System.IO.Enumeration.FileSystemEnumerableFactory.UserFiles(String directory, String expression, EnumerationOptions options)
   at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
   at System.IO.Directory.GetFiles(String path, String searchPattern, EnumerationOptions enumerationOptions)
   at System.IO.Tests.Directory_GetFiles_str_str_so.GetEntries(String path) in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\Directory\GetFiles.cs:line 156
   at System.IO.Tests.Directory_GetFileSystemEntries_str.<>c__DisplayClass16_0.<InvalidPath_Core>b__0() in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\Directory\GetFileSystemEntries_str.cs:line 217
----- Inner Stack Trace -----
   at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound)
   at System.IO.Enumeration.FileSystemEnumerator`1.Init()
   at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized)
   at System.IO.Enumeration.FileSystemEnumerableFactory.UserFiles(String directory, String expression, EnumerationOptions options)
   at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options)
   at System.IO.Directory.GetFiles(String path, String searchPattern, EnumerationOptions enumerationOptions)
   at System.IO.Tests.Directory_GetFiles_str_str_so.GetEntries(String path) in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\Directory\GetFiles.cs:line 156
   at System.IO.Tests.Directory_GetFileSystemEntries_str.<>c__DisplayClass16_0.<InvalidPath_Core>b__0() in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\Directory\GetFileSystemEntries_str.cs:line 217]]></stack-trace>a


      <test name="System.IO.Tests.File_Copy_str_str_b.WindowsAlternateDataStreamOverwrite(defaultStream: \&quot;\&quot;, alternateStream: \&quot;:bar\&quot;)" type="System.IO.Tests.File_Copy_str_str_b" method="WindowsAlternateDataStreamOverwrite" time="0.0189737" result="Fail">
        <failure exception-type="System.IO.IOException">
          <message><![CDATA[System.IO.IOException : The filename, directory name, or volume label syntax is incorrect. : 'd:\\tmp\\File_Copy_str_str_b_2zbupqah.syf\\WindowsAlternateDataStreamOverwrite_330_58ea8323\\WindowsAlternateDataStreamOverwrite_331_17770b55:bar']]></message>
          <stack-trace><![CDATA[   at System.IO.FileSystem.CopyFile(String sourceFullPath, String destFullPath, Boolean overwrite)
   at System.IO.Tests.File_Copy_str_str_b.Copy(String source, String dest) in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\File\Copy.cs:line 262
   at System.IO.Tests.File_Copy_str_str_b.WindowsAlternateDataStreamOverwrite(String defaultStream, String alternateStream) in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\File\Copy.cs:line 337]]></stack-trace>
        </failure>


     <test name="System.IO.Tests.File_Copy_str_str_b.CopyFileWithData(data: [0x001b], readOnly: True)" type="System.IO.Tests.File_Copy_str_str_b" method="CopyFileWithData" time="0.0117538" result="Fail">
        <failure exception-type="Xunit.Sdk.InRangeException">
          <message><![CDATA[Assert.InRange() Failure\r\nRange:  (3/12/2022 4:19:01 PM - 3/12/2022 4:19:03 PM)\r\nActual: 3/12/2022 4:19:04 PM]]></message>
          <stack-trace><![CDATA[   at System.IO.Tests.File_Copy_str_str.CopyFileWithData(Char[] data, Boolean readOnly) in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\File\Copy.cs:line 151]]></stack-trace>
        </failure>


              <test name="System.IO.Tests.File_OpenSpecial.FileModeOpenOrCreate(streamSpecifier: \&quot;::$DATA\&quot;)" type="System.IO.Tests.File_OpenSpecial" method="FileModeOpenOrCreate" time="0.0060604" result="Fail">
        <failure exception-type="System.IO.IOException">
          <message><![CDATA[System.IO.IOException : The filename, directory name, or volume label syntax is incorrect. : 'd:\\tmp\\File_OpenSpecial_ka1dkj3q.gur\\FileModeOpenOrCreate_159_959b61b8::$DATA']]></message>
          <stack-trace><![CDATA[   at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.File.Open(String path, FileMode mode, FileAccess access)
   at System.IO.Tests.File_OpenSpecial.CreateFileStream(String path, FileMode mode, FileAccess access) in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\File\Open.cs:line 100
   at System.IO.Tests.FileStream_ctor_str_fm_fa.CreateFileStream(String path, FileMode mode) in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\FileStream\ctor_str_fm_fa.cs:line 13
   at System.IO.Tests.FileStream_ctor_str_fm.FileModeOpenOrCreate(String streamSpecifier) in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\FileStream\ctor_str_fm.cs:line 160]]></stack-trace>
        </failure>


             <test name="System.IO.Tests.FileInfo_Open_fm_fa_fs.FileShareDeleteExistingMultipleClients" type="System.IO.Tests.FileInfo_Open_fm_fa_fs" method="FileShareDeleteExistingMultipleClients" time="0.0108056" result="Fail">
        <failure exception-type="Xunit.Sdk.EqualException">
          <message><![CDATA[Assert.Equal() Failure\r\nExpected: True\r\nActual:   False]]></message>
          <stack-trace><![CDATA[   at System.IO.Tests.FileStream_ctor_str_fm_fa_fs.FileShareDeleteExistingMultipleClients() in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\FileStream\ctor_str_fm_fa_fs.delete.cs:line 109]]></stack-trace>
        </failure>
      </test>

   <test name="System.IO.Tests.File_OpenHandle.FileShareDeleteNew" type="System.IO.Tests.File_OpenHandle" method="FileShareDeleteNew" time="0.0015238" result="Fail">
     <failure exception-type="Xunit.Sdk.EqualException">
       <message><![CDATA[Assert.Equal() Failure\r\nExpected: True\r\nActual:   False]]></message>
       <stack-trace><![CDATA[   at System.IO.Tests.FileStream_ctor_str_fm_fa_fs.FileShareDeleteNew() in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\FileStream\ctor_str_fm_fa_fs.delete.cs:line 23]]></stack-trace>
     </failure>
   </test>

      <test name="System.IO.Tests.File_GetSetTimes.SetDateTimeMax" type="System.IO.Tests.File_GetSetTimes" method="SetDateTimeMax" time="0.0025802" result="Fail">
        <failure exception-type="System.IO.IOException">
          <message><![CDATA[System.IO.IOException : The parameter is incorrect. : 'd:\\tmp\\File_GetSetTimes_3px4x4pa.og3\\SetDateTimeMax_166_883fe965']]></message>
          <stack-trace><![CDATA[   at System.IO.FileSystem.SetFileTime(String fullPath, Boolean asDirectory, Int64 creationTime, Int64 lastAccessTime, Int64 lastWriteTime, Int64 changeTime, UInt32 fileAttributes)
   at System.IO.FileSystem.SetLastWriteTime(String fullPath, DateTimeOffset time, Boolean asDirectory)
   at System.IO.File.SetLastWriteTimeUtc(String path, DateTime lastWriteTimeUtc)
   at System.IO.Tests.File_GetSetTimes.SetDateTimeMax() in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\File\GetSetTimes.cs:line 170]]></stack-trace>
        </failure>

  <failure exception-type="System.IO.IOException">
    <message><![CDATA[System.IO.IOException : There is not enough space on the disk. : 'd:\\tmp\\LargeFileTests_hkwm0evp.odb\\NoInt32OverflowInTheBufferingLogic_35_9e60fcce']]></message>
    <stack-trace><![CDATA[   at System.IO.Strategies.BufferedFileStreamStrategy.FlushWrite()
at System.IO.Strategies.BufferedFileStreamStrategy.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.FileSystem.Tests.LargeFileTests.NoInt32OverflowInTheBufferingLogic() in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\LargeFileTests.cs:line 47]]></stack-trace>
  </failure>

   <test name="System.IO.Tests.File_Copy_str_str_b.CopyFileWithData(data: ['ÿ', 0x0091, 'f', 'f', 'Æ', ...], readOnly: True)" type="System.IO.Tests.File_Copy_str_str_b" method="CopyFileWithData" time="0.0178819" result="Fail">
     <failure exception-type="Xunit.Sdk.InRangeException">
       <message><![CDATA[Assert.InRange() Failure\r\nRange:  (3/12/2022 4:19:01 PM - 3/12/2022 4:19:03 PM)\r\nActual: 3/12/2022 4:19:04 PM]]></message>
       <stack-trace><![CDATA[   at System.IO.Tests.File_Copy_str_str.CopyFileWithData(Char[] data, Boolean readOnly) in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\File\Copy.cs:line 151]]></stack-trace>
     </failure>
   </test>


   <test name="System.IO.Tests.File_GetSetTimes.SetUptoNanoseconds" type="System.IO.Tests.File_GetSetTimes" method="SetUptoNanoseconds" time="0.0027906" result="Fail">
     <failure exception-type="Xunit.Sdk.EqualException">
       <message><![CDATA[Assert.Equal() Failure\r\nExpected: 2022-03-12T17:19:54.4348787Z\r\nActual:   2022-03-12T17:19:56.0000000Z]]></message>
       <stack-trace><![CDATA[   at System.IO.Tests.File_GetSetTimes.SetUptoNanoseconds() in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\File\GetSetTimes.cs:line 157]]></stack-trace>
     </failure>
   </test>

On Unix one can make an in-memory FAT32 volume to test on like this, but I don’t know how to do that on Windows.

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 2
  • Comments: 22 (22 by maintainers)

Most upvoted comments

@adamsitnik oh yeah, I was supposed to change TEMP and TMP for the user profile. I changed the system variables. That fixed it, thank you.

@Danyy427 sure, you’re welcome to have it. Suggestion: start with a small PR to make sure you’re on the right track.

“CreateSymbolicLink -> IOException Incorrect function” I am aware of this and am forced to depend on it. Changing the error message is a good idea but I’m catching it by HResult.

Noticed that FileSystem.CreateSymbolicLink throws “IOException Incorrect function. : ‘…path…’” when on FAT32. I’m not sure whether that was expected, but it seems reasonable ish message? @Jozkee

FAT32 doesn’t support symlinks, only NTFS if you are on Windows. Currently there is no condition on Symbolic Link tests that prevents them from running on such file system, we should probably address that.

Right, my comment was about the message. We could in theory say “Symbolic links are not supported on this file system.” or just “Could not create symbolic link.” instead of getting the OS message. My care level is low though.

Maybe we could put a virtual hard drive/ISO file in runtime-assets that has a FAT32 file system and have a test leg use a mounted copy of that?