Skip to content

Commit 3a18916

Browse files
authored
refactor: fix brittle EventTests (#599)
The `FileSystemWatcher.EventTests` sometimes fail, due to race-condition. Therefore make the following changes: - Continually make the triggering changes in a background task, until the `CancellationToken` is cancelled at the end of the test - Add and listen to separate triggers for when the triggering change was made and when the change was detected in the callback - Make tests synchronous - Add class `TestBase` with common timeout settings and use them throughout the Testably.Abstractions.Tests project.
1 parent 223504f commit 3a18916

File tree

17 files changed

+136
-97
lines changed

17 files changed

+136
-97
lines changed

Tests/Helpers/Testably.Abstractions.TestHelpers/FileSystemTestBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Testably.Abstractions.TestHelpers;
1313
/// <remarks>
1414
/// Important: You have to mark your class as ´partial`!
1515
/// </remarks>
16-
public abstract class FileSystemTestBase<TFileSystem>
16+
public abstract class FileSystemTestBase<TFileSystem> : TestBase
1717
where TFileSystem : IFileSystem
1818
{
1919
public abstract string BasePath { get; }

Tests/Helpers/Testably.Abstractions.TestHelpers/RandomSystemTestBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Testably.Abstractions.TestHelpers;
1212
/// <remarks>
1313
/// Important: You have to mark your class as ´partial`!
1414
/// </remarks>
15-
public abstract class RandomSystemTestBase<TRandomSystem>
15+
public abstract class RandomSystemTestBase<TRandomSystem> : TestBase
1616
where TRandomSystem : IRandomSystem
1717
{
1818
public TRandomSystem RandomSystem { get; }
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace Testably.Abstractions.TestHelpers;
2+
3+
/// <summary>
4+
/// Base class for generated tests.
5+
/// </summary>
6+
public abstract class TestBase
7+
{
8+
/// <summary>
9+
/// The delay in milliseconds when wanting to ensure a timeout in the test.
10+
/// </summary>
11+
public const int EnsureTimeout = 500;
12+
13+
/// <summary>
14+
/// The delay in milliseconds when expecting a success in the test.
15+
/// </summary>
16+
public const int ExpectSuccess = 30000;
17+
18+
/// <summary>
19+
/// The delay in milliseconds when expecting a timeout in the test.
20+
/// </summary>
21+
public const int ExpectTimeout = 30;
22+
}

Tests/Helpers/Testably.Abstractions.TestHelpers/TimeSystemTestBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Testably.Abstractions.TestHelpers;
1212
/// <remarks>
1313
/// Important: You have to mark your class as ´partial`!
1414
/// </remarks>
15-
public abstract class TimeSystemTestBase<TTimeSystem>
15+
public abstract class TimeSystemTestBase<TTimeSystem> : TestBase
1616
where TTimeSystem : ITimeSystem
1717
{
1818
public TTimeSystem TimeSystem { get; }

Tests/Testably.Abstractions.Tests/FileSystem/File/CopyTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ public void Copy_ShouldCopyFileWithContent(
257257

258258
FileSystem.File.WriteAllText(sourceName, contents);
259259

260-
TimeSystem.Thread.Sleep(1000);
260+
TimeSystem.Thread.Sleep(EnsureTimeout);
261261

262262
FileSystem.File.Copy(sourceName, destinationName);
263263
FileSystem.Should().HaveFile(sourceName)

Tests/Testably.Abstractions.Tests/FileSystem/FileInfo/CopyToTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public void CopyTo_ShouldCopyFileWithContent(
112112
FileSystem.File.WriteAllText(sourceName, contents);
113113
IFileInfo sut = FileSystem.FileInfo.New(sourceName);
114114

115-
TimeSystem.Thread.Sleep(1000);
115+
TimeSystem.Thread.Sleep(EnsureTimeout);
116116

117117
IFileInfo result = sut.CopyTo(destinationName);
118118

Tests/Testably.Abstractions.Tests/FileSystem/FileStream/ReadTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public void BeginRead_ShouldCopyContentsToBuffer(
5656
}
5757
}, null);
5858

59-
ms.Wait(30000);
59+
ms.Wait(ExpectSuccess).Should().BeTrue();
6060
buffer.Should().BeEquivalentTo(bytes);
6161
}
6262

@@ -107,7 +107,7 @@ public void EndRead_ShouldNotAdjustTimes(string path, byte[] bytes)
107107
}
108108
}, null);
109109

110-
ms.Wait(10000);
110+
ms.Wait(ExpectSuccess).Should().BeTrue();
111111
}
112112

