Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 2f50375

Browse files
committed
Merge pull request #2588 from ianhays/linkunlink
Modified the Unix implementation of FileMove and fixed the corresponding broken FileSystemWatcher tests
2 parents f88a586 + cae7c51 commit 2f50375

File tree

8 files changed

+242
-77
lines changed

8 files changed

+242
-77
lines changed

src/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.Created.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,6 @@ public static void FileSystemWatcher_Created_Negative()
9999
testFile.WriteByte(0xFF);
100100
testFile.Flush();
101101

102-
// rename a file in the same directory
103-
testFile.Move(testFile.Path + "_rename");
104-
105102
// renaming a directory
106103
testDir.Move(testDir.Path + "_rename");
107104

src/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.Deleted.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ public static void FileSystemWatcher_Deleted_Directory()
4545
}
4646
}
4747

48-
4948
[Fact]
5049
public static void FileSystemWatcher_Deleted_Negative()
5150
{
@@ -70,9 +69,6 @@ public static void FileSystemWatcher_Deleted_Negative()
7069
testFile.WriteByte(0xFF);
7170
testFile.Flush();
7271

73-
// rename a file in the same directory
74-
testFile.Move(testFile.Path + "_rename");
75-
7672
// renaming a directory
7773
testDir.Move(testDir.Path + "_rename");
7874

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.IO;
6+
using System.Threading;
7+
using Xunit;
8+
9+
public partial class FileSystemWatcher_4000_Tests
10+
{
11+
#region WindowsTests
12+
13+
[Theory]
14+
[InlineData(WatcherChangeTypes.Changed, false)]
15+
[InlineData(WatcherChangeTypes.Created, false)]
16+
[InlineData(WatcherChangeTypes.Deleted, false)]
17+
[InlineData(WatcherChangeTypes.Renamed, true)]
18+
[PlatformSpecific(PlatformID.Windows)]
19+
public static void Windows_File_Move_To_Same_Directory_Triggers_Event(WatcherChangeTypes eventType, bool moveRaisesEvent)
20+
{
21+
MoveAndCheck_SameDirectory(eventType, moveRaisesEvent);
22+
}
23+
24+
[Theory]
25+
[OuterLoop]
26+
[InlineData(WatcherChangeTypes.Changed, false)]
27+
[InlineData(WatcherChangeTypes.Created, false)]
28+
[InlineData(WatcherChangeTypes.Deleted, false)]
29+
[InlineData(WatcherChangeTypes.Renamed, true)]
30+
[PlatformSpecific(PlatformID.Windows)]
31+
public static void Windows_File_Move_To_Different_Directory_Triggers_Event(WatcherChangeTypes eventType, bool moveRaisesEvent)
32+
{
33+
MoveAndCheck_DifferentDirectory(eventType, moveRaisesEvent);
34+
}
35+
36+
[Theory]
37+
[InlineData(WatcherChangeTypes.Changed, true)]
38+
[InlineData(WatcherChangeTypes.Created, true)]
39+
[InlineData(WatcherChangeTypes.Deleted, false)]
40+
[InlineData(WatcherChangeTypes.Renamed, true)]
41+
[PlatformSpecific(PlatformID.Windows)]
42+
public static void Windows_File_Move_In_Nested_Directory_Triggers_Event(WatcherChangeTypes eventType, bool moveRaisesEvent)
43+
{
44+
MoveAndCheck_NestedDirectory(eventType, moveRaisesEvent);
45+
}
46+
47+
[Theory]
48+
[InlineData(WatcherChangeTypes.Changed, false)]
49+
[InlineData(WatcherChangeTypes.Created, false)]
50+
[InlineData(WatcherChangeTypes.Deleted, false)]
51+
[InlineData(WatcherChangeTypes.Renamed, true)]
52+
[PlatformSpecific(PlatformID.Windows)]
53+
public static void Windows_File_Move_With_Set_NotifyFilter_Triggers_Event(WatcherChangeTypes eventType, bool moveRaisesEvent)
54+
{
55+
MoveAndCheck_WithNotifyFilter(eventType, moveRaisesEvent);
56+
}
57+
58+
#endregion
59+
60+
#region UnixTests
61+
62+
[Theory]
63+
[InlineData(WatcherChangeTypes.Changed, false)]
64+
[InlineData(WatcherChangeTypes.Created, true)]
65+
[InlineData(WatcherChangeTypes.Deleted, true)]
66+
[InlineData(WatcherChangeTypes.Renamed, false)]
67+
[PlatformSpecific(PlatformID.AnyUnix)]
68+
public static void Unix_File_Move_To_Same_Directory_Triggers_Event(WatcherChangeTypes eventType, bool moveRaisesEvent)
69+
{
70+
MoveAndCheck_SameDirectory(eventType, moveRaisesEvent);
71+
}
72+
73+
[Theory]
74+
[OuterLoop]
75+
[InlineData(WatcherChangeTypes.Changed, false)]
76+
[InlineData(WatcherChangeTypes.Created, true)]
77+
[InlineData(WatcherChangeTypes.Deleted, true)]
78+
[InlineData(WatcherChangeTypes.Renamed, false)]
79+
[PlatformSpecific(PlatformID.AnyUnix)]
80+
public static void Unix_File_Move_To_Different_Directory_Triggers_Event(WatcherChangeTypes eventType, bool moveRaisesEvent)
81+
{
82+
MoveAndCheck_DifferentDirectory(eventType, moveRaisesEvent);
83+
84+
}
85+
86+
[Theory]
87+
[InlineData(WatcherChangeTypes.Changed, false)]
88+
[InlineData(WatcherChangeTypes.Created, true)]
89+
[InlineData(WatcherChangeTypes.Deleted, true)]
90+
[InlineData(WatcherChangeTypes.Renamed, false)]
91+
[PlatformSpecific(PlatformID.AnyUnix)]
92+
public static void Unix_File_Move_In_Nested_Directory_Triggers_Event(WatcherChangeTypes eventType, bool moveRaisesEvent)
93+
{
94+
MoveAndCheck_NestedDirectory(eventType, moveRaisesEvent);
95+
}
96+
97+
[Theory]
98+
[InlineData(WatcherChangeTypes.Changed, false)]
99+
[InlineData(WatcherChangeTypes.Created, false)]
100+
[InlineData(WatcherChangeTypes.Deleted, true)]
101+
[InlineData(WatcherChangeTypes.Renamed, false)]
102+
[PlatformSpecific(PlatformID.AnyUnix)]
103+
public static void Unix_File_Move_With_Set_NotifyFilter_Triggers_Event(WatcherChangeTypes eventType, bool moveRaisesEvent)
104+
{
105+
MoveAndCheck_WithNotifyFilter(eventType, moveRaisesEvent);
106+
}
107+
108+
#endregion
109+
110+
#region TestHelpers
111+
112+
/// <summary>
113+
/// Sets up watchers for the type given before performing a File.Move operation and checking for
114+
/// events. If moveRaisesEvent is true, we make sure that the given event type is observed. If false,
115+
/// we ensure that it is not observed.
116+
///
117+
/// This test will move the source file to a destination file in the same directory i.e. rename it
118+
/// </summary>
119+
private static void MoveAndCheck_SameDirectory(WatcherChangeTypes eventType, bool moveRaisesEvent)
120+
{
121+
using (var dir = Utility.CreateTestDirectory(Guid.NewGuid().ToString()))
122+
using (var watcher = new FileSystemWatcher())
123+
{
124+
// put everything in our own directory to avoid collisions
125+
watcher.Path = Path.GetFullPath(dir.Path);
126+
watcher.Filter = "*.*";
127+
128+
// create a file
129+
using (var testFile = new TemporaryTestFile(Path.Combine(dir.Path, "file")))
130+
{
131+
watcher.EnableRaisingEvents = true;
132+
AutoResetEvent eventOccured = Utility.WatchForEvents(watcher, eventType);
133+
134+
// Move the testFile to a different name in the same directory
135+
testFile.Move(testFile.Path + "_" + eventType.ToString());
136+
137+
// Test that the event is observed or not observed
138+
if (moveRaisesEvent)
139+
Utility.ExpectEvent(eventOccured, eventType.ToString());
140+
else
141+
Utility.ExpectNoEvent(eventOccured, eventType.ToString());
142+
}
143+
}
144+
}
145+
146+
/// <summary>
147+
/// Sets up watchers for the type given before performing a File.Move operation and checking for
148+
/// events. If moveRaisesEvent is true, we make sure that the given event type is observed. If false,
149+
/// we ensure that it is not observed.
150+
///
151+
/// This test checks for when the file being moved has a destination directory that is outside of
152+
/// the path of the FileSystemWatcher.
153+
/// </summary>
154+
private static void MoveAndCheck_DifferentDirectory(WatcherChangeTypes eventType, bool moveRaisesEvent)
155+
{
156+
using (var dir = Utility.CreateTestDirectory(Guid.NewGuid().ToString()))
157+
using (var dir_unwatched = new TemporaryTestDirectory(Path.GetRandomFileName()))
158+
using (var watcher = new FileSystemWatcher())
159+
{
160+
// put everything in our own directory to avoid collisions
161+
watcher.Path = Path.GetFullPath(dir.Path);
162+
watcher.Filter = "*.*";
163+
164+
// create a file
165+
using (var testFile = new TemporaryTestFile(Path.Combine(dir.Path, "file")))
166+
{
167+
watcher.EnableRaisingEvents = true;
168+
AutoResetEvent eventOccured = Utility.WatchForEvents(watcher, eventType);
169+
170+
// Move the testFile to a different name in the same directory
171+
testFile.Move(Path.Combine(dir_unwatched.Path, testFile.Name + "_" + eventType.ToString()));
172+
173+
// Test which events are thrown
174+
if (moveRaisesEvent)
175+
Utility.ExpectEvent(eventOccured, eventType.ToString());
176+
else
177+
Utility.ExpectNoEvent(eventOccured, eventType.ToString());
178+
}
179+
}
180+
}
181+
182+
/// <summary>
183+
/// Sets up watchers for the type given before performing a File.Move operation and checking for
184+
/// events. If moveRaisesEvent is true, we make sure that the given event type is observed. If false,
185+
/// we ensure that it is not observed.
186+
///
187+
/// This test will move the source file of a file within a nested directory
188+
/// </summary>
189+
private static void MoveAndCheck_NestedDirectory(WatcherChangeTypes eventType, bool moveRaisesEvent)
190+
{
191+
Utility.TestNestedDirectoriesHelper(eventType, (AutoResetEvent eventOccured, TemporaryTestDirectory ttd) =>
192+
{
193+
using (var nestedFile = new TemporaryTestFile(Path.Combine(ttd.Path, "nestedFile" + eventType.ToString())))
194+
{
195+
nestedFile.Move(nestedFile.Path + "_2");
196+
if (moveRaisesEvent)
197+
Utility.ExpectEvent(eventOccured, eventType.ToString());
198+
else
199+
Utility.ExpectNoEvent(eventOccured, eventType.ToString());
200+
}
201+
});
202+
}
203+
204+
/// <summary>
205+
/// Sets up watchers for the type given before performing a File.Move operation and checking for
206+
/// events. If moveRaisesEvent is true, we make sure that the given event type is observed. If false,
207+
/// we ensure that it is not observed.
208+
///
209+
/// This test will use the NotifyFilter attribute of the FileSystemWatcher before the move and subsequent
210+
/// checks are made.
211+
/// </summary>
212+
private static void MoveAndCheck_WithNotifyFilter(WatcherChangeTypes eventType, bool moveRaisesEvent)
213+
{
214+
using (var file = Utility.CreateTestFile(Guid.NewGuid().ToString()))
215+
using (var watcher = new FileSystemWatcher("."))
216+
{
217+
watcher.NotifyFilter = NotifyFilters.FileName;
218+
watcher.Filter = Path.GetFileName(file.Path);
219+
AutoResetEvent eventOccured = Utility.WatchForEvents(watcher, eventType);
220+
221+
string newName = file.Path + "_" + eventType.ToString();
222+
Utility.EnsureDelete(newName);
223+
224+
watcher.EnableRaisingEvents = true;
225+
226+
file.Move(newName);
227+
228+
if (moveRaisesEvent)
229+
Utility.ExpectEvent(eventOccured, eventType.ToString());
230+
else
231+
Utility.ExpectNoEvent(eventOccured, eventType.ToString());
232+
}
233+
}
234+
235+
#endregion
236+
}

src/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.NotifyFilter.cs

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -72,26 +72,6 @@ public static void FileSystemWatcher_NotifyFilter_DirectoryName()
7272
}
7373
}
7474

75-
[Fact]
76-
public static void FileSystemWatcher_NotifyFilter_FileName()
77-
{
78-
using (var file = Utility.CreateTestFile())
79-
using (var watcher = new FileSystemWatcher("."))
80-
{
81-
watcher.NotifyFilter = NotifyFilters.FileName;
82-
watcher.Filter = Path.GetFileName(file.Path);
83-
AutoResetEvent eventOccured = Utility.WatchForEvents(watcher, WatcherChangeTypes.Renamed);
84-
85-
string newName = file.Path + "_rename";
86-
Utility.EnsureDelete(newName);
87-
88-
watcher.EnableRaisingEvents = true;
89-
90-
file.Move(newName);
91-
92-
Utility.ExpectEvent(eventOccured, "changed");
93-
}
94-
}
9575

9676
[Fact]
9777
[ActiveIssue(2011, PlatformID.OSX)]
@@ -253,13 +233,6 @@ public static void FileSystemWatcher_NotifyFilter_Negative()
253233

254234
// None of these should trigger any events
255235
Utility.ExpectNoEvent(eventOccured, "any");
256-
257-
// finally, change name and expect a name change
258-
eventOccured = Utility.WatchForEvents(watcher, WatcherChangeTypes.Renamed);
259-
260-
file.Move(newName);
261-
262-
Utility.ExpectEvent(eventOccured, "changed");
263236
}
264237
}
265238
}

src/System.IO.FileSystem.Watcher/tests/FileSystemWatcher.Renamed.cs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,6 @@
77

88
public partial class FileSystemWatcher_4000_Tests
99
{
10-
[Fact]
11-
public static void FileSystemWatcher_Renamed_File()
12-
{
13-
using (var file = Utility.CreateTestFile())
14-
using (var watcher = new FileSystemWatcher("."))
15-
{
16-
watcher.Filter = Path.GetFileName(file.Path);
17-
AutoResetEvent eventOccured = Utility.WatchForEvents(watcher, WatcherChangeTypes.Renamed);
18-
19-
string newName = file.Path + "_rename";
20-
Utility.EnsureDelete(newName);
21-
22-
watcher.EnableRaisingEvents = true;
23-
24-
file.Move(newName);
25-
26-
Utility.ExpectEvent(eventOccured, "renamed");
27-
}
28-
}
29-
30-
3110
[Fact]
3211
public static void FileSystemWatcher_Renamed_Directory()
3312
{
@@ -88,17 +67,4 @@ public static void FileSystemWatcher_Renamed_NestedDirectory()
8867
Utility.ExpectEvent(are, "renamed");
8968
});
9069
}
91-
92-
[Fact]
93-
public static void FileSystemWatcher_Renamed_FileInNestedDirectory()
94-
{
95-
Utility.TestNestedDirectoriesHelper(WatcherChangeTypes.Renamed, (AutoResetEvent are, TemporaryTestDirectory ttd) =>
96-
{
97-
using (var nestedFile = new TemporaryTestFile(Path.Combine(ttd.Path, "nestedFile")))
98-
{
99-
nestedFile.Move(nestedFile.Path + "_2");
100-
Utility.ExpectEvent(are, "renamed");
101-
}
102-
});
103-
}
10470
}

