using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Aaru.Checksums;
using Aaru.CommonTypes;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
using Aaru.Core;
using FluentAssertions;
using NUnit.Framework;
using FileAttributes = Aaru.CommonTypes.Structs.FileAttributes;
namespace Aaru.Tests.Issues;
/// This will extract (and discard data) all files in all filesystems detected in an image.
public abstract class FsExtractHashIssueTest
{
protected abstract string DataFolder { get; }
protected abstract string TestFile { get; }
protected abstract Dictionary ParsedOptions { get; }
protected abstract bool Debug { get; }
protected abstract bool Xattrs { get; }
protected abstract string Encoding { get; }
protected abstract bool ExpectPartitions { get; }
protected abstract string Namespace { get; }
[Test]
public void Test()
{
Environment.CurrentDirectory = DataFolder;
var filtersList = new FiltersList();
IFilter inputFilter = filtersList.GetFilter(TestFile);
Dictionary options = ParsedOptions;
options["debug"] = Debug.ToString();
Assert.IsNotNull(inputFilter, Localization.Cannot_open_specified_file);
Encoding encodingClass = null;
if(Encoding != null)
encodingClass = Claunia.Encoding.Encoding.GetEncoding(Encoding);
PluginBase plugins = GetPluginBase.Instance;
var imageFormat = ImageFormat.Detect(inputFilter) as IMediaImage;
Assert.NotNull(imageFormat, Localization.Image_format_not_identified_not_proceeding_with_analysis);
Assert.AreEqual(ErrorNumber.NoError, imageFormat.Open(inputFilter), Localization.Unable_to_open_image_format);
List partitions = Core.Partitions.GetAll(imageFormat);
if(partitions.Count == 0)
{
Assert.IsFalse(ExpectPartitions, Localization.No_partitions_found);
partitions.Add(new Partition
{
Description = "Whole device",
Length = imageFormat.Info.Sectors,
Offset = 0,
Size = imageFormat.Info.SectorSize * imageFormat.Info.Sectors,
Sequence = 1,
Start = 0
});
}
bool filesystemFound = false;
Assert.True(File.Exists($"{TestFile}.unittest.json"));
var serializerOptions = new JsonSerializerOptions
{
Converters =
{
new JsonStringEnumConverter()
},
MaxDepth = 1536, // More than this an we get a StackOverflowException
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNameCaseInsensitive = true
};
var sr = new FileStream($"{TestFile}.unittest.json", FileMode.Open);
FsExtractHashData expectedData = JsonSerializer.Deserialize(sr, serializerOptions);
Assert.NotNull(expectedData);
Assert.AreEqual(expectedData.Partitions.Length, partitions.Count,
string.Format(Localization.Excepted_0_partitions_but_found_1, expectedData.Partitions.Length,
partitions.Count));
for(int i = 0; i < partitions.Count; i++)
{
Core.Filesystems.Identify(imageFormat, out List idPlugins, partitions[i]);
if(idPlugins.Count == 0)
{
Assert.IsNull(expectedData.Partitions[i],
string.Format(Localization.Expected_no_filesystems_identified_in_partition_0_but_found_1,
i, idPlugins.Count));
continue;
}
if(expectedData.Partitions[i].Volumes is null)
continue;
Assert.AreEqual(expectedData.Partitions[i].Volumes.Length, idPlugins.Count,
string.Format(Localization.Expected_0_filesystems_identified_in_partition_1_but_found_2,
expectedData.Partitions[i].Volumes.Length, i, idPlugins.Count));
for(int j = 0; j < idPlugins.Count; j++)
{
string pluginName = idPlugins[j];
if(!plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out IReadOnlyFilesystem plugin))
continue;
Assert.IsNotNull(plugin, Localization.Could_not_instantiate_filesystem_plugin);
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
Invoke(Array.Empty