fix: unblock CI — nc_pid type error, 400-LOC split, harness abort count

Three failures that tonight's --no-verify checkpoints hid:
- nc_session.rs::nc_pid used Deadline::after (Result<Deadline>) where
  operation_deadline yields Result<Instant> — E0308 broke Native check
  (macOS/Windows) and the FFI cdylib builds. Reverted to the compiling form;
  the speculative deadline floor did not fix NT3 anyway.
- resolve_query_tests.rs hit 403 lines; split the hydration adapters/tests
  into resolve_query_hydration_tests.rs (both now well under 400).
- test_harness_contract.py pinned 9 abort_suite sites; the branch legitimately
  has 10 (all required-fixture guards). Updated the invariant.

cargo check --all-targets --locked, clippy, fmt, source rules, harness
contract, and 1562 unit tests all green locally.
This commit is contained in:
Lahfir 2026-07-12 16:44:04 -07:00
parent eae58df5c2
commit 39de14291a
5 changed files with 157 additions and 147 deletions

View file

@ -91,6 +91,8 @@ mod observed_tree_tests;
#[cfg(test)]
mod ownership_tests;
#[cfg(test)]
mod resolve_query_hydration_tests;
#[cfg(test)]
mod resolve_query_tests;
#[cfg(test)]
mod resolve_tests;

View file

@ -0,0 +1,152 @@
use super::resolve_query_tests::window;
use super::{
LocatorMaterialization, LocatorResolveRequest, LocatorSelection, ObservationRequest,
ObservationRoot, ObservedTree, resolve_query,
};
use crate::{
AdapterError, ErrorCode,
adapter::{ActionOps, InputOps, ObservationOps, SystemOps},
locator::LocatorQuery,
};
use std::sync::atomic::{AtomicUsize, Ordering};
struct HydrationRetryAdapter {
window_observations: AtomicUsize,
hydration_observations: AtomicUsize,
}
impl ObservationOps for HydrationRetryAdapter {
fn observe_tree(
&self,
root: ObservationRoot<'_>,
_request: &ObservationRequest,
) -> Result<ObservedTree, AdapterError> {
match root {
ObservationRoot::Window(_) => {
self.window_observations.fetch_add(1, Ordering::SeqCst);
Ok(button_tree())
}
ObservationRoot::Element { .. } => {
let attempt = self.hydration_observations.fetch_add(1, Ordering::SeqCst);
if attempt == 0 {
return Err(AdapterError::stale_ref("hydration retry")
.with_details(serde_json::json!({ "retryable": true })));
}
Ok(button_tree())
}
}
}
fn resolve_locator_anchor(
&self,
_entry: &crate::RefEntry,
_deadline: crate::Deadline,
) -> Result<crate::NativeHandle, AdapterError> {
Ok(crate::NativeHandle::null())
}
}
impl ActionOps for HydrationRetryAdapter {}
impl InputOps for HydrationRetryAdapter {}
impl SystemOps for HydrationRetryAdapter {}
fn button_tree() -> ObservedTree {
super::test_support::tree(
vec![super::test_support::node(
0,
super::test_support::evidence("button", Some("Save")),
Vec::new(),
&[],
)],
vec![0],
true,
)
}
#[test]
fn hydration_retry_preserves_failed_attempt_statistics() {
let adapter = HydrationRetryAdapter {
window_observations: AtomicUsize::new(0),
hydration_observations: AtomicUsize::new(0),
};
let request = LocatorResolveRequest {
selection: LocatorSelection::Strict,
deadline: crate::Deadline::after(1_000).unwrap(),
max_raw_depth: 10,
materialization: LocatorMaterialization::SelectedMatches,
};
let resolution = resolve_query(
&adapter,
&LocatorQuery::default(),
ObservationRoot::Window(&window()),
&request,
)
.unwrap();
assert_eq!(adapter.window_observations.load(Ordering::SeqCst), 2);
assert_eq!(adapter.hydration_observations.load(Ordering::SeqCst), 2);
assert_eq!(resolution.stats.reads.observation_attempts, 3);
}
struct IncompleteHydrationAdapter {
hydration_observations: AtomicUsize,
}
impl ObservationOps for IncompleteHydrationAdapter {
fn observe_tree(
&self,
root: ObservationRoot<'_>,
_request: &ObservationRequest,
) -> Result<ObservedTree, AdapterError> {
if matches!(root, ObservationRoot::Window(_)) {
return Ok(button_tree());
}
self.hydration_observations.fetch_add(1, Ordering::SeqCst);
let mut evidence = super::test_support::evidence("button", Some("Save"));
evidence.ref_evidence.bounds = super::LocatorField::Unknown;
Ok(super::test_support::tree(
vec![super::test_support::node(0, evidence, Vec::new(), &[])],
vec![0],
true,
))
}
fn resolve_locator_anchor(
&self,
_entry: &crate::RefEntry,
_deadline: crate::Deadline,
) -> Result<crate::NativeHandle, AdapterError> {
Ok(crate::NativeHandle::null())
}
}
impl ActionOps for IncompleteHydrationAdapter {}
impl InputOps for IncompleteHydrationAdapter {}
impl SystemOps for IncompleteHydrationAdapter {}
#[test]
fn selected_hydration_rejects_incomplete_snapshot_evidence() {
let adapter = IncompleteHydrationAdapter {
hydration_observations: AtomicUsize::new(0),
};
let request = LocatorResolveRequest {
selection: LocatorSelection::Strict,
deadline: crate::Deadline::after(35).unwrap(),
max_raw_depth: 10,
materialization: LocatorMaterialization::SelectedMatches,
};
let error = match resolve_query(
&adapter,
&LocatorQuery::default(),
ObservationRoot::Window(&window()),
&request,
) {
Ok(_) => panic!("incomplete hydration unexpectedly succeeded"),
Err(error) => error,
};
assert_eq!(error.code(), ErrorCode::Timeout.as_str());
assert!(adapter.hydration_observations.load(Ordering::SeqCst) >= 1);
}

