Ejemplo n.º 1
0
        public async Task CreateFinalFileAsync_Deletes_Partial_Files_If_Configuration_Says_So()
        {
            // Use default constructor (implying cleanup = false)
            var store = new TusDiskStore(_fixture.Path);

            var p1 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            var p2 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            await store.AppendDataAsync(p1, new MemoryStream(new byte[] { 1 }), CancellationToken.None);

            await store.AppendDataAsync(p2, new MemoryStream(new byte[] { 2 }), CancellationToken.None);

            _ = await store.CreateFinalFileAsync(new[] { p1, p2 }, null, CancellationToken.None);

            (await store.FileExistAsync(p1, CancellationToken.None)).ShouldBeTrue();
            (await store.FileExistAsync(p2, CancellationToken.None)).ShouldBeTrue();

            // Cleanup = true
            store = new TusDiskStore(_fixture.Path, true);

            p1 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            p2 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            await store.AppendDataAsync(p1, new MemoryStream(new byte[] { 1 }), CancellationToken.None);

            await store.AppendDataAsync(p2, new MemoryStream(new byte[] { 2 }), CancellationToken.None);

            _ = await store.CreateFinalFileAsync(new[] { p1, p2 }, null, CancellationToken.None);

            (await store.FileExistAsync(p1, CancellationToken.None)).ShouldBeFalse();
            (await store.FileExistAsync(p2, CancellationToken.None)).ShouldBeFalse();

            // Assert that all files are gone (regression on bug)
            var p1Files = Directory.EnumerateFiles(_fixture.Path, p1 + "*");

            p1Files.Any().ShouldBeFalse("Meta files for partial file 1 has not been deleted");

            var p2Files = Directory.EnumerateFiles(_fixture.Path, p2 + "*");

            p2Files.Any().ShouldBeFalse("Meta files for partial file 1 has not been deleted");

            // Cleanup = false
            store = new TusDiskStore(_fixture.Path, false);

            p1 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            p2 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            await store.AppendDataAsync(p1, new MemoryStream(new byte[] { 1 }), CancellationToken.None);

            await store.AppendDataAsync(p2, new MemoryStream(new byte[] { 2 }), CancellationToken.None);

            _ = await store.CreateFinalFileAsync(new[] { p1, p2 }, null, CancellationToken.None);

            (await store.FileExistAsync(p1, CancellationToken.None)).ShouldBeTrue();
            (await store.FileExistAsync(p2, CancellationToken.None)).ShouldBeTrue();
        }
Ejemplo n.º 2
0
        public async Task CreateFinalFileAsync_Deletes_Partial_Files_If_Configuration_Says_So()
        {
            // Use default constructor.
            var store = new TusDiskStore(_fixture.Path);

            var p1 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            var p2 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            await store.AppendDataAsync(p1, new MemoryStream(new byte[] { 1 }), CancellationToken.None);

            await store.AppendDataAsync(p2, new MemoryStream(new byte[] { 2 }), CancellationToken.None);

            var f = await store.CreateFinalFileAsync(new[] { p1, p2 }, null, CancellationToken.None);

            f.ShouldNotBeNullOrWhiteSpace();
            (await store.FileExistAsync(p1, CancellationToken.None)).ShouldBeTrue();
            (await store.FileExistAsync(p2, CancellationToken.None)).ShouldBeTrue();

            // Cleanup = true
            store = new TusDiskStore(_fixture.Path, true);

            p1 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            p1.ShouldNotBeNullOrWhiteSpace();
            p2 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            p2.ShouldNotBeNullOrWhiteSpace();

            await store.AppendDataAsync(p1, new MemoryStream(new byte[] { 1 }), CancellationToken.None);

            await store.AppendDataAsync(p2, new MemoryStream(new byte[] { 2 }), CancellationToken.None);

            f = await store.CreateFinalFileAsync(new[] { p1, p2 }, null, CancellationToken.None);

            f.ShouldNotBeNullOrWhiteSpace();
            (await store.FileExistAsync(p1, CancellationToken.None)).ShouldBeFalse();
            (await store.FileExistAsync(p2, CancellationToken.None)).ShouldBeFalse();

            // Cleanup = false
            store = new TusDiskStore(_fixture.Path, false);

            p1 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            p2 = await store.CreatePartialFileAsync(1, null, CancellationToken.None);

            await store.AppendDataAsync(p1, new MemoryStream(new byte[] { 1 }), CancellationToken.None);

            await store.AppendDataAsync(p2, new MemoryStream(new byte[] { 2 }), CancellationToken.None);

            f = await store.CreateFinalFileAsync(new[] { p1, p2 }, null, CancellationToken.None);

            f.ShouldNotBeNullOrWhiteSpace();
            (await store.FileExistAsync(p1, CancellationToken.None)).ShouldBeTrue();
            (await store.FileExistAsync(p2, CancellationToken.None)).ShouldBeTrue();
        }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
            }
        }