Skip to content
Prev Previous commit
Next Next commit
Update test
  • Loading branch information
tmds committed Oct 11, 2021
commit ed16197f05cbf9391aafc3dac075ff36c59c5831
188 changes: 117 additions & 71 deletions src/libraries/System.IO.FileSystem/tests/Enumeration/AttributeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,106 +9,152 @@ namespace System.IO.Tests.Enumeration
{
public class AttributeTests : FileSystemTest
{
private class DefaultFileAttributes : FileSystemEnumerator<string>
private class FileSystemEntryProperties
{
public DefaultFileAttributes(string directory, EnumerationOptions options)
public string FileName { get; init; }
public FileAttributes Attributes { get; init; }
public DateTimeOffset CreationTimeUtc { get; init; }
public bool IsDirectory { get; init; }
public bool IsHidden { get; init; }
public DateTimeOffset LastAccessTimeUtc { get; init; }
public DateTimeOffset LastWriteTimeUtc { get; init; }
public long Length { get; init; }
public string Directory { get; init; }
public string FullPath { get; init; }
public string SpecifiedFullPath { get; init; }
}

private class GetPropertiesEnumerator : FileSystemEnumerator<FileSystemEntryProperties>
{
public GetPropertiesEnumerator(string directory, EnumerationOptions options)
: base(directory, options)
{
}
{ }

protected override bool ContinueOnError(int error)
{
Assert.False(true, $"Should not have errored {error}");
return false;
}

protected override bool ShouldIncludeEntry(ref FileSystemEntry entry)
=> !entry.IsDirectory;

protected override string TransformEntry(ref FileSystemEntry entry)
protected override FileSystemEntryProperties TransformEntry(ref FileSystemEntry entry)
{
string path = entry.ToFullPath();
File.Delete(path);

// Attributes require a stat call on Unix- ensure that we have the right attributes
// even if the returned file is deleted.
Assert.Equal(FileAttributes.Normal, entry.Attributes);
Assert.Equal(path, entry.ToFullPath());
return new string(entry.FileName);
return new FileSystemEntryProperties
{
FileName = new string(entry.FileName),
Attributes = entry.Attributes,
CreationTimeUtc = entry.CreationTimeUtc,
IsDirectory = entry.IsDirectory,
IsHidden = entry.IsHidden,
LastAccessTimeUtc = entry.LastAccessTimeUtc,
LastWriteTimeUtc = entry.LastWriteTimeUtc,
Length = entry.Length,
Directory = new string(entry.Directory),
FullPath = entry.ToFullPath(),
SpecifiedFullPath = entry.ToSpecifiedFullPath()
};
}
}

[Fact]
public void FileAttributesAreExpected()
// The test is performed using two items with different properties (file/dir, file length)
// to check cached values from the previous entry don't leak into the non-existing entry.
[InlineData("dir1", "dir2")]
[InlineData("file1", "file2")]
[InlineData("dir1", "file1")]
[InlineData("file1", "dir1")]
[Theory]
public void PropertiesWhenItemNoLongerExists(string item1, string item2)
{
DirectoryInfo testDirectory = Directory.CreateDirectory(GetTestFilePath());
FileInfo fileOne = new FileInfo(Path.Combine(testDirectory.FullName, GetTestFileName()));

fileOne.Create().Dispose();

if (PlatformDetection.IsWindows)
{
// Archive should always be set on a new file. Clear it and other expected flags to
// see that we get "Normal" as the default when enumerating.
FileSystemInfo item1Info = CreateItem(testDirectory, item1);
FileSystemInfo item2Info = CreateItem(testDirectory, item2);

Assert.True((fileOne.Attributes & FileAttributes.Archive) != 0);
fileOne.Attributes &= ~(FileAttributes.Archive | FileAttributes.NotContentIndexed);
}

using (var enumerator = new DefaultFileAttributes(testDirectory.FullName, new EnumerationOptions() { AttributesToSkip = 0 }))
using (var enumerator = new GetPropertiesEnumerator(testDirectory.FullName, new EnumerationOptions() { AttributesToSkip = 0 }))
{
// Move to the first item.
Assert.True(enumerator.MoveNext());
Assert.Equal(fileOne.Name, enumerator.Current);
Assert.False(enumerator.MoveNext());
}
}
FileSystemEntryProperties entry = enumerator.Current;

private class DefaultDirectoryAttributes : FileSystemEnumerator<string>
{
public DefaultDirectoryAttributes(string directory, EnumerationOptions options)
: base(directory, options)
{
}
Assert.True(entry.FileName == item1 || entry.FileName == item2, "Unexpected item");

protected override bool ShouldIncludeEntry(ref FileSystemEntry entry)
=> entry.IsDirectory;
// Delete both items.
DeleteItem(testDirectory, item1);
DeleteItem(testDirectory, item2);

protected override bool ContinueOnError(int error)
{
Assert.False(true, $"Should not have errored {error}");
return false;
}
// Move to the second item.
FileSystemInfo expected = entry.FileName == item1 ? item2Info : item1Info;
Assert.True(enumerator.MoveNext());
entry = enumerator.Current;
Assert.Equal(expected.Name, entry.FileName);

// Values determined during enumeration.
Assert.Equal(expected is DirectoryInfo, entry.IsDirectory);
Assert.Equal(expected.Attributes, entry.Attributes);
Assert.Equal(testDirectory.FullName, entry.Directory);
Assert.Equal(expected.FullName, entry.FullPath);
Assert.Equal(expected.FullName, entry.SpecifiedFullPath);

if (PlatformDetection.IsWindows)
{
Assert.Equal((expected.Attributes & FileAttributes.Hidden) != 0, entry.IsHidden);
Assert.Equal(expected.CreationTimeUtc, entry.CreationTimeUtc);
Assert.Equal(expected.LastAccessTimeUtc, entry.LastAccessTimeUtc);
Assert.Equal(expected.LastWriteTimeUtc, entry.LastWriteTimeUtc);
Assert.Equal((expected.Attributes & FileAttributes.Hidden) != 0, entry.IsHidden);
if (expected is FileInfo fileInfo)
{
Assert.Equal(fileInfo.Length, entry.Length);
}
}
else
{
// Because the item is deleted, we can no longer retrieve these values and defaults are returned instead.
Assert.Equal(entry.FileName.StartsWith('.'), entry.IsHidden);
Assert.Equal(new DateTimeOffset(DateTime.FromFileTimeUtc(0)), entry.CreationTimeUtc);
Assert.Equal(new DateTimeOffset(DateTime.FromFileTimeUtc(0)), entry.LastAccessTimeUtc);
Assert.Equal(new DateTimeOffset(DateTime.FromFileTimeUtc(0)), entry.LastWriteTimeUtc);
if (expected is FileInfo fileInfo)
{
Assert.Equal(0, entry.Length);
}
}

protected override string TransformEntry(ref FileSystemEntry entry)
{
string path = entry.ToFullPath();
Directory.Delete(path);

// Attributes require a stat call on Unix- ensure that we have the right attributes
// even if the returned directory is deleted.
Assert.Equal(FileAttributes.Directory, entry.Attributes);
Assert.Equal(path, entry.ToFullPath());
return new string(entry.FileName);
Assert.False(enumerator.MoveNext());
}
}

[Fact]
public void DirectoryAttributesAreExpected()
{
DirectoryInfo testDirectory = Directory.CreateDirectory(GetTestFilePath());
DirectoryInfo subDirectory = Directory.CreateDirectory(Path.Combine(testDirectory.FullName, GetTestFileName()));

if (PlatformDetection.IsWindows)
static FileSystemInfo CreateItem(DirectoryInfo testDirectory, string item)
{
// Clear possible extra flags to see that we get Directory
subDirectory.Attributes &= ~FileAttributes.NotContentIndexed;
string fullPath = Path.Combine(testDirectory.FullName, item);
if (item.StartsWith("dir"))
{
Directory.CreateDirectory(fullPath);
var info = new DirectoryInfo(fullPath);
info.Refresh();
return info;
}
else
{
// use the last char to have different lengths for different files.
Assert.True(item == "file1" || item == "file2");
int length = (int)item[item.Length - 1];
File.WriteAllBytes(fullPath, new byte[length]);
var info = new FileInfo(fullPath);
info.Refresh();
return info;
}
}

using (var enumerator = new DefaultDirectoryAttributes(testDirectory.FullName, new EnumerationOptions() { AttributesToSkip = 0 }))
static void DeleteItem(DirectoryInfo testDirectory, string item)
{
Assert.True(enumerator.MoveNext());
Assert.Equal(subDirectory.Name, enumerator.Current);
Assert.False(enumerator.MoveNext());
string fullPath = Path.Combine(testDirectory.FullName, item);
if (item.StartsWith("dir"))
{
Directory.Delete(fullPath);
}
else
{
File.Delete(fullPath);
}
}
}

Expand Down