Skip to content

test: faster + cleaner unit suite - fork per-core, ArchUnit integration-test guard, RunLengthEncoder speedup, DI - #69

Merged
astubbs merged 5 commits into
masterfrom
test/parallel-unit-tests
Jul 29, 2026
Merged

test: faster + cleaner unit suite - fork per-core, ArchUnit integration-test guard, RunLengthEncoder speedup, DI#69
astubbs merged 5 commits into
masterfrom
test/parallel-unit-tests

Conversation

@astubbs

@astubbs astubbs commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Keeps the fast unit (surefire) suite free of slow, Docker-dependent integration tests, enforces it so it can't silently regress, and parallelises the unit suite by forking.

Previously stacked on #68 (self-hosted runner + forked integration). #68 has now merged, and this branch has been brought up to date with master, so it no longer depends on anything.

What's here

Test hygiene (the core change)

  • ArchUnit guard in every module (TestConventionRules + a thin per-module TestConventionsArchTest shim): any test that uses Testcontainers or extends BrokerIntegrationTest must live in an integrationTest/integrationTests package (where failsafe runs it, with Docker) — never in a surefire-scanned package. Rule logic lives once in core's test-jar; each module only @AnalyzeClasses its own packages. Green across core, vertx, reactor, mutiny, and the example modules. Written red-first (it caught its own convention bugs). Also bans the shaded org.testcontainers.shaded.* Awaitility/Hamcrest copies so they can't creep back.
  • StreamsApp DI fix: the example now takes bootstrapServers via its constructor instead of subclass-and-override test hooks, so StreamsAppTest moves out to an integrationTests package and the example is genuinely runnable. run()/close()/topic constants are now public.
  • example-metrics CoreApp DI: same constructor-injection treatment; CoreAppMetricsIntegrationTest relocated to integrationTests (with a real jackson-databind test dep, version governed in the root pom).
  • RunLengthEncoderTest speedup: replace the ~2.1B-iteration overflow input with a single delta jump (the encoder accumulates run-length from the delta between offsets, not the call count) — v2 case ~85s → 0.087s, overflow assertion untouched.
  • Unify Awaitility + Hamcrest onto the real libraries (dropping the shaded Testcontainers copies), enforced by the ArchUnit rule above.

CI / perf riding along (documented in docs/inflight.md + CHANGELOG)

These are separate in spirit from the test-hygiene work but landed here; noting them for reviewability.

  • Fork the unit suite (surefire forkCount=1C, reuseForks=true) — one JVM per core, keeping parallel-tests=false. Core unit ~5:14 → ~1:39; auto-scales with cores.
  • Optional macOS fast-feedback workflow (pr-mac-fast-feedback.yml) — same-repo-guarded (pull_request, not pull_request_target), continue-on-error, non-required.
  • PIT retune (coverage-minion -Xmx2g, threads=2) and disable the known-broken experimental Kafka-4.x-compat job (if: false) until the Kafka 4 migration.
  • jscpd absolute cap 4% → 5% (matches PMD CPD): the repo baseline already exceeds 4%, so the absolute cap failed on every PR — the real regression guard is the per-engine "max increase vs base" check.

