Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/SharpCompress/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,9 @@
"net10.0": {
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[10.0.0, )",
"resolved": "10.0.0",
"contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA=="
"requested": "[10.0.2, )",
"resolved": "10.0.2",
"contentHash": "sXdDtMf2qcnbygw9OdE535c2lxSxrZP8gO4UhDJ0xiJbl1wIqXS1OTcTDFTIJPOFd6Mhcm8gPEthqWGUxBsTqw=="
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",
Expand Down Expand Up @@ -264,9 +264,9 @@
"net8.0": {
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[8.0.22, )",
"resolved": "8.0.22",
"contentHash": "MhcMithKEiyyNkD2ZfbDZPmcOdi0GheGfg8saEIIEfD/fol3iHmcV8TsZkD4ZYz5gdUuoX4YtlVySUU7Sxl9SQ=="
"requested": "[8.0.23, )",
"resolved": "8.0.23",
"contentHash": "GqHiB1HbbODWPbY/lc5xLQH8siEEhNA0ptpJCC6X6adtAYNEzu5ZlqV3YHA3Gh7fuEwgA8XqVwMtH2KNtuQM1Q=="
},
"Microsoft.NETFramework.ReferenceAssemblies": {
"type": "Direct",
Expand Down
243 changes: 243 additions & 0 deletions tests/SharpCompress.Test/Rar/Rar5AsyncExtractionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using SharpCompress.Archives;
using SharpCompress.Archives.Rar;
using SharpCompress.Common;
using SharpCompress.Readers;
using SharpCompress.Test.Mocks;
using Xunit;

namespace SharpCompress.Test.Rar;

/// <summary>
/// Tests specifically designed to exercise the Unpack5Async code path for RAR5 archives.
/// These tests use AsyncOnlyStream to ensure that async methods are actually being called.
/// </summary>
public class Rar5AsyncExtractionTests : ArchiveTests
{
[Fact]
public async Task Rar5_Basic_Reader_ExtractAll_Async()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar5.rar"));
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));

while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
}
}
VerifyFiles();
}

[Fact]
public async Task Rar5_None_Reader_ExtractAll_Async()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar5.none.rar"));
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));

while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
}
}
VerifyFiles();
}

[Fact]
public async Task Rar5_Solid_ExtractAllEntries_Async()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar5.solid.rar"));
await using var archive = RarArchive.OpenAsyncArchive(new AsyncOnlyStream(stream));

Assert.True(await archive.IsSolidAsync());

await using var reader = await archive.ExtractAllEntriesAsync();
while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
}
}
VerifyFiles();
}

[Fact]
public async Task Rar5_Solid_Reader_ExtractAll_Async()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar5.solid.rar"));
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));

while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
}
}
VerifyFiles();
}

[Fact]
public async Task Rar5_Reader_OpenEntryStream_Async()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar5.rar"));
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));

while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
var entryStream = await reader.OpenEntryStreamAsync();
try
{
var file = Path.GetFileName(reader.Entry.Key).NotNull();
var folder = Path.GetDirectoryName(reader.Entry.Key) ?? "";
var destdir = Path.Combine(SCRATCH_FILES_PATH, folder);
if (!Directory.Exists(destdir))
{
Directory.CreateDirectory(destdir);
}
var destinationFileName = Path.Combine(destdir, file);

using var fs = File.OpenWrite(destinationFileName);
await entryStream.CopyToAsync(fs);
}
finally
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
await entryStream.DisposeAsync();
#else
entryStream.Dispose();
#endif
}
}
}
VerifyFiles();
}

[Fact]
public async Task Rar5_Encrypted_FilesOnly_Reader_Async()
{
using var stream = File.OpenRead(
Path.Combine(TEST_ARCHIVES_PATH, "Rar5.encrypted_filesOnly.rar")
);
await using var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
new ReaderOptions { Password = "test" }
);

while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
}
}
VerifyFiles();
}

[Fact]
public async Task Rar5_Encrypted_FilesAndHeader_Reader_Async()
{
using var stream = File.OpenRead(
Path.Combine(TEST_ARCHIVES_PATH, "Rar5.encrypted_filesAndHeader.rar")
);
await using var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
new ReaderOptions { Password = "test" }
);

while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
}
}
VerifyFiles();
}

[Fact]
public async Task Rar5_CRC_Blake2_Reader_Async()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar5.crc_blake2.rar"));
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));

while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
}
}
VerifyFiles();
}

[Fact]
public async Task Rar5_Comment_Reader_Async()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar5.comment.rar"));
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));

while (await reader.MoveToNextEntryAsync())
{
if (!reader.Entry.IsDirectory)
{
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
}
}
VerifyFiles();
}

[Fact]
public async Task Rar5_Solid_Skip_Some_Entries_Reader_Async()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar5.solid.rar"));
await using var reader = await ReaderFactory.OpenAsyncReader(new AsyncOnlyStream(stream));

while (await reader.MoveToNextEntryAsync())
{
// Only extract jpg files to test skipping in solid archive
if (!reader.Entry.IsDirectory && reader.Entry.Key.NotNull().Contains("jpg"))
{
Assert.Equal(CompressionType.Rar, reader.Entry.CompressionType);
await reader.WriteEntryToDirectoryAsync(SCRATCH_FILES_PATH);
}
}
}

[Fact]
public async Task Rar5_WriteToDirectory_Async()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar5.rar"));
await using var archive = RarArchive.OpenAsyncArchive(new AsyncOnlyStream(stream));

await archive.WriteToDirectoryAsync(SCRATCH_FILES_PATH);
VerifyFiles();
}

[Fact]
public async Task Rar5_Solid_WriteToDirectory_Async()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar5.solid.rar"));
await using var archive = RarArchive.OpenAsyncArchive(new AsyncOnlyStream(stream));

Assert.True(await archive.IsSolidAsync());
await archive.WriteToDirectoryAsync(SCRATCH_FILES_PATH);
VerifyFiles();
}
}