src/System.IO.FileSystem.Watcher/tests/System.IO.FileSystem.Watcher.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<Compile Include="FileSystemWatcher.InternalBufferSize.cs" />
2525
<Compile Include="FileSystemWatcher.NotifyFilter.cs" />
2626
<Compile Include="FileSystemWatcher.Renamed.cs" />
27+
<Compile Include="FileSystemWatcher.MoveFile.cs" />
2728
<Compile Include="Utility\TemporaryTestDirectory.cs" />
2829
<Compile Include="Utility\TemporaryTestFile.cs" />
2930
<Compile Include="Utility\TestFileSystemWatcher.cs" />

src/System.IO.FileSystem.Watcher/tests/Utility/Utility.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public static void TestNestedDirectoriesHelper(
106106
Action<AutoResetEvent, TemporaryTestDirectory> action,
107107
NotifyFilters changeFilers = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName)
108108
{
109-
using (var dir = Utility.CreateTestDirectory())
109+
using (var dir = Utility.CreateTestDirectory(Guid.NewGuid().ToString()))
110110
using (var watcher = new FileSystemWatcher())
111111
{
112112
AutoResetEvent createdOccured = Utility.WatchForEvents(watcher, WatcherChangeTypes.Created); // not "using" to avoid race conditions with FSW callbacks

0 commit comments

Comments
 (0)