Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
danmoseley opened this issue Mar 12, 2022 · 22 comments
Open

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

danmoseley opened this issue Mar 12, 2022 · 22 comments
Labels
area-System.IO good first issue Issue should be easy to implement, good for first-time contributors help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@danmoseley
Copy link
Member

danmoseley commented Mar 12, 2022

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)

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.

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.IO untriaged New issue has not been triaged by the area owner labels Mar 12, 2022
@ghost
Copy link

ghost commented Mar 12, 2022

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

Issue Details

Some tests in System.IO.FileSystem are conditionalized on being run on a FAT32 volume (specifically, that temp is on FAT32 -- where the repo is is not relevant)

So I'd expect this library to pass when temp is on FAT32. 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

... c__DisplayClass16_0.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.b__0() in D:\git\runtime\src\libraries\System.IO.FileSystem\tests\Directory\GetFileSystemEntries_str.cs:line 217]]>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]]>

 <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]]>

         <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_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]]>

``` ```
Author: danmoseley
Assignees: -
Labels:

area-System.IO, untriaged

Milestone: -

@danmoseley
Copy link
Member Author

It occurs to me that these tests of course ought to pass on Linux against FAT32.

@danmoseley danmoseley added good first issue Issue should be easy to implement, good for first-time contributors help wanted [up-for-grabs] Good issue for external contributors labels Mar 12, 2022
@jkoritzinsky
Copy link
Member

jkoritzinsky commented Mar 12, 2022

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?

@danmoseley
Copy link
Member Author

That's an interesting idea. I also notice ramdisk.inf/ramdisk.sys in the Windows directory, which may be an old SDK sample. didn't try to get it to work.

@adamsitnik
Copy link
Member

@danmoseley I totally agree with you, I've added this issue to #54495.

@adamsitnik adamsitnik removed the untriaged New issue has not been triaged by the area owner label Mar 14, 2022
@deeprobin
Copy link
Contributor

We could create a virtual filesystem for NTFS & FAT32.
(on windows we could mount a temporary drive with the target fs - I think this is on linux also possible)

@danmoseley
Copy link
Member Author

I should add that I don't think this is an urgent/critical problem. There have been very few filesystem specific bugs that I recall (eg this one), FAT32 is not the only other interesting filesystem, and despite these tests apparently not having run for a while, all the failures appear to be simply test issues. If there's a cheap way to work in a new filesystem into the matrix, that would be nice, but not vital and likely not worth doing if it slowed the tests down or made them more fragile.

@deeprobin
Copy link
Contributor

I'm pretty sure it makes file system specific tests slower....
The Windows API is not the fastest after all. I think it would be a slightly larger test setup and you would have to make sure that the virtual disk is destroyed after the test run (or on cancel ^C)

It might be a great experiment for tests that are really file system specific but you have to weigh it up if it's worth investing the time.

Relevant APIs for Windows implementation:

@danmoseley
Copy link
Member Author

danmoseley commented Mar 16, 2022

Forgot to reset the variables so I accidentally ran all the tests on FAT32.

Not much else of note

  1. 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
  2. setting new DateTime(1970, 1, 1, 1, 1, 1) on a FAT32 file fails with "IOException : The parameter is incorrect. : '..path'". Again not unreasonable.
  3. various file system watcher failures due to certain events not firing on FAT32 changes, eg moving between directories

Both 1 and 2 are OS supplied messages, so on Linux against FAT32 they will be some other message.

Not surprisingly most of System.IO.FileSystem.AccessControl.Tests failed.

Nothing of concern though.

@jozkee
Copy link
Member

jozkee commented Mar 16, 2022

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.

@danmoseley
Copy link
Member Author

danmoseley commented Mar 16, 2022

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.

@joshudson
Copy link
Contributor

"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.

@danmoseley
Copy link
Member Author

@joshudson any interest in offering a PR for that message?

Note of course that checking HResult makes your code Windows only. Unless and until this old issue progresses.

@joshudson
Copy link
Contributor

