From 391f1aa9e711ed0246b96e7e3b1f05ee621cd037 Mon Sep 17 00:00:00 2001
From: Yuri Schimke
expected is a failure this repository predicted and can
explain: the assertion is right and the answer is currently no, which is the finding rather
- than a problem with it. ECH on the JVM is the present example — OkHttp's
-
not run against a suite whose endpoint is down is the
diff --git a/site/tools/collect_results.py b/site/tools/collect_results.py
index 87eb643..673c391 100644
--- a/site/tools/collect_results.py
+++ b/site/tools/collect_results.py
@@ -103,8 +103,8 @@ def severity_of(suite_name: str) -> str:
# Failures that are the point rather than the problem.
#
# A suite here is asking a question whose answer is currently "no", and saying so is why it
-# exists — EchTest reports that OkHttp can't do ECH on the JVM, and a green EchTest would mean
-# the finding had been lost, not that the bug was fixed. Those failures are shown, and shown in
+# exists — EchTest reports that OkHttp can't do ECH on the JVM, and BasicLoomTest reports the
+# monitor pinning that JEP 491 fixes only from JDK 24. Those failures are shown, and shown in
# amber, but folded away: the page's red is reserved for a result nobody predicted.
#
# The reason is required, and is what the page shows instead of a stack trace. Cases are named
@@ -169,8 +169,21 @@ def normalise_case(name: str) -> str:
return " ".join(name.split())
-def expected_reason(suite_name: str, case_name: str) -> str:
+def expected_reason(
+ suite_name: str,
+ case_name: str,
+ platform: str,
+ variant: str,
+) -> str:
"""Why this case failing is the expected answer, or empty if it isn't."""
+ if suite_name == "BasicLoomTest" and case_name == "testHttpsRequest":
+ jdk = re.search(r"\bJDK (\d+)", f"{variant} {platform}")
+ if jdk and 21 <= int(jdk.group(1)) < 24:
+ return (
+ "Before JDK 24, Http2Connection.newStream holds intrinsic monitors across "
+ "Http2Writer.flush's blocking write, which pins the virtual thread's carrier. "
+ "JEP 491 removes this monitor-based pinning from JDK 24."
+ )
return EXPECTED_FAILURES.get(suite_name, {}).get(case_name, "")
@@ -224,7 +237,11 @@ def parse_suite(
raw_name = case.get("name", "")
case_name = normalise_case(raw_name)
- reason = expected_reason(simple_name, case_name) if status == "failed" else ""
+ reason = (
+ expected_reason(simple_name, case_name, platform, variant)
+ if status == "failed"
+ else ""
+ )
if reason:
status = "expected"
diff --git a/site/topics/loom.html b/site/topics/loom.html
index 6a327a7..24c5323 100644
--- a/site/topics/loom.html
+++ b/site/topics/loom.html
@@ -63,10 +63,11 @@
About these results
ConscryptPlatform drops the config list, and no released Conscrypt has the
- method for it to call. These are folded shut, and each carries its reason where a stack
- trace would otherwise be. When one starts passing, it becomes an unexpected pass to look at.
+ than a problem with it. Examples include ECH on the JVM and monitor-based virtual-thread
+ pinning before JDK 24. These are folded shut, and each carries its reason where a stack trace
+ would otherwise be. When one starts passing, it becomes an unexpected pass to look at.
An observed pinning signature
Http2Connection.newStream holds a monitor across Http2Writer.flush's
blocking write. That is a true statement about the published artifact, not a broken test — so
- the suite runs under the loomTest Gradle task with ignoreFailures.
- The assertion stays exactly as written. When present, the failure is recorded in the JUnit XML and shown above and on
- the status page as a findings result, and
- the build stays green. A finding about OkHttp should not read as this repository being red.
+ the suite runs under the loomTest Gradle task with ignoreFailures, and
+ the assertion stays exactly as written. On JDK 21 through 23, the status collector classifies
+ this predicted failure as expected and supplies the reason
+ in place of the stack trace. On JDK 24 and later the exemption does not apply: a pinning trace
+ there is an unpredicted finding.
Why the answer depends on the JDK
@@ -76,7 +77,7 @@ Why the answer depends on the JDK
code that pins on 21 should not pin on 24 and later. Recording that difference — same artifact,
same test, different runtime — is exactly what a testbed running against published versions is
for. The suite is gated with @EnabledForJreRange(min = JRE.JAVA_21), and the
- daily run currently runs on 21.
+ daily run includes both 21 and 25, showing the behavior before and after that JDK change.