forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Mainly, I added several tests (with lots of theory-based parameterized inputs) to stress WriteAsync: many concurrent writes, long chains of writes, etc., for various size inputs and buffers, async vs not, etc. - There were multiple variations on Flush tests based on whether to use Flush(), Flush(false), or False(true). I combined these all into single theories. - I then added some more Flush tests for some missing cases highlighted by code coverage, e.g. flushing reads. - I then duplicated these tests for FlushAsync, and added some additional tests specific to FlushAsync, e.g. cancellation. - I added a few tests for pipes. Commit migrated from dotnet/corefx@bb34d5a
- Loading branch information
1 parent
550a223
commit 26253f6
Showing
7 changed files
with
540 additions
and
154 deletions.
There are no files selected for viewing
39 changes: 0 additions & 39 deletions
39
src/libraries/System.IO.FileSystem/tests/FileStream/Flush.Sharing.cs
This file was deleted.
Oops, something went wrong.
135 changes: 122 additions & 13 deletions
135
src/libraries/System.IO.FileSystem/tests/FileStream/Flush.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,156 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System; | ||
using System.IO; | ||
using Xunit; | ||
|
||
namespace System.IO.FileSystem.Tests | ||
{ | ||
public partial class FileStream_Flush : FileSystemTest | ||
{ | ||
[Fact] | ||
public void FlushThrowsForDisposedStream() | ||
[Theory] | ||
[InlineData(null)] | ||
[InlineData(false)] | ||
[InlineData(true)] | ||
public void FlushThrowsForDisposedStream(bool? flushToDisk) | ||
{ | ||
using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create)) | ||
{ | ||
fs.Dispose(); | ||
Assert.Throws<ObjectDisposedException>(() => fs.Flush()); | ||
Assert.Throws<ObjectDisposedException>(() => Flush(fs, flushToDisk)); | ||
} | ||
} | ||
|
||
[Fact] | ||
public void BasicFlushFunctionality() | ||
[Theory] | ||
[InlineData(null)] | ||
[InlineData(false)] | ||
[InlineData(true)] | ||
public void BasicFlushFunctionality(bool? flushToDisk) | ||
{ | ||
using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create)) | ||
{ | ||
fs.WriteByte(0); | ||
fs.Flush(); | ||
Flush(fs, flushToDisk); | ||
|
||
fs.WriteByte(0xFF); | ||
Flush(fs, flushToDisk); | ||
} | ||
} | ||
|
||
[Fact] | ||
public void FlushOnReadOnlyFileDoesNotThrow() | ||
[Theory] | ||
[InlineData(null)] | ||
[InlineData(false)] | ||
[InlineData(true)] | ||
public void FlushWhenNothingToFlush(bool? flushToDisk) | ||
{ | ||
string fileName = GetTestFilePath(); | ||
using (FileStream fs = new FileStream(fileName, FileMode.Create)) | ||
using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create)) | ||
{ | ||
fs.WriteByte(0); | ||
Flush(fs, flushToDisk); | ||
|
||
Flush(fs, flushToDisk); | ||
Flush(fs, flushToDisk); | ||
Flush(fs, flushToDisk); | ||
} | ||
} | ||
|
||
using (FileStream fs = new FileStream(fileName, FileMode.Open)) | ||
[Theory] | ||
[InlineData(null)] | ||
[InlineData(false)] | ||
[InlineData(true)] | ||
public void FlushOnReadOnlyStreamDoesNotThrow(bool? flushToDisk) | ||
{ | ||
string fileName = GetTestFilePath(); | ||
File.WriteAllBytes(fileName, new byte[] { 0 }); | ||
File.SetAttributes(fileName, FileAttributes.ReadOnly); | ||
try | ||
{ | ||
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) | ||
{ | ||
Flush(fs, flushToDisk); | ||
} | ||
} | ||
finally | ||
{ | ||
File.SetAttributes(fileName, FileAttributes.Normal); | ||
} | ||
} | ||
|
||
[Theory] | ||
[InlineData(null)] | ||
[InlineData(false)] | ||
[InlineData(true)] | ||
public void FlushAfterReading(bool? flushToDisk) | ||
{ | ||
string fileName = GetTestFilePath(); | ||
File.WriteAllBytes(fileName, TestBuffer); | ||
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 2)) | ||
{ | ||
Assert.Equal(TestBuffer[0], fs.ReadByte()); | ||
Flush(fs, flushToDisk); | ||
} | ||
} | ||
|
||
[Theory] | ||
[InlineData(null)] | ||
[InlineData(false)] | ||
[InlineData(true)] | ||
public void FlushWriteWithOtherClient(bool? flushToDisk) | ||
{ | ||
string fileName = GetTestFilePath(); | ||
|
||
// ensure that we'll be using a buffer larger than our test data | ||
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, TestBuffer.Length * 2)) | ||
using (FileStream fsr = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) | ||
{ | ||
fs.Write(TestBuffer, 0, TestBuffer.Length); | ||
Assert.Equal(TestBuffer.Length, fs.Length); | ||
|
||
// Make sure that we've actually buffered it, read handle won't see any changes | ||
Assert.Equal(0, fsr.Length); | ||
|
||
// This should cause a write, after it completes the two handles should be in sync | ||
Flush(fs, flushToDisk); | ||
Assert.Equal(TestBuffer.Length, fsr.Length); | ||
|
||
byte[] buffer = new byte[TestBuffer.Length]; | ||
fsr.Read(buffer, 0, buffer.Length); | ||
Assert.Equal(TestBuffer, buffer); | ||
} | ||
} | ||
|
||
[Fact] | ||
public void FlushCallsFlush_flushToDisk_False() | ||
{ | ||
using (StoreFlushArgFileStream fs = new StoreFlushArgFileStream(GetTestFilePath(), FileMode.Create)) | ||
{ | ||
fs.Flush(); | ||
Assert.True(fs.LastFlushArg.HasValue); | ||
Assert.False(fs.LastFlushArg.Value); | ||
} | ||
} | ||
|
||
private static void Flush(FileStream fs, bool? flushArg) | ||
{ | ||
if (!flushArg.HasValue) | ||
fs.Flush(); | ||
else | ||
fs.Flush(flushArg.Value); | ||
} | ||
|
||
private sealed class StoreFlushArgFileStream : FileStream | ||
{ | ||
public StoreFlushArgFileStream(string path, FileMode mode) : base(path, mode) | ||
{ | ||
} | ||
|
||
public bool? LastFlushArg; | ||
|
||
public override void Flush(bool flushToDisk) | ||
{ | ||
LastFlushArg = flushToDisk; | ||
base.Flush(flushToDisk); | ||
} | ||
} | ||
|
||
} | ||
} |
118 changes: 118 additions & 0 deletions
118
src/libraries/System.IO.FileSystem/tests/FileStream/FlushAsync.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
|
||
namespace System.IO.FileSystem.Tests | ||
{ | ||
public partial class FileStream_FlushAsync : FileSystemTest | ||
{ | ||
[Fact] | ||
public async Task FlushAsyncThrowsForDisposedStream() | ||
{ | ||
using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create)) | ||
{ | ||
fs.Dispose(); | ||
await Assert.ThrowsAsync<ObjectDisposedException>(() => fs.FlushAsync()); | ||
} | ||
} | ||
|
||
[Fact] | ||
public async Task BasicFlushAsyncFunctionality() | ||
{ | ||
using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create)) | ||
{ | ||
fs.WriteByte(0); | ||
await fs.FlushAsync(); | ||
|
||
fs.WriteByte(0xFF); | ||
await fs.FlushAsync(); | ||
} | ||
} | ||
|
||
[Fact] | ||
public async Task FlushAsyncWhenNothingToFlush() | ||
{ | ||
using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create)) | ||
{ | ||
fs.WriteByte(0); | ||
await fs.FlushAsync(); | ||
|
||
await fs.FlushAsync(); | ||
await fs.FlushAsync(); | ||
await fs.FlushAsync(); | ||
} | ||
} | ||
|
||
[Fact] | ||
public async Task FlushAsyncOnReadOnlyFileDoesNotThrow() | ||
{ | ||
string fileName = GetTestFilePath(); | ||
File.WriteAllBytes(fileName, new byte[] { 0 }); | ||
File.SetAttributes(fileName, FileAttributes.ReadOnly); | ||
try | ||
{ | ||
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) | ||
{ | ||
await fs.FlushAsync(); | ||
} | ||
} | ||
finally | ||
{ | ||
File.SetAttributes(fileName, FileAttributes.Normal); | ||
} | ||
} | ||
|
||
[Theory] | ||
[InlineData(null)] | ||
[InlineData(false)] | ||
[InlineData(true)] | ||
public async Task FlushAfterReading(bool? flushToDisk) | ||
{ | ||
string fileName = GetTestFilePath(); | ||
File.WriteAllBytes(fileName, TestBuffer); | ||
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 2)) | ||
{ | ||
Assert.Equal(TestBuffer[0], fs.ReadByte()); | ||
await fs.FlushAsync(); | ||
} | ||
} | ||
|
||
[Fact] | ||
public async Task FlushAsyncWriteWithOtherClient() | ||
{ | ||
string fileName = GetTestFilePath(); | ||
|
||
// ensure that we'll be using a buffer larger than our test data | ||
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, TestBuffer.Length * 2)) | ||
using (FileStream fsr = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) | ||
{ | ||
fs.Write(TestBuffer, 0, TestBuffer.Length); | ||
Assert.Equal(TestBuffer.Length, fs.Length); | ||
|
||
// Make sure that we've actually buffered it, read handle won't see any changes | ||
Assert.Equal(0, fsr.Length); | ||
|
||
// This should cause a write, after it completes the two handles should be in sync | ||
await fs.FlushAsync(); | ||
Assert.Equal(TestBuffer.Length, fsr.Length); | ||
|
||
byte[] buffer = new byte[TestBuffer.Length]; | ||
fsr.Read(buffer, 0, buffer.Length); | ||
Assert.Equal(TestBuffer, buffer); | ||
} | ||
} | ||
|
||
[Fact] | ||
public void FlushAsyncWithCanceledToken() | ||
{ | ||
using (FileStream fs = File.OpenWrite(GetTestFilePath())) | ||
{ | ||
Assert.True(fs.FlushAsync(new CancellationToken(true)).IsCanceled); | ||
} | ||
} | ||
|
||
} | ||
} |
Oops, something went wrong.