зеркало из https://github.com/mono/corefx.git
Using FUTIMENS instead of FUTIMES (#34271)
* test added * rearranging order for if statements * reducing thread sleep time and reverting millisecond test change * adding comment * removing comment, adding tick equality check, failing if not able to create file with non-zero nano or milli second * correcting test for hfs system * NanoSeconds -> Nanoseconds, Millisec -> milliseconds HFs assert converted to false
This commit is contained in:
Родитель
61bbac188e
Коммит
862b6c67d0
|
@ -1314,22 +1314,21 @@ int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destinationFd)
|
|||
while ((ret = fstat_(inFd, &sourceStat)) < 0 && errno == EINTR);
|
||||
if (ret == 0)
|
||||
{
|
||||
#if HAVE_FUTIMES
|
||||
struct timeval origTimes[2];
|
||||
origTimes[0].tv_sec = sourceStat.st_atime;
|
||||
origTimes[0].tv_usec = ST_ATIME_NSEC(&sourceStat) / 1000;
|
||||
origTimes[1].tv_sec = sourceStat.st_mtime;
|
||||
origTimes[1].tv_usec = ST_MTIME_NSEC(&sourceStat) / 1000;
|
||||
while ((ret = futimes(outFd, origTimes)) < 0 && errno == EINTR);
|
||||
#elif HAVE_FUTIMENS
|
||||
// futimes is not a POSIX function, and not available on Android,
|
||||
// but futimens is
|
||||
#if HAVE_FUTIMENS
|
||||
// futimens is prefered because it has a higher resolution.
|
||||
struct timespec origTimes[2];
|
||||
origTimes[0].tv_sec = (time_t)sourceStat.st_atime;
|
||||
origTimes[0].tv_nsec = ST_ATIME_NSEC(&sourceStat);
|
||||
origTimes[1].tv_sec = (time_t)sourceStat.st_mtime;
|
||||
origTimes[1].tv_nsec = ST_MTIME_NSEC(&sourceStat);
|
||||
while ((ret = futimens(outFd, origTimes)) < 0 && errno == EINTR);
|
||||
#elif HAVE_FUTIMES
|
||||
struct timeval origTimes[2];
|
||||
origTimes[0].tv_sec = sourceStat.st_atime;
|
||||
origTimes[0].tv_usec = ST_ATIME_NSEC(&sourceStat) / 1000;
|
||||
origTimes[1].tv_sec = sourceStat.st_mtime;
|
||||
origTimes[1].tv_usec = ST_MTIME_NSEC(&sourceStat) / 1000;
|
||||
while ((ret = futimes(outFd, origTimes)) < 0 && errno == EINTR);
|
||||
#endif
|
||||
}
|
||||
if (ret != 0)
|
||||
|
|
|
@ -18,6 +18,48 @@ namespace System.IO.Tests
|
|||
return new FileInfo(path);
|
||||
}
|
||||
|
||||
private static bool HasNonZeroNanoseconds(DateTime dt) => dt.Ticks % 10 != 0;
|
||||
|
||||
public FileInfo GetNonZeroMilliseconds()
|
||||
{
|
||||
FileInfo fileinfo = new FileInfo(GetTestFilePath());
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
fileinfo.Create().Dispose();
|
||||
if (fileinfo.LastWriteTime.Millisecond != 0)
|
||||
break;
|
||||
|
||||
// This case should only happen 1/1000 times, unless the OS/Filesystem does
|
||||
// not support millisecond granularity.
|
||||
|
||||
// If it's 1/1000, or low granularity, this may help:
|
||||
Thread.Sleep(1234);
|
||||
}
|
||||
|
||||
Assert.NotEqual(0, fileinfo.LastWriteTime.Millisecond);
|
||||
return fileinfo;
|
||||
}
|
||||
|
||||
public FileInfo GetNonZeroNanoseconds()
|
||||
{
|
||||
FileInfo fileinfo = new FileInfo(GetTestFilePath());
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
fileinfo.Create().Dispose();
|
||||
if (HasNonZeroNanoseconds(fileinfo.LastWriteTime))
|
||||
break;
|
||||
|
||||
// This case should only happen 1/10 times, unless the OS/Filesystem does
|
||||
// not support nanosecond granularity.
|
||||
|
||||
// If it's 1/10, or low granularity, this may help:
|
||||
Thread.Sleep(123);
|
||||
}
|
||||
|
||||
Assert.True(HasNonZeroNanoseconds(fileinfo.LastWriteTime), "Tests failed to create a file with non-zero nanoseconds.");
|
||||
return fileinfo;
|
||||
}
|
||||
|
||||
public override FileInfo GetMissingItem() => new FileInfo(GetTestFilePath());
|
||||
|
||||
public override string GetItemPath(FileInfo item) => item.FullName;
|
||||
|
@ -70,25 +112,64 @@ namespace System.IO.Tests
|
|||
[ConditionalFact(nameof(isNotHFS))]
|
||||
public void CopyToMillisecondPresent()
|
||||
{
|
||||
FileInfo input = new FileInfo(GetTestFilePath());
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
input.Create().Dispose();
|
||||
if (input.LastWriteTime.Millisecond != 0)
|
||||
break;
|
||||
|
||||
// This case should only happen 1/1000 times, unless the OS/Filesystem does
|
||||
// not support millisecond granularity.
|
||||
|
||||
// If it's 1/1000, or low granularity, this may help:
|
||||
Thread.Sleep(1234);
|
||||
}
|
||||
|
||||
FileInfo input = GetNonZeroMilliseconds();
|
||||
FileInfo output = new FileInfo(Path.Combine(GetTestFilePath(), input.Name));
|
||||
|
||||
Assert.Equal(0, output.LastWriteTime.Millisecond);
|
||||
output.Directory.Create();
|
||||
output = input.CopyTo(output.FullName, true);
|
||||
Assert.NotEqual(0, input.LastWriteTime.Millisecond);
|
||||
|
||||
Assert.Equal(input.LastWriteTime.Millisecond, output.LastWriteTime.Millisecond);
|
||||
Assert.NotEqual(0, output.LastWriteTime.Millisecond);
|
||||
}
|
||||
|
||||
[ConditionalFact(nameof(isNotHFS))]
|
||||
public void CopyToNanosecondsPresent()
|
||||
{
|
||||
FileInfo input = GetNonZeroNanoseconds();
|
||||
FileInfo output = new FileInfo(Path.Combine(GetTestFilePath(), input.Name));
|
||||
|
||||
output.Directory.Create();
|
||||
output = input.CopyTo(output.FullName, true);
|
||||
|
||||
Assert.Equal(input.LastWriteTime.Ticks, output.LastWriteTime.Ticks);
|
||||
Assert.True(HasNonZeroNanoseconds(output.LastWriteTime));
|
||||
}
|
||||
|
||||
[ConditionalFact(nameof(isHFS))]
|
||||
public void CopyToNanosecondsPresent_HFS()
|
||||
{
|
||||
FileInfo input = new FileInfo(GetTestFilePath());
|
||||
input.Create().Dispose();
|
||||
FileInfo output = new FileInfo(Path.Combine(GetTestFilePath(), input.Name));
|
||||
|
||||
output.Directory.Create();
|
||||
output = input.CopyTo(output.FullName, true);
|
||||
|
||||
Assert.Equal(input.LastWriteTime.Ticks, output.LastWriteTime.Ticks);
|
||||
Assert.False(HasNonZeroNanoseconds(output.LastWriteTime));
|
||||
}
|
||||
|
||||
[ConditionalFact(nameof(isHFS))]
|
||||
public void MoveToMillisecondPresent_HFS()
|
||||
{
|
||||
FileInfo input = new FileInfo(GetTestFilePath());
|
||||
input.Create().Dispose();
|
||||
|
||||
string dest = Path.Combine(input.DirectoryName, GetTestFileName());
|
||||
input.MoveTo(dest);
|
||||
FileInfo output = new FileInfo(dest);
|
||||
Assert.Equal(0, output.LastWriteTime.Millisecond);
|
||||
}
|
||||
|
||||
[ConditionalFact(nameof(isNotHFS))]
|
||||
public void MoveToMillisecondPresent()
|
||||
{
|
||||
FileInfo input = GetNonZeroMilliseconds();
|
||||
string dest = Path.Combine(input.DirectoryName, GetTestFileName());
|
||||
|
||||
input.MoveTo(dest);
|
||||
FileInfo output = new FileInfo(dest);
|
||||
Assert.NotEqual(0, output.LastWriteTime.Millisecond);
|
||||
}
|
||||
|
||||
|
@ -100,61 +181,10 @@ namespace System.IO.Tests
|
|||
FileInfo output = new FileInfo(Path.Combine(GetTestFilePath(), input.Name));
|
||||
output.Directory.Create();
|
||||
output = input.CopyTo(output.FullName, true);
|
||||
Assert.Equal(0, input.LastWriteTime.Millisecond);
|
||||
Assert.Equal(input.LastWriteTime.Millisecond, output.LastWriteTime.Millisecond);
|
||||
Assert.Equal(0, output.LastWriteTime.Millisecond);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyToMillisecondPresent()
|
||||
{
|
||||
FileInfo input = new FileInfo(Path.Combine(TestDirectory, GetTestFileName()));
|
||||
input.Create().Dispose();
|
||||
|
||||
string driveFormat = new DriveInfo(input.DirectoryName).DriveFormat;
|
||||
if (!driveFormat.Equals(HFS, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
if (input.LastWriteTime.Millisecond != 0)
|
||||
break;
|
||||
|
||||
// This case should only happen 1/1000 times, unless the OS/Filesystem does
|
||||
// not support millisecond granularity.
|
||||
|
||||
// If it's 1/1000, or low granularity, this may help:
|
||||
Thread.Sleep(1234);
|
||||
input = new FileInfo(Path.Combine(TestDirectory, GetTestFileName()));
|
||||
input.Create().Dispose();
|
||||
}
|
||||
|
||||
FileInfo output = new FileInfo(Path.Combine(TestDirectory, GetTestFileName(), input.Name));
|
||||
Assert.Equal(0, output.LastWriteTime.Millisecond);
|
||||
output.Directory.Create();
|
||||
output = input.CopyTo(output.FullName, true);
|
||||
|
||||
Assert.NotEqual(0, input.LastWriteTime.Millisecond);
|
||||
Assert.NotEqual(0, output.LastWriteTime.Millisecond);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[PlatformSpecific(TestPlatforms.OSX)]
|
||||
public void CopyToMillisecondPresent_HFS()
|
||||
{
|
||||
FileInfo input = new FileInfo(Path.Combine(TestDirectory, GetTestFileName()));
|
||||
input.Create().Dispose();
|
||||
FileInfo output = new FileInfo(Path.Combine(TestDirectory, GetTestFileName(), input.Name));
|
||||
|
||||
string driveFormat = new DriveInfo(input.DirectoryName).DriveFormat;
|
||||
if (driveFormat.Equals(HFS, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
output.Directory.Create();
|
||||
output = input.CopyTo(output.FullName, true);
|
||||
Assert.Equal(0, input.LastWriteTime.Millisecond);
|
||||
Assert.Equal(0, output.LastWriteTime.Millisecond);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeleteAfterEnumerate_TimesStillSet()
|
||||
{
|
||||
|
@ -190,8 +220,7 @@ namespace System.IO.Tests
|
|||
Assert.InRange(fi.CreationTimeUtc, before, fi.LastWriteTimeUtc);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInAppContainer))] // Can't read root in appcontainer
|
||||
[PlatformSpecific(TestPlatforms.Windows)]
|
||||
public void PageFileHasTimes()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче