test: replace create authority source pin
This commit is contained in:
parent
84034f732c
commit
14d371a05b
5 changed files with 159 additions and 79 deletions
|
|
@ -1498,3 +1498,43 @@ Verification follows the proportionate R3 policy:
|
||||||
- a targeted scan finds source reads only in the two explicitly retained
|
- a targeted scan finds source reads only in the two explicitly retained
|
||||||
whole-tree policy methods. The final inventory and twelve-assembly Release
|
whole-tree policy methods. The final inventory and twelve-assembly Release
|
||||||
gate remain deferred to closeout.
|
gate remain deferred to closeout.
|
||||||
|
|
||||||
|
## Batch AF create-authority drift-model contract replacement
|
||||||
|
|
||||||
|
Batch AF converts the final approved test-model/source correspondence check.
|
||||||
|
`CreateAuthorityDriftModelSourcePinTests` is renamed to
|
||||||
|
`CreateAuthorityDriftModelContractTests`; its descriptive test method
|
||||||
|
`HandCalledDriftProbe_StillModelsTheExecutorDrainAdvance` is retained. No
|
||||||
|
product source changes and no test is removed.
|
||||||
|
|
||||||
|
The replacement no longer regexes two Runtime files. It inspects compiled
|
||||||
|
Runtime metadata and proves:
|
||||||
|
|
||||||
|
- `ApplyWeenieDescriptionAction` applies the accepted description, refreshes
|
||||||
|
the canonical snapshot, advances create authority exactly once, and then
|
||||||
|
advances the executor baseline in semantic execution order;
|
||||||
|
- `RegisterEntityCore` still has the named Boolean initial-residence input,
|
||||||
|
refreshes the ordinary existing-generation snapshot, and places the one
|
||||||
|
registration-time authority advance behind a conditional branch that skips
|
||||||
|
over the call; and
|
||||||
|
- the Runtime assembly contains exactly those two call sites targeting
|
||||||
|
`RuntimeEntityDirectory.AdvanceCreateAuthority`: the modeled executor drain
|
||||||
|
and the gated ordinary registration route.
|
||||||
|
|
||||||
|
This is the stale-model alarm the source regex intended, but it now survives
|
||||||
|
comments, whitespace, local renames, and equivalent expression refactors.
|
||||||
|
The expectation-item 6/8 probe comments in the hydration and supersession
|
||||||
|
suites now say `metadata-pinned` and name the new contract class, preserving
|
||||||
|
the rationale without leaving misleading source-pin references.
|
||||||
|
|
||||||
|
Verification follows the proportionate R3 policy:
|
||||||
|
|
||||||
|
- the contract plus its hydration and supersession behavior suites pass 90/90;
|
||||||
|
- the complete `AcDream.App.Tests` hermetic lane passes 5,381/5,381 with zero
|
||||||
|
skips or failures;
|
||||||
|
- the complete locked Release build covers all 44 projects with zero warnings
|
||||||
|
and zero errors; and
|
||||||
|
- targeted scans find no source reader in the renamed contract and no stale
|
||||||
|
source-pin comment in the affected tests. With this batch, all 85 approved
|
||||||
|
replacements are implemented; final inventory reconciliation and the one
|
||||||
|
complete Release gate follow next.
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ public sealed class LiveEntityCreateSupersessionRecoveryTests
|
||||||
// covered.
|
// covered.
|
||||||
// C3c-R1 F3: honest MODEL of the executor drain's advance
|
// C3c-R1 F3: honest MODEL of the executor drain's advance
|
||||||
// (ApplyWeenieDescriptionAction — the sole production site,
|
// (ApplyWeenieDescriptionAction — the sole production site,
|
||||||
// source-pinned by CreateAuthorityDriftModelSourcePinTests); a
|
// metadata-pinned by CreateAuthorityDriftModelContractTests); a
|
||||||
// nested production OnCreate can no longer reach it —
|
// nested production OnCreate can no longer reach it —
|
||||||
// post-residence registration is description-only
|
// post-residence registration is description-only
|
||||||
// (RuntimeEntityObjectLifetime :660-665,
|
// (RuntimeEntityObjectLifetime :660-665,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using AcDream.App.Tests.Architecture;
|
||||||
|
using AcDream.Runtime.Entities;
|
||||||
|
|
||||||
|
namespace AcDream.App.Tests.World;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The create-authority drift probes in the expectation-item 6/8 tests
|
||||||
|
/// (`LiveEntityHydrationControllerTests` and
|
||||||
|
/// `LiveEntityCreateSupersessionRecoveryTests`) hand-call
|
||||||
|
/// <see cref="RuntimeEntityRecord.AdvanceCreateAuthority"/> as an honest model
|
||||||
|
/// of the executor drain's advance: the sole production drain site that
|
||||||
|
/// advances create authority for an existing incarnation. A nested production
|
||||||
|
/// OnCreate cannot produce that drift because the initial-residence
|
||||||
|
/// registration route branches around the ordinary registration-time advance.
|
||||||
|
/// This compiled contract flags the model as stale if either route changes, so
|
||||||
|
/// those probes can be re-derived from the new production boundary.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class CreateAuthorityDriftModelContractTests
|
||||||
|
{
|
||||||
|
private const BindingFlags Declared = BindingFlags.Instance
|
||||||
|
| BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic
|
||||||
|
| BindingFlags.DeclaredOnly;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void HandCalledDriftProbe_StillModelsTheExecutorDrainAdvance()
|
||||||
|
{
|
||||||
|
MethodInfo drain = RequiredMethod(
|
||||||
|
typeof(RuntimeInitialCreateContinuationExecutor),
|
||||||
|
"ApplyWeenieDescriptionAction");
|
||||||
|
AssertCallOrder(
|
||||||
|
drain,
|
||||||
|
(typeof(RuntimeEntityDirectory),
|
||||||
|
nameof(RuntimeEntityDirectory.ApplyAcceptedWeenieDescriptionSnapshot)),
|
||||||
|
(typeof(RuntimeEntityDirectory), nameof(RuntimeEntityDirectory.RefreshSnapshot)),
|
||||||
|
(typeof(RuntimeEntityDirectory),
|
||||||
|
nameof(RuntimeEntityDirectory.AdvanceCreateAuthority)),
|
||||||
|
(typeof(RuntimeInitialCreateResidenceState), "AdvanceExecutorBaseline"));
|
||||||
|
Assert.Single(
|
||||||
|
CompiledCallGraph.Read(drain),
|
||||||
|
call => IsAuthorityAdvance(call.Target));
|
||||||
|
|
||||||
|
MethodInfo registration = RequiredMethod(
|
||||||
|
typeof(RuntimeEntityObjectLifetime),
|
||||||
|
"RegisterEntityCore");
|
||||||
|
ParameterInfo residenceFlag = Assert.Single(
|
||||||
|
registration.GetParameters(),
|
||||||
|
parameter => parameter.Name == "beginInitialResidence"
|
||||||
|
&& parameter.ParameterType == typeof(bool));
|
||||||
|
Assert.NotNull(residenceFlag);
|
||||||
|
|
||||||
|
IReadOnlyList<CompiledCall> registrationCalls =
|
||||||
|
CompiledCallGraph.Read(registration);
|
||||||
|
CompiledCall refresh = Assert.Single(
|
||||||
|
registrationCalls,
|
||||||
|
call => call.Target.DeclaringType == typeof(RuntimeEntityDirectory)
|
||||||
|
&& call.Target.Name == nameof(RuntimeEntityDirectory.RefreshSnapshot));
|
||||||
|
CompiledCall ordinaryAdvance = Assert.Single(
|
||||||
|
registrationCalls,
|
||||||
|
call => IsAuthorityAdvance(call.Target));
|
||||||
|
Assert.True(refresh.Offset < ordinaryAdvance.Offset);
|
||||||
|
Assert.Contains(
|
||||||
|
CompiledCallGraph.ReadBranches(registration),
|
||||||
|
branch => branch.OpCode.FlowControl == FlowControl.Cond_Branch
|
||||||
|
&& branch.Offset > refresh.Offset
|
||||||
|
&& branch.Offset < ordinaryAdvance.Offset
|
||||||
|
&& branch.TargetOffset > ordinaryAdvance.Offset);
|
||||||
|
|
||||||
|
MethodBase[] productionCallSites =
|
||||||
|
MethodsCallingRuntimeAuthorityAdvance().ToArray();
|
||||||
|
Assert.Equal(2, productionCallSites.Length);
|
||||||
|
Assert.Contains(drain, productionCallSites);
|
||||||
|
Assert.Contains(registration, productionCallSites);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<MethodBase> MethodsCallingRuntimeAuthorityAdvance() =>
|
||||||
|
typeof(RuntimeEntityObjectLifetime).Assembly.GetTypes()
|
||||||
|
.SelectMany(type => type.GetMethods(Declared)
|
||||||
|
.Cast<MethodBase>()
|
||||||
|
.Concat(type.GetConstructors(Declared)))
|
||||||
|
.Where(method => method.GetMethodBody() is not null)
|
||||||
|
.Where(method => CompiledCallGraph.Read(method).Any(call =>
|
||||||
|
IsAuthorityAdvance(call.Target)));
|
||||||
|
|
||||||
|
private static bool IsAuthorityAdvance(MethodBase method) =>
|
||||||
|
method.DeclaringType == typeof(RuntimeEntityDirectory)
|
||||||
|
&& method.Name == nameof(RuntimeEntityDirectory.AdvanceCreateAuthority);
|
||||||
|
|
||||||
|
private static MethodInfo RequiredMethod(Type owner, string name) =>
|
||||||
|
owner.GetMethod(
|
||||||
|
name,
|
||||||
|
BindingFlags.Instance | BindingFlags.Static
|
||||||
|
| BindingFlags.Public | BindingFlags.NonPublic)
|
||||||
|
?? throw new MissingMethodException(owner.FullName, name);
|
||||||
|
|
||||||
|
private static void AssertCallOrder(
|
||||||
|
MethodBase method,
|
||||||
|
params (Type Type, string Method)[] expected)
|
||||||
|
{
|
||||||
|
IReadOnlyList<CompiledCall> calls = CompiledCallGraph.Read(method);
|
||||||
|
int cursor = -1;
|
||||||
|
foreach ((Type type, string name) in expected)
|
||||||
|
{
|
||||||
|
int found = Enumerable.Range(cursor + 1, calls.Count - cursor - 1)
|
||||||
|
.FirstOrDefault(index => calls[index].Target.DeclaringType == type
|
||||||
|
&& calls[index].Target.Name == name, -1);
|
||||||
|
Assert.True(found > cursor,
|
||||||
|
$"Missing compiled edge after {cursor}: {type.FullName}.{name}.");
|
||||||
|
cursor = found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace AcDream.App.Tests.World;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The create-authority drift probes in the expectation-item 6/8 tests
|
|
||||||
/// (LiveEntityHydrationControllerTests + LiveEntityCreateSupersessionRecoveryTests)
|
|
||||||
/// hand-call <c>record.Canonical.AdvanceCreateAuthority()</c> as an HONEST
|
|
||||||
/// MODEL of the executor drain's advance — the SOLE remaining production
|
|
||||||
/// site that advances create authority for an existing incarnation. A
|
|
||||||
/// nested production OnCreate can no longer produce that drift:
|
|
||||||
/// post-residence ExistingGeneration registration is description-only
|
|
||||||
/// (RuntimeEntityObjectLifetime gates the advance on
|
|
||||||
/// <c>!beginInitialResidence</c>) and <c>ConsumeExecuted</c> removes the
|
|
||||||
/// completed residence entry at Released, closing the FIFO-adoption path
|
|
||||||
/// (empirically confirmed: the restored nested-OnCreate probe produced no
|
|
||||||
/// drift and no CreateSupersessionRecovery). This pin flags the model as
|
|
||||||
/// STALE if the production site ever moves or loses the advance — the
|
|
||||||
/// item 6/8 probes must be re-derived from wherever it goes.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class CreateAuthorityDriftModelSourcePinTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void HandCalledDriftProbe_StillModelsTheExecutorDrainAdvance()
|
|
||||||
{
|
|
||||||
string executor = ReadRuntimeSource(
|
|
||||||
"Entities",
|
|
||||||
"RuntimeInitialCreateContinuationExecutor.cs");
|
|
||||||
|
|
||||||
// Exactly one production advance, and it lives inside the
|
|
||||||
// WeenieDescription drain stage the probes model.
|
|
||||||
Assert.Single(
|
|
||||||
Regex.Matches(executor, @"_entities\.AdvanceCreateAuthority\(")
|
|
||||||
.Cast<Match>());
|
|
||||||
Assert.Matches(
|
|
||||||
new Regex(
|
|
||||||
@"private bool ApplyWeenieDescriptionAction[\s\S]{0,6000}?"
|
|
||||||
+ @"_entities\.AdvanceCreateAuthority\(canonical\);"),
|
|
||||||
executor);
|
|
||||||
|
|
||||||
// The registration-time advance stays gated OFF the residence
|
|
||||||
// route — the reason a nested production OnCreate cannot reach the
|
|
||||||
// modeled drift.
|
|
||||||
string lifetime = ReadRuntimeSource(
|
|
||||||
"Entities",
|
|
||||||
"RuntimeEntityObjectLifetime.cs");
|
|
||||||
Assert.Matches(
|
|
||||||
new Regex(
|
|
||||||
@"if \(!beginInitialResidence\)\s*"
|
|
||||||
+ @"Entities\.AdvanceCreateAuthority\(retained\);"),
|
|
||||||
lifetime);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string ReadRuntimeSource(params string[] relativePath)
|
|
||||||
{
|
|
||||||
DirectoryInfo? directory = new(AppContext.BaseDirectory);
|
|
||||||
while (directory is not null)
|
|
||||||
{
|
|
||||||
if (File.Exists(Path.Combine(directory.FullName, "AcDream.slnx")))
|
|
||||||
{
|
|
||||||
return File.ReadAllText(Path.Combine(
|
|
||||||
directory.FullName,
|
|
||||||
"src",
|
|
||||||
"AcDream.Runtime",
|
|
||||||
Path.Combine(relativePath)));
|
|
||||||
}
|
|
||||||
|
|
||||||
directory = directory.Parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new DirectoryNotFoundException("Could not find AcDream.slnx.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1371,7 +1371,7 @@ public sealed class LiveEntityHydrationControllerTests
|
||||||
// honest MODEL of the executor drain's advance
|
// honest MODEL of the executor drain's advance
|
||||||
// (RuntimeInitialCreateContinuationExecutor
|
// (RuntimeInitialCreateContinuationExecutor
|
||||||
// .ApplyWeenieDescriptionAction — the sole production site,
|
// .ApplyWeenieDescriptionAction — the sole production site,
|
||||||
// source-pinned by CreateAuthorityDriftModelSourcePinTests). A nested
|
// metadata-pinned by CreateAuthorityDriftModelContractTests). A nested
|
||||||
// production OnCreate can no longer reach it here:
|
// production OnCreate can no longer reach it here:
|
||||||
// post-residence ExistingGeneration registration is
|
// post-residence ExistingGeneration registration is
|
||||||
// description-only (RuntimeEntityObjectLifetime gates the
|
// description-only (RuntimeEntityObjectLifetime gates the
|
||||||
|
|
@ -1509,7 +1509,7 @@ public sealed class LiveEntityHydrationControllerTests
|
||||||
// honest MODEL of the executor drain's advance
|
// honest MODEL of the executor drain's advance
|
||||||
// (RuntimeInitialCreateContinuationExecutor
|
// (RuntimeInitialCreateContinuationExecutor
|
||||||
// .ApplyWeenieDescriptionAction — the sole production site,
|
// .ApplyWeenieDescriptionAction — the sole production site,
|
||||||
// source-pinned by CreateAuthorityDriftModelSourcePinTests). A nested
|
// metadata-pinned by CreateAuthorityDriftModelContractTests). A nested
|
||||||
// production OnCreate can no longer reach it here:
|
// production OnCreate can no longer reach it here:
|
||||||
// post-residence ExistingGeneration registration is
|
// post-residence ExistingGeneration registration is
|
||||||
// description-only (RuntimeEntityObjectLifetime gates the
|
// description-only (RuntimeEntityObjectLifetime gates the
|
||||||
|
|
@ -1864,7 +1864,7 @@ public sealed class LiveEntityHydrationControllerTests
|
||||||
// revalidation guard stays covered.
|
// revalidation guard stays covered.
|
||||||
// C3c-R1 F3: honest MODEL of the executor drain's advance
|
// C3c-R1 F3: honest MODEL of the executor drain's advance
|
||||||
// (ApplyWeenieDescriptionAction — the sole production site,
|
// (ApplyWeenieDescriptionAction — the sole production site,
|
||||||
// source-pinned by CreateAuthorityDriftModelSourcePinTests); a
|
// metadata-pinned by CreateAuthorityDriftModelContractTests); a
|
||||||
// nested production OnCreate can no longer reach it —
|
// nested production OnCreate can no longer reach it —
|
||||||
// post-residence registration is description-only
|
// post-residence registration is description-only
|
||||||
// (RuntimeEntityObjectLifetime :660-665,
|
// (RuntimeEntityObjectLifetime :660-665,
|
||||||
|
|
@ -1983,7 +1983,7 @@ public sealed class LiveEntityHydrationControllerTests
|
||||||
// WeenieDescription stage; model that advance directly.
|
// WeenieDescription stage; model that advance directly.
|
||||||
// C3c-R1 F3: honest MODEL of the executor drain's advance
|
// C3c-R1 F3: honest MODEL of the executor drain's advance
|
||||||
// (ApplyWeenieDescriptionAction — the sole production site,
|
// (ApplyWeenieDescriptionAction — the sole production site,
|
||||||
// source-pinned by CreateAuthorityDriftModelSourcePinTests); a
|
// metadata-pinned by CreateAuthorityDriftModelContractTests); a
|
||||||
// nested production OnCreate can no longer reach it —
|
// nested production OnCreate can no longer reach it —
|
||||||
// post-residence registration is description-only
|
// post-residence registration is description-only
|
||||||
// (RuntimeEntityObjectLifetime :660-665,
|
// (RuntimeEntityObjectLifetime :660-665,
|
||||||
|
|
@ -2019,7 +2019,7 @@ public sealed class LiveEntityHydrationControllerTests
|
||||||
// (AdvanceCreateAuthority), not at registration; model it directly.
|
// (AdvanceCreateAuthority), not at registration; model it directly.
|
||||||
// C3c-R1 F3: honest MODEL of the executor drain's advance
|
// C3c-R1 F3: honest MODEL of the executor drain's advance
|
||||||
// (ApplyWeenieDescriptionAction — the sole production site,
|
// (ApplyWeenieDescriptionAction — the sole production site,
|
||||||
// source-pinned by CreateAuthorityDriftModelSourcePinTests); a nested
|
// metadata-pinned by CreateAuthorityDriftModelContractTests); a nested
|
||||||
// production OnCreate can no longer reach it — post-residence
|
// production OnCreate can no longer reach it — post-residence
|
||||||
// registration is description-only (RuntimeEntityObjectLifetime
|
// registration is description-only (RuntimeEntityObjectLifetime
|
||||||
// :660-665, !beginInitialResidence gate) and ConsumeExecuted
|
// :660-665, !beginInitialResidence gate) and ConsumeExecuted
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue