1

I am testing software in C# and must ensure proper behavior (graceful failure) occurs when a program is given an invalid full path. Initially this is trivial,as I give something like "Q:\\fakepath" and since there is no Q drive mounted on the system, the program fails as expected.

However, I would like my test to be robust and want a way to generate a path that is guaranteed to not exist and to not be able to exist. The path must be full since if it doesn't start with a drive letter it will be treated relative to some directory, resulting in no failure.

Some approaches I have though of are to search for local drives that are mounted and then pick a drive letter that does not appear. This would work fine and I might end up using this, but I would prefer a more elegant solution such as using a drive letter that could not possibly exist.

Another (potential) option is to use invalid characters in the path name. However, using invalid characters is not preferred as it actually results in a different failure mode of the program.

So formally: How can I most elegantly generate a full path that is guaranteed not be invalid?

EDIT: The program I am testing will go ahead and create a directory (including parent directories) if it is on a valid drive but in a location that does not already exist. Hence, this path needs to be something that couldn't be created with something like Directory.CreateDirectory(<path>), not just something that doesn't already exist.

Jon Deaton
  • 3,943
  • 6
  • 28
  • 41
  • 1
    "if it doesn't start with a drive letter it will be treated relative to some directory, resulting in no failure." It does not seem right. – Gabriel Aug 12 '17 at 02:30
  • Indeed this does not but I tested the behavior and any path given without `:` in the beginning will be treated as relative and be appended to the "home" directory of the program that I am testing. – Jon Deaton Aug 12 '17 at 02:31
  • 3
    I bet the path `$"C:\\{Guid.NewGuid()}"` won't exist everytime. – Biscuits Aug 12 '17 at 02:41
  • 2
    Btw., if a unit test is the thing you're after, you should consider mocking external dependencies; in this case, the file system. – Biscuits Aug 12 '17 at 02:58
  • @Biscuits yeah I agree that for unit tests that would be the way to go but these are actually CI tests – Jon Deaton Aug 14 '17 at 20:18
  • Fair point, Jon :) – Biscuits Aug 15 '17 at 12:22

5 Answers5

2

One method would be to use the Windows API to create a temporary folder. This might sound counterintuitive, but now you have a known empty folder, any path you specify inside it is guaranteed to not exist. For example:

//From https://stackoverflow.com/a/278457/1663001:
public string GetTemporaryDirectory()
{
    string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
    Directory.CreateDirectory(tempDirectory);
    return tempDirectory;
}

public string GetNonexistantPath()
{
    return Path.Combine(GetTemporaryDirectory(), "no-such-file");
}
DavidG
  • 113,891
  • 12
  • 217
  • 223
  • By the question and the comments, I suspect "invalid" and "non existent" aren't the same thing in this context. – Gabriel Aug 12 '17 at 02:38
  • @Gabriel The question says *want a way to generate a path that is guaranteed to not exist*, seems fairly clear to me? – DavidG Aug 12 '17 at 02:39
  • +1 for the cleverness. As a suggestion, you don't have to create the temp directory, you could check if it exists, and if it does, combine some more random paths until it doesn't. – Marcos Dimitrio Aug 12 '17 at 02:41
  • @DavidG Read all the question and his reply for my comment. Maybe you'll get why I *suspect* this. – Gabriel Aug 12 '17 at 02:41
  • @MarcosDimitrio Yes, that's a reasonable optimisation – DavidG Aug 12 '17 at 02:42
  • @Gabriel I don't get that vibe, but it's possible – DavidG Aug 12 '17 at 02:42
  • This is a clever approach although after testing this, it is apparent that the program will go ahead and create the directory pointed to by the path (including parent directories) so in this case it actually went ahead and actually created a directory called "no-such-file" in `Temp`. For a second there I was quite excited as the program did not fail and I thought I had found a bug. – Jon Deaton Aug 12 '17 at 02:48
  • 1
    He said "if it doesn't start with a drive letter it will be treated relative to some directory, resulting in no failure". So *non existence* may not be a problem here. And all this talk about drive letters *indicates* he's looking for really invalid paths. (Anyway, I am just speculating.) – Gabriel Aug 12 '17 at 02:49
  • @JonDeaton So you don't *just* want an invalid path, you want it to be invalid forever? – DavidG Aug 12 '17 at 02:50
1

You could try using one of the reserved words, for instance C:\NUL (case-sensitive). Trying to create such directory will cause a DirectoryNotFoundException. More details here.

Marcos Dimitrio
  • 6,651
  • 5
  • 38
  • 62
Diado
  • 2,229
  • 3
  • 18
  • 21
1

One way to get a guaranteed invalid folder path is have a file that exists with the same name as part of the directory path.

public string Example()
{
    string filePath = Path.GetTempFileName(); //Creates a uniquely named, zero-byte temporary file on disk.
    var invalidDirectoryPath = Path.Combine(filePath, "CanNotExist");
    Directory.CreateDirectory(invalidDirectoryPath); //throws a IOException
}
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
0

You can use some really long path (say a thousand characters). Your program won't probably be able to create it as it is invalid.

Gabriel
  • 1,922
  • 2
  • 19
  • 37
  • @DavidG I didn't know that, thank you for pointing out. However judging by [this thread](https://stackoverflow.com/questions/27680647/does-max-path-issue-still-exists-in-windows-10) it is not the default behavior, so my suggestion may still be relevant. – Gabriel Aug 12 '17 at 03:05
0

You can try this approach. Not sure though it would work or not but a worth try.

use path: Q:\asddsafkdjfkasjdfklahsjfhskdjfladjfhsafjklasdjfkashfkajsdfhasdklfjashdfkljasdhfklajdfajsdfklajsfkjasjfhadkfjasflhakldfjashdfklajsdjfhaksldjfahsdkljadfklajfkjlkajfkljagkjklfdjgklajdkfljgskljgklfjskgjfkljdsgkfsdgsfgsdfgsfggsdfgsfdgsgwesdfgdgjgfadfsfgffgfsdghijklm

Don't bother about counting the total number of letters, you can do the same using http://www.lettercount.com/

The trick is the max length of windows folder can be 260. Though I tried in on Windows 10 and the max length allowed to me is 247. Source_MAX_Length_Of_Folder_On_Windows

So, this folder is guaranteed to be never found. Cheers :)

Although, I think the most elegant solution is checking the mounted drives and generate a path afterwards that you have already mentioned and decided to keep it as a last option.

  • NTFS actually allows for 32k long paths, it is just a windows API limitation of 260. [if you use `\\?\ ` prefix for the path to bypass the api you can have much longer names](https://stackoverflow.com/a/1880480/80274) – Scott Chamberlain Aug 12 '17 at 06:20