-
Notifications
You must be signed in to change notification settings - Fork 5k
Remove PathTooLongException and associated tests. #14124
Remove PathTooLongException and associated tests. #14124
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall we should IMO keep the tests which tests long path. Mainly we want to ensure that the OS APIs are translated into the right exception (should be backward compatible).
The tests won't have fixed file name, but can grow the file name until they hit the OS limit.
Assert.Throws<PathTooLongException>(() => Create(path)); | ||
}); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should keep a test which checks the long path (even though it is "variable" and not known ahead of time).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the OS thinks in this case (with a long segment). It might not consider them too long and just "invalid". 255 is a limit that does vary (sometimes is smaller, but no known bigger cases). We should have a test just to validate they fail, but I'm not too concerned about which exception it is, just that it is consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exception should be compatible with Desktop for compat.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exception should be compatible with Desktop for compat.
It can't be by design.
Windows doesn't always return "TooLong". The whole point of this is to not second-guess the OS. We already get this wrong for some file system formats and we're currently blocking any new ones that might support > 255.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Compat" with this change is we should get an IOException of some sort.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit more detail. "TooLong" from the OS typically has to do with not being able to allocate a string that is large enough. This doesn't necessarily have to happen with a path you pass in, at least not before it fails for other reasons. So you may have \\?\C:\Foo\DoesNotExist\{somesuperlongsegment}
and the error you get may be "DirectoryNotFound" as it navigates the path.
255 as a max isn't always true- we already get it wrong (it is shorter in a number of cases I'm aware of) and there is no technical reason that there can't be existing or new device drivers that support segments that are longer than that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify for this test, are you saying we should add the test back and just expect a different type of IOException?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes- these exceptions may change, but as long as they're some type of IOException we should be ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That means we should have tests growing the path length until an IOException happens, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd keep the tests running, but updated. I don't see PathHelper.Windows.cs, which has PathTooLong in a number of places- you should also be able to stop keeping track of the segment length in there as a result.
Assert.Throws<PathTooLongException>(() => Create(path)); | ||
}); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the OS thinks in this case (with a long segment). It might not consider them too long and just "invalid". 255 is a limit that does vary (sometimes is smaller, but no known bigger cases). We should have a test just to validate they fail, but I'm not too concerned about which exception it is, just that it is consistent.
[ActiveIssue(11687)] | ||
[PlatformSpecific(TestPlatforms.Windows)] | ||
public void DirectoryLongerThanMaxLongPath_ThrowsPathTooLongException() | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These ones should still be throwing the same exception.
[PlatformSpecific(TestPlatforms.Windows)] | ||
public void WindowsSearchPatternLongSegment() | ||
{ | ||
// Create a path segment longer than the normal max of 255 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, on this one I don't care what it throws, just as long as it fails with some sort of IO exception.
{ | ||
string testDir = GetTestFilePath(); | ||
Directory.CreateDirectory(testDir); | ||
Assert.All((IOInputs.GetPathsLongerThanMaxLongPath(GetTestFilePath())), (path) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should continue to throw in some way. I would expect either "too long" or "not found" or possibly "invalid" for any of these long paths. It depends on where they get kicked back in the system.
DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath()); | ||
Assert.Throws<PathTooLongException>(() => Create(Path.Combine(testDir.FullName, new string('a', 300)))); | ||
|
||
//TODO #645: File creation does not yet have long path support on Unix or Windows |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a weird commented out blob. It should just be deleted- it should fail with segments that are this long.
public void LongPath() | ||
{ | ||
DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath()); | ||
Assert.Throws<PathTooLongException>(() => Create(Path.Combine(testDir.FullName, new string('a', 300)))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, should throw something.
|
||
Assert.All(IOInputs.GetPathsLongerThanMaxLongPath(GetTestFilePath()), (path) => | ||
{ | ||
Assert.Throws<PathTooLongException>(() => Move(testFileSource, path)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, some exception
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assert.All(paths, (path) => | ||
{ | ||
Assert.Throws<PathTooLongException>(() => Create(path)); | ||
}); | ||
} | ||
|
||
#endregion | ||
#endregion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You've lost some indenting here apparently
What errors did you actually get back? Specifically in We should validate the HResult is what we expect and/or if it is something "new" that fits one of the existing cases we might want to add it. Specifically I'm wondering if |
Looking through things a bit, one other one I would expect is |
I am trying to debug in VS but having issues. I keep getting inconsistent results, I can do the following:
I used to be able to run the main build:
But now it's failing randomly with:
Then in Visual Studio I can build the solution fine:
But I am seeing "errors" in the files and I see nothing in Test Explorer: I am using Debug build: I looked and it seems like the xUnit test runner VSIX is deprecated and that it should be finding my tests. Any ideas what I am doing wrong? |
Sorry about the delayed response, everyone is OOF with an office move. Unfortunately our debugging experience / instructions are less than optimal at the moment. @weshaggard, am I missing any documentation on this that you are aware of? I'm going to open some issues on documenting and improving the experience (particularly from the IDE). Use the The Test Explorer is not currently usable with CoreFX projects. Right click on the test project you want to debug and set it as the startup project. The filtering isn't quite right so you'll need to tweak things a bit before you can run. If you build the relevant test .builds from the command line you'll get a dump something like the following:
In the debug tab for the properties for the test project you'll see these values. You'll want to tweak the existing command line arguments from
to whatever you get from the command prompt plus
Then you'll be able to set breakpoints and F5 to run/debug. Note that I'm not sure why it won't run the Windows specific tests, I'll look more next week. In the meantime, just pull the attribute while you're testing. The developer guide has instructions that you can go through. |
This is how I debug tests. Make sure VS is on the path (eg use a developer command prompt) then: msbuild thetestproject.csproj /t:buildandtest /p:testdebugger=devenv.exe When Xunit starts it will pop the debugger. First time around it will not guess the correct debug engine, you must open solution properties and change it to the Core debug engine (I am using VS2015) Now set your breakpoints and hit F5. You can Save the solution and open that solution next time and F5 it will just work without need to reset debugger engine or breakpoints. |
@JeremyKuhne thanks for taking the time to write that up, I appreciate it. Setting the build to Windows_Debug did fix the intellisense issue. I also changed the project properties debug tab setting and that is letting me debug in VS. One strange thing I am seeing is that when exceptions are thrown, that I believe are supposed to be thrown, the debugger is displaying and highlighting them. If I continue it's fine and the tests continue to run. Not sure why that is happening. I checked my exception settings and this is what I have: I also see this option: But it seems problematic for times when I want to see that this type of exception was thrown when it shouldn't be. This is making it super slow to debug :) Is there a setting I need to change? Here are some of the Win32Errors I am seeing(sorry I missed the path on the first two): = Directory/GetFileSystemEntries_str_str.cs = File/Create.cs Thanks again for taking the time to walk me through this. |
One more question. What is the process for debugging on other OSes? I see there is a failure in Jenkins:
But I would guess we can't just remote in and check that XML file :) |
@alexperovich can you point to your instructions for debugging a unit test on unix? |
@alexperovich ping? @JeremyKuhne can you please help? The PR is stuck for 2 weeks :( |
@alexperovich @JeremyKuhne ping - the PR is stuck for 1 month :( |
@stephenmichaelf @danmosemsft Sorry for the delay. I was on vacation. Instructions for debugging on unix are here: https://github.com/dotnet/corefx/blob/master/Documentation/debugging/unix-instructions.md |
@dotnet-bot test this please |
Kicking the CI again as the results were deleted. @stephenmichaelf Sorry about the holiday delays. For first chance exceptions you want to have them off generally- this case in particular is a pain as the ones you care about are hit all the time. What I would do is set a breakpoint in the code that converts the windows error and at the beginning of the tests you care about. Disable/Enable the the error conversion breakpoint when you enter/leave the test you care about. You can also specify arbitrary tests to run in the command line. This link has more details. |
@karelz @alexperovich @JeremyKuhne Thanks everyone for the help! I will take a look at this again. |
Thank you for the advice it was very helpful, I am now able to run the tests one by one from VS. @JeremyKuhne I was debugging the other OSes and I see that the failures in Unix are being throw by:
Which throws and then checks /Common/Interop/Unix/Interop.IOErrors.cs:
Should I get rid of that case and let it fall through to the default which throws an IOException? Is that the behavior we are looking for? I was doing more debugging and I found more places that the PathTooLongException is being thrown in PathHelper.Windows.cs and removed them. After I removed them I started to get unhandled exceptions there: An exception of type 'System.IO.PathTooLongException' occurred in system.runtime.extensions.dll but was not handled in user code. It doesn't seem like these are being caught and converted now but I was under the impression we should remove all PathTooLong throws that aren't in conversion code. I will now check the codes they are throwing in GetExceptionForWin32Error. Am I making this change harder than it has to be or is it just tricky? :) |
@JeremyKuhne was OOF sick today. CC @ianhays if he can help ... |
That is the Unix specific helper for errors and shouldn't be changed. We want to surface PathTooLong if the OS tells us that the path is too long. The Path class code moved to CoreCLR you'll need to update Path there. The only reason I didn't delete it here is that CoreRT (the WinRT CoreCLR) doesn't have the equivalent move (yet). I've put up a PR to rename these files to reflect this better (they have .uap now). |
@stephenmichaelf do you plan to continue in the manner @JeremyKuhne proposes? |
@danmosemsft @JeremyKuhne Yes I can do that. Just to clarify I should:
Thanks! |
I'd add
If you add |
@stephenmichaelf was the previous answer sufficient? |
@karelz Yes I think it is, thanks! I will have a push for this tomorrow. |
@stephenmichaelf ping? |
@stephenmichaelf ping again? |
@stephenmichaelf would love to see this go in, we get a lot of feedback about long path limits... |
I'm going to close this one as it's been a month. We can certainly reopen if anyone would like to finish it off. |
BTW: I unassigned the bug. If anyone wants to finish it off later (incl. @stephenmichaelf), please let us know on the main issue #8655. |
Remove preemptive check for path too long. Refer to #8655 .
@JeremyKuhne @karelz