Repository navigation
Description
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)
runtime/src/libraries/System.IO.FileSystem/tests/FileStream/ctor_options.Windows.cs
Line 61 in 7db092a
| public static bool IsFat32 |
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
- Test uses alternate data streams. Skip on FAT32
- Test expects sub second timestamps. Modify to not expect that on FAT32
- Test makes a file exceeding FAT32 4GB file limit. Skip on FAT32
- 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: \"\", alternateStream: \":bar\")" 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: \"::$DATA\")" 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.
Activity
danmoseley commentedon Mar 12, 2022
It occurs to me that these tests of course ought to pass on Linux against FAT32.
jkoritzinsky commentedon 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 commentedon Mar 12, 2022
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 commentedon Mar 14, 2022
@danmoseley I totally agree with you, I've added this issue to #54495.
deeprobin commentedon Mar 15, 2022
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 commentedon Mar 15, 2022
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 commentedon Mar 15, 2022
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 commentedon Mar 16, 2022
Forgot to reset the variables so I accidentally ran all the tests on FAT32.
Not much else of note
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 commentedon Mar 16, 2022
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 commentedon Mar 16, 2022
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 commentedon Mar 22, 2022
"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 commentedon Mar 22, 2022
@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 commentedon Mar 23, 2022
Nope! I use magic readonly variables. https://github.com/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.
danmoseley commentedon May 10, 2022
@Danyy427 sure, you're welcome to have it. Suggestion: start with a small PR to make sure you're on the right track.
adamsitnik commentedon May 17, 2022
@Danyy427 something is wrong:
for some reason the test project is not using your FAT32 drive
adamsitnik commentedon May 17, 2022
Hmm I can see that most the tests are using
FileCleanupTestBase.GetTestFilePath()which uses
Path.GetTempPath():runtime/src/libraries/Common/tests/TestUtilities/System/IO/FileCleanupTestBase.cs
Line 26 in 847231b
which performs the
GetTempPathWsys-callruntime/src/libraries/System.Private.CoreLib/src/System/IO/Path.Windows.cs
Line 157 in 215b39a
which is documented to use the environment variables you have mentioned:
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?
danmoseley commentedon May 17, 2022
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.