Note of course that checking HResult makes your code Windows only.

Nope! I use magic readonly variables. https:/joshudson/Emet/blob/master/README.md

Anyway I'm not going to make a PR because I don't want to deal with the localization code.

@Danyy427
Copy link
Contributor

Danyy427 commented May 10, 2022

@danmoseley is this one still open?

@danmoseley
Copy link
Member Author

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

@Danyy427
Copy link
Contributor

@danmoseley I created a FAT32 volume on my windows machine and moved TEMP and TMP variables. The tests did pass with a bunch of skips. Weren't they supposed to fail?

Microsoft (R) Build Engine version 17.3.0-preview-22226-04+f15ed2652 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  Microsoft.Interop.SourceGeneration -> D:\Runtime\runtime\artifacts\bin\Microsoft.Interop.SourceGeneration\Debug\netst
  andard2.0\Microsoft.Interop.SourceGeneration.dll
  LibraryImportGenerator -> D:\Runtime\runtime\artifacts\bin\LibraryImportGenerator\Debug\netstandard2.0\Microsoft.Inte
  rop.LibraryImportGenerator.dll
  TestUtilities -> D:\Runtime\runtime\artifacts\bin\TestUtilities\Debug\net6.0\TestUtilities.dll
  System.Diagnostics.EventLog.Messages -> D:\Runtime\runtime\artifacts\bin\System.Diagnostics.EventLog.Messages\Debug\n
  etstandard2.0\System.Diagnostics.EventLog.Messages.dll
  System.Runtime -> D:\Runtime\runtime\artifacts\bin\System.Runtime\ref\Debug\net7.0\System.Runtime.dll
  System.Collections.NonGeneric -> D:\Runtime\runtime\artifacts\bin\System.Collections.NonGeneric\ref\Debug\net7.0\Syst
  em.Collections.NonGeneric.dll
  System.Security.Claims -> D:\Runtime\runtime\artifacts\bin\System.Security.Claims\ref\Debug\net7.0\System.Security.Cl
  aims.dll
  System.Security.Principal.Windows -> D:\Runtime\runtime\artifacts\bin\System.Security.Principal.Windows\ref\Debug\net
  7.0\System.Security.Principal.Windows.dll
  System.Security.AccessControl -> D:\Runtime\runtime\artifacts\bin\System.Security.AccessControl\ref\Debug\net7.0\Syst
  em.Security.AccessControl.dll
  System.IO.FileSystem.AccessControl -> D:\Runtime\runtime\artifacts\bin\System.IO.FileSystem.AccessControl\ref\Debug\n
  et7.0\System.IO.FileSystem.AccessControl.dll
  System.IO.FileSystem.AccessControl -> D:\Runtime\runtime\artifacts\bin\System.IO.FileSystem.AccessControl\Debug\net7.
  0-windows\System.IO.FileSystem.AccessControl.dll
  System.Diagnostics.EventLog -> D:\Runtime\runtime\artifacts\bin\System.Diagnostics.EventLog\ref\Debug\net7.0\System.D
  iagnostics.EventLog.dll
  System.Diagnostics.EventLog -> D:\Runtime\runtime\artifacts\bin\System.Diagnostics.EventLog\Debug\net7.0-windows\Syst
  em.Diagnostics.EventLog.dll
  System.ServiceProcess.ServiceController -> D:\Runtime\runtime\artifacts\bin\System.ServiceProcess.ServiceController\r
  ef\Debug\net7.0\System.ServiceProcess.ServiceController.dll
  System.ServiceProcess.ServiceController -> D:\Runtime\runtime\artifacts\bin\System.ServiceProcess.ServiceController\D
  ebug\net7.0-windows\System.ServiceProcess.ServiceController.dll
  StreamConformanceTests -> D:\Runtime\runtime\artifacts\bin\StreamConformanceTests\Debug\net7.0\StreamConformanceTests
  .dll
  System.IO.FileSystem.Tests -> D:\Runtime\runtime\artifacts\bin\System.IO.FileSystem.Tests\Debug\net7.0-windows\System
  .IO.FileSystem.Tests.dll
  ----- start Tue 05/17/2022 19:46:49.61 ===============  To repro directly: ==========================================
  ===========
  pushd D:\Runtime\runtime\artifacts\bin\System.IO.FileSystem.Tests\Debug\net7.0-windows\
  "D:\Runtime\runtime\artifacts\bin\testhost\net7.0-windows-Debug-x64\dotnet.exe" exec --runtimeconfig System.IO.FileSy
  stem.Tests.runtimeconfig.json --depsfile System.IO.FileSystem.Tests.deps.json xunit.console.dll System.IO.FileSystem.
  Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing
  popd
  ===========================================================================================================
    Discovering: System.IO.FileSystem.Tests (method display = ClassAndMethod, method display options = None)
    Discovered:  System.IO.FileSystem.Tests (found 3688 of 4077 test cases)
    Starting:    System.IO.FileSystem.Tests (parallel test collections = on, max threads = 16)
      System.IO.Tests.Directory_EnumFiles_str_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_GetFileSystemInfos_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_EnumFiles_str_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_GetFiles_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_CreateDirectory.PathWithReservedDeviceNameAsPath_ThrowsDirectoryNotFoundException [SKIP
  ]
        Condition(s) not met: "ReservedDeviceNamesAreBlocked"
      System.IO.Tests.File_Create_str_i_fo.CaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_GetFiles_str_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_GetSetTimes.TimesIncludeMillisecondPart_LowTempRes [SKIP]
        Condition(s) not met: "LowTemporalResolution"
      System.IO.Tests.DirectoryInfo_EnumerateFiles_str_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_Exists.DoesCaseSensitiveComparisons [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_EnumFSI_str_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_GetDirectories_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_EnumerateFiles_str_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_EnumFSE_str_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_GetFileSystemInfos_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.FileInfo_Exists.CaseSensitivity [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_Create.RootPath_AppContainer [SKIP]
        Condition(s) not met: "IsInAppContainer"
      System.IO.Tests.FileInfo_GetSetTimes.CopyToMillisecondPresent_LowTempRes [SKIP]
        Condition(s) not met: "LowTemporalResolution"
      System.IO.Tests.FileInfo_GetSetTimes.MoveToMillisecondPresent_LowTempRes [SKIP]
        Condition(s) not met: "LowTemporalResolution"
      System.IO.Tests.FileInfo_GetSetTimes.CopyToNanosecondsPresent_LowTempRes [SKIP]
        Condition(s) not met: "LowTemporalResolution"
      System.IO.Tests.FileInfo_GetSetTimes.TimesIncludeMillisecondPart_LowTempRes [SKIP]
        Condition(s) not met: "LowTemporalResolution"
      System.IO.Tests.Directory_CreateDirectory.PathWithReservedDeviceNameAsExtendedPath [SKIP]
        Condition(s) not met: "ReservedDeviceNamesAreBlocked"
      System.IO.Tests.Directory_CreateDirectory.RootPath_AppContainer [SKIP]
        Condition(s) not met: "IsInAppContainer"
      System.IO.Tests.DirectoryInfo_Create.PathWithReservedDeviceNameAsPath_ThrowsDirectoryNotFoundException [SKIP]
        Condition(s) not met: "ReservedDeviceNamesAreBlocked"
      System.IO.Tests.DirectoryInfo_Create.PathWithReservedDeviceNameAsExtendedPath [SKIP]
        Condition(s) not met: "ReservedDeviceNamesAreBlocked"
      System.IO.Tests.DirectoryInfo_Exists.CaseSensitivity [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.File_Exists.DoesCaseSensitiveComparisons [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.PathDirectory_Exists.DoesCaseSensitiveComparisons [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_EnumFSE_str_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.FileInfo_Create.CaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_GetFileSystemEntries_str_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_GetDirectories_str_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_ToString.ParentToString_Framework [SKIP]
        Condition(s) not met: "IsNetFramework"
      System.IO.Tests.Directory_EnumDir_str_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_EnumDir_str_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_GetDirectories_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_GetFileSystemEntries_str_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_GetFiles_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_EnumFSE_str_str_so_alldirs.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.File_Create_str_i.CaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_EnumFSI_str_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_GetFileSystemEntries_str_str_so_alldirs.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_GetDirectories_str_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.DirectoryInfo_EnumDir_str_str.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_EnumDir_str_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.Directory_GetFiles_str_str_so.SearchPatternCaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.File_Create_str.CaseSensitive [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.File_GetSetTimes.TimesIncludeMillisecondPart_LowTempRes [SKIP]
        Condition(s) not met: "LowTemporalResolution"
      System.IO.Tests.Directory_GetSetTimes.TimesIncludeMillisecondPart_LowTempRes [SKIP]
        Condition(s) not met: "LowTemporalResolution"
      System.IO.Tests.PathFile_Exists.DoesCaseSensitiveComparisons [SKIP]
        Condition(s) not met: "IsCaseSensitiveOS"
      System.IO.Tests.FileStream_ctor_options.WhenFileIsTooLargeTheErrorMessageContainsAllDetails [SKIP]
        Condition(s) not met: "IsFat32"
      System.IO.Tests.FileInfo_Open_options.WhenFileIsTooLargeTheErrorMessageContainsAllDetails [SKIP]
        Condition(s) not met: "IsFat32"
      System.IO.Tests.File_Open_str_options.WhenFileIsTooLargeTheErrorMessageContainsAllDetails [SKIP]
        Condition(s) not met: "IsFat32"
      System.IO.Tests.File_OpenHandle.WhenFileIsTooLargeTheErrorMessageContainsAllDetails [SKIP]
        Condition(s) not met: "IsFat32"
    Finished:    System.IO.FileSystem.Tests
  === TEST EXECUTION SUMMARY ===
     System.IO.FileSystem.Tests  Total: 8589, Errors: 0, Failed: 0, Skipped: 54, Time: 26.193s
  ----- end Tue 05/17/2022 19:47:19.79 ----- exit code 0 ----------------------------------------------------------

Build succeeded.
    0 Warning(s)
    0 Error(s)

@adamsitnik
Copy link
Member

@Danyy427 something is wrong:

      System.IO.Tests.FileStream_ctor_options.WhenFileIsTooLargeTheErrorMessageContainsAllDetails [SKIP]
        Condition(s) not met: "IsFat32"

for some reason the test project is not using your FAT32 drive

@Danyy427
Copy link
Contributor

Danyy427 commented May 17, 2022

@adamsitnik would I have to do anything besides changing TEMP and TMP variables (and restarting my PC) for the project to start using the new TEMP location specifically? Should I perhaps rebuild the project for example?

@adamsitnik
Copy link
Member

Hmm I can see that most the tests are using FileCleanupTestBase.GetTestFilePath()

which uses Path.GetTempPath():

which performs the GetTempPathW sys-call

while ((result = Interop.Kernel32.GetTempPathW(builder.Capacity, ref builder.GetPinnableReference())) > builder.Capacity)

which is documented to use the environment variables you have mentioned:

The path specified by the TMP environment variable.
The path specified by the TEMP environment variable.
The path specified by the USERPROFILE environment variable.
The Windows directory.

would I have to do anything besides changing TEMP and TMP variables (and restarting my PC)

restarting the PC should not be required, all you need to do is to start a new command prompt

could you print the TMP env var?

echo %TMP%

@Danyy427
Copy link
Contributor

@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.

@danmoseley
Copy link
Member Author

User profile vs system shouldn’t matter. You may have just forgotten to open a fresh command prompt after making the change.
Note that on Unix GetTempPath() reads TMPDIR so if you were doing this for Linux that’s what you would set. Fat32 on Linux is out of scope here.

@jeffhandley jeffhandley added this to the Future milestone Jul 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.IO good first issue Issue should be easy to implement, good for first-time contributors help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

No branches or pull requests

8 participants