File tree Expand file tree Collapse file tree
app/src/test/java/com/sysadmindoc/callshield/data Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -153,6 +153,8 @@ All notable changes to CallShield will be documented in this file.
153153- Release artifacts now carry an exact CycloneDX SBOM, in-toto/SLSA provenance
154154 record, and SHA-256 sidecar bound to the release-runtime lockfile; version tags
155155 also receive a GitHub OIDC build-provenance attestation.
156+ - The screener hot path now has an executable 50 ms p99 JVM benchmark covering
157+ the same verdict call used by the detection pipeline.
156158
157159## v1.7.35 — 2026-08-10
158160
Original file line number Diff line number Diff line change @@ -112,6 +112,36 @@ class HotPathBenchmarkTest {
112112 )
113113 }
114114
115+ @Test
116+ fun spamScreener_verdict_p99_stays_under_50ms () {
117+ val numbers =
118+ listOf (
119+ " +12125551234" ,
120+ " +18005551234" ,
121+ " +19005551234" ,
122+ " +15555555555" ,
123+ " +13105550000" ,
124+ " +16465551111" ,
125+ " +17185559999" ,
126+ " +14155551234" ,
127+ )
128+ repeat(200 ) { SpamMLScorer .verdict(numbers[it % numbers.size]) }
129+
130+ val elapsedNanos =
131+ LongArray (1_000 ) { index ->
132+ val start = System .nanoTime()
133+ SpamMLScorer .verdict(numbers[index % numbers.size])
134+ System .nanoTime() - start
135+ }.sorted()
136+ val p99 = elapsedNanos[(elapsedNanos.size * 99 / 100 ).coerceAtMost(elapsedNanos.lastIndex)]
137+ val ceilingNanos = (50_000_000.0 * headroom).toLong()
138+
139+ assertTrue(
140+ " Spam screener verdict p99 took ${p99 / 1_000_000.0 } ms, ceiling ${ceilingNanos / 1_000_000.0 } ms" ,
141+ p99 < ceilingNanos,
142+ )
143+ }
144+
115145 @Test
116146 fun spamHeuristics_pure_checks_1k_iterations_under_ceiling () {
117147 // Only hit the context-free heuristics so the test stays in pure JVM.
You can’t perform that action at this time.
0 commit comments