113113
DateTime creationTime = FileSystem.File.GetCreationTimeUtc(path);
@@ -202,7 +202,7 @@ public void Read_ShouldFillBuffer(string path, byte[] bytes)
202202
public async Task ReadAsync_CanReadFalse_ShouldThrowNotSupportedException(
203203
string path, byte[] bytes)
204204
{
205-
using CancellationTokenSource cts = new(30000);
205+
using CancellationTokenSource cts = new(ExpectSuccess);
206206
byte[] buffer = new byte[bytes.Length];
207207
await FileSystem.File.WriteAllBytesAsync(path, bytes, cts.Token);
208208
Exception? exception;
@@ -228,7 +228,7 @@ public async Task ReadAsync_CanReadFalse_ShouldThrowNotSupportedException(
228228
public async Task ReadAsync_Memory_CanReadFalse_ShouldThrowNotSupportedException(
229229
string path, byte[] bytes)
230230
{
231-
using CancellationTokenSource cts = new(30000);
231+
using CancellationTokenSource cts = new(ExpectSuccess);
232232
byte[] buffer = new byte[bytes.Length];
233233
await FileSystem.File.WriteAllBytesAsync(path, bytes, cts.Token);
234234
Exception? exception;
@@ -253,7 +253,7 @@ public async Task ReadAsync_Memory_CanReadFalse_ShouldThrowNotSupportedException
253253
[AutoData]
254254
public async Task ReadAsync_ShouldFillBuffer(string path, byte[] bytes)
255255
{
256-
using CancellationTokenSource cts = new(30000);
256+
using CancellationTokenSource cts = new(ExpectSuccess);
257257
byte[] buffer = new byte[bytes.Length];
258258
await FileSystem.File.WriteAllBytesAsync(path, bytes, cts.Token);
259259
await using FileSystemStream stream = FileSystem.File.OpenRead(path);

Tests/Testably.Abstractions.Tests/FileSystem/FileStream/WriteTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void BeginWrite_ShouldCopyContentsToFile(
5757
}
5858
}, null);
5959

60-
ms.Wait(30000);
60+
ms.Wait(ExpectSuccess).Should().BeTrue();
6161
}
6262

6363
FileSystem.Should().HaveFile(path)
@@ -108,7 +108,7 @@ public void EndWrite_ShouldAdjustTimes(string path, byte[] bytes)
108108
}
109109
}, null);
110110

111-
ms.Wait(10000);
111+
ms.Wait(ExpectSuccess).Should().BeTrue();
112112
}
113113

114114
DateTime creationTime = FileSystem.File.GetCreationTimeUtc(path);
@@ -210,7 +210,7 @@ public void Write_ShouldFillBuffer(string path, byte[] bytes)
210210
public async Task WriteAsync_CanWriteFalse_ShouldThrowNotSupportedException(
211211
string path, byte[] bytes)
212212
{
213-
using CancellationTokenSource cts = new(30000);
213+
using CancellationTokenSource cts = new(ExpectSuccess);
214214
byte[] buffer = new byte[bytes.Length];
215215
await FileSystem.File.WriteAllBytesAsync(path, bytes, cts.Token);
216216
Exception? exception;
@@ -236,7 +236,7 @@ public async Task WriteAsync_CanWriteFalse_ShouldThrowNotSupportedException(
236236
[AutoData]
237237
public async Task WriteAsync_ShouldFillBuffer(string path, byte[] bytes)
238238
{
239-
using CancellationTokenSource cts = new(30000);
239+
using CancellationTokenSource cts = new(ExpectSuccess);
240240

241241
await using (FileSystemStream stream = FileSystem.File.Create(path))
242242
{

Tests/Testably.Abstractions.Tests/FileSystem/FileSystemWatcher/EnableRaisingEventsTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ public void EnableRaisingEvents_SetToFalse_ShouldStop(string path1, string path2
3030
};
3131
fileSystemWatcher.EnableRaisingEvents = true;
3232
FileSystem.Directory.Delete(path1);
33-
ms.Wait(10000).Should().BeTrue();
33+
ms.Wait(ExpectSuccess).Should().BeTrue();
3434
ms.Reset();
3535

3636
fileSystemWatcher.EnableRaisingEvents = false;
3737

3838
FileSystem.Directory.Delete(path2);
39-
ms.Wait(30).Should().BeFalse();
39+
ms.Wait(ExpectTimeout).Should().BeFalse();
4040
}
4141

4242
[SkippableTheory]
@@ -62,6 +62,6 @@ public void EnableRaisingEvents_ShouldBeInitializedAsFalse(string path)
6262

6363
FileSystem.Directory.Delete(path);
6464

65-
ms.Wait(30).Should().BeFalse();
65+
ms.Wait(ExpectTimeout).Should().BeFalse();
6666
}
6767
}

0 commit comments

Comments
 (0)