Build Snapshot from archives
Download from archives Process XCI files in archives
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using LibHac.Ncm;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
@@ -21,6 +22,7 @@ namespace TinfoilVibeServerTest.Tests
|
||||
private Mock<IArchiveHandler> _archiveHander;
|
||||
private Mock<IOptionsMonitor<SnapshotOptions>> _mockOptions;
|
||||
private SnapshotOptions _options;
|
||||
private MemoryCache _memoryCache;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
@@ -42,69 +44,92 @@ namespace TinfoilVibeServerTest.Tests
|
||||
_loggerMock = new Mock<ILogger<SnapshotService>>();
|
||||
_archiveHander = new Mock<IArchiveHandler>();
|
||||
_nspExtractorMock = new Mock<INSPExtractor>();
|
||||
var memoryCacheOptions = Options.Create(new MemoryCacheOptions());
|
||||
_memoryCache = new MemoryCache(memoryCacheOptions);
|
||||
|
||||
|
||||
_nspExtractorMock.Setup(extractor => extractor.ExtractHashFromStream(It.IsAny<Stream>())).Returns("HASH");
|
||||
_nspExtractorMock.Setup(extractor => extractor.ExtractFromStream(It.IsAny<Stream>())).Returns(
|
||||
new NcaMetadataWithHash(titleId: "0000000000000000","0000000000000000", version: 1, ContentMetaType.Application, "HASH"));
|
||||
//Settings.RootDirs = new List<string> { "TestData/Root1", "TestData/Root2" };
|
||||
_service = new SnapshotService(_mockOptions.Object, _nspExtractorMock.Object, _archiveHander.Object, _loggerMock.Object);
|
||||
_service = new SnapshotService(_memoryCache, _mockOptions.Object, _nspExtractorMock.Object, _archiveHander.Object, _loggerMock.Object);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
_service.Dispose();
|
||||
_memoryCache.Dispose();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task BuildSnapshot_WhenFilesChanged_ShouldPersist()
|
||||
{
|
||||
// Arrange
|
||||
await File.WriteAllTextAsync(_options.SnapshotFile, "[]");
|
||||
var initialHash = _service.GetSnapshot()?.Hash;
|
||||
// Add a file to Root1
|
||||
var newFile = Path.Combine(_options.RootDirectories.First(), "new.nsp");
|
||||
FileSystemExtensions.EnsureDirectoryExists(Path.GetDirectoryName(newFile));
|
||||
// Create a new valid NSP file
|
||||
// copy to temp to touch modified date
|
||||
foreach (var file in Directory.GetFiles("../../../Data/"))
|
||||
var rebuilding = false;
|
||||
var rebuilt = false;
|
||||
CancellationTokenSource snapshotRebuilding = new();
|
||||
_service.SnapshotRebuilding += (sender, args) =>
|
||||
{
|
||||
var filename = Path.GetFileName(file);
|
||||
var destFilename = Path.Combine(Path.GetTempPath(), filename);
|
||||
File.Copy(file, destFilename, true);
|
||||
var info = new FileInfo(destFilename)
|
||||
{
|
||||
LastWriteTimeUtc = DateTime.UtcNow
|
||||
};
|
||||
info.CopyTo(Path.Combine(_options.RootDirectories.First(),filename), true);
|
||||
}
|
||||
|
||||
// Act
|
||||
rebuilding = true;
|
||||
snapshotRebuilding.Cancel();
|
||||
};
|
||||
CancellationTokenSource snapshotPersisting = new();
|
||||
_service.SnapshotRebuilt+= (sender, args) =>
|
||||
{
|
||||
rebuilt = true;
|
||||
snapshotPersisting.Cancel();
|
||||
// Assert
|
||||
var newHash = _service.GetSnapshot()?.Hash;
|
||||
Assert.That(newHash, Is.Not.EqualTo(initialHash));
|
||||
|
||||
|
||||
};
|
||||
Task.Delay(300).Wait();
|
||||
_loggerMock.Verify(
|
||||
l => l.Log(
|
||||
LogLevel.Information,
|
||||
It.IsAny<EventId>(),
|
||||
It.Is<It.IsAnyType>((v, t) => v.ToString().Contains("Snapshot rebuilt")),
|
||||
null,
|
||||
It.IsAny<Func<It.IsAnyType, Exception, string>>()), Times.Once);
|
||||
Timer timer = new(state =>
|
||||
{
|
||||
snapshotPersisting.Cancel();
|
||||
snapshotRebuilding.Cancel();
|
||||
}, null, 20*1000, 0);
|
||||
await File.WriteAllTextAsync(_options.SnapshotFile, "[]", snapshotPersisting.Token);
|
||||
// Add a file to Root1
|
||||
var newFile = Path.Combine(_options.RootDirectories.First(), "new.nsp");
|
||||
|
||||
// Act
|
||||
await File.WriteAllTextAsync(newFile,"TEST");
|
||||
|
||||
Task.Delay(4000).Wait();
|
||||
try
|
||||
{
|
||||
while (_memoryCache.Count > 0)
|
||||
{
|
||||
Task.Delay(200).Wait(snapshotRebuilding.Token);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Assert.That(rebuilding, Is.True);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
while (_memoryCache.Count > 0)
|
||||
{
|
||||
Task.Delay(200).Wait(snapshotPersisting.Token);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException e)
|
||||
{
|
||||
Assert.That(rebuilt, Is.True);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task BuildSnapshot_NoChange_ShouldNotPersist()
|
||||
{
|
||||
// Act
|
||||
_service.BuildSnapshot();
|
||||
_service.BuildSnapshotAsync();
|
||||
|
||||
// Act again – snapshot should be identical
|
||||
_service.BuildSnapshot();
|
||||
_service.BuildSnapshotAsync();
|
||||
|
||||
// Assert
|
||||
_loggerMock.Verify(
|
||||
|
||||
Reference in New Issue
Block a user