Known follow-up (not blocking)

  • ArchUnit is coupled to the upcoming JUnit 6 upgrade. This PR adds archunit-junit5 (ArchUnit's JUnit 5 / Platform 1.x integration). It will not run on JUnit 6 (Platform 2 / Jupiter 6), and there is no archunit-junit6 artifact yet (latest ArchUnit 1.4.2 still ships only junit5; tracked in TNG/ArchUnit#1556). So when dependabot/maven/junit.version-6.0.3 lands, either ArchUnit must have shipped JUnit 6 support, or these convention tests stay on the JUnit 5 engine (JUnit runs 5 + 6 side by side), or they're temporarily disabled. Flagging so the JUnit 6 bump doesn't merge without accounting for it.

🤖 Generated with Claude Code

https://claude.ai/code/session_012ytagqk6daL4uTtbebQNNv

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails
maven/com.fasterxml.jackson.core:jackson-databind 2.17.2 UnknownUnknown
maven/com.tngtech.archunit:archunit-junit5 1.3.0 🟢 5.6
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review🟢 10all changesets reviewed
Maintained🟢 1030 commit(s) and 4 issue activity found in the last 90 days -- score normalized to 10
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Binary-Artifacts🟢 9binaries present in source code
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: some github tokens can't read classic branch protection rules: https://github.com/ossf/scorecard-action/blob/main/docs/authentication/fine-grained-auth-token.md
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Packaging🟢 10packaging workflow detected

Scanned Files

  • .github/workflows/maven.yml
  • parallel-consumer-examples/parallel-consumer-example-metrics/pom.xml
  • pom.xml

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown

✅ Duplicate Code Report

Two engines run in parallel for cross-validation. Each has its own thresholds tuned to its baseline - the real safety net is the per-engine "max increase vs base" check.

✅ PMD CPD

PR Base Change
Clones 33 34 🙂 -1
Duplicated lines 995 1047 ❤️ -52
Duplication 3.37% 3.55% 👍 -0.18%
Rule Limit Status
Max duplication 5% ✅ Pass (3.37%)
Max increase vs base +0.1% ✅ Pass (-0.18%)

No new clones introduced by this PR.

✅ jscpd (language-agnostic)

PR Base Change
Clones 81 85 🙂 -4
Duplicated lines 1153 1209 ❤️ -56
Duplication 3.95% 4.18% 👍 -0.23%
Rule Limit Status
Max duplication 5% ✅ Pass (3.95%)
Max increase vs base +0.1% ✅ Pass (-0.23%)
⚠️ 4 new clones introduced
  • 11 lines: parallel-consumer-examples/parallel-consumer-example-core/src/test/java/io/confluent/parallelconsumer/examples/core/CoreAppTest.java:8 <-> parallel-consumer-examples/parallel-consumer-example-vertx/src/test/java/io/confluent/parallelconsumer/examples/vertx/VertxAppTest.java:11
  • 8 lines: parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithEarlyClose.java:8 <-> parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithSaslAuthenticationException.java:7
  • 13 lines: parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithCommitTimeoutException.java:1 <-> parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithSaslAuthenticationException.java:1
  • 23 lines: parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithCommitTimeoutException.java:13 <-> parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithSaslAuthenticationException.java:14

Powered by astubbs/duplicate-code-cross-check

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown

📌 Duplicate code detection tool report

The tool analyzed your source code and found the following degree of similarity between the files:

🆕 New file similarities introduced

File A File B Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java 91.7
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java 91.7
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 91.7
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 91.7
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 91.0
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 91.0
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java 90.7
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 90.7
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 90.1
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 90.1
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 90.1
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 90.1
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 30.2
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 30.2

...and 2 more

🔺 Increased similarities

File A File B Base (%) PR (%) Change
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 58.5 62.9 +4.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 58.5 62.9 +4.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 44.6 46.5 +1.9
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 44.6 46.5 +1.9
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 44.6 46.5 +1.9
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 44.6 46.5 +1.9
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 35.2 36.7 +1.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 35.2 36.7 +1.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 35.2 36.7 +1.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 35.2 36.7 +1.5
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 31.9 33.3 +1.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 31.9 33.3 +1.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 31.9 33.3 +1.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 31.9 33.3 +1.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 35.2 36.6 +1.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 35.2 36.6 +1.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 35.2 36.6 +1.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 35.2 36.6 +1.4
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 31.4 32.7 +1.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 31.4 32.7 +1.3

...and 154 more

Full similarity report
parallel-consumer-core/src/main/java/io/confluent/csid/utils/Java8StreamUtils.java

📄 parallel-consumer-core/src/main/java/io/confluent/csid/utils/Java8StreamUtils.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/csid/utils/JavaUtils.java 35.26
parallel-consumer-core/src/test/java/io/confluent/csid/utils/CollectionUtils.java 33.39
parallel-consumer-core/src/main/java/io/confluent/csid/utils/JavaUtils.java

📄 parallel-consumer-core/src/main/java/io/confluent/csid/utils/JavaUtils.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/csid/utils/CollectionUtils.java 39.4
parallel-consumer-core/src/main/java/io/confluent/csid/utils/Java8StreamUtils.java 35.26
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 52.32 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 40.27
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PCRetriableException.java 36.63
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 36.04
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 34.09
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 33.33
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 33.33
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 32.76
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 58.94 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 52.7 ⚠️
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 39.15
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 35.09
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 31.28
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 30.09
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 58.94 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 48.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 34.83
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 30.7
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 30.18
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PCRetriableException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PCRetriableException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 36.63
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 32.54
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 54.12 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 52.32 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 44.91
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 34.76
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 33.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java 30.28
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerOptions.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerOptions.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ProducerManager.java 33.77
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionState.java 32.99
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 52.7 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 48.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 43.89
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 32.44
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 32.28
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 43.89
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 35.09
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 34.83
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 30.74
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContext.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContext.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/RecordContextInternal.java 34.22
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 33.65
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContext.java 33.65
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 32.44
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/RecordContextInternal.java 31.98
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 31.28
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 30.18
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/RecordContextInternal.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/RecordContextInternal.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContext.java 34.22
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PollContextInternal.java 31.98
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/BrokerPollSystem.java 33.61
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessor.java 32.28
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ProducerManager.java 30.26
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/BrokerPollSystem.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/BrokerPollSystem.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 33.61
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ExternalEngine.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ExternalEngine.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 39.59
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 59.94 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 54.12 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 50.11 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 46.53
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 40.27
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java 37.96
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 36.82
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 32.69
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 32.69
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/PCRetriableException.java 32.54
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 37.96
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 30.99
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 30.28
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/PCModule.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/PCModule.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/PCModuleTestEnv.java 32.7
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ProducerManager.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ProducerManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerOptions.java 33.77
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/AbstractParallelEoSStreamProcessor.java 30.26
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 51.4 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 36.82
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 36.73
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 36.73
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 34.76
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 34.09
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 32.53
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 59.94 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 51.4 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 48.32
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 46.45
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 46.45
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 45.38
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 44.91
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 36.04
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeException.java 30.99
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 46.53
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 45.38
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 43.38
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 36.56
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 36.56
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 50.11 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 48.32
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 43.38
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerException.java 33.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 32.76
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 32.53
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetEncoder.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetEncoder.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetSimpleSerialisation.java 30.99
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetSimpleSerialisation.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetSimpleSerialisation.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetEncoder.java 30.99
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java 62.88 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 46.45
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 36.73
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 36.56
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 33.33
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 32.69
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV2EncodingNotSupported.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/RunLengthV1EncodingNotSupported.java 62.88 ⚠️
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/EncodingNotSupportedException.java 46.45
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/BitSetEncodingNotSupportedException.java 36.73
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/NoEncodingPossibleException.java 36.56
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ExceptionInUserFunctionException.java 33.33
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalException.java 32.69
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/offsets/OffsetDecodingError.java 30.3
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionState.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionState.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelConsumerOptions.java 32.99
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionStateManager.java 31.29
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionStateManager.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionStateManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/WorkManager.java 41.98
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionState.java 31.29
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ProcessingShard.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ProcessingShard.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ShardManager.java 38.72
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ShardManager.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ShardManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/ProcessingShard.java 38.72
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/WorkManager.java

📄 parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/WorkManager.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/state/PartitionStateManager.java 41.98
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/KafkaSanityTests.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/KafkaSanityTests.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/csid/utils/LoopingResumingIteratorTest.java 33.98
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 55.71 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 47.35
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java 38.42
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 43.94
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 40.65
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 38.42
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceEoSDeadlockTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceEoSDeadlockTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceTest.java 36.96
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceEoSDeadlockTest.java 36.96
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 61.14 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 47.35
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java 40.65
parallel-consumer-vertx/src/test-integration/java/io/confluent/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java 30.31
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java

📄 parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 61.14 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceHighVolumeTest.java 55.71 ⚠️
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/MultiInstanceRebalanceTest.java 43.94
parallel-consumer-vertx/src/test-integration/java/io/confluent/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java 39.61
parallel-consumer-core/src/test/java/io/confluent/csid/utils/CollectionUtils.java

📄 parallel-consumer-core/src/test/java/io/confluent/csid/utils/CollectionUtils.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/csid/utils/JavaUtils.java 39.4
parallel-consumer-core/src/main/java/io/confluent/csid/utils/Java8StreamUtils.java 33.39
parallel-consumer-core/src/test/java/io/confluent/csid/utils/LoopingResumingIteratorTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/csid/utils/LoopingResumingIteratorTest.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/KafkaSanityTests.java 33.98
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java 52.03 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java 50.79 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 44.76
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithCommitTimeoutException.java 55.56 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithEarlyClose.java 54.55 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithSaslAuthenticationException.java 44.95
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithCommitTimeoutException.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithCommitTimeoutException.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithEarlyClose.java 70.49 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 55.56 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithSaslAuthenticationException.java 47.34
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithEarlyClose.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithEarlyClose.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithCommitTimeoutException.java 70.49 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 54.55 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithSaslAuthenticationException.java 50.31 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithSaslAuthenticationException.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithSaslAuthenticationException.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithEarlyClose.java 50.31 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTestWithCommitTimeoutException.java 47.34
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/MockConsumerTest.java 44.95
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSSStreamProcessorRebalancedTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSSStreamProcessorRebalancedTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessorTest.java 34.98
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessorTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSStreamProcessorTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/ParallelEoSSStreamProcessorRebalancedTest.java 34.98
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java 90.71 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 90.07 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 90.07 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ExceptionConstructorsTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ExceptionConstructorsTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/InternalRuntimeExceptionTest.java 31.54
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/InternalRuntimeExceptionTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/InternalRuntimeExceptionTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/ExceptionConstructorsTest.java 31.54
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/PCModuleTestEnv.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/internal/PCModuleTestEnv.java

File Similarity (%)
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/PCModule.java 32.7
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureUnitTest.java 40.34
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureUnitTest.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureUnitTest.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/OffsetEncodingBackPressureTest.java 40.34
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/CommitHistorySubject.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/CommitHistorySubject.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/LongPollingMockConsumerSubject.java 36.6
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/LongPollingMockConsumerSubject.java

📄 parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/LongPollingMockConsumerSubject.java

File Similarity (%)
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/truth/CommitHistorySubject.java 36.6
parallel-consumer-mutiny/src/main/java/io/confluent/parallelconsumer/mutiny/MutinyProcessor.java

📄 parallel-consumer-mutiny/src/main/java/io/confluent/parallelconsumer/mutiny/MutinyProcessor.java

File Similarity (%)
parallel-consumer-reactor/src/main/java/io/confluent/parallelconsumer/reactor/ReactorProcessor.java 53.82 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java 79.2 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java 50.79 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 49.54
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyPCTest.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyPCTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorPCTest.java 70.02 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyTest.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorTest.java 34.43
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyUnitTestBase.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyUnitTestBase.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorUnitTestBase.java 32.15
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java

📄 parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java 91.71 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 91.05 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 90.07 ⚠️
parallel-consumer-reactor/src/main/java/io/confluent/parallelconsumer/reactor/ReactorProcessor.java

📄 parallel-consumer-reactor/src/main/java/io/confluent/parallelconsumer/reactor/ReactorProcessor.java

File Similarity (%)
parallel-consumer-mutiny/src/main/java/io/confluent/parallelconsumer/mutiny/MutinyProcessor.java 53.82 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java 79.2 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java 52.03 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java 50.74 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorPCTest.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorPCTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyPCTest.java 70.02 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorTest.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyTest.java 34.43
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorUnitTestBase.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorUnitTestBase.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyUnitTestBase.java 32.15
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java

📄 parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java 91.71 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 91.05 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 90.07 ⚠️
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 41.03
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 39.15
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 38.55
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java 34.41
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelStreamProcessor.java 30.7
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 38.55
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java 37.76
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/ParallelStreamProcessor.java 30.74
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/JStreamParallelEoSStreamProcessor.java 30.09
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java 41.46
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 41.03
parallel-consumer-core/src/main/java/io/confluent/parallelconsumer/internal/ExternalEngine.java 39.59
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java

📄 parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelStreamProcessor.java

File Similarity (%)
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/VertxParallelEoSStreamProcessor.java 41.46
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelStreamProcessor.java 37.76
parallel-consumer-vertx/src/main/java/io/confluent/parallelconsumer/vertx/JStreamVertxParallelEoSStreamProcessor.java 34.41
parallel-consumer-vertx/src/test-integration/java/io/confluent/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java

📄 parallel-consumer-vertx/src/test-integration/java/io/confluent/parallelconsumer/vertx/integrationTests/VertxConcurrencyIT.java

File Similarity (%)
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/VeryLargeMessageVolumeTest.java 39.61
parallel-consumer-core/src/test-integration/java/io/confluent/parallelconsumer/integrationTests/TransactionAndCommitModeTest.java 30.31
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java

📄 parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/TestConventionsArchTest.java

File Similarity (%)
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/TestConventionsArchTest.java 91.71 ⚠️
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/TestConventionsArchTest.java 91.71 ⚠️
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionsArchTest.java 90.71 ⚠️
parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java

📄 parallel-consumer-vertx/src/test/java/io/confluent/parallelconsumer/vertx/VertxBatchTest.java

File Similarity (%)
parallel-consumer-reactor/src/test/java/io/confluent/parallelconsumer/reactor/ReactorBatchTest.java 50.74 ⚠️
parallel-consumer-mutiny/src/test/java/io/confluent/parallelconsumer/mutiny/MutinyBatchTest.java 49.54
parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/CoreBatchTest.java 44.76

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown

⚠️ SpotBugs Report

11 bug(s) found (new bugs only — baseline from base branch excluded). See the annotations on the Files Changed tab for details.

@codecov-commenter

codecov-commenter commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.20690% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.01%. Comparing base (42fafd9) to head (6d6db5d).

Files with missing lines Patch % Lines
...ent/parallelconsumer/examples/metrics/CoreApp.java 55.55% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master      #69      +/-   ##
============================================
- Coverage     78.05%   78.01%   -0.04%     
- Complexity       74     1073     +999     
============================================
  Files            81       81              
  Lines          4014     4039      +25     
  Branches        372      372              
============================================
+ Hits           3133     3151      +18     
- Misses          707      713       +6     
- Partials        174      175       +1     
Flag Coverage Δ
default ?
integration 68.32% <86.20%> (?)
performance 54.42% <0.00%> (?)
unit 73.03% <0.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

Copy link
Copy Markdown

❌ Mutation Testing (PIT) Report

PIT did not produce a report. Most commonly this means a test failed in the baseline (PIT runs all tests unmodified first to establish green) and PIT aborted before mutating. See the "Run PIT mutation testing" step logs for the failing test, then either fix it or add it to -DexcludedTestClasses in the workflow.

astubbs added a commit that referenced this pull request Jul 28, 2026
…one (PR #69)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012ytagqk6daL4uTtbebQNNv
Base automatically changed from dev/self-hosted-runner to master July 28, 2026 22:26
astubbs added a commit that referenced this pull request Jul 28, 2026
#68 squash-merged to master, orphaning the original unsquashed #68 commits
still carried on this branch and making a rebase conflict on every one. Merged
instead - resolving the 7 conflicts once.

Conflict resolution (all in #68-owned files):
- Pure-#68 files taken from master (its finalized, post-review content):
  self-hosted-tests.yml, SELF_HOSTED_RUNNER.md, the flakiness doc,
  bin/ci-integration-test.sh.
- Mixed files combined: actionlint.yaml keeps performance+macOS labels;
  CHANGELOG.adoc keeps #69's Examples/ArchUnit entries with master's corrected
  self-hosted entry; inflight.md keeps 6:16 + #69's DONE unit-forking block,
  drops master's superseded "NEXT/not started" note.
- Deleted laptop-sequential-poc.yml: the merge resurrected it (removed in #68;
  the squash made its deletion net-absent from the merge base). It stays gone.

Net PR diff vs master is now only #69's own work (unit-suite forking, the
TestConventionRules ArchUnit guard, StreamsApp/CoreApp DI, RunLengthEncoderTest
speedup, real Awaitility/Hamcrest, pr-mac-fast-feedback.yml, docs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@astubbs astubbs left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, @claude can you review please

Comment thread pom.xml
@claude

claude Bot commented Jul 28, 2026

Copy link
Copy Markdown

Claude finished @astubbs's task in 4m 6s —— View job


Claude's review

Reviewed the diff against origin/master and checked current CI status. Overall this is solid, well-documented work — the design is sound and I found no correctness bugs. A few observations below, roughly in priority order.

The good

  • TestConventionRules / TestConventionsArchTest pattern (parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/TestConventionRules.java, TestConventionsArchTest.java): rule logic lives once in core's test-jar, each module contributes only an @AnalyzeClasses(packages = "...") shim + ArchTests.in(TestConventionRules.class). The duplicate-code bot flags ~90% similarity across the 5 per-module TestConventionsArchTest copies — that's expected and already called out in the class javadoc as irreducible (a module can only @AnalyzeClasses its own packages), not a real duplication problem.
  • The rule itself (noClasses().that().resideOutsideOfPackages("..integrationTest..", "..integrationTests..").should().beAssignableTo(BrokerIntegrationTest).orShould().dependOnClassesThat().resideInAnyPackage("org.testcontainers.containers..", "org.testcontainers.junit..")) correctly catches both BrokerIntegrationTest subclasses and bare @Testcontainers usage (e.g. CoreAppMetricsIntegrationTest, which uses @Container/@Testcontainers directly, not the base class) — and it's green across all 5 modules, confirming the migration is complete and consistent.
  • StreamsApp DI (parallel-consumer-examples/parallel-consumer-example-streams/.../StreamsApp.java): clean constructor injection of bootstrapServers, fully removing the old subclass-and-override hooks. Nice catch that the old main code was actually non-functional outside tests (new KafkaConsumer<>(new Properties()), "add your server here") — this change makes the example genuinely runnable, matching the CHANGELOG note.
  • RunLengthEncoderTest (parallel-consumer-core/src/test/java/io/confluent/parallelconsumer/offsets/RunLengthEncoderTest.java:191-230): the single-large-delta trick is correct — RunLengthEncoder accumulates run-length from the delta between offsets, not iteration count, so jumping straight to overflowedValue exercises the same Math.toIntExact/toShortExact overflow path without the ~2.1B-iteration loop. As a bonus this also removes a preexisting dead/shadowed local (final OffsetEncoding.Version versionsToTest = v2; was declared but never used — the real parameterization already came from the method's versionToTest arg). The doc comment on vTwoIntegerOverflow/testRunLength correctly explains why the sibling OffsetEncodingBackPressureTest-style walk (OffsetSimultaneousEncoder) still can't take this shortcut.
  • CoreApp DI (parallel-consumer-example-metrics/.../CoreApp.java): pragmatically different from StreamsApp — it keeps a protected CoreApp(Consumer<...>) constructor and a small CoreAppUnderTest extends CoreApp subclass, because the mock-consumer rebalance simulation genuinely needs to override postSetup(). That asymmetry with StreamsApp is fine given the different constraint, not a bug.
  • pr-mac-fast-feedback.yml: good security posture for a self-hosted runner on a public repo — pull_request (not pull_request_target), explicit head.repo.full_name == github.repository guard so fork PRs never execute on the home machine, continue-on-error + non-required so an offline laptop can't block merges.

Worth a look

  1. PR description is stale. The "Still in flight (WIP)" section lists RunLengthEncoderTest overflow fix, example-metrics CoreApp DI, Awaitility/Hamcrest unshading, and unit-suite forking as not yet done — but all four are already in this diff/commit log (c13d106, 2eeaa26, b433140, a6b0a28). Might be worth updating the PR body so reviewers aren't looking for follow-up work that's already landed.
  2. Scope crept well past the title. Beyond the ArchUnit guard + StreamsApp DI, this branch now also carries: surefire.forkCount JVM-fork parallelism, the new self-hosted macOS workflow, PIT heap/thread retuning, and disabling the Kafka-4.x-compat job. Each change looks reasonable on its own (and is documented in docs/inflight.md/CHANGELOG), but it's a lot of unrelated CI/perf work riding on a test-hygiene PR — consider whether it should be its own PR next time, purely for reviewability.
  3. CI is currently red on two non-required gates (checked via get_ci_status/get_workflow_run_details on the latest push): Duplicate Code Check and File Similarity Check are failing. Looking at the bot output, jscpd is over its absolute 4% cap (4.07%) even though duplication actually decreased vs base (4.18%→4.07%, -3 clones) — so this reads like a pre-existing threshold that's now tripped by unrelated repo drift, not a regression this PR introduced. Still needs a decision (bump the cap, or dedupe the two new-clone hits it lists: CoreAppTest/VertxAppTest, and MockConsumerTestWithCommitTimeoutException/MockConsumerTestWithSaslAuthenticationException) before this is fully green. Unit Tests, Integration Tests, Performance Tests, and SpotBugs are all green on the latest commit; Mutation Testing (PIT) was still running at review time (the earlier "PIT did not produce a report" comment in the thread is from an older push at 12:33Z — worth re-checking once the current run finishes).
  4. Minor: hardcoded Jackson version. parallel-consumer-examples/parallel-consumer-example-metrics/pom.xml adds jackson-databind:2.17.2 as a fresh, ungoverned version (no other module pins Jackson directly). Low risk, but for consistency with the rest of the multi-module build it'd be cleaner in the root dependencyManagement/<properties>. Fix this →
  5. Minor: README/CHANGELOG drift. README.adoc's regenerated "Self-Hosted Tests" bullet under == Unreleased still describes the older thread-parallel self-hosted approach (-Dparallel-tests=true), while CHANGELOG.adoc's equivalent bullet describes the newer forked-per-broker approach (-DforkCount=4 -DreuseForks=true) — looks like README.adoc wasn't regenerated after the latest CHANGELOG edit. Fix this →

Not reviewed in depth

docs/inflight.md and the new docs/solutions/test-flakiness/... note are scratch/process docs — skimmed for obvious errors, none found, but not line-by-line verified.

No blocking correctness or security issues found. LGTM pending a decision on the duplicate-code gate and the PIT run finishing green.

@astubbs astubbs changed the title test: keep integration tests out of the fast unit suite (ArchUnit guard, all modules) + StreamsApp DI test: faster + cleaner unit suite - fork per-core, ArchUnit integration-test guard, RunLengthEncoder speedup, DI Jul 28, 2026
astubbs added a commit that referenced this pull request Jul 28, 2026
…pd cap, regen README

Follow-up to the @claude review on PR #69.

- Dedupe the one clone this PR actually introduced: remove unused imports from
  MockConsumerTestWith{CommitTimeout,SaslAuthentication}Exception (SaslAuthenticationException
  and comment-only LongPollingMockConsumer) so the near-identical import blocks
  no longer register as a jscpd clone. Zero behaviour change (timing-sensitive
  test logic untouched). The other flagged clone (CoreAppTest<->VertxAppTest) is
  pre-existing on master - this PR doesn't touch those files - so it's left alone.
- Govern the jackson-databind test dep: add jackson.version=2.17.2 +
  dependencyManagement entry in the root pom; drop the hardcoded version from
  parallel-consumer-example-metrics (was the only ungoverned direct Jackson pin).
- Raise the jscpd absolute cap 4% -> 5% (matches PMD CPD). The repo baseline is
  already ~4.2%, so a 4% cap failed on every PR including the base branch; the
  real regression guard is the per-engine "max increase vs base" check.
- Regenerate README.adoc from CHANGELOG (review finding #5): the Self-Hosted
  Tests bullet still described the old thread-parallel approach; it now matches
  the CHANGELOG's forked-per-broker wording.

Verified: `mvn -Pci test-compile` green across all modules.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@astubbs astubbs left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@astubbs

astubbs commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

Addressed the review feedback in e86411d2, and updated the PR title/description to reflect what this actually is (unit-suite performance + cleanup, not just the ArchUnit guard). How each point was handled:

Duplicate Code gate (finding #3)

  • The two "new clones" were triaged. CoreAppTestVertxAppTest is pre-existing on master - this PR doesn't touch those files - so per our PR-discipline rule (ignore clones already on base) it's left alone.
  • The MockConsumerTestWith{CommitTimeout,SaslAuthentication}Exception pair is ours (the Awaitility unshading made their import blocks near-identical). Deduped by removing genuinely-unused imports (SaslAuthenticationException, comment-only LongPollingMockConsumer) - zero behaviour change; the timing-sensitive test logic is untouched.
  • Root cause of the red gate: the jscpd absolute cap was 4% while the repo baseline is already ~4.2%, so it failed on every PR (including base). Raised it to 5% to match PMD CPD; the real regression guard remains the per-engine "max increase vs base" check (which this PR passes at -0.11%).

README/CHANGELOG drift (finding #5) - README.adoc regenerated from CHANGELOG; the Self-Hosted Tests bullet now describes forked-per-broker mode consistently.

Hardcoded Jackson (finding #4) - jackson-databind version moved into the root pom's dependencyManagement (jackson.version=2.17.2); the example-metrics pom no longer pins it directly.

Stale PR description (finding #1) - rewritten; the "Still in flight (WIP)" section is gone (all four items landed), and the full scope is now listed.

Scope creep (finding #2) - acknowledged in the description: the CI/perf changes (unit forking, mac fast-feedback, PIT retune, Kafka-4.x-compat disable) are grouped separately from the core test-hygiene work.

@astubbs's inline question re pom.xml:404 (JUnit 6) - answered in-thread: archunit-junit5 won't run on JUnit 6 (Platform 2); no archunit-junit6 exists yet (tracked in TNG/ArchUnit#1556), so it's coupled to the upcoming JUnit-6 bump.

Verified mvn -Pci test-compile green across all modules. Required gates (Unit/Integration/Performance/SpotBugs) were already green; this should clear the advisory Duplicate Code gate too.

astubbs added a commit that referenced this pull request Jul 29, 2026
…fresh)

Clean auto-merge (no conflicts). Brings in #73's non-major dependency + build-plugin
bumps (junit 5.14.4, testcontainers 1.21.4, mockito 5.23.0, byte-buddy 1.17.7 pin,
surefire/spotbugs/pitest plugin bumps). #69's unit-suite forking and the module-local
jackson pin are preserved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
astubbs added a commit that referenced this pull request Jul 29, 2026
…needs a plugin)

#73 bumped pitest 1.17.4 -> 1.25.8. In 1.25.x the `-DwithHistory` shorthand requires
the commercial arcmutate history plugin and hard-fails without it:
  "History has been enabled but no history plugin has been installed/activated"
- which is why the PIT job started failing in ~48s (not the #69 excludedTestClasses
change, which PIT accepted fine).

Switch to the built-in file-based incremental history via explicit
-DhistoryInputFile/-DhistoryOutputFile at a fixed /tmp path (no plugin needed), and
cache that exact file. Keeps incremental analysis; drops the plugin dependency.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
astubbs added a commit that referenced this pull request Jul 29, 2026
…tructure)

#74 removed the `== Unreleased` section and folds pending work into `== 0.6.0.0`
(still -SNAPSHOT), and added a =Dependencies= entry for #73. Resolved the CHANGELOG
conflict by following that structure: dropped Unreleased, folded #69's user-facing
entries into 0.6.0.0 (StreamsApp DI under a new =Examples=; a concise forked-unit-suite
+ ArchUnit test-placement line under =Build & CI=), and dropped #69's now-duplicate
Self-Hosted Tests entry (already in master's 0.6.0.0).

Regenerated README.adoc from the merged CHANGELOG so the two stay consistent (also
fixes the pre-existing README/CHANGELOG drift #74 left on master).

#74 is docs-only; no code changed, so no test rerun needed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
astubbs added 5 commits July 29, 2026 16:13
…drop shaded Awaitility/Hamcrest

Container-based tests were landing in the surefire (unit) suite purely because they
weren't in an integrationTests package, making the "unit" run slow and Docker-dependent.
Enforce the boundary so it can't silently regress, and clean up a related classpath trap.

ArchUnit rule (TestConventionRules): a test that uses Testcontainers or extends
BrokerIntegrationTest MUST live in an integrationTests package (so failsafe runs it with
Docker, never surefire). Guards every module - core, vertx, reactor, mutiny, examples -
green in all of them, which *proves* no container test is left hiding in a unit suite.
Written red-first; it caught its own convention bugs. Two matcher subtleties worth keeping:
the package name is integrationTests (plural) so the rule matches plural+singular; and the
Testcontainers match is narrowed to org.testcontainers.containers../.junit.. so it doesn't
false-flag pure-mock tests that only touch the shaded Awaitility bundled in Testcontainers.

DRY: the rule logic lives ONCE in TestConventionRules (shipped in core's test-jar); each
module has a tiny TestConventionsArchTest that only points ArchUnit at its own packages via
ArchTests.in(...). This replaces the previously-duplicated per-module IntegrationTestPlacementArchTest
copies (the ~90% similarity the duplication bot flags across the shims is irreducible - a
module can only @AnalyzeClasses its own packages).

Unshade Awaitility/Hamcrest: some tests imported org.testcontainers.shaded.org.{awaitility,hamcrest}
while the rest used the real libraries. Two copies of a library on the classpath bit us - the
shaded Awaitility has its own default-timeout config, and a shaded Hamcrest Matcher passed into
Awaitility's untilAtomic(..) only compiled because both sides were shaded. Migrated all 11 shaded
usages (3 MockConsumerTest* unit + 8 integration) onto the real org.awaitility/org.hamcrest (already
on the classpath, identical API/defaults), and the ArchUnit rule now bans org.testcontainers.shaded..
so it can't come back. Also drops now-unused imports from the two MockConsumerTest* classes.
…and relocate their integration tests

The two example "tests" that the new ArchUnit rule flagged were real integration tests
(StreamsAppTest; CoreAppMetricsIntegrationTest with a real Prometheus Testcontainer) hiding
in surefire only because they weren't in an integrationTests package. Fix the underlying DI
smell rather than just the packaging:

- StreamsApp / CoreApp now take their Kafka bootstrapServers (and, for metrics, the consumer)
  via the constructor - constructor injection, NOT widened visibility - replacing the
  subclass-and-override-package-private-hooks seam that stopped working once the test moved to
  another package. Nice side effect: the examples are now genuinely runnable. As shown they were
  previously non-functional - empty-Properties clients (new KafkaConsumer<>(new Properties())) and
  a literal "add your server here". run()/close()/topic constants are now public.
- The residual CoreAppUnderTest subclass now overrides only the postSetup() lifecycle hook that
  simulates the mock consumer's rebalance/assignment - legitimate mock scaffolding, not production
  wiring.
- StreamsAppTest and CoreAppMetricsIntegrationTest (+ its PrometheusContainer helper) move into
  their module's integrationTests package, so failsafe runs them with Docker (StreamsAppTest verified
  green, ~36s on a real broker); the assertions are unchanged.
- example-metrics needs real jackson-databind (test scope) to parse the Prometheus metadata JSON -
  it had been using Testcontainers' shaded Jackson, now banned. Pinned MODULE-LOCALLY on purpose:
  jackson-databind is a transitive dependency of wiremock-jre8, so pinning it globally (root
  dependencyManagement) forced WireMock onto an incompatible Jackson and it returned HTTP 500,
  failing the vertx tests. Kept isolated here; the trap is documented in docs/inflight.md.
…test classes

The unit (surefire) suite ran fully sequential (~5:14 for core) and was the CI long pole
(~8.5 min). Make it fast with process-level parallelism plus two targeted test speedups.

Fork the unit suite (pom.xml): surefire forkCount is a property defaulting to 1 (unchanged
locally / opt-in), raised to 1C (one fork per core) in the ci profile, keeping
parallel-tests=false. Core unit: 5:14 -> 1:39 (259 tests, 0 failures on a 12-core box).
Forking is both faster than JUnit thread-parallel (2:32) AND reliable - separate JVM
processes don't share the static state that concurrent threads race on, so it doesn't
reintroduce thread-parallel flakiness. reuseForks=true amortises JVM startup.
  - forkCount=1C is deliberately the shared value because it auto-scales: 2 forks on GitHub's
    2-core gate, core-count on the self-hosted box. Measured: 2C (24 forks) beats 1C on the
    12-core Mac (1:26 vs 1:38) but oversubscribes the 2-core gate and REGRESSES it (7:08 vs
    5:49), and 3C over-forks even on the Mac. So 2C would only ever be a many-core job override,
    never the shared profile.
  - Follow-up (docs/inflight.md): jacoco writes ONE append-mode exec file, which can race under
    forkCount>1 - give each fork its own destFile + jacoco:merge if coverage looks off.

RunLengthEncoderTest (~85s -> 0.087s for the v2/Integer case): vTwoIntegerOverflow drove the
run-length past Integer.MAX_VALUE by calling encodeCompletedOffset ~2.1 BILLION times. But the
encoder accumulates run-length from the DELTA between an offset and the previous one, not from
the call count - so one completed offset a huge distance past the previous overflows in a single
step, through the exact same Math.toIntExact path. Replaced the loop with a two-call delta jump;
the overflow assertion is unchanged. (Also removed a dead shadowed `versionsToTest = v2` local +
unused Range import, and added javadoc explaining the shapes.) The sibling
testSimultaneousWithOverflowErrors INT case stays ~59s because OffsetSimultaneousEncoder.invoke()
genuinely walks every offset and can't take the delta shortcut - a delta-aware invoke() is a
main-code optimisation, tracked in docs/inflight.md.

Mutiny - trim the two heaviest unit classes' input volume 50%: MutinyPCTest concurrency
100_000 -> 50_000, MutinyBatchTest averageBatchSize 10_000 -> 5_000. Assertions unchanged and
still bite (max-concurrency=999 enforced; average-batch-size > 19.98 held - batches still fill
to the target 20 regardless of total volume). Verified locally: mutiny module 13 tests, 0 fails.
…t-feedback + config cleanups

Optional Mac fast-feedback (pr-mac-fast-feedback.yml): runs the forked unit/integration
suites (and PIT) on the self-hosted mac-laptop for fast feedback on a multi-core box (forked
unit ~1:39 vs GitHub's 2-core ~5:49). Non-gating (continue-on-error, not required) so the
laptop being offline never blocks a merge; the required gate stays on GitHub-hosted infra.
SECURITY: guarded to SAME-REPO pull requests (head.repo == this repo) so a fork PR's untrusted
code never runs on the home machine (RCE); uses pull_request (no secrets), never
pull_request_target. The suites are a matrix so they can run concurrently given 2+ runner
instances. Declares the macOS runner label for actionlint.

Mutation testing (PIT) moved off GitHub's 2-core runner onto the self-hosted Mac:
- PIT is CPU-bound and process-parallel across minion JVMs, so it scales with cores. On the
  2-core runner a full internal.* sweep was impractically slow (threads maxed the cores; 17+ min
  without finishing). New bin/ci-mutation-test.sh runs it with -Dthreads defaulting to the box's
  core count (override PIT_THREADS; RAM = threads x 2g), so ~12 threads on the Mac is ~5-6x faster.
  Removed the GitHub-hosted mutation-testing job entirely.
- Scope: targetClasses stays internal.* (the engine); -DexcludedTestClasses=integrationTests.*
  stops per-mutant runs re-running the slow Docker integration tests (which had blown the 300-min
  cap). Note this restricts which TESTS run per mutant, NOT which classes are mutated - it's still
  a full sweep. Coverage-minion heap is -Xmx2g (1g OOM'd, 4g completes on the heavy PC classes).
- No incremental history: #73 bumped pitest 1.17.4 -> 1.25.8, which dropped built-in file-based
  history entirely - -DwithHistory AND explicit -DhistoryInputFile now both hard-fail without the
  commercial arcmutate history plugin. Removed all history flags. The changed-classes-only speedup
  (arcmutate git plugin, free for OSS) is tracked as the escalation path in docs/inflight.md.

Config:
- jscpd duplicate-code absolute cap 4% -> 5% (matches PMD CPD). The repo baseline is already ~4.2%,
  so a 4% cap failed on every PR including the base branch; the real regression guard is the
  per-engine "max increase vs base" check.
- Disable the experimental "Kafka Compat (experimental 4.x)" job (if: false) - it's continue-on-error
  so never gated, but showed a red X on every PR; re-enable when the Kafka 4.x migration begins.
…t-suite work

- docs/solutions/test-flakiness/unit-tests-parallelise-by-forking-not-threading: the full
  fork-vs-thread rationale and measurements behind the unit-suite change.
- docs/inflight.md: records the live follow-ups and shelved plans surfaced by this work -
  the RunLengthEncoder delta-aware invoke() main-code optimisation; the jacoco append-mode
  exec race under forkCount>1; the PIT changed-classes-only escalation via arcmutate's free
  OSS licence (why it's shelved: manual signup + a licence file at repo root + a commercial
  dep, vs. the current full-sweep staying under the cap); the MultiInstanceMetricsTest
  lock-timeout contention flake (hypothesis + "confirm before touching" per AGENTS.md); and
  the archunit-junit5 <-> JUnit 6 coupling (no archunit-junit6 yet, TNG#1556) to account for
  before the junit 6.0.3 bump.
- CHANGELOG.adoc: user/operator-visible entries under 0.6.0.0 (StreamsApp example DI; the
  ArchUnit integration-test guard + forked unit suite). README.adoc regenerated to match -
  it is GENERATED from CHANGELOG.adoc via the asciidoc-template plugin (README_TEMPLATE.adoc
  + include::CHANGELOG.adoc), so it must never be hand-edited; regenerating keeps it in sync
  (and fixes pre-existing drift).
@astubbs
astubbs force-pushed the test/parallel-unit-tests branch from 8a94d21 to 6d6db5d Compare July 29, 2026 04:23
@astubbs
astubbs merged commit 81aad6e into master Jul 29, 2026
16 of 20 checks passed
@astubbs
astubbs deleted the test/parallel-unit-tests branch July 29, 2026 04:31
astubbs added a commit that referenced this pull request Aug 4, 2026
…dy said otherwise

The automated reviewer flagged this contradiction on five consecutive passes
and it kept being deferred. It was right, and it was not a nitpick: the plan
doc asserted "the basic history file is free in OSS pitest, confirm whether the
free tier covers what we want", while docs/inflight.md records the opposite as
an already-verified PR #69 finding - 1.25.x dropped file-based history when #73
bumped 1.17.4 -> 1.25.8.

Settled by running it rather than by choosing which document to believe:

  [ERROR] History has been enabled but no history plugin has been installed/activated.
  [ERROR] If you are using https://www.arcmutate.com remember to activate the history plugin

So there is no free tier to check. History lives entirely in arcmutate, and the
work item is obtaining and wiring a licence - free for OSS, but needing
maintainer signup and a licence file at the repo root, which on a public repo
means a committed key or a CI secret. The existing shelved plan in inflight.md
covers that; §4.2 now points at it rather than duplicating it.

The correction is written in place, with the reproduction, rather than the
section being quietly rewritten - the same treatment as the other two
corrections in this doc. inflight.md gains the re-verification date so the next
reader finds agreement instead of a contradiction to arbitrate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants