public void ReadAsyncDisposedThrows() { using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create)) { fs.Dispose(); Assert.Throws <ObjectDisposedException>(() => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], 0, 1))); // even for noop ReadAsync Assert.Throws <ObjectDisposedException>(() => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], 0, 0))); // out of bounds checking happens first Assert.Throws <ArgumentException>(null, () => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[2], 1, 2))); // count is checked prior Assert.Throws <ArgumentOutOfRangeException>("count", () => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], 0, -1))); // offset is checked prior Assert.Throws <ArgumentOutOfRangeException>("offset", () => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], -1, -1))); // buffer is checked first Assert.Throws <ArgumentNullException>("buffer", () => FSAssert.CompletesSynchronously(fs.ReadAsync(null, -1, -1))); } }
public void ReadOnlyThrows() { string fileName = GetTestFilePath(); using (FileStream fs = new FileStream(fileName, FileMode.Create)) { } using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { Assert.Throws <NotSupportedException>(() => FSAssert.CompletesSynchronously(fs.WriteAsync(new byte[1], 0, 1))); fs.Dispose(); // Disposed checking happens first Assert.Throws <ObjectDisposedException>(() => FSAssert.CompletesSynchronously(fs.WriteAsync(new byte[1], 0, 1))); // out of bounds checking happens first Assert.Throws <ArgumentException>(null, () => FSAssert.CompletesSynchronously(fs.WriteAsync(new byte[2], 1, 2))); // count is checked prior Assert.Throws <ArgumentOutOfRangeException>("count", () => FSAssert.CompletesSynchronously(fs.WriteAsync(new byte[1], 0, -1))); // offset is checked prior Assert.Throws <ArgumentOutOfRangeException>("offset", () => FSAssert.CompletesSynchronously(fs.WriteAsync(new byte[1], -1, -1))); // buffer is checked first Assert.Throws <ArgumentNullException>("buffer", () => FSAssert.CompletesSynchronously(fs.WriteAsync(null, -1, -1))); } }
public void BufferOutOfBoundsThrows() { using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create)) { // offset out of bounds Assert.Throws <ArgumentException>(null, () => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], 1, 1))); // offset out of bounds for 0 count ReadAsync Assert.Throws <ArgumentException>(null, () => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], 2, 0))); // offset out of bounds even for 0 length buffer Assert.Throws <ArgumentException>(null, () => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[0], 1, 0))); // combination offset and count out of bounds Assert.Throws <ArgumentException>(null, () => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[2], 1, 2))); // edges Assert.Throws <ArgumentException>(null, () => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[0], int.MaxValue, 0))); Assert.Throws <ArgumentException>(null, () => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[0], int.MaxValue, int.MaxValue))); } }
public void NullBufferThrows() { using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create)) { Assert.Throws <ArgumentNullException>("buffer", () => FSAssert.CompletesSynchronously(fs.ReadAsync(null, 0, 1))); } }
public void ThrowWhenHandlePositionIsChanged() { string fileName = GetTestFilePath(); using (FileStream fs = new FileStream(fileName, FileMode.Create)) { // write some data to move the position, flush to ensure OS position is updated fs.Write(TestBuffer, 0, TestBuffer.Length); fs.Flush(); if (fs.SafeFileHandle.IsInvalid) { // nothing to test return; } using (FileStream fsr = new FileStream(fs.SafeFileHandle, FileAccess.Read, TestBuffer.Length)) { Assert.Equal(TestBuffer.Length, fs.Position); Assert.Equal(TestBuffer.Length, fsr.Position); // Operations on original filestream will fail if data is in buffer and position changes. // Put data in FS write buffer and update position from FSR fs.WriteByte(0); fsr.Position = 0; Assert.Throws <IOException>(() => fs.Position); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.Read(new byte[1], 0, 1)); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], 0, 1))); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.ReadByte()); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.Seek(0, SeekOrigin.End)); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.SetLength(2)); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.Flush()); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.Dispose()); } } }
public void FileShareWithoutWriteThrows() { string fileName = GetTestFilePath(); // Open without write sharing using (FileStream fs = CreateFileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read | FileShare.Delete)) { FSAssert.ThrowsSharingViolation(() => CreateFileStream(fileName, FileMode.Open, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete)); } }
public void NegativeOffsetThrows() { using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create)) { Assert.Throws <ArgumentOutOfRangeException>("offset", () => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], -1, 1))); // buffer is checked first Assert.Throws <ArgumentNullException>("buffer", () => FSAssert.CompletesSynchronously(fs.ReadAsync(null, -1, 1))); } }
public void FileShareWithoutDeleteThrows() { string fileName = GetTestFilePath(); string newFileName = GetTestFilePath(); // Create without delete sharing using (FileStream fs = CreateFileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) { FSAssert.ThrowsSharingViolation(() => File.Delete(fileName)); FSAssert.ThrowsSharingViolation(() => File.Move(fileName, newFileName)); } Assert.True(File.Exists(fileName)); }
public void CancelledTokenFastPath() { CancellationTokenSource cts = new CancellationTokenSource(); cts.Cancel(); CancellationToken cancelledToken = cts.Token; string fileName = GetTestFilePath(); using (FileStream fs = new FileStream(fileName, FileMode.Create)) { FSAssert.IsCancelled(fs.WriteAsync(new byte[1], 0, 1, cancelledToken), cancelledToken); } using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { // before read only check FSAssert.IsCancelled(fs.WriteAsync(new byte[1], 0, 1, cancelledToken), cancelledToken); fs.Dispose(); // before disposed check FSAssert.IsCancelled(fs.WriteAsync(new byte[1], 0, 1, cancelledToken), cancelledToken); // out of bounds checking happens first Assert.Throws <ArgumentException>(null, () => FSAssert.CompletesSynchronously(fs.WriteAsync(new byte[2], 1, 2, cancelledToken))); // count is checked prior Assert.Throws <ArgumentOutOfRangeException>("count", () => FSAssert.CompletesSynchronously(fs.WriteAsync(new byte[1], 0, -1, cancelledToken))); // offset is checked prior Assert.Throws <ArgumentOutOfRangeException>("offset", () => FSAssert.CompletesSynchronously(fs.WriteAsync(new byte[1], -1, -1, cancelledToken))); // buffer is checked first Assert.Throws <ArgumentNullException>("buffer", () => FSAssert.CompletesSynchronously(fs.WriteAsync(null, -1, -1, cancelledToken))); } }
public void WriteAsyncBufferedCompletesSynchronously() { // It doesn't make sense to spin up a background thread just to do a memcpy. // This isn't working now for useAsync:true since we always have a usercallback // that get's run on the threadpool (see Win32FileStream.EndWriteTask) // This isn't working now for useAsync:false since we always call // Stream.WriteAsync that queues Read on a background thread foreach (bool useAsync in new[] { true, false }) { using (FileStream fs = new FileStream(GetTestFilePath(), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete, TestBuffer.Length * 2, useAsync)) { byte[] buffer = new byte[TestBuffer.Length]; // Existing issue: FileStreamAsyncResult doesn't set CompletedSynchronously correctly. // write should now complete synchronously since it is just copying to the write buffer FSAssert.CompletesSynchronously(fs.WriteAsync(buffer, 0, buffer.Length)); } } }
public async Task ReadAsyncBufferedCompletesSynchronously() { // It doesn't make sense to spin up a background thread just to do a memcpy. string fileName = GetTestFilePath(); using (FileStream fs = new FileStream(fileName, FileMode.Create)) { fs.Write(TestBuffer, 0, TestBuffer.Length); fs.Write(TestBuffer, 0, TestBuffer.Length); } // This isn't working now for useAsync:true since we always have a usercallback // that get's run on the threadpool (see Win32FileStream.EndReadTask) // This isn't working now for useAsync:false since we always call // Stream.ReadAsync that queues Read on a background thread foreach (bool useAsync in new[] { true, false }) { using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete, TestBuffer.Length * 2, useAsync)) { byte[] buffer = new byte[TestBuffer.Length]; // Existing issue: FileStreamAsyncResult doesn't set CompletedSynchronously correctly. // prime the internal buffer Assert.Equal(TestBuffer.Length, await fs.ReadAsync(buffer, 0, buffer.Length)); Assert.Equal(TestBuffer, buffer); Array.Clear(buffer, 0, buffer.Length); // read should now complete synchronously since it is serviced by the read buffer filled in the first request Assert.Equal(TestBuffer.Length, FSAssert.CompletesSynchronously(fs.ReadAsync(buffer, 0, buffer.Length))); Assert.Equal(TestBuffer, buffer); } } }
public void ThrowWhenHandlePositionIsChanged() { string fileName = GetTestFilePath(); using (FileStream fs = new FileStream(fileName, FileMode.Create)) { // write some data to move the position, flush to ensure OS position is updated fs.Write(TestBuffer, 0, TestBuffer.Length); fs.Flush(); if (fs.SafeFileHandle.IsInvalid) { // nothing to test return; } using (FileStream fsr = new FileStream(fs.SafeFileHandle, FileAccess.Read, TestBuffer.Length)) { Assert.Equal(TestBuffer.Length, fs.Position); Assert.Equal(TestBuffer.Length, fsr.Position); // Operations on original filestream will fail if data is in buffer and position changes. // Put data in FS write buffer and update position from FSR fs.WriteByte(0); fsr.Position = 0; Assert.Throws <IOException>(() => fs.Position); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.Read(new byte[1], 0, 1)); fs.WriteByte(0); fsr.Position++; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) // TODO: [ActiveIssue(812)]: Remove guard when async I/O is properly implemented on Unix { Assert.Throws <IOException>(() => FSAssert.CompletesSynchronously(fs.ReadAsync(new byte[1], 0, 1))); } else { Assert.ThrowsAsync <IOException>(() => fs.ReadAsync(new byte[1], 0, 1)).Wait(); } fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.ReadByte()); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.Seek(0, SeekOrigin.End)); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.SetLength(2)); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.Flush()); fs.WriteByte(0); fsr.Position++; Assert.Throws <IOException>(() => fs.Dispose()); } } }