void TestDirectory(IReadOnlyFilesystem fs, string path, Dictionary <string, FileData> children, string testFile) { Errno ret = fs.ReadDir(path, out List <string> contents); Assert.AreEqual(Errno.NoError, ret, $"Unexpected error {ret} when reading directory \"{path}\" of {testFile}."); if (children.Count == 0 && contents.Count == 0) { return; } if (path == "/") { path = ""; } List <string> expectedNotFound = new List <string>(); foreach (KeyValuePair <string, FileData> child in children) { string childPath = $"{path}/{child.Key}"; ret = fs.Stat(childPath, out FileEntryInfo stat); if (ret == Errno.NoSuchFile || !contents.Contains(child.Key)) { expectedNotFound.Add(child.Key); continue; } contents.Remove(child.Key); Assert.AreEqual(Errno.NoError, ret, $"Unexpected error {ret} retrieving stats for \"{childPath}\" in {testFile}"); stat.Should().BeEquivalentTo(child.Value.Info, $"Wrong info for \"{childPath}\" in {testFile}"); byte[] buffer = new byte[0]; if (child.Value.Info.Attributes.HasFlag(FileAttributes.Directory)) { ret = fs.Read(childPath, 0, 1, ref buffer); Assert.AreEqual(Errno.IsDirectory, ret, $"Got wrong data for directory \"{childPath}\" in {testFile}"); Assert.IsNotNull(child.Value.Children, $"Contents for \"{childPath}\" in {testFile} must be defined in unit test declaration!"); if (child.Value.Children != null) { TestDirectory(fs, childPath, child.Value.Children, testFile); } } else if (child.Value.Info.Attributes.HasFlag(FileAttributes.Symlink)) { ret = fs.ReadLink(childPath, out string link); Assert.AreEqual(Errno.NoError, ret, $"Got wrong data for symbolic link \"{childPath}\" in {testFile}"); Assert.AreEqual(child.Value.LinkTarget, link, $"Invalid target for symbolic link \"{childPath}\" in {testFile}"); } else { // This ensure the buffer does not hang for collection TestFile(fs, childPath, child.Value.MD5, child.Value.Info.Length, testFile); } ret = fs.ListXAttr(childPath, out List <string> xattrs); if (ret == Errno.NotSupported) { Assert.IsNull(child.Value.XattrsWithMd5, $"Defined extended attributes for \"{childPath}\" in {testFile} are not supported by filesystem."); continue; } Assert.AreEqual(Errno.NoError, ret, $"Unexpected error {ret} when listing extended attributes for \"{childPath}\" in {testFile}"); if (xattrs.Count > 0) { Assert.IsNotNull(child.Value.XattrsWithMd5, $"Extended attributes for \"{childPath}\" in {testFile} must be defined in unit test declaration!"); } if (xattrs.Count > 0 || child.Value.XattrsWithMd5?.Count > 0) { TestFileXattrs(fs, childPath, child.Value.XattrsWithMd5, testFile); } } Assert.IsEmpty(expectedNotFound, $"Could not find the children of \"{path}\" in {testFile}: {string.Join(" ", expectedNotFound)}"); Assert.IsEmpty(contents, $"Found the following unexpected children of \"{path}\" in {testFile}: {string.Join(" ", contents)}"); }