-
Notifications
You must be signed in to change notification settings - Fork 4.9k
/
Copy pathGetSetTimes.cs
181 lines (156 loc) · 8 KB
/
GetSetTimes.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Xunit;
namespace System.IO.Tests
{
public class File_GetSetTimes : StaticGetSetTimes
{
// OSX has the limitation of setting upto 2262-04-11T23:47:16 (long.Max) date.
// 32bit Unix has time_t up to ~ 2038.
private static bool SupportsLongMaxDateTime => PlatformDetection.IsWindows || (!PlatformDetection.Is32BitProcess && !PlatformDetection.IsOSXLike);
protected override string GetExistingItem()
{
string path = GetTestFilePath();
File.Create(path).Dispose();
return path;
}
[Fact]
[PlatformSpecific(TestPlatforms.Linux)]
public void BirthTimeIsNotNewerThanLowestOfAccessModifiedTimes()
{
// On Linux, we synthesize CreationTime from the oldest of status changed time and write time
// if birth time is not available. So WriteTime should never be earlier.
// Set different values for all three
// Status changed time will be when the file was first created, in this case)
string path = GetExistingItem();
File.SetLastWriteTime(path, DateTime.Now.AddMinutes(1));
File.SetLastAccessTime(path, DateTime.Now.AddMinutes(2));
// Assert.InRange is inclusive.
Assert.InRange(File.GetCreationTimeUtc(path), DateTime.MinValue, File.GetLastWriteTimeUtc(path));
}
[Fact]
[PlatformSpecific(TestPlatforms.Linux)]
public async Task CreationTimeSet_GetReturnsExpected_WhenNotInFuture()
{
// On Linux, we synthesize CreationTime from the oldest of status changed time (ctime) and write time (mtime).
// Changing the CreationTime, updates mtime and causes ctime to change to the current time.
// When setting CreationTime to a value that isn't in the future, getting the CreationTime should return the same value.
string path = GetTestFilePath();
File.WriteAllText(path, "");
// Set the creation time to a value in the past that is between ctime and now.
await Task.Delay(600);
DateTime newCreationTimeUTC = System.DateTime.UtcNow.Subtract(TimeSpan.FromMilliseconds(300));
File.SetCreationTimeUtc(path, newCreationTimeUTC);
Assert.Equal(newCreationTimeUTC, File.GetLastWriteTimeUtc(path));
Assert.Equal(newCreationTimeUTC, File.GetCreationTimeUtc(path));
}
public override IEnumerable<TimeFunction> TimeFunctions(bool requiresRoundtripping = false)
{
if (IOInputs.SupportsGettingCreationTime && (!requiresRoundtripping || IOInputs.SupportsSettingCreationTime))
{
yield return TimeFunction.Create(
((path, time) => File.SetCreationTime(path, time)),
((path) => File.GetCreationTime(path)),
DateTimeKind.Local);
yield return TimeFunction.Create(
((path, time) => File.SetCreationTimeUtc(path, time)),
((path) => File.GetCreationTimeUtc(path)),
DateTimeKind.Unspecified);
yield return TimeFunction.Create(
((path, time) => File.SetCreationTimeUtc(path, time)),
((path) => File.GetCreationTimeUtc(path)),
DateTimeKind.Utc);
}
yield return TimeFunction.Create(
((path, time) => File.SetLastAccessTime(path, time)),
((path) => File.GetLastAccessTime(path)),
DateTimeKind.Local);
yield return TimeFunction.Create(
((path, time) => File.SetLastAccessTimeUtc(path, time)),
((path) => File.GetLastAccessTimeUtc(path)),
DateTimeKind.Unspecified);
yield return TimeFunction.Create(
((path, time) => File.SetLastAccessTimeUtc(path, time)),
((path) => File.GetLastAccessTimeUtc(path)),
DateTimeKind.Utc);
yield return TimeFunction.Create(
((path, time) => File.SetLastWriteTime(path, time)),
((path) => File.GetLastWriteTime(path)),
DateTimeKind.Local);
yield return TimeFunction.Create(
((path, time) => File.SetLastWriteTimeUtc(path, time)),
((path) => File.GetLastWriteTimeUtc(path)),
DateTimeKind.Unspecified);
yield return TimeFunction.Create(
((path, time) => File.SetLastWriteTimeUtc(path, time)),
((path) => File.GetLastWriteTimeUtc(path)),
DateTimeKind.Utc);
}
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInAppContainer))] // Can't read root in appcontainer
[PlatformSpecific(TestPlatforms.Windows)]
public void PageFileHasTimes()
{
// Typically there is a page file on the C: drive, if not, don't bother trying to track it down.
string pageFilePath = Directory.EnumerateFiles(@"C:\", "pagefile.sys").FirstOrDefault();
if (pageFilePath != null)
{
Assert.All(TimeFunctions(), (item) =>
{
var time = item.Getter(pageFilePath);
Assert.NotEqual(DateTime.FromFileTime(0), time);
});
}
}
[Fact]
public void SetLastWriteTimeTicks()
{
string firstFile = GetTestFilePath();
string secondFile = GetTestFilePath();
File.WriteAllText(firstFile, "");
File.WriteAllText(secondFile, "");
File.SetLastAccessTimeUtc(secondFile, DateTime.UtcNow);
long firstFileTicks = File.GetLastWriteTimeUtc(firstFile).Ticks;
long secondFileTicks = File.GetLastWriteTimeUtc(secondFile).Ticks;
Assert.True(firstFileTicks <= secondFileTicks, $"First File Ticks\t{firstFileTicks}\nSecond File Ticks\t{secondFileTicks}");
}
[ConditionalFact(nameof(HighTemporalResolution))] // OSX HFS driver format/Browser Platform do not support nanosecond granularity.
public void SetUptoNanoseconds()
{
string file = GetTestFilePath();
File.WriteAllText(file, "");
DateTime dateTime = DateTime.UtcNow;
File.SetLastWriteTimeUtc(file, dateTime);
long ticks = File.GetLastWriteTimeUtc(file).Ticks;
Assert.Equal(dateTime, File.GetLastWriteTimeUtc(file));
Assert.Equal(ticks, dateTime.Ticks);
}
[ActiveIssue("https://github.com/dotnet/runtime/issues/43166", TestPlatforms.Linux)]
[ConditionalFact(nameof(SupportsLongMaxDateTime))]
public void SetDateTimeMax()
{
string file = GetTestFilePath();
File.WriteAllText(file, "");
DateTime dateTime = new DateTime(9999, 4, 11, 23, 47, 17, 21, DateTimeKind.Utc);
File.SetLastWriteTimeUtc(file, dateTime);
long ticks = File.GetLastWriteTimeUtc(file).Ticks;
Assert.Equal(dateTime, File.GetLastWriteTimeUtc(file));
Assert.Equal(ticks, dateTime.Ticks);
}
[Fact]
public void SetLastAccessTimeTicks()
{
string firstFile = GetTestFilePath();
string secondFile = GetTestFilePath();
File.WriteAllText(firstFile, "");
File.WriteAllText(secondFile, "");
File.SetLastWriteTimeUtc(secondFile, DateTime.UtcNow);
long firstFileTicks = File.GetLastAccessTimeUtc(firstFile).Ticks;
long secondFileTicks = File.GetLastAccessTimeUtc(secondFile).Ticks;
Assert.True(firstFileTicks <= secondFileTicks, $"First File Ticks\t{firstFileTicks}\nSecond File Ticks\t{secondFileTicks}");
}
}
}