mirror of
https://github.com/par274/sharpemu.git
synced 2026-08-04 00:49:45 +08:00
Ampr: fix path case on Linux (#750)
This commit is contained in:
@@ -6,6 +6,9 @@ using Xunit;
|
||||
|
||||
namespace SharpEmu.Libs.Tests.Ampr;
|
||||
|
||||
// AmprFileRegistry is process-global static state, so the classes that index
|
||||
// or clear it must not run concurrently with each other.
|
||||
[Collection("AmprFileRegistry")]
|
||||
public class AmprFileRegistryTests
|
||||
{
|
||||
[Fact]
|
||||
@@ -62,6 +65,79 @@ public class AmprFileRegistryTests
|
||||
Assert.Equal(host, d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void App0_index_cache_keeps_files_that_differ_only_by_case()
|
||||
{
|
||||
var root = Path.Combine(Path.GetTempPath(), "sharpemu-ampr-case-" + Guid.NewGuid().ToString("N"));
|
||||
var cacheDir = Path.Combine(root, "..", "sharpemu-ampr-cache-" + Guid.NewGuid().ToString("N"));
|
||||
var upper = Path.Combine(root, "data", "ASSET.bin");
|
||||
var lower = Path.Combine(root, "data", "asset.bin");
|
||||
var previousCacheDir = Environment.GetEnvironmentVariable("SHARPEMU_AMPR_INDEX_CACHE");
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(Path.Combine(root, "sce_sys"));
|
||||
Directory.CreateDirectory(Path.Combine(root, "data"));
|
||||
File.WriteAllText(Path.Combine(root, "sce_sys", "param.json"), "{}");
|
||||
File.WriteAllBytes(upper, [1, 2, 3]);
|
||||
if (File.Exists(lower))
|
||||
{
|
||||
// Case-insensitive host: the two names are one file, so there is
|
||||
// nothing for an ignore-case index to lose.
|
||||
return;
|
||||
}
|
||||
|
||||
File.WriteAllBytes(lower, [4, 5, 6]);
|
||||
Environment.SetEnvironmentVariable("SHARPEMU_AMPR_INDEX_CACHE", cacheDir);
|
||||
|
||||
var normalizedRoot = Path.GetFullPath(root);
|
||||
var expectedUpper = Path.Combine(normalizedRoot, "data", "ASSET.bin");
|
||||
var expectedLower = Path.Combine(normalizedRoot, "data", "asset.bin");
|
||||
|
||||
// Fresh tree walk, which also writes the on-disk index cache.
|
||||
AmprFileRegistry.ClearForTests();
|
||||
AmprFileRegistry.EnsureApp0Indexed(root);
|
||||
AssertResolves(expectedUpper, expectedLower);
|
||||
|
||||
// Second boot: served from the cache the walk just wrote.
|
||||
AmprFileRegistry.ClearForTests();
|
||||
AmprFileRegistry.EnsureApp0Indexed(root);
|
||||
AssertResolves(expectedUpper, expectedLower);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Environment.SetEnvironmentVariable("SHARPEMU_AMPR_INDEX_CACHE", previousCacheDir);
|
||||
AmprFileRegistry.ClearForTests();
|
||||
TryDeleteDirectory(cacheDir);
|
||||
TryDeleteDirectory(root);
|
||||
}
|
||||
|
||||
static void AssertResolves(string expectedUpper, string expectedLower)
|
||||
{
|
||||
Assert.True(
|
||||
AmprFileRegistry.TryGetHostPath(
|
||||
AmprFileRegistry.ComputeFileId("$/data/ASSET.bin"), out var actualUpper),
|
||||
"data/ASSET.bin is missing from the app0 index.");
|
||||
Assert.True(
|
||||
AmprFileRegistry.TryGetHostPath(
|
||||
AmprFileRegistry.ComputeFileId("$/data/asset.bin"), out var actualLower),
|
||||
"data/asset.bin is missing from the app0 index.");
|
||||
Assert.Equal(expectedUpper, actualUpper);
|
||||
Assert.Equal(expectedLower, actualLower);
|
||||
}
|
||||
}
|
||||
|
||||
private static void TryDeleteDirectory(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(path, recursive: true);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Temp cleanup is best-effort.
|
||||
}
|
||||
}
|
||||
|
||||
private static uint FnvUtf8(string text)
|
||||
{
|
||||
const uint offset = 2166136261;
|
||||
|
||||
@@ -8,6 +8,7 @@ using Xunit;
|
||||
|
||||
namespace SharpEmu.Libs.Tests.Ampr;
|
||||
|
||||
[Collection("AmprFileRegistry")]
|
||||
public sealed class AmprWriteAddressTests
|
||||
{
|
||||
[Fact]
|
||||
|
||||
@@ -9,6 +9,7 @@ using Xunit;
|
||||
|
||||
namespace SharpEmu.Libs.Tests.Ampr;
|
||||
|
||||
[Collection("AmprFileRegistry")]
|
||||
public sealed class AprStreamingContractTests
|
||||
{
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user