public async Task CreateFileAsync_Throws_An_Exception_If_The_File_Id_Already_Exist() { var expectedFileId = Guid.NewGuid().ToString(); var nonUniqueFileIdProvider = Substitute.For <ITusFileIdProvider>(); nonUniqueFileIdProvider.CreateId(null).ReturnsForAnyArgs(expectedFileId); nonUniqueFileIdProvider.ValidateId(null).ReturnsForAnyArgs(true); var store = new TusDiskStore(_fixture.Path, false, TusDiskBufferSize.Default, nonUniqueFileIdProvider); var fileId = await store.CreateFileAsync(1, null, CancellationToken.None); fileId.ShouldBe(expectedFileId); await store.AppendDataAsync(fileId, new MemoryStream(new[] { (byte)1 }), CancellationToken.None); var filePath = Path.Combine(_fixture.Path, fileId); File.Exists(filePath).ShouldBeTrue(); new FileInfo(filePath).Length.ShouldBe(1); await Assert.ThrowsAnyAsync <Exception>(async() => await store.CreateFileAsync(1, null, CancellationToken.None)); File.Exists(filePath).ShouldBeTrue(); new FileInfo(filePath).Length.ShouldBe(1); }
public async Task AppendDataAsync_Uses_The_Read_And_Write_Buffers_Correctly(int readBufferSize, int writeBufferSize, int fileSize, int expectedNumberOfWrites, int expectedNumberOfReads) { int readsPerWrite = (int)Math.Ceiling((double)writeBufferSize / readBufferSize); var store = new TusDiskStore(_fixture.Path, false, new TusDiskBufferSize(writeBufferSize, readBufferSize)); var totalNumberOfWrites = 0; var totalNumberOfReads = 0; var numberOfReadsSinceLastWrite = 0; var firstWrite = true; int bytesWritten = 0; var fileId = await store.CreateFileAsync(fileSize, null, CancellationToken.None); var requestStream = new RequestStreamFake(async(RequestStreamFake stream, byte[] bufferToFill, int offset, int count, CancellationToken cancellationToken) => { count.ShouldBe(readBufferSize); numberOfReadsSinceLastWrite++; var bytesRead = await stream.ReadBackingStreamAsync(bufferToFill, offset, count, cancellationToken); // Need to subtract from readsPerWrite due to this expression being checked _after_ the write has happened. var previousReadShouldHaveTriggeredWrite = numberOfReadsSinceLastWrite == readsPerWrite - (firstWrite ? 0 : 1) + 1; if (bytesRead != 0 && previousReadShouldHaveTriggeredWrite) { numberOfReadsSinceLastWrite = 0; firstWrite = false; GetLengthFromFileOnDisk().ShouldBe(bytesWritten); totalNumberOfWrites++; } totalNumberOfReads++; bytesWritten += bytesRead; return(bytesRead); }, new byte[fileSize]); await store.AppendDataAsync(fileId, requestStream, CancellationToken.None); GetLengthFromFileOnDisk().ShouldBe(fileSize); totalNumberOfWrites++; // -1 due to the last read returning 0 bytes as the stream is then drained Assert.Equal(expectedNumberOfReads, totalNumberOfReads - 1); Assert.Equal(expectedNumberOfWrites, totalNumberOfWrites); long GetLengthFromFileOnDisk() { return(new FileInfo(Path.Combine(_fixture.Path, fileId)).Length); } }
public async Task CreateFileAsync_Uses_The_Provided_TusFileIdProvider_To_Create_Ids() { var customProvider = Substitute.For <ITusFileIdProvider>(); var customFileId = 0; var createIdCalls = 0; customProvider.CreateId(null).ReturnsForAnyArgs(_ => (++customFileId).ToString()).AndDoes(_ => createIdCalls++); customProvider.ValidateId(null).ReturnsForAnyArgs(true); var store = new TusDiskStore(_fixture.Path, true, TusDiskBufferSize.Default, customProvider); for (var i = 0; i < 10; i++) { var fileId = await store.CreateFileAsync(i, null, CancellationToken.None); fileId.ShouldBe(customFileId.ToString()); var filePath = Path.Combine(_fixture.Path, fileId); File.Exists(filePath).ShouldBeTrue(); createIdCalls.ShouldBe(i + 1); } }
public async Task AppendDataAsync_Uses_The_Read_And_Write_Buffers_Correctly(int readBufferSize, int writeBufferSize, int fileSize, int expectedNumberOfWrites, int expectedNumberOfReads) { int numberOfReadsPerWrite = (int)Math.Ceiling((double)writeBufferSize / readBufferSize); var store = new TusDiskStore(_fixture.Path, false, new TusDiskBufferSize(writeBufferSize, readBufferSize)); var totalNumberOfWrites = 0; var totalNumberOfReads = 0; var numberOfReadsSinceLastWrite = 0; int totalBytesWritten = 0; var fileId = await store.CreateFileAsync(fileSize, null, CancellationToken.None); var requestStream = new RequestStreamFake(async(RequestStreamFake stream, byte[] bufferToFill, int offset, int count, CancellationToken cancellationToken) => { count.ShouldBe(readBufferSize); var bytesReadFromStream = await stream.ReadBackingStreamAsync(bufferToFill, offset, count, cancellationToken); // There should have been a write after the previous read. if (numberOfReadsSinceLastWrite > numberOfReadsPerWrite) { // Calculate the amount of data that should have been written to disk so far. var expectedFileSizeRightNow = CalculateExpectedFileSize(totalNumberOfReads, readBufferSize, writeBufferSize); // Assert that the size on disk is correct. GetLengthFromFileOnDisk().ShouldBe(expectedFileSizeRightNow); totalNumberOfWrites++; // Set to one as the write happened on the previous write, making this the second read since that write. numberOfReadsSinceLastWrite = 1; } numberOfReadsSinceLastWrite++; totalNumberOfReads++; totalBytesWritten += bytesReadFromStream; return(bytesReadFromStream); }, new byte[fileSize]); await store.AppendDataAsync(fileId, requestStream, CancellationToken.None); GetLengthFromFileOnDisk().ShouldBe(fileSize); totalNumberOfWrites++; // -1 due to the last read returning 0 bytes as the stream is then drained Assert.Equal(expectedNumberOfReads, totalNumberOfReads - 1); Assert.Equal(expectedNumberOfWrites, totalNumberOfWrites); long GetLengthFromFileOnDisk() { return(new FileInfo(Path.Combine(_fixture.Path, fileId)).Length); } }