Files
TinfoilVibeServer/TinfoilVibeServerTest/Tests/SnapshotServiceTests.cs
T
ecenshu 209b766a1f Build Snapshot from archives
Download from archives
Process XCI files in archives
2025-11-07 13:31:37 +10:30

144 lines
5.2 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.Collections.Generic;
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;
using NUnit.Framework;
using TinfoilVibeServer.Models;
using TinfoilVibeServer.Services;
using TinfoilVibeServer.Utilities;
namespace TinfoilVibeServerTest.Tests
{
[TestFixture]
public class SnapshotServiceTests
{
private Mock<ILogger<SnapshotService>> _loggerMock;
private SnapshotService _service;
private Mock<INSPExtractor> _nspExtractorMock;
private Mock<IArchiveHandler> _archiveHander;
private Mock<IOptionsMonitor<SnapshotOptions>> _mockOptions;
private SnapshotOptions _options;
private MemoryCache _memoryCache;
[SetUp]
public void SetUp()
{
_mockOptions = new Mock<IOptionsMonitor<SnapshotOptions>>();
_options = new SnapshotOptions()
{
RomExtensions = [".nsp"],
RootDirectories = ["TestData/ROMS"],
SnapshotFile = "TestData/snapshot.json",
SnapshotBackupFile = "TestData/snapshot.bak"
};
/*// ensure ROM test directory has test files removed
foreach (var file in Directory.GetFiles("TestData/ROMS"))
{
File.Delete(file);
}*/
_mockOptions.Setup(m => m.CurrentValue).Returns(_options);
_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(_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
var initialHash = _service.GetSnapshot()?.Hash;
var rebuilding = false;
var rebuilt = false;
CancellationTokenSource snapshotRebuilding = new();
_service.SnapshotRebuilding += (sender, args) =>
{
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));
};
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.BuildSnapshotAsync();
// Act again snapshot should be identical
_service.BuildSnapshotAsync();
// Assert
_loggerMock.Verify(
l => l.Log(
LogLevel.Information,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((v, t) => v.ToString().Contains("persisting new snapshot")),
null,
It.IsAny<Func<It.IsAnyType, Exception, string>>()), Times.Never);
}
}
}