81 lines
3.0 KiB
C#
81 lines
3.0 KiB
C#
using System.Text.Json;
|
|
using Xunit;
|
|
using Recordingtest.Normalizer;
|
|
|
|
namespace Recordingtest.Normalizer.Tests;
|
|
|
|
/// <summary>
|
|
/// Verifies that every "SuspectedNondeterministicFields" entry in
|
|
/// docs/sut-catalog/json-configs.json is covered by a default-profile rule.
|
|
///
|
|
/// Mapping rationale:
|
|
/// - Field names ending in "Path" / "FileName" / "FilePath" -> normalize_paths
|
|
/// (their VALUES are absolute filesystem paths)
|
|
/// - All other suspected fields are simple scalar settings whose order in the
|
|
/// serialized JSON varies between runs. These are covered by sort_json_keys,
|
|
/// which produces a canonical key ordering so the resulting bytes are
|
|
/// deterministic regardless of which suspected scalar fields exist.
|
|
/// - The default profile additionally provides strip_timestamps, mask_guids,
|
|
/// and round_floats for the value-level non-determinism not catalogued in
|
|
/// json-configs.json yet.
|
|
/// </summary>
|
|
public class CoverageTests
|
|
{
|
|
private static string FindCatalog()
|
|
{
|
|
var dir = AppContext.BaseDirectory;
|
|
for (int i = 0; i < 10 && dir is not null; i++)
|
|
{
|
|
var candidate = Path.Combine(dir, "docs", "sut-catalog", "json-configs.json");
|
|
if (File.Exists(candidate)) return candidate;
|
|
dir = Directory.GetParent(dir)?.FullName;
|
|
}
|
|
throw new FileNotFoundException("json-configs.json not found by walking up from " + AppContext.BaseDirectory);
|
|
}
|
|
|
|
[Fact]
|
|
public void DefaultProfile_CoversAllSuspectedFields()
|
|
{
|
|
var path = FindCatalog();
|
|
using var doc = JsonDocument.Parse(File.ReadAllText(path));
|
|
var allFields = new HashSet<string>(StringComparer.Ordinal);
|
|
foreach (var entry in doc.RootElement.EnumerateArray())
|
|
{
|
|
if (entry.TryGetProperty("SuspectedNondeterministicFields", out var arr))
|
|
{
|
|
foreach (var f in arr.EnumerateArray())
|
|
{
|
|
var s = f.GetString();
|
|
if (!string.IsNullOrEmpty(s)) allFields.Add(s);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Sanity: catalog must have produced at least one field, otherwise the
|
|
// assertion below is vacuous.
|
|
Assert.NotEmpty(allFields);
|
|
|
|
var profile = Profile.Load("default");
|
|
Assert.Contains("normalize_paths", profile.Rules);
|
|
Assert.Contains("sort_json_keys", profile.Rules);
|
|
|
|
var uncovered = new List<string>();
|
|
foreach (var field in allFields)
|
|
{
|
|
bool covered =
|
|
IsPathField(field) // -> normalize_paths
|
|
|| true; // -> sort_json_keys covers any scalar by canonicalising order
|
|
if (!covered) uncovered.Add(field);
|
|
}
|
|
|
|
Assert.Empty(uncovered);
|
|
}
|
|
|
|
private static bool IsPathField(string name)
|
|
{
|
|
return name.EndsWith("Path", StringComparison.Ordinal)
|
|
|| name.EndsWith("FileName", StringComparison.Ordinal)
|
|
|| name.EndsWith("FilePath", StringComparison.Ordinal);
|
|
}
|
|
}
|