View file

@ -84,7 +84,7 @@ fn child_label_cap(_: usize) -> ObservedTree {
observed_tree(true, stats)
}
fn window() -> WindowInfo {
pub(super) fn window() -> WindowInfo {
WindowInfo {
id: "w-1".into(),
title: "Fixture".into(),
@ -260,144 +260,3 @@ fn strict_unknown_incomplete_result_fails_closed() {
assert_eq!(error.details.unwrap()["kind"], "locator_incomplete");
assert_eq!(adapter.builds.load(Ordering::SeqCst), 1);
}
struct HydrationRetryAdapter {
window_observations: AtomicUsize,
hydration_observations: AtomicUsize,
}
impl ObservationOps for HydrationRetryAdapter {
fn observe_tree(
&self,
root: ObservationRoot<'_>,
_request: &ObservationRequest,
) -> Result<ObservedTree, AdapterError> {
match root {
ObservationRoot::Window(_) => {
self.window_observations.fetch_add(1, Ordering::SeqCst);
Ok(button_tree())
}
ObservationRoot::Element { .. } => {
let attempt = self.hydration_observations.fetch_add(1, Ordering::SeqCst);
if attempt == 0 {
return Err(AdapterError::stale_ref("hydration retry")
.with_details(serde_json::json!({ "retryable": true })));
}
Ok(button_tree())
}
}
}
fn resolve_locator_anchor(
&self,
_entry: &crate::RefEntry,
_deadline: crate::Deadline,
) -> Result<crate::NativeHandle, AdapterError> {
Ok(crate::NativeHandle::null())
}
}
impl ActionOps for HydrationRetryAdapter {}
impl InputOps for HydrationRetryAdapter {}
impl SystemOps for HydrationRetryAdapter {}
fn button_tree() -> ObservedTree {
super::test_support::tree(
vec![super::test_support::node(
0,
super::test_support::evidence("button", Some("Save")),
Vec::new(),
&[],
)],
vec![0],
true,
)
}
#[test]
fn hydration_retry_preserves_failed_attempt_statistics() {
let adapter = HydrationRetryAdapter {
window_observations: AtomicUsize::new(0),
hydration_observations: AtomicUsize::new(0),
};
let request = LocatorResolveRequest {
selection: LocatorSelection::Strict,
deadline: crate::Deadline::after(1_000).unwrap(),
max_raw_depth: 10,
materialization: LocatorMaterialization::SelectedMatches,
};
let resolution = resolve_query(
&adapter,
&LocatorQuery::default(),
ObservationRoot::Window(&window()),
&request,
)
.unwrap();
assert_eq!(adapter.window_observations.load(Ordering::SeqCst), 2);
assert_eq!(adapter.hydration_observations.load(Ordering::SeqCst), 2);
assert_eq!(resolution.stats.reads.observation_attempts, 3);
}
struct IncompleteHydrationAdapter {
hydration_observations: AtomicUsize,
}
impl ObservationOps for IncompleteHydrationAdapter {
fn observe_tree(
&self,
root: ObservationRoot<'_>,
_request: &ObservationRequest,
) -> Result<ObservedTree, AdapterError> {
if matches!(root, ObservationRoot::Window(_)) {
return Ok(button_tree());
}
self.hydration_observations.fetch_add(1, Ordering::SeqCst);
let mut evidence = super::test_support::evidence("button", Some("Save"));
evidence.ref_evidence.bounds = super::LocatorField::Unknown;
Ok(super::test_support::tree(
vec![super::test_support::node(0, evidence, Vec::new(), &[])],
vec![0],
true,
))
}
fn resolve_locator_anchor(
&self,
_entry: &crate::RefEntry,
_deadline: crate::Deadline,
) -> Result<crate::NativeHandle, AdapterError> {
Ok(crate::NativeHandle::null())
}
}
impl ActionOps for IncompleteHydrationAdapter {}
impl InputOps for IncompleteHydrationAdapter {}
impl SystemOps for IncompleteHydrationAdapter {}
#[test]
fn selected_hydration_rejects_incomplete_snapshot_evidence() {
let adapter = IncompleteHydrationAdapter {
hydration_observations: AtomicUsize::new(0),
};
let request = LocatorResolveRequest {
selection: LocatorSelection::Strict,
deadline: crate::Deadline::after(35).unwrap(),
max_raw_depth: 10,
materialization: LocatorMaterialization::SelectedMatches,
};
let error = match resolve_query(
&adapter,
&LocatorQuery::default(),
ObservationRoot::Window(&window()),
&request,
) {
Ok(_) => panic!("incomplete hydration unexpectedly succeeded"),
Err(error) => error,
};
assert_eq!(error.code(), ErrorCode::Timeout.as_str());
assert!(adapter.hydration_observations.load(Ordering::SeqCst) >= 1);
}

View file

@ -133,13 +133,10 @@ fn reactivate_app(_name: &str, _deadline: Deadline) {}
pub(super) fn nc_pid(deadline: Deadline) -> Option<i32> {
let mut command = std::process::Command::new("/usr/bin/pgrep");
command.arg("-x").arg("NotificationCenter");
let pgrep_deadline = operation_deadline(deadline, std::time::Duration::from_secs(1))
.or_else(|_| Deadline::after(500))
.ok()?;
let output = crate::system::process::run_with_deadline(
&mut command,
"pgrep NotificationCenter",
pgrep_deadline,
operation_deadline(deadline, std::time::Duration::from_secs(1)).ok()?,
)
.ok()?;

View file

@ -27,7 +27,7 @@ class HarnessContractTests(unittest.TestCase):
self.assertEqual(len(exits), 1, exits)
self.assertEqual(exits[0][0], "lib.sh")
self.assertEqual(len(abort_calls), 9, abort_calls)
self.assertEqual(len(abort_calls), 10, abort_calls)
source = (E2E_ROOT / "lib.sh").read_text()
abort = re.search(r"abort_suite\(\) \{(?P<body>.*?)\n\}", source, re.DOTALL)
self.assertIsNotNone(abort)