mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-23 07:25:11 +00:00
add more tests
This commit is contained in:
129
tests/SharpCompress.Test/Tar/TarWriterNonSeekableTests.cs
Normal file
129
tests/SharpCompress.Test/Tar/TarWriterNonSeekableTests.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Archives.Tar;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Test.Mocks;
|
||||
using SharpCompress.Writers.Tar;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpCompress.Test.Tar;
|
||||
|
||||
/// <summary>
|
||||
/// Regression tests for writing tar archives to non-seekable (forward-only) output streams.
|
||||
/// Tar is a forward-only format with no header back-patching, so streaming to a
|
||||
/// <see cref="ForwardOnlyStream"/> must produce a valid, readable archive. The sources are
|
||||
/// seekable so the writer can derive each entry's size up front (see TarWriter.cs).
|
||||
/// </summary>
|
||||
public class TarWriterNonSeekableTests
|
||||
{
|
||||
private static readonly DateTime FixedModificationTime = new(2024, 5, 15, 10, 30, 0);
|
||||
|
||||
private static (string Name, byte[] Content)[] CreateStreamingTestEntries() =>
|
||||
[
|
||||
(
|
||||
"first.txt",
|
||||
Encoding.UTF8.GetBytes(
|
||||
string.Concat(Enumerable.Repeat("Hello streaming tar! ", 500))
|
||||
)
|
||||
),
|
||||
(
|
||||
"nested/second.txt",
|
||||
Encoding.UTF8.GetBytes(
|
||||
string.Concat(Enumerable.Repeat("Another entry with different content. ", 300))
|
||||
)
|
||||
),
|
||||
];
|
||||
|
||||
private static async Task<byte[]> WriteArchiveToNonSeekableAsync(
|
||||
(string Name, byte[] Content)[] entries
|
||||
)
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
await using (
|
||||
var writer = new TarWriter(
|
||||
new ForwardOnlyStream(ms),
|
||||
new TarWriterOptions(CompressionType.None, true)
|
||||
)
|
||||
)
|
||||
{
|
||||
foreach (var (name, content) in entries)
|
||||
{
|
||||
using var source = new MemoryStream(content);
|
||||
await writer.WriteAsync(name, source, FixedModificationTime);
|
||||
}
|
||||
}
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
private static byte[] WriteArchiveToNonSeekableSync((string Name, byte[] Content)[] entries)
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
using (
|
||||
var writer = new TarWriter(
|
||||
new ForwardOnlyStream(ms),
|
||||
new TarWriterOptions(CompressionType.None, true)
|
||||
)
|
||||
)
|
||||
{
|
||||
foreach (var (name, content) in entries)
|
||||
{
|
||||
using var source = new MemoryStream(content);
|
||||
writer.Write(name, source, FixedModificationTime);
|
||||
}
|
||||
}
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
private static async Task AssertRoundTripsAsync(
|
||||
byte[] tar,
|
||||
(string Name, byte[] Content)[] entries
|
||||
)
|
||||
{
|
||||
using var archive = TarArchive.OpenArchive(new MemoryStream(tar));
|
||||
var fileEntries = archive.Entries.Where(e => !e.IsDirectory).ToList();
|
||||
Assert.Equal(entries.Length, fileEntries.Count);
|
||||
foreach (var (name, content) in entries)
|
||||
{
|
||||
var entry = fileEntries.Single(e => e.Key == name);
|
||||
using var extracted = new MemoryStream();
|
||||
#if LEGACY_DOTNET
|
||||
using (var entryStream = await entry.OpenEntryStreamAsync())
|
||||
#else
|
||||
await using (var entryStream = await entry.OpenEntryStreamAsync())
|
||||
#endif
|
||||
{
|
||||
await entryStream.CopyToAsync(extracted);
|
||||
}
|
||||
Assert.Equal(content, extracted.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Tar_Async_NonSeekable_RoundTrips()
|
||||
{
|
||||
var entries = CreateStreamingTestEntries();
|
||||
var tar = await WriteArchiveToNonSeekableAsync(entries);
|
||||
await AssertRoundTripsAsync(tar, entries);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Tar_Sync_NonSeekable_RoundTrips()
|
||||
{
|
||||
var entries = CreateStreamingTestEntries();
|
||||
var tar = WriteArchiveToNonSeekableSync(entries);
|
||||
await AssertRoundTripsAsync(tar, entries);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Tar_Async_NonSeekable_Matches_Sync_Output()
|
||||
{
|
||||
var entries = CreateStreamingTestEntries();
|
||||
var asyncTar = await WriteArchiveToNonSeekableAsync(entries);
|
||||
var syncTar = WriteArchiveToNonSeekableSync(entries);
|
||||
|
||||
Assert.Equal(syncTar, asyncTar);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user