Skip to content

Commit 9226a00

Browse files
committed
Add CDI Lite signature test evidence
1 parent c6e1fa4 commit 9226a00

3 files changed

Lines changed: 292 additions & 4 deletions

File tree

.github/scripts/collect-cdi-lite-tck-evidence.sh

Lines changed: 139 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ cd "${repo_root}"
77

88
evidence_dir="build/tck-evidence/jdk-${java_version}"
99
result_dir="tck-runner/build/test-results/fullTckTest"
10+
signature_dir="tck-runner/build/reports/cdi-signature-test"
11+
signature_result_dir="tck-runner/build/test-results/cdiSignatureTest"
1012
summary_file="${evidence_dir}/summary.md"
1113
index_file="${evidence_dir}/index.html"
1214

@@ -54,6 +56,106 @@ if [ -d "${result_dir}" ]; then
5456
done
5557
fi
5658

59+
property_value() {
60+
local file="$1"
61+
local key="$2"
62+
sed -n "s/^${key}=//p" "${file}" | head -1
63+
}
64+
65+
signature_status="not-run"
66+
signature_tests="0"
67+
signature_failures="0"
68+
signature_errors="0"
69+
signature_skipped="0"
70+
signature_tool="unavailable"
71+
signature_file="unavailable"
72+
signature_source="unavailable"
73+
signature_boot_cp="unavailable"
74+
signature_packages="unavailable"
75+
signature_api_artifacts="unavailable"
76+
signature_report="unavailable"
77+
78+
rm -rf "${evidence_dir}/signature-test"
79+
if [ -d "${signature_dir}" ]; then
80+
mkdir -p "${evidence_dir}/signature-test"
81+
for signature_artifact in \
82+
signature-test.properties \
83+
signature-test-report.txt \
84+
cdi-api-jdk17.sig; do
85+
if [ -f "${signature_dir}/${signature_artifact}" ]; then
86+
cp "${signature_dir}/${signature_artifact}" "${evidence_dir}/signature-test/${signature_artifact}"
87+
fi
88+
done
89+
fi
90+
91+
if [ -d "${signature_result_dir}" ]; then
92+
mkdir -p "${evidence_dir}/signature-test/junit-xml"
93+
for result_file in "${signature_result_dir}"/TEST-*.xml; do
94+
[ -f "${result_file}" ] || continue
95+
perl -0pe 's#<system-out>.*?</system-out>\n?##gs; s#<system-err>.*?</system-err>\n?##gs' \
96+
"${result_file}" > "${evidence_dir}/signature-test/junit-xml/$(basename "${result_file}")"
97+
done
98+
fi
99+
100+
if [ -f "${signature_dir}/signature-test.properties" ]; then
101+
signature_status="$(property_value "${signature_dir}/signature-test.properties" status)"
102+
signature_tests="$(property_value "${signature_dir}/signature-test.properties" tests)"
103+
signature_failures="$(property_value "${signature_dir}/signature-test.properties" failures)"
104+
signature_errors="$(property_value "${signature_dir}/signature-test.properties" errors)"
105+
signature_skipped="$(property_value "${signature_dir}/signature-test.properties" skipped)"
106+
signature_tool="$(property_value "${signature_dir}/signature-test.properties" sigtestTool)"
107+
signature_file="$(property_value "${signature_dir}/signature-test.properties" signatureFile)"
108+
signature_source="$(property_value "${signature_dir}/signature-test.properties" signatureSource)"
109+
signature_boot_cp="$(property_value "${signature_dir}/signature-test.properties" bootCpRelease)"
110+
signature_packages="$(property_value "${signature_dir}/signature-test.properties" packages)"
111+
signature_api_artifacts="$(property_value "${signature_dir}/signature-test.properties" apiArtifacts)"
112+
signature_report="$(property_value "${signature_dir}/signature-test.properties" report)"
113+
fi
114+
115+
if [ -d "${evidence_dir}/signature-test" ]; then
116+
cat > "${evidence_dir}/signature-test/index.html" <<EOF
117+
<!doctype html>
118+
<html lang="en">
119+
<head>
120+
<meta charset="utf-8">
121+
<meta name="viewport" content="width=device-width, initial-scale=1">
122+
<title>ODI CDI Lite Signature-Test Evidence - JDK ${java_version}</title>
123+
<style>
124+
body { font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; line-height: 1.5; max-width: 960px; margin: 2rem auto; padding: 0 1rem; color: #1f2933; }
125+
code, pre { background: #f5f7fa; border-radius: 4px; }
126+
code { padding: 0.1rem 0.25rem; }
127+
table { border-collapse: collapse; width: 100%; margin: 1rem 0; }
128+
th, td { border: 1px solid #d9e2ec; padding: 0.5rem; text-align: left; }
129+
th { background: #f5f7fa; }
130+
</style>
131+
</head>
132+
<body>
133+
<h1>ODI CDI Lite Signature-Test Evidence - JDK ${java_version}</h1>
134+
<table>
135+
<tr><th>Status</th><th>Tests</th><th>Failures</th><th>Errors</th><th>Skipped</th></tr>
136+
<tr><td>${signature_status}</td><td>${signature_tests}</td><td>${signature_failures}</td><td>${signature_errors}</td><td>${signature_skipped}</td></tr>
137+
</table>
138+
<ul>
139+
<li>Tool: ${signature_tool}</li>
140+
<li>TCK signature file: ${signature_file}</li>
141+
<li>Signature source: ${signature_source}</li>
142+
<li>Boot class path release: ${signature_boot_cp}</li>
143+
<li>Checked packages: <code>${signature_packages}</code></li>
144+
<li>API artifacts: <code>${signature_api_artifacts}</code></li>
145+
</ul>
146+
<p>The signature file is extracted dynamically from the resolved Jakarta CDI TCK artifact during the CI run.</p>
147+
<h2>Artifacts</h2>
148+
<ul>
149+
<li><a href="./${signature_report}">Signature-test report</a></li>
150+
<li><a href="./signature-test.properties">Signature-test metadata</a></li>
151+
<li><a href="./${signature_file}">TCK signature file</a></li>
152+
<li><a href="./junit-xml/TEST-cdi-signature-test.xml">JUnit XML</a></li>
153+
</ul>
154+
</body>
155+
</html>
156+
EOF
157+
fi
158+
57159
cat > "${summary_file}" <<EOF
58160
# ODI CDI Lite TCK Results - JDK ${java_version}
59161
@@ -93,7 +195,24 @@ Excluded TestNG groups: \`cdi-full\`, \`integration\`, \`javaee-full\`, \`se\`.
93195
94196
## Additional Certification Requirements
95197
96-
- Signature-test evidence: pending; this workflow does not claim signature tests passed.
198+
- Signature-test evidence: ${signature_status}
199+
200+
## Signature Test
201+
202+
- Status: ${signature_status}
203+
- Tests: ${signature_tests}
204+
- Failures: ${signature_failures}
205+
- Errors: ${signature_errors}
206+
- Skipped: ${signature_skipped}
207+
- Tool: ${signature_tool}
208+
- TCK signature file: ${signature_file}
209+
- Signature source: ${signature_source}
210+
- Boot class path release: ${signature_boot_cp}
211+
- Checked packages: ${signature_packages}
212+
- API artifacts: ${signature_api_artifacts}
213+
- Report: ./signature-test/${signature_report}
214+
215+
The signature file is extracted dynamically from the resolved Jakarta CDI TCK artifact during the CI run.
97216
98217
## Environment
99218
@@ -109,6 +228,7 @@ ${java_runtime}
109228
## Artifacts
110229
111230
- Sanitized JUnit XML: ./junit-xml/
231+
- Signature-test evidence: ./signature-test/
112232
113233
Raw Gradle console output and unsanitized Gradle reports are intentionally not published because the build runs with secret-backed environment variables.
114234
EOF
@@ -170,7 +290,23 @@ cat > "${index_file}" <<EOF
170290
</ul>
171291
172292
<h2>Additional Certification Requirements</h2>
173-
<p>Signature-test evidence is pending; this workflow does not claim signature tests passed.</p>
293+
<p>Signature-test evidence: ${signature_status}</p>
294+
295+
<h2>Signature Test</h2>
296+
<table>
297+
<tr><th>Status</th><th>Tests</th><th>Failures</th><th>Errors</th><th>Skipped</th></tr>
298+
<tr><td>${signature_status}</td><td>${signature_tests}</td><td>${signature_failures}</td><td>${signature_errors}</td><td>${signature_skipped}</td></tr>
299+
</table>
300+
<ul>
301+
<li>Tool: ${signature_tool}</li>
302+
<li>TCK signature file: ${signature_file}</li>
303+
<li>Signature source: ${signature_source}</li>
304+
<li>Boot class path release: ${signature_boot_cp}</li>
305+
<li>Checked packages: <code>${signature_packages}</code></li>
306+
<li>API artifacts: <code>${signature_api_artifacts}</code></li>
307+
<li>Report: <a href="./signature-test/${signature_report}">signature-test/${signature_report}</a></li>
308+
</ul>
309+
<p>The signature file is extracted dynamically from the resolved Jakarta CDI TCK artifact during the CI run.</p>
174310
175311
<h2>Environment</h2>
176312
<ul>
@@ -185,6 +321,7 @@ cat > "${index_file}" <<EOF
185321
<ul>
186322
<li><a href="./summary.md">Markdown summary</a></li>
187323
<li><a href="./junit-xml/">Sanitized JUnit XML results</a></li>
324+
<li><a href="./signature-test/">Signature-test evidence</a></li>
188325
</ul>
189326
<p>Raw Gradle console output and unsanitized Gradle reports are intentionally not published because the build runs with secret-backed environment variables.</p>
190327
</body>

.github/workflows/tck.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ jobs:
7373
GH_USERNAME: ${{ secrets.GH_USERNAME }}
7474
run: |
7575
set -euo pipefail
76-
./gradlew :micronaut-tck-runner:fullTckTest --no-daemon --continue
76+
./gradlew :micronaut-tck-runner:fullTckTest :micronaut-tck-runner:cdiSignatureTest --no-daemon --continue
7777
7878
- name: Collect CDI Lite TCK evidence
7979
if: always()
@@ -85,7 +85,9 @@ jobs:
8585
uses: mikepenz/action-junit-report@bccf2e31636835cf0874589931c4116687171386 # v6
8686
with:
8787
check_name: CDI Lite TCK run / Test Report (25)
88-
report_paths: 'tck-runner/build/test-results/fullTckTest/TEST-*.xml'
88+
report_paths: |
89+
tck-runner/build/test-results/fullTckTest/TEST-*.xml
90+
tck-runner/build/test-results/cdiSignatureTest/TEST-*.xml
8991
check_retries: 'true'
9092

9193
- name: Upload CDI Lite TCK evidence

tck-runner/build.gradle.kts

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import java.io.ByteArrayOutputStream
2+
import java.io.File
3+
import org.gradle.api.tasks.JavaExec
4+
15
plugins {
26
id("org.eclipse.odi.build.internal.base")
37
id("com.adarshr.test-logger")
@@ -7,6 +11,22 @@ description = "CDI TCK runner"
711

812
val generatedCdiTckSources = layout.buildDirectory.dir("generated/sources/cdiTck/java/test")
913

14+
val cdiSignatureApi by configurations.creating {
15+
isCanBeConsumed = false
16+
isCanBeResolved = true
17+
}
18+
19+
val cdiSignatureTck by configurations.creating {
20+
isCanBeConsumed = false
21+
isCanBeResolved = true
22+
isTransitive = false
23+
}
24+
25+
val cdiSignatureTool by configurations.creating {
26+
isCanBeConsumed = false
27+
isCanBeResolved = true
28+
}
29+
1030
dependencies {
1131
annotationProcessor(project(":micronaut-odi-processor-cdi"))
1232

@@ -36,6 +56,10 @@ dependencies {
3656
type = "xml"
3757
}
3858
}
59+
60+
cdiSignatureApi(libs.cdi.api)
61+
cdiSignatureTck(libs.cdi.tck.impl)
62+
cdiSignatureTool("jakarta.tck:sigtest-maven-plugin:2.6")
3963
}
4064

4165
val observingBeanSource = "org/jboss/cdi/tck/tests/se/events/lifecycle/ObservingBean.java"
@@ -108,6 +132,131 @@ tasks.register<Test>("fullTckTest") {
108132
}
109133
}
110134

135+
fun xmlEscape(value: String): String {
136+
return value
137+
.replace("&", "&amp;")
138+
.replace("<", "&lt;")
139+
.replace(">", "&gt;")
140+
.replace("\"", "&quot;")
141+
.replace("'", "&apos;")
142+
}
143+
144+
tasks.register<JavaExec>("cdiSignatureTest") {
145+
group = "verification"
146+
description = "Runs the Jakarta CDI API signature test using the TCK-provided signature file."
147+
148+
val cdiVersion = libs.cdi.tck.impl.get().versionConstraint.requiredVersion
149+
val outputDir = layout.buildDirectory.dir("reports/cdi-signature-test")
150+
val signatureFile = outputDir.map { it.file("cdi-api-jdk17.sig") }
151+
val signatureReport = outputDir.map { it.file("signature-test-report.txt") }
152+
val metadataFile = outputDir.map { it.file("signature-test.properties") }
153+
val junitReport = layout.buildDirectory.file("test-results/cdiSignatureTest/TEST-cdi-signature-test.xml")
154+
val output = ByteArrayOutputStream()
155+
lateinit var extractedSignatureFile: File
156+
lateinit var tckJar: File
157+
lateinit var apiArtifacts: List<File>
158+
159+
inputs.files(cdiSignatureApi)
160+
inputs.files(cdiSignatureTck)
161+
inputs.files(cdiSignatureTool)
162+
outputs.dir(outputDir)
163+
outputs.file(junitReport)
164+
165+
classpath = cdiSignatureTool
166+
mainClass.set("com.sun.tdk.signaturetest.Main")
167+
standardOutput = output
168+
errorOutput = output
169+
isIgnoreExitValue = true
170+
171+
doFirst {
172+
val outputDirectory = outputDir.get().asFile
173+
outputDirectory.mkdirs()
174+
175+
tckJar = cdiSignatureTck.resolve()
176+
.singleOrNull { it.name == "cdi-tck-core-impl-$cdiVersion.jar" }
177+
?: error("Could not resolve cdi-tck-core-impl-$cdiVersion.jar")
178+
copy {
179+
from(zipTree(tckJar)) {
180+
include("cdi-api-jdk17.sig")
181+
}
182+
into(outputDirectory)
183+
}
184+
185+
extractedSignatureFile = signatureFile.get().asFile
186+
if (!extractedSignatureFile.isFile) {
187+
error("Could not extract ${extractedSignatureFile.name} from ${tckJar.name}")
188+
}
189+
190+
apiArtifacts = cdiSignatureApi.resolve().sortedBy { it.name }
191+
val apiClasspath = apiArtifacts.joinToString(File.pathSeparator) { it.absolutePath }
192+
val signatureArgs = listOf(
193+
"Test",
194+
"-FileName", extractedSignatureFile.absolutePath,
195+
"-static",
196+
"-b",
197+
"-Mode", "bin",
198+
"-ApiVersion", cdiVersion,
199+
"-PackageWithoutSubpackages", "jakarta.decorator",
200+
"-Package", "jakarta.enterprise",
201+
"-PackageWithoutSubpackages", "jakarta.interceptor",
202+
"-BootCP", "17",
203+
"-Classpath", apiClasspath
204+
)
205+
args(signatureArgs)
206+
}
207+
208+
doLast {
209+
val rawReport = output.toString(Charsets.UTF_8)
210+
val sanitizedReport = rawReport
211+
.lineSequence()
212+
.filterNot { it.contains("SignatureTest.args:") }
213+
.joinToString(System.lineSeparator())
214+
.trimEnd() + System.lineSeparator()
215+
val passed = rawReport.contains("STATUS:Passed.")
216+
signatureReport.get().asFile.writeText(sanitizedReport)
217+
metadataFile.get().asFile.writeText(
218+
"""
219+
status=${if (passed) "passed" else "failed"}
220+
tests=1
221+
failures=${if (passed) 0 else 1}
222+
errors=0
223+
skipped=0
224+
sigtestTool=jakarta.tck:sigtest-maven-plugin:2.6
225+
signatureFile=${extractedSignatureFile.name}
226+
signatureSource=${tckJar.name}
227+
bootCpRelease=17
228+
packages=jakarta.decorator,jakarta.enterprise.**,jakarta.interceptor
229+
apiArtifacts=${apiArtifacts.joinToString(",") { it.name }}
230+
report=${signatureReport.get().asFile.name}
231+
""".trimIndent() + System.lineSeparator()
232+
)
233+
234+
val junitFile = junitReport.get().asFile
235+
junitFile.parentFile.mkdirs()
236+
val failureElement = if (passed) {
237+
""
238+
} else {
239+
"""
240+
<failure type="junit.framework.AssertionFailedError" message="CDI signature test failed">${xmlEscape(sanitizedReport)}</failure>
241+
""".trimIndent()
242+
}
243+
junitFile.writeText(
244+
"""
245+
<?xml version="1.0" encoding="UTF-8"?>
246+
<testsuite name="CDI signature test" tests="1" failures="${if (passed) 0 else 1}" errors="0" skipped="0" time="0.0">
247+
<testcase classname="jakarta.enterprise.cdi.signature" name="cdi-api-jdk17" time="0.0">
248+
${if (failureElement.isBlank()) "" else " $failureElement"}
249+
</testcase>
250+
</testsuite>
251+
""".trimIndent() + System.lineSeparator()
252+
)
253+
254+
if (!passed) {
255+
throw GradleException("CDI signature test failed; see ${signatureReport.get().asFile}")
256+
}
257+
}
258+
}
259+
111260
tasks.register<Test>("singleTest") {
112261
configureCdiLiteTck()
113262
val suiteFile = layout.buildDirectory.file("generated-testng/singleTest.xml")

0 commit comments

Comments
 (0)