Files

273 lines
9.0 KiB
C#

using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using SharpCompress.Archives;
using SharpCompress.Archives.GZip;
using SharpCompress.Archives.Zip;
using SharpCompress.Common;
using SharpCompress.Compressors;
using SharpCompress.Compressors.Deflate;
using SharpCompress.Readers;
using SharpCompress.Test.Mocks;
using SharpCompress.Writers;
using Xunit;
namespace SharpCompress.Test.GZip;
public class AsyncTests : TestBase
{
[Fact]
public async ValueTask Reader_Async_Extract_All()
{
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
#if NETFRAMEWORK
using var stream = File.OpenRead(testArchive);
#else
await using var stream = File.OpenRead(testArchive);
#endif
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));
await reader.WriteAllToDirectoryAsync(SCRATCH_FILES_PATH);
// Just verify some files were extracted
var extractedFiles = Directory.GetFiles(
SCRATCH_FILES_PATH,
"*",
SearchOption.AllDirectories
);
Assert.True(extractedFiles.Length > 0, "No files were extracted");
}
[Fact]
public async ValueTask Reader_Async_Extract_Single_Entry()
{
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
#if NETFRAMEWORK
using var stream = File.OpenRead(testArchive);
#else
await using var stream = File.OpenRead(testArchive);
#endif
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));
while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
var outputPath = Path.Combine(SCRATCH_FILES_PATH, reader.Entry.Key!);
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
#if NETFRAMEWORK
using var outputStream = File.Create(outputPath);
#else
await using var outputStream = File.Create(outputPath);
#endif
await reader.WriteEntryToAsync(outputStream);
break; // Just test one entry
}
}
}
[Fact]
public async ValueTask Archive_Entry_Async_Open_Stream()
{
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
await using var archive = GZipArchive.OpenAsyncArchive(
new AsyncOnlyStream(File.OpenRead(testArchive))
);
await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory).Take(1))
{
#if NETFRAMEWORK
using var entryStream = await entry.OpenEntryStreamAsync();
#else
await using var entryStream = await entry.OpenEntryStreamAsync();
#endif
Assert.NotNull(entryStream);
Assert.True(entryStream.CanRead);
// Read some data to verify it works
var buffer = new byte[1024];
var read = await entryStream.ReadAsync(buffer, 0, buffer.Length);
Assert.True(read > 0);
}
}
[Fact]
public async ValueTask Writer_Async_Write_Single_File()
{
var outputPath = Path.Combine(SCRATCH_FILES_PATH, "async_test.zip");
#if NETFRAMEWORK
using (var stream = File.Create(outputPath))
#else
await using (var stream = File.Create(outputPath))
#endif
using (
var writer = WriterFactory.OpenAsyncWriter(
new AsyncOnlyStream(stream),
ArchiveType.Zip,
new WriterOptions(CompressionType.Deflate) { LeaveStreamOpen = false }
)
)
{
var testFile = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
#if NETFRAMEWORK
using var fileStream = File.OpenRead(testFile);
#else
await using var fileStream = File.OpenRead(testFile);
#endif
await writer.WriteAsync("test_entry.bin", fileStream, new DateTime(2023, 1, 1));
}
// Verify the archive was created and contains the entry
Assert.True(File.Exists(outputPath));
await using var archive = ZipArchive.OpenAsyncArchive(outputPath);
Assert.Single(await archive.EntriesAsync.Where(e => !e.IsDirectory).ToListAsync());
}
[Fact]
public async ValueTask Async_With_Cancellation_Token()
{
using var cts = new CancellationTokenSource();
cts.CancelAfter(10000); // 10 seconds should be plenty
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
#if NETFRAMEWORK
using var stream = File.OpenRead(testArchive);
#else
await using var stream = File.OpenRead(testArchive);
#endif
await using var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
cancellationToken: cts.Token
);
await reader.WriteAllToDirectoryAsync(SCRATCH_FILES_PATH, cts.Token);
// Just verify some files were extracted
var extractedFiles = Directory.GetFiles(
SCRATCH_FILES_PATH,
"*",
SearchOption.AllDirectories
);
Assert.True(extractedFiles.Length > 0, "No files were extracted");
}
[Fact]
public async ValueTask Stream_Extensions_Async()
{
var testFile = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
var outputPath = Path.Combine(SCRATCH_FILES_PATH, "async_copy.bin");
#if NETFRAMEWORK
using var inputStream = File.OpenRead(testFile);
using var outputStream = File.Create(outputPath);
#else
await using var inputStream = File.OpenRead(testFile);
await using var outputStream = File.Create(outputPath);
#endif
// Test the async extension method
var buffer = new byte[8192];
int bytesRead;
while ((bytesRead = await inputStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await outputStream.WriteAsync(buffer, 0, bytesRead);
}
Assert.True(File.Exists(outputPath));
Assert.True(new FileInfo(outputPath).Length > 0);
}
[Fact]
public async ValueTask EntryStream_ReadAsync_Works()
{
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz");
#if NETFRAMEWORK
using var stream = File.OpenRead(testArchive);
#else
await using var stream = File.OpenRead(testArchive);
#endif
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));
while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
#if NETFRAMEWORK
using var entryStream = await reader.OpenEntryStreamAsync();
#else
await using var entryStream = await reader.OpenEntryStreamAsync();
#endif
var buffer = new byte[4096];
var totalRead = 0;
int bytesRead;
// Test ReadAsync on EntryStream
while ((bytesRead = await entryStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
totalRead += bytesRead;
}
Assert.True(totalRead > 0, "Should have read some data from entry stream");
break; // Test just one entry
}
}
}
[Fact]
public async ValueTask CompressionStream_Async_ReadWrite()
{
var testData = new byte[1024];
new Random(42).NextBytes(testData);
var compressedPath = Path.Combine(SCRATCH_FILES_PATH, "async_compressed.gz");
// Test async write with GZipStream
#if NETFRAMEWORK
using (var fileStream = File.Create(compressedPath))
using (var gzipStream = new GZipStream(fileStream, CompressionMode.Compress))
#else
await using (var fileStream = File.Create(compressedPath))
await using (var gzipStream = new GZipStream(fileStream, CompressionMode.Compress))
#endif
{
await gzipStream.WriteAsync(testData, 0, testData.Length);
await gzipStream.FlushAsync();
}
Assert.True(File.Exists(compressedPath));
Assert.True(new FileInfo(compressedPath).Length > 0);
#if NETFRAMEWORK
using (var fileStream = File.OpenRead(compressedPath))
using (var gzipStream = new GZipStream(fileStream, CompressionMode.Decompress))
#else
// Test async read with GZipStream
await using (var fileStream = File.OpenRead(compressedPath))
await using (var gzipStream = new GZipStream(fileStream, CompressionMode.Decompress))
#endif
{
var decompressed = new byte[testData.Length];
var totalRead = 0;
int bytesRead;
while (
totalRead < decompressed.Length
&& (
bytesRead = await gzipStream.ReadAsync(
decompressed,
totalRead,
decompressed.Length - totalRead
)
) > 0
)
{
totalRead += bytesRead;
}
Assert.Equal(testData.Length, totalRead);
Assert.Equal(testData, decompressed);
}
}
}