test: record published HistorianGateway 1.0 package verification

This commit is contained in:
Joseph Doherty
2026-11-10 14:40:37 -05:00
parent 67bc61236a
commit dc2a60f8fc
3 changed files with 87 additions and 10 deletions
+8 -4
View File
@@ -1,8 +1,10 @@
# HistorianGateway consumer TLS migration — issue 131
`consumer-1.0.0.patch` is a future consumer change, kept separate from the buildable
application while the paired Client/Contracts 1.0.0 packages are being released.
The application in this checkout remains pinned to published 0.4.0.
`consumer-1.0.0.patch` is a reviewable consumer change, kept separate from the
buildable application in this checkout. Real paired Client/Contracts 1.0.0
packages are now published and the isolated owning-project proof passed (RESULTS.md).
The application in this checkout remains pinned to published 0.4.0 until the patch
is applied by the coordinator.
The patch changes both central package pins to 1.0.0 and maps the new option as:
@@ -70,4 +72,6 @@ validation does not create or publish any fake package/version. Restore uses an
independent copy-on-write/copy cache, isolated HTTP cache and CLI home. Neither
user checkout is built or edited. Full owning-suite TRX, required TLS failure
classification, command exits and execution guard are retained under the task
output. Never treat source validation as stable published-package verification.
output. Published mode additionally checks package assets/provenance, absence of
source overrides, and exact package-to-test-bin DLL hashes. Never treat source
validation as stable published-package verification.
+50 -6
View File
@@ -1,4 +1,47 @@
# HG issue 131 validation evidence
# HG issue 131 — actual published 1.0.0 verification
Both real stable **Client 1.0.0** and **Contracts 1.0.0** were observed in the live
Gitea indexes at 2026-11-10 19:35:54 UTC and restored into a fresh isolated cache.
The future consumer patch was applied only to a separate SDK 2 consumer archive.
Application files in this working branch remain on 0.4.0, unchanged.
- Full Gateway owning project: **529 total, 523 passed, 0 failed, 6 existing live skips**.
- Restore, test and repository execution-count guard exits: **0 / 0 / 0**.
- All **3 real TLS/h2c wire cases passed** against the published packages.
- Strict default rejected with AuthenticationException **UntrustedRoot**, before RPC.
- Explicit opt-out and plaintext/stale-TLS-settings cases each completed one RPC.
- Both assets entries are **type=package, version=1.0.0**, from the actual Gitea
source. No source ProjectReference override: the archived Gateway csproj is
byte-identical to the normal consumer csproj.
- The only package folder is the task-isolated cache. Both copied test-bin DLL
hashes equal the package DLL hashes. No package was packed or published here.
Actual package RepositoryCommit for BOTH packages:
`ea9f21c850fb618767e12690924f9966f1e433ac`.
Consumer archive base: `4ea379fa92e571492ff9f49889a5eb91e3ad1e1a`.
Applied patch SHA-256: `9452ee82b2bace7828a384b9f6048e9c931e8b4ec2078e0ee1baa175d0652fac`.
| Package | NuGet package SHA-256 | Consumed DLL SHA-256 |
|---|---|---|
| ZB.MOM.WW.HistorianGateway.Client 1.0.0 | `0a3f2836727671c07c0c393e705cc9737d2ed44258213a51fb4acf0d0ab7129e` | `b89a02e0d228ec549c4dfb755694f7f67b573a6077f06ff2781165e884fc5e12` |
| ZB.MOM.WW.HistorianGateway.Contracts 1.0.0 | `83ffd12bcbbf919c973ba522560e10aa93a4cb8c686a3232030a2cfa5f00995e` | `e60d3d4650be5d251982f7847404daf1b666f61d56e2b0ccb844af8677e97743` |
Proof metadata/source/hash/readback checks:
`/tmp/historiangw-131-published-20261110T193638Z/published-package-proof.json`.
Full run metadata (including typed TLS error and package readback):
`/tmp/historiangw-131-published-20261110T193638Z/metadata.json`.
Fresh actual-package TRX: `/tmp/historiangw-131-published-20261110T193638Z/test-results`.
Restore/test/guard logs: `/tmp/historiangw-131-published-20261110T193638Z`.
This completes the isolated SDK 2 owning-project proof. The coordinator separately
owns the consumer-master full solution build, Astra review, landing/push and issue
131 comment/closure. No issue action, package publication, or HG user-checkout
mutation was performed by this validation lane. The live AVEVA fixture skips do
not substitute for the three executed local wire tests.
---
# Earlier archived-source validation
Future consumer patch validated against exact archived HG source commit
`e4321915ebc5e0704a68ecad21b85c1cc1c80d6b`. Consumer archive base:
@@ -8,8 +51,9 @@ Future consumer patch validated against exact archived HG source commit
## Scope and isolation
Mode: **unreleased source project references**, not published-package verification.
Both live package feed indexes still listed only 0.4.0, 0.3.0, 0.2.0, 0.1.0 after
validation. Stable Client/Contracts 1.0.0 verification remains pending.
At that earlier source-validation time, both feed indexes still listed only
0.4.0, 0.3.0, 0.2.0, 0.1.0. The published-package run below supersedes that pending
release-availability status.
The user's HG checkout was only read by git archive. Only the disposable archived
consumer Gateway csproj had its two package references replaced by project
@@ -49,6 +93,6 @@ Archived-source Client DLL SHA-256:
Archived-source Contracts DLL SHA-256:
`ebaaa43ffc485288054eb864a59ec59264d8d9c4ea6871319fd7995192370751`.
No stable release was consumed by this run. The real paired 1.0.0 packages must be
restored, the full owning suite/solution built and reviewed, and the consumer change
landed before issue 131 is closed. No issue comment/close was performed here.
That earlier run consumed source only. Actual stable-package proof is recorded
above. Consumer-master solution build/review/landing and issue handling are owned
by the coordinator; no issue comment/close was performed here.
@@ -4,6 +4,33 @@ import argparse, datetime, hashlib, io, json, os, shutil, subprocess, tarfile, u
import xml.etree.ElementTree as ET
from pathlib import Path
def verify_published_packages(root, consumer, cache, project):
relative = Path('src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.csproj')
assert (consumer/relative).read_bytes() == (root/relative).read_bytes(), 'Unexpected source-project override'
assets = json.loads((consumer/project.parent/'obj/project.assets.json').read_text())
assert all(Path(p).resolve() == cache.resolve() for p in assets['packageFolders'])
proof = {'no_source_project_reference_override': True, 'packages': {}}
for name in ['Client', 'Contracts']:
ident = 'ZB.MOM.WW.HistorianGateway.' + name
library = assets['libraries'][ident + '/1.0.0']
assert library['type'] == 'package'
package = cache/ident.lower()/'1.0.0'
provenance = json.loads((package/'.nupkg.metadata').read_text())
assert provenance['source'].startswith('https://gitea.dohertylan.com/api/packages/dohertj2/nuget')
dll = package/'lib/net10.0'/(ident + '.dll')
copied = consumer/project.parent/'bin/Release/net10.0'/(ident + '.dll')
digest = hashlib.sha256(dll.read_bytes()).hexdigest()
assert digest == hashlib.sha256(copied.read_bytes()).hexdigest()
nuspec = ET.parse(package/(ident.lower() + '.nuspec'))
assert nuspec.findtext('.//{*}version') == '1.0.0'
repository = nuspec.find('.//{*}repository')
proof['packages'][ident] = {'version': '1.0.0', 'asset_type': 'package',
'source': provenance['source'], 'dll_sha256': digest,
'nupkg_sha256': hashlib.sha256((package/(ident.lower() + '.1.0.0.nupkg')).read_bytes()).hexdigest(),
'repository': repository.attrib if repository is not None else None,
'test_bin_dll_matches_package': True}
return proof
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--consumer-root', type=Path, required=True)
parser.add_argument('--hg-root', type=Path, required=True)
@@ -93,5 +120,7 @@ for trx in results.glob('*.trx'):
xml=ET.parse(trx);metadata['results'].append(xml.find('.//t:Counters',ns).attrib)
metadata['tls_cases']=[{'name':r.get('testName'),'outcome':r.get('outcome'),'output':'\n'.join(p.text or '' for p in r.findall('.//t:StdOut',ns)),
'error':r.findtext('.//t:Message','',ns)} for r in xml.findall('.//t:UnitTestResult',ns) if 'HistorianGatewayTlsPolicyWireTests' in r.get('testName','')]
if published:
metadata['package_proof'] = verify_published_packages(root, consumer, cache, project)
(out/'metadata.json').write_text(json.dumps(metadata,indent=2));print(json.dumps(metadata,indent=2),flush=True)
raise SystemExit(test if test else guard.returncode)