mirror of
https://github.com/aaru-dps/Aaru.git
synced 2026-07-08 17:56:18 +00:00
Add ArchiveTest class and update Structs for archive testing
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Aaru.Archives\Aaru.Archives.csproj"/>
|
||||
<ProjectReference Include="..\Aaru.Checksums\Aaru.Checksums.csproj"/>
|
||||
<ProjectReference Include="..\Aaru.CommonTypes\Aaru.CommonTypes.csproj"/>
|
||||
<ProjectReference Include="..\Aaru.Core\Aaru.Core.csproj"/>
|
||||
|
||||
179
Aaru.Tests/Archives/ArchiveTest.cs
Normal file
179
Aaru.Tests/Archives/ArchiveTest.cs
Normal file
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using Aaru.CommonTypes;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.CommonTypes.Structs;
|
||||
using Aaru.Core;
|
||||
using FluentAssertions;
|
||||
using FluentAssertions.Execution;
|
||||
using NUnit.Framework;
|
||||
using FileAttributes = Aaru.CommonTypes.Structs.FileAttributes;
|
||||
|
||||
namespace Aaru.Tests.Archives;
|
||||
|
||||
public abstract class ArchiveTest
|
||||
{
|
||||
public abstract string DataFolder { get; }
|
||||
public abstract IArchive Plugin { get; }
|
||||
public abstract ArchiveTestExpected[] Tests { get; }
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void InitTest() => PluginBase.Init();
|
||||
|
||||
[Test]
|
||||
public void Identify()
|
||||
{
|
||||
Environment.CurrentDirectory = DataFolder;
|
||||
|
||||
using(new AssertionScope())
|
||||
{
|
||||
foreach(ArchiveTestExpected test in Tests)
|
||||
{
|
||||
string testFile = test.TestFile;
|
||||
|
||||
bool exists = File.Exists(testFile);
|
||||
exists.Should().BeTrue(Localization._0_not_found, testFile);
|
||||
|
||||
if(!exists) continue;
|
||||
|
||||
IFilter filter = PluginRegister.Singleton.GetFilter(testFile);
|
||||
filter.Should().NotBeNull(Localization.Filter_0, testFile);
|
||||
|
||||
ErrorNumber openedFilter = filter.Open(testFile);
|
||||
openedFilter.Should().Be(ErrorNumber.NoError, string.Format(Localization.Open_0, testFile));
|
||||
|
||||
if(openedFilter != ErrorNumber.NoError) continue;
|
||||
|
||||
var archive = Activator.CreateInstance(Plugin.GetType()) as IArchive;
|
||||
archive.Should().NotBeNull(Localization.Could_not_instantiate_filesystem_for_0, testFile);
|
||||
|
||||
archive.Identify(filter).Should().BeTrue(Localization.Not_identified_for_0, testFile);
|
||||
|
||||
filter.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Contents()
|
||||
{
|
||||
Environment.CurrentDirectory = DataFolder;
|
||||
|
||||
using(new AssertionScope())
|
||||
{
|
||||
foreach(ArchiveTestExpected test in Tests)
|
||||
{
|
||||
string testFile = test.TestFile;
|
||||
|
||||
bool exists = File.Exists(testFile);
|
||||
exists.Should().BeTrue(Localization._0_not_found, testFile);
|
||||
|
||||
if(!exists) continue;
|
||||
|
||||
IFilter filter = PluginRegister.Singleton.GetFilter(testFile);
|
||||
filter.Should().NotBeNull(Localization.Filter_0, testFile);
|
||||
|
||||
ErrorNumber openedFilter = filter.Open(testFile);
|
||||
openedFilter.Should().Be(ErrorNumber.NoError, string.Format(Localization.Open_0, testFile));
|
||||
|
||||
if(openedFilter != ErrorNumber.NoError) continue;
|
||||
|
||||
var archive = Activator.CreateInstance(Plugin.GetType()) as IArchive;
|
||||
archive.Should().NotBeNull(Localization.Could_not_instantiate_filesystem_for_0, testFile);
|
||||
|
||||
ErrorNumber openedArchive = archive.Open(filter, Encoding.ASCII);
|
||||
openedArchive.Should().Be(ErrorNumber.NoError, string.Format(Localization.Open_0, testFile));
|
||||
|
||||
if(openedArchive != ErrorNumber.NoError)
|
||||
{
|
||||
filter.Close();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
archive.NumberOfEntries.Should()
|
||||
.Be(test.EntryCount,
|
||||
string.Format(Localization.Expected_0_partitions_in_1_but_found_2,
|
||||
test.EntryCount,
|
||||
testFile,
|
||||
archive.NumberOfEntries));
|
||||
|
||||
ArchiveEntryData[] expectedEntries = test.Contents;
|
||||
|
||||
if(expectedEntries is null && File.Exists($"{testFile}.contents.json"))
|
||||
{
|
||||
JsonSerializerOptions serializerOptions = new()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
using FileStream stream = new($"{testFile}.contents.json", FileMode.Open, FileAccess.Read);
|
||||
expectedEntries = JsonSerializer.Deserialize<ArchiveEntryData[]>(stream, serializerOptions);
|
||||
}
|
||||
|
||||
expectedEntries.Should().NotBeNull();
|
||||
|
||||
if(expectedEntries is null)
|
||||
{
|
||||
filter.Close();
|
||||
archive.Close();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
expectedEntries.Length.Should()
|
||||
.Be(archive.NumberOfEntries,
|
||||
string.Format(Localization.Expected_0_partitions_in_1_but_found_2,
|
||||
expectedEntries.Length,
|
||||
testFile,
|
||||
archive.NumberOfEntries));
|
||||
|
||||
using(new AssertionScope())
|
||||
{
|
||||
for(var i = 0; i < archive.NumberOfEntries; i++)
|
||||
{
|
||||
ErrorNumber filenameErrno = archive.GetFilename(i, out string fileName);
|
||||
|
||||
filenameErrno.Should()
|
||||
.Be(ErrorNumber.NoError,
|
||||
string.Format(Localization.Cannot_open_image_for_0, testFile));
|
||||
|
||||
ErrorNumber statErrno = archive.Stat(i, out FileEntryInfo stat);
|
||||
|
||||
statErrno.Should()
|
||||
.Be(ErrorNumber.NoError,
|
||||
string.Format(Localization.Cannot_open_image_for_0, testFile));
|
||||
|
||||
string entryType = GetEntryType(stat.Attributes);
|
||||
long entrySize = stat.Length;
|
||||
|
||||
fileName.Should().Be(expectedEntries[i].Path, testFile);
|
||||
entryType.Should().Be(expectedEntries[i].Type, testFile);
|
||||
entrySize.Should().Be(expectedEntries[i].Size, testFile);
|
||||
}
|
||||
}
|
||||
|
||||
archive.Close();
|
||||
filter.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static string GetEntryType(FileAttributes attributes)
|
||||
{
|
||||
if(attributes.HasFlag(FileAttributes.Directory)) return "directory";
|
||||
|
||||
if(attributes.HasFlag(FileAttributes.Symlink)) return "symlink";
|
||||
|
||||
if(attributes.HasFlag(FileAttributes.CharDevice)) return "chardevice";
|
||||
|
||||
if(attributes.HasFlag(FileAttributes.BlockDevice)) return "blockdevice";
|
||||
|
||||
if(attributes.HasFlag(FileAttributes.FIFO)) return "fifo";
|
||||
|
||||
return "file";
|
||||
}
|
||||
}
|
||||
@@ -10,12 +10,12 @@ public class MediaInfoTest
|
||||
{
|
||||
/// <summary>Expected media type</summary>
|
||||
public MediaType MediaType;
|
||||
/// <summary>Expected number of sectors in media</summary>
|
||||
public ulong Sectors;
|
||||
/// <summary>Expected media sector size</summary>
|
||||
public uint SectorSize;
|
||||
public uint SectorSize;
|
||||
/// <summary>Expected number of sectors in media</summary>
|
||||
public ulong Sectors;
|
||||
/// <summary>File that contains the image to test</summary>
|
||||
public string TestFile;
|
||||
public string TestFile;
|
||||
|
||||
public override string ToString() => TestFile;
|
||||
}
|
||||
@@ -25,25 +25,25 @@ public class MediaInfoTest
|
||||
public class FileSystemTest : MediaInfoTest
|
||||
{
|
||||
/// <summary>Application ID</summary>
|
||||
public string ApplicationId;
|
||||
public string ApplicationId;
|
||||
/// <summary>Can the volume boot?</summary>
|
||||
public bool Bootable;
|
||||
/// <summary>Clusters in volume</summary>
|
||||
public long Clusters;
|
||||
public bool Bootable;
|
||||
/// <summary>Bytes per cluster</summary>
|
||||
public uint ClusterSize;
|
||||
public uint ClusterSize;
|
||||
/// <summary>Clusters in volume</summary>
|
||||
public long Clusters;
|
||||
public Dictionary<string, FileData> Contents;
|
||||
public string ContentsJson;
|
||||
public Encoding Encoding;
|
||||
public string Namespace;
|
||||
/// <summary>System or OEM ID</summary>
|
||||
public string SystemId;
|
||||
public string SystemId;
|
||||
/// <summary>Filesystem type. null if always the same, as defined in test class</summary>
|
||||
public string Type;
|
||||
public string Type;
|
||||
/// <summary>Volume name</summary>
|
||||
public string VolumeName;
|
||||
public string VolumeName;
|
||||
/// <summary>Volume serial number or set identifier</summary>
|
||||
public string VolumeSerial;
|
||||
public string VolumeSerial;
|
||||
}
|
||||
|
||||
public class BlockImageTestExpected : MediaInfoTest
|
||||
@@ -52,6 +52,24 @@ public class BlockImageTestExpected : MediaInfoTest
|
||||
public BlockPartitionVolumes[] Partitions;
|
||||
}
|
||||
|
||||
public class ArchiveTestExpected
|
||||
{
|
||||
public ArchiveEntryData[] Contents;
|
||||
public string ContentsJson;
|
||||
public int EntryCount;
|
||||
public string TestFile;
|
||||
|
||||
public override string ToString() => TestFile;
|
||||
}
|
||||
|
||||
public class ArchiveEntryData
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public long Size { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string LinkTarget { get; set; }
|
||||
}
|
||||
|
||||
public class TrackInfoTestExpected
|
||||
{
|
||||
public ulong End;
|
||||
@@ -78,24 +96,24 @@ public class TapeImageTestExpected : BlockImageTestExpected
|
||||
|
||||
public class FluxCaptureTestExpected
|
||||
{
|
||||
/// <summary>Capture index for this head/track/subTrack combination</summary>
|
||||
public uint CaptureIndex;
|
||||
/// <summary>Expected data resolution in picoseconds</summary>
|
||||
public ulong DataResolution;
|
||||
/// <summary>Physical head (0-based)</summary>
|
||||
public uint Head;
|
||||
public uint Head;
|
||||
/// <summary>Expected index resolution in picoseconds</summary>
|
||||
public ulong IndexResolution;
|
||||
/// <summary>Physical sub-track (0-based, e.g. half-track)</summary>
|
||||
public byte SubTrack;
|
||||
/// <summary>Physical track (0-based)</summary>
|
||||
public ushort Track;
|
||||
/// <summary>Physical sub-track (0-based, e.g. half-track)</summary>
|
||||
public byte SubTrack;
|
||||
/// <summary>Capture index for this head/track/subTrack combination</summary>
|
||||
public uint CaptureIndex;
|
||||
/// <summary>Expected index resolution in picoseconds</summary>
|
||||
public ulong IndexResolution;
|
||||
/// <summary>Expected data resolution in picoseconds</summary>
|
||||
public ulong DataResolution;
|
||||
}
|
||||
|
||||
public class FluxImageTestExpected : BlockImageTestExpected
|
||||
{
|
||||
/// <summary>Expected number of flux captures in the image</summary>
|
||||
public uint FluxCaptureCount;
|
||||
public uint FluxCaptureCount;
|
||||
/// <summary>Expected flux captures to validate</summary>
|
||||
public FluxCaptureTestExpected[] FluxCaptures;
|
||||
}
|
||||
@@ -104,7 +122,7 @@ public class PartitionTest
|
||||
{
|
||||
public Partition[] Partitions;
|
||||
/// <summary>File that contains the partition scheme to test</summary>
|
||||
public string TestFile;
|
||||
public string TestFile;
|
||||
}
|
||||
|
||||
public class FsExtractHashData
|
||||
|
||||
Reference in New Issue
Block a user