Strengthen split target conformance consumption
This commit is contained in:
parent
52a5dd1e56
commit
ef16b0c90b
5 changed files with 135 additions and 0 deletions
|
|
@ -280,6 +280,13 @@ Exit criteria:
|
|||
|
||||
Recently cut:
|
||||
|
||||
- Split-target conformance consumption now verifies graduation state instead of
|
||||
only split-target presence. The generic consumer supports
|
||||
`--expect-split-target-status`, `--expect-split-target-blocker`, and
|
||||
`--expect-split-target-proof`; the parity harness runs
|
||||
`scripts/run-split-target-conformance-consumer-smoke.ps1`; and EveFlutter /
|
||||
EveUnity consumers can now prove that the targets remain incubating for named
|
||||
blockers while their current split-readiness proofs stay passed.
|
||||
- Runtime owner conformance consumption now verifies runtime target health
|
||||
instead of only runtime presence. The generic consumer supports
|
||||
`--expect-runtime-status`, `--expect-runtime-feature`,
|
||||
|
|
|
|||
|
|
@ -120,6 +120,18 @@ That script runs the export consumer from `flutter/eve_parity` and asserts the
|
|||
runtime pack, Sai provider fixture, Flutter runtime targets, and `EveFlutter`
|
||||
split target without reading `tools/parity/parity-manifest.json`.
|
||||
|
||||
Split-target consumer smoke:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File .\scripts\run-split-target-conformance-consumer-smoke.ps1
|
||||
```
|
||||
|
||||
That script asserts that EveFlutter and EveUnity are exported as incubating
|
||||
split targets, that their current split-readiness proofs are passed, and that
|
||||
their graduation blockers remain visible to consumers. A target being present
|
||||
is not enough; future owner repos must be able to consume why it is or is not
|
||||
ready to leave Eve incubation.
|
||||
|
||||
The Flutter widget smoke also exercises `EveProviderCatalog` and
|
||||
`EveProviderPicker` against a conformance-export-shaped provider list. That is
|
||||
the runtime-side provider picker proof; it consumes provider entries and plugin
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ try {
|
|||
& (Join-Path $PSScriptRoot "run-conformance-consumer-smoke.ps1")
|
||||
& (Join-Path $PSScriptRoot "run-plugin-owner-conformance-consumer-smoke.ps1")
|
||||
& (Join-Path $PSScriptRoot "run-runtime-owner-conformance-consumer-smoke.ps1")
|
||||
& (Join-Path $PSScriptRoot "run-split-target-conformance-consumer-smoke.ps1")
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
|
|
|||
53
scripts/run-split-target-conformance-consumer-smoke.ps1
Normal file
53
scripts/run-split-target-conformance-consumer-smoke.ps1
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
param(
|
||||
[string] $SourceDirectory = "artifacts\conformance\latest",
|
||||
[string] $SmokeDirectory = "artifacts\split-target-conformance-consumer-smoke"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$projectRoot = Split-Path -Parent $PSScriptRoot
|
||||
$sourcePath = if ([System.IO.Path]::IsPathRooted($SourceDirectory)) {
|
||||
$SourceDirectory
|
||||
} else {
|
||||
Join-Path $projectRoot $SourceDirectory
|
||||
}
|
||||
$smokePath = if ([System.IO.Path]::IsPathRooted($SmokeDirectory)) {
|
||||
$SmokeDirectory
|
||||
} else {
|
||||
Join-Path $projectRoot $SmokeDirectory
|
||||
}
|
||||
$exportPath = Join-Path $smokePath "export"
|
||||
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $sourcePath "index.json"))) {
|
||||
throw "Conformance export not found: $sourcePath"
|
||||
}
|
||||
|
||||
if (Test-Path -LiteralPath $exportPath) {
|
||||
Remove-Item -LiteralPath $exportPath -Recurse -Force
|
||||
}
|
||||
New-Item -ItemType Directory -Force -Path $smokePath | Out-Null
|
||||
Copy-Item -LiteralPath $sourcePath -Destination $exportPath -Recurse
|
||||
|
||||
Push-Location $projectRoot
|
||||
try {
|
||||
node .\tools\conformance\consume-export.mjs $exportPath `
|
||||
--expect-split-target EveFlutter `
|
||||
--expect-split-target-status EveFlutter:incubating `
|
||||
--expect-split-target-proof "EveFlutter:Provider picker consumes provider advertisements" `
|
||||
--expect-split-target-proof "EveFlutter:Conformance pack can be consumed" `
|
||||
--expect-split-target-proof "EveFlutter:Flutter lifecycle evidence is declared" `
|
||||
--expect-split-target-blocker "EveFlutter:Tagged EveFlutter release" `
|
||||
--expect-split-target EveUnity `
|
||||
--expect-split-target-status EveUnity:incubating `
|
||||
--expect-split-target-proof "EveUnity:Unity lifecycle evidence is declared" `
|
||||
--expect-split-target-blocker "EveUnity:Tagged UPM release" `
|
||||
--expect-split-target-blocker "EveUnity:Unity batchmode EditMode runner" `
|
||||
--expect-split-target-blocker "EveUnity:Unity batchmode or editor capture artifact"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Split target conformance consumer smoke failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
Write-Host "Split target conformance consumer smoke passed: $exportPath"
|
||||
|
|
@ -25,6 +25,9 @@ if (!exportDirectory) {
|
|||
" --expect-runtime-feature <runtimeId:feature>",
|
||||
" --expect-runtime-command-schema <runtimeId:schema>",
|
||||
" --expect-runtime-capture-status <runtimeId:status>",
|
||||
" --expect-split-target-status <targetId:status>",
|
||||
" --expect-split-target-blocker <targetId:blocker-substring>",
|
||||
" --expect-split-target-proof <targetId:proof-substring>",
|
||||
].join("\n"));
|
||||
process.exit(2);
|
||||
}
|
||||
|
|
@ -208,6 +211,41 @@ function validateIndex(index, directory, expectations, errors) {
|
|||
for (const expectedSplitTarget of expectations.splitTargets) {
|
||||
if (!splitTargets.some(target => target.id === expectedSplitTarget)) errors.push(`splitTargets:${expectedSplitTarget}:missing`);
|
||||
}
|
||||
for (const expectation of expectations.splitTargetStatuses) {
|
||||
const target = splitTargets.find(candidate => candidate.id === expectation.targetId);
|
||||
if (!target) {
|
||||
errors.push(`splitTargets:${expectation.targetId}:missing`);
|
||||
continue;
|
||||
}
|
||||
if (target.status !== expectation.status) {
|
||||
errors.push(`splitTargets:${expectation.targetId}:status:expected ${expectation.status} got ${target.status || ""}`);
|
||||
}
|
||||
}
|
||||
for (const expectation of expectations.splitTargetBlockers) {
|
||||
const target = splitTargets.find(candidate => candidate.id === expectation.targetId);
|
||||
if (!target) {
|
||||
errors.push(`splitTargets:${expectation.targetId}:missing`);
|
||||
continue;
|
||||
}
|
||||
const blockers = Array.isArray(target.blockers) ? target.blockers : [];
|
||||
if (!blockers.some(blocker => blocker.includes(expectation.blocker))) {
|
||||
errors.push(`splitTargets:${expectation.targetId}:blocker:${expectation.blocker}:missing`);
|
||||
}
|
||||
}
|
||||
for (const expectation of expectations.splitTargetProofs) {
|
||||
const target = splitTargets.find(candidate => candidate.id === expectation.targetId);
|
||||
if (!target) {
|
||||
errors.push(`splitTargets:${expectation.targetId}:missing`);
|
||||
continue;
|
||||
}
|
||||
const proofs = Array.isArray(target.proofs) ? target.proofs : [];
|
||||
const proof = proofs.find(candidate => candidate.description?.includes(expectation.proof));
|
||||
if (!proof) {
|
||||
errors.push(`splitTargets:${expectation.targetId}:proof:${expectation.proof}:missing`);
|
||||
} else if (proof.status !== "passed") {
|
||||
errors.push(`splitTargets:${expectation.targetId}:proof:${expectation.proof}:expected passed got ${proof.status || ""}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!plugins.some(plugin => plugin.pluginId === "sai.vn" && plugin.abiFixturePath)) {
|
||||
errors.push("plugins:sai.vn:abiFixturePath:missing");
|
||||
|
|
@ -246,6 +284,9 @@ function parseArguments(args) {
|
|||
runtimeCaptureStatuses: [],
|
||||
scenarios: [],
|
||||
splitTargets: [],
|
||||
splitTargetStatuses: [],
|
||||
splitTargetBlockers: [],
|
||||
splitTargetProofs: [],
|
||||
};
|
||||
const optionTargets = new Map([
|
||||
["--expect-pack", expectations.packs],
|
||||
|
|
@ -264,6 +305,9 @@ function parseArguments(args) {
|
|||
["--expect-runtime-feature", expectations.runtimeFeatures],
|
||||
["--expect-runtime-command-schema", expectations.runtimeCommandSchemas],
|
||||
["--expect-runtime-capture-status", expectations.runtimeCaptureStatuses],
|
||||
["--expect-split-target-status", expectations.splitTargetStatuses],
|
||||
["--expect-split-target-blocker", expectations.splitTargetBlockers],
|
||||
["--expect-split-target-proof", expectations.splitTargetProofs],
|
||||
]);
|
||||
|
||||
for (let index = 1; index < args.length; index += 1) {
|
||||
|
|
@ -296,6 +340,12 @@ function parseArguments(args) {
|
|||
target.push(parseRuntimeExpectation(value, "schema"));
|
||||
} else if (option === "--expect-runtime-capture-status") {
|
||||
target.push(parseRuntimeExpectation(value, "status"));
|
||||
} else if (option === "--expect-split-target-status") {
|
||||
target.push(parseSplitTargetExpectation(value, "status"));
|
||||
} else if (option === "--expect-split-target-blocker") {
|
||||
target.push(parseSplitTargetExpectation(value, "blocker"));
|
||||
} else if (option === "--expect-split-target-proof") {
|
||||
target.push(parseSplitTargetExpectation(value, "proof"));
|
||||
} else {
|
||||
target.push(value);
|
||||
}
|
||||
|
|
@ -341,6 +391,18 @@ function parseRuntimeExpectation(value, field) {
|
|||
};
|
||||
}
|
||||
|
||||
function parseSplitTargetExpectation(value, field) {
|
||||
const separator = value.indexOf(":");
|
||||
if (separator <= 0 || separator === value.length - 1) {
|
||||
console.error(`Expected split target ${field} in <targetId:${field}> form, got: ${value}`);
|
||||
process.exit(2);
|
||||
}
|
||||
return {
|
||||
targetId: value.slice(0, separator),
|
||||
[field]: value.slice(separator + 1),
|
||||
};
|
||||
}
|
||||
|
||||
function mergeRuntimeRecords(topLevelRuntimes, runtimeTargets) {
|
||||
const byId = new Map();
|
||||
for (const runtime of runtimeTargets) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue