1
0
Files
common/test/AMWD.Common.Tests/Packing/Ar/ArReaderTest.cs

354 lines
7.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using AMWD.Common.Packing.Ar;
namespace AMWD.Common.Tests.Packing.Ar
{
[TestClass]
public class ArReaderTest
{
private readonly DateTime _fixedDateTime = new(2023, 03, 01, 10, 20, 30, 0, DateTimeKind.Utc);
private Dictionary<string, ArFileInfo> _files;
private MemoryStream _inStream;
[TestInitialize]
public void Initialize()
{
_files = new Dictionary<string, ArFileInfo>
{
{
"abcd.tmp",
new ArFileInfo
{
FileName = "abcd.tmp",
FileSize = 14,
GroupId = 456,
Mode = 33188,
ModifyTime = _fixedDateTime,
UserId = 123
}
},
{
"efgh.tmp",
new ArFileInfo
{
FileName = "efgh.tmp",
FileSize = 14,
GroupId = 456,
Mode = 33188,
ModifyTime = _fixedDateTime,
UserId = 123
}
},
{
"ijkl.tmp",
new ArFileInfo
{
FileName = "ijkl.tmp",
FileSize = 13,
GroupId = 456,
Mode = 33188,
ModifyTime = _fixedDateTime,
UserId = 123
}
}
};
_inStream = new MemoryStream();
_inStream.Write(Encoding.ASCII.GetBytes("!<arch>\n"));
foreach (var file in _files)
{
int unixSeconds = (int)file.Value.ModifyTime.Subtract(DateTime.UnixEpoch).TotalSeconds;
_inStream.Write(Encoding.ASCII.GetBytes($"{file.Key,-16}{unixSeconds,-12}123 456 100644 {file.Value.FileSize,-10}`\n"));
_inStream.Write(Encoding.UTF8.GetBytes(new string('a', (int)file.Value.FileSize)));
if (file.Value.FileSize % 2 != 0)
_inStream.Write(Encoding.ASCII.GetBytes("\n"));
}
_inStream.Seek(0, SeekOrigin.Begin);
}
[TestCleanup]
public void Cleanup()
{
_inStream.Dispose();
_inStream = null;
}
[TestMethod]
public void ShouldInitializeArchive()
{
// Arrange
_inStream.Dispose();
_inStream = new MemoryStream();
_inStream.Write(Encoding.ASCII.GetBytes("!<arch>\n"));
_inStream.Seek(0, SeekOrigin.Begin);
// Act
var reader = new ArReader(_inStream);
// Assert
Assert.IsNotNull(reader);
Assert.IsFalse(reader.GetFileList().Any());
}
[TestMethod]
public void ShouldInitializeWithFiles()
{
// Arrange
// Act
var reader = new ArReader(_inStream);
// Assert
Assert.IsNotNull(reader);
Assert.IsTrue(reader.GetFileList().Any());
}
[TestMethod]
public void ShouldListFileNames()
{
// Arrange
var reader = new ArReader(_inStream);
// Act
var fileList = reader.GetFileList().ToList();
// Assert
Assert.IsNotNull(reader);
Assert.AreEqual(_files.Count, fileList.Count);
foreach (string name in _files.Keys)
Assert.IsTrue(fileList.Contains(name));
}
[TestMethod]
public void ShouldReturnValidFileInfo()
{
// Arrange
var infos = new List<ArFileInfo>();
var reader = new ArReader(_inStream);
// Act
foreach (string name in _files.Keys)
infos.Add(reader.GetFileInfo(name));
// Assert
Assert.IsNotNull(reader);
Assert.AreEqual(_files.Count, infos.Count);
foreach (var expected in _files.Values)
{
var actual = infos.Single(fi => fi.FileName == expected.FileName);
Assert.AreEqual(expected.FileName, actual.FileName);
Assert.AreEqual(expected.FileSize, actual.FileSize);
Assert.AreEqual(expected.GroupId, actual.GroupId);
Assert.AreEqual(expected.Mode, actual.Mode);
Assert.AreEqual(expected.ModifyTime, actual.ModifyTime);
Assert.AreEqual(expected.UserId, actual.UserId);
}
}
[TestMethod]
public void ShouldReturnValidFileContent()
{
// Arrange
var contents = new Dictionary<string, string>();
var reader = new ArReader(_inStream);
// Act
foreach (string name in _files.Keys)
{
using var ms = new MemoryStream();
reader.ReadFile(name, ms);
ms.Seek(0, SeekOrigin.Begin);
contents.Add(name, Encoding.UTF8.GetString(ms.ToArray()));
}
// Assert
Assert.IsNotNull(reader);
Assert.AreEqual(_files.Count, contents.Count);
foreach (var expected in _files.Values)
{
string content = contents[expected.FileName];
if (expected.FileSize % 2 != 0)
Assert.AreEqual(13, content.Length);
else
Assert.AreEqual(14, content.Length);
Assert.AreEqual(new string('a', (int)expected.FileSize), content);
}
}
[TestMethod]
public void ShouldWriteFileToDisk()
{
// Arrange
string tmpFile = Path.GetTempFileName();
var reader = new ArReader(_inStream);
try
{
// Act
using var ms = new MemoryStream();
reader.ReadFile("abcd.tmp", ms);
reader.ReadFile("abcd.tmp", tmpFile);
// Assert
CollectionAssert.AreEqual(ms.ToArray(), File.ReadAllBytes(tmpFile));
}
finally
{
File.Delete(tmpFile);
}
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowExceptionOnMissingRead()
{
// Arrange
using var stream = new OverrideStream();
stream.CanReadOR = false;
stream.CanSeekOR = true;
stream.CanWriteOR = true;
// Act
var reader = new ArReader(stream);
// Assert - ArgumentException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowExceptionOnMissingSeek()
{
// Arrange
using var stream = new OverrideStream();
stream.CanReadOR = true;
stream.CanSeekOR = false;
stream.CanWriteOR = true;
// Act
var reader = new ArReader(stream);
// Assert - ArgumentException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void ShouldThrowExceptionOnMissingWrite()
{
// Arrange
using var stream = new OverrideStream();
stream.CanReadOR = true;
stream.CanSeekOR = true;
stream.CanWriteOR = false;
var reader = new ArReader(_inStream);
// Act
reader.ReadFile("abcd.tmp", stream);
// Assert - ArgumentException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(FormatException))]
public void ShouldThrowExceptionOnInvalidArchive()
{
// Arrange
_inStream.Seek(8, SeekOrigin.Begin);
// Act
_ = new ArReader(_inStream);
// Assert - FormatException
Assert.Fail();
}
[TestMethod]
[ExpectedException(typeof(FormatException))]
public void ShouldThrowExceptionOnInvalidMagic()
{
// Arrange
_inStream.Seek(0, SeekOrigin.End);
_inStream.Write(Encoding.ASCII.GetBytes($"{"foo.bar",-16}{"123456789",-12}123 456 100644 {"0",-10}´\n"));
_inStream.Seek(0, SeekOrigin.Begin);
// Act
_ = new ArReader(_inStream);
// Assert - FormatException
Assert.Fail();
}
[TestMethod]
public void ShouldWriteNothingToStreamForMissingFile()
{
// Arrange
var reader = new ArReader(_inStream);
// Act
using var ms = new MemoryStream();
reader.ReadFile("foo.bar", ms);
ms.Seek(0, SeekOrigin.Begin);
// Assert
Assert.AreEqual(0, ms.Length);
}
[TestMethod]
public void ShouldWriteNothingToDiskForMissingFile()
{
// Arrange
string tmpFile = Path.GetTempFileName();
var reader = new ArReader(_inStream);
try
{
// Act
reader.ReadFile("foo.bar", tmpFile);
// Assert
Assert.AreEqual(0, new FileInfo(tmpFile).Length);
}
finally
{
File.Delete(tmpFile);
}
}
private class OverrideStream : MemoryStream
{
public override bool CanWrite => CanWriteOR;
public bool CanWriteOR { get; set; }
public override bool CanSeek => CanSeekOR;
public bool CanSeekOR { get; set; }
public override bool CanRead => CanReadOR;
public bool CanReadOR { get; set; }
}
}
}