diff --git a/Aaru.Tests/Filesystems/ReadOnlyFilesystemTest.cs b/Aaru.Tests/Filesystems/ReadOnlyFilesystemTest.cs index 33b3fdfd8..c67efcb54 100644 --- a/Aaru.Tests/Filesystems/ReadOnlyFilesystemTest.cs +++ b/Aaru.Tests/Filesystems/ReadOnlyFilesystemTest.cs @@ -137,7 +137,7 @@ namespace Aaru.Tests.Filesystems if(test.Contents is null) continue; - TestDirectory(fs, "/", test.Contents, testFile); + TestDirectory(fs, "/", test.Contents, testFile, true); } }); } @@ -232,7 +232,7 @@ namespace Aaru.Tests.Filesystems } } - Dictionary BuildDirectory(IReadOnlyFilesystem fs, string path) + internal static Dictionary BuildDirectory(IReadOnlyFilesystem fs, string path) { if(path == "/") path = ""; @@ -265,7 +265,7 @@ namespace Aaru.Tests.Filesystems return children; } - string BuildFile(IReadOnlyFilesystem fs, string path, long length) + static string BuildFile(IReadOnlyFilesystem fs, string path, long length) { byte[] buffer = new byte[length]; fs.Read(path, 0, length, ref buffer); @@ -273,7 +273,8 @@ namespace Aaru.Tests.Filesystems return Md5Context.Data(buffer, out _); } - void TestDirectory(IReadOnlyFilesystem fs, string path, Dictionary children, string testFile) + internal static void TestDirectory(IReadOnlyFilesystem fs, string path, Dictionary children, + string testFile, bool testXattr) { Errno ret = fs.ReadDir(path, out List contents); @@ -322,7 +323,7 @@ namespace Aaru.Tests.Filesystems $"Contents for \"{childPath}\" in {testFile} must be defined in unit test declaration!"); if(child.Value.Children != null) - TestDirectory(fs, childPath, child.Value.Children, testFile); + TestDirectory(fs, childPath, child.Value.Children, testFile, testXattr); } else if(child.Value.Info.Attributes.HasFlag(FileAttributes.Symlink)) { @@ -339,6 +340,9 @@ namespace Aaru.Tests.Filesystems // This ensure the buffer does not hang for collection TestFile(fs, childPath, child.Value.MD5, child.Value.Info.Length, testFile); + if(!testXattr) + continue; + ret = fs.ListXAttr(childPath, out List xattrs); if(ret == Errno.NotSupported) @@ -368,7 +372,7 @@ namespace Aaru.Tests.Filesystems $"Found the following unexpected children of \"{path}\" in {testFile}: {string.Join(" ", contents)}"); } - void TestFile(IReadOnlyFilesystem fs, string path, string md5, long length, string testFile) + static void TestFile(IReadOnlyFilesystem fs, string path, string md5, long length, string testFile) { byte[] buffer = new byte[length]; Errno ret = fs.Read(path, 0, length, ref buffer); @@ -380,7 +384,8 @@ namespace Aaru.Tests.Filesystems Assert.AreEqual(md5, data, $"Got MD5 {data} for \"{path}\" in {testFile} but expected {md5}"); } - void TestFileXattrs(IReadOnlyFilesystem fs, string path, Dictionary xattrs, string testFile) + static void TestFileXattrs(IReadOnlyFilesystem fs, string path, Dictionary xattrs, + string testFile) { fs.ListXAttr(path, out List contents); diff --git a/Aaru.Tests/Images/OpticalMediaImageTest.cs b/Aaru.Tests/Images/OpticalMediaImageTest.cs index b8bfe90b1..eb612e5bc 100644 --- a/Aaru.Tests/Images/OpticalMediaImageTest.cs +++ b/Aaru.Tests/Images/OpticalMediaImageTest.cs @@ -1,14 +1,20 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Threading.Tasks; using Aaru.Checksums; using Aaru.CommonTypes; using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Structs; +using Aaru.Core; +using Aaru.Tests.Filesystems; using FluentAssertions; using FluentAssertions.Execution; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; using NUnit.Framework; namespace Aaru.Tests.Images @@ -101,6 +107,142 @@ namespace Aaru.Tests.Images $"Last sector for tracks is {latestEndSector}, but it is {image.Info.Sectors} for image"); }); } + + using(new AssertionScope()) + { + Assert.Multiple(() => + { + foreach(TrackInfoTestExpected track in test.Tracks) + { + if(track.FileSystems is null) + continue; + + ulong trackStart = track.Start + track.Pregap; + + if(track.Number == 1 && + track.Pregap >= 150) + trackStart -= 150; + + var partition = new Partition + { + Length = track.End - trackStart + 1, + Start = trackStart + }; + + Core.Filesystems.Identify(image, out List idPlugins, partition); + + Assert.AreEqual(track.FileSystems.Length, idPlugins.Count, + $"Expected {track.FileSystems.Length} filesystems in {testFile} but found {idPlugins.Count}"); + + for(int i = 0; i < track.FileSystems.Length; i++) + { + PluginBase plugins = GetPluginBase.Instance; + bool found = plugins.PluginsList.TryGetValue(idPlugins[i], out IFilesystem plugin); + + // ReSharper disable once ConditionIsAlwaysTrueOrFalse + // It is not the case, it changes + if(!found) + continue; + + var fs = Activator.CreateInstance(plugin.GetType()) as IFilesystem; + + Assert.NotNull(fs, $"Could not instantiate filesystem for {testFile}"); + + fs.GetInformation(image, partition, out _, null); + + if(track.FileSystems[i].ApplicationId != null) + Assert.AreEqual(track.FileSystems[i].ApplicationId, + fs.XmlFsType.ApplicationIdentifier, + $"Application ID: {testFile}"); + + Assert.AreEqual(track.FileSystems[i].Bootable, fs.XmlFsType.Bootable, + $"Bootable: {testFile}"); + + Assert.AreEqual(track.FileSystems[i].Clusters, fs.XmlFsType.Clusters, + $"Clusters: {testFile}"); + + Assert.AreEqual(track.FileSystems[i].ClusterSize, fs.XmlFsType.ClusterSize, + $"Cluster size: {testFile}"); + + if(track.FileSystems[i].SystemId != null) + Assert.AreEqual(track.FileSystems[i].SystemId, fs.XmlFsType.SystemIdentifier, + $"System ID: {testFile}"); + + Assert.AreEqual(track.FileSystems[i].Type, fs.XmlFsType.Type, + $"Filesystem type: {testFile}"); + + Assert.AreEqual(track.FileSystems[i].VolumeName, fs.XmlFsType.VolumeName, + $"Volume name: {testFile}"); + + Assert.AreEqual(track.FileSystems[i].VolumeSerial, fs.XmlFsType.VolumeSerial, + $"Volume serial: {testFile}"); + + var rofs = Activator.CreateInstance(plugin.GetType()) as IReadOnlyFilesystem; + + if(rofs == null) + { + if(track.FileSystems[i].Contents != null || + track.FileSystems[i].ContentsJson != null || + File.Exists($"{testFile}.track{track.Number}.filesystem{i}.contents.json")) + Assert.NotNull(rofs, + $"Could not instantiate filesystem for {testFile}, track {track.Number}, filesystem {i}"); + + continue; + } + + track.FileSystems[i].Encoding ??= Encoding.ASCII; + + Errno ret = rofs.Mount(image, partition, track.FileSystems[i].Encoding, null, + track.FileSystems[i].Namespace); + + Assert.AreEqual(Errno.NoError, ret, $"Unmountable: {testFile}"); + + var serializer = new JsonSerializer + { + Formatting = Formatting.Indented, + MaxDepth = 16384, + NullValueHandling = NullValueHandling.Ignore + }; + + serializer.Converters.Add(new StringEnumConverter()); + + if(track.FileSystems[i].ContentsJson != null) + { + track.FileSystems[i].Contents = + serializer. + Deserialize< + Dictionary>(new JsonTextReader(new StringReader(track. + FileSystems[i].ContentsJson))); + } + else if(File.Exists($"{testFile}.track{track.Number}.filesystem{i}.contents.json")) + { + var sr = + new + StreamReader($"{testFile}.track{track.Number}.filesystem{i}.contents.json"); + + track.FileSystems[i].Contents = + serializer. + Deserialize>(new JsonTextReader(sr)); + } + + if(track.FileSystems[i].Contents is null) + continue; + + ReadOnlyFilesystemTest.TestDirectory(rofs, "/", track.FileSystems[i].Contents, + testFile, false); + + /* Uncomment to generate JSON file + var contents = ReadOnlyFilesystemTest.BuildDirectory(rofs, "/"); + + var sw = new StreamWriter($"{testFile}.track{track.Number}.filesystem{i}.contents.json"); + serializer.Serialize(sw, contents); + sw.Close(); +*/ + } + } + }); + } } }); } diff --git a/Aaru.Tests/Structs.cs b/Aaru.Tests/Structs.cs index f0261d038..bf0562537 100644 --- a/Aaru.Tests/Structs.cs +++ b/Aaru.Tests/Structs.cs @@ -52,11 +52,13 @@ namespace Aaru.Tests public class TrackInfoTestExpected { - public ulong End; - public byte? Flags; - public ulong Pregap; - public int Session; - public ulong Start; + public ulong End; + public FileSystemTest[] FileSystems; + public byte? Flags; + public byte Number; + public ulong Pregap; + public int Session; + public ulong Start; } public class OpticalImageTestExpected : BlockImageTestExpected