Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
warku123
force-pushed
the
fix/unit-test-cleanup-upstream-ready
branch
from
August 7, 2026 09:00
f07db70 to
7503eaf
Compare
warku123
force-pushed
the
fix/unit-test-cleanup-upstream-ready
branch
from
August 31, 2026 08:48
597eb51 to
684ac90
Compare
warku123
force-pushed
the
fix/unit-test-cleanup-upstream-ready
branch
from
September 10, 2026 09:21
464dec0 to
f531d1e
Compare
warku123
force-pushed
the
fix/unit-test-cleanup-upstream-ready
branch
from
September 10, 2026 09:40
f531d1e to
87cf221
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes test-isolation and lifecycle defects in
frameworktests so the full test chain can run reliably with retry disabled (retry=0). Today several tests fail on the first attempt and only pass via test-retry, hiding real failures and making JaCoCo coverage non-deterministic. Unless marked victim-side, every change is made in the writer — the test that leaked state or resources — so victims need no defensive code.Backup resource leak (writer-side). What:
BackupManagerTestandBackupServerTestnow fully close theBackupServerchannel/event loop and executors they create. How: keep manager/server instances; exception-safe@After(server close, fallback manager stop, then DNS/Args restore); condition-based readiness instead of fixed sleeps; assert channel/executor termination. Previously they left aBackupServer:WAITINGthread per run, andBackupServerTest#testhit a 60 s teardown timeout in the same worker JVM.Transactions async/executor lifecycle (writer and victim are the same class). What:
TransactionsMsgHandlerTestno longer injects its private same-namedTrxEventinto the production queue, waits deterministically for the scheduler, closes every handler/pool, and asserts on the correct map. How: real production events, aCountDownLatch,finallycleanup including the original executor replaced via reflection, and corrected assertions. Previously it caused a schedulerClassCastExceptionand its own coverage oflambda$handleSmartContract$2flipped between zero and partial.VM thread-local snapshot leak (writer-side). What:
TransferToAccountTestandRuntimeImplTestnow clear the thread-localVMConfigsnapshot they install (infinally/@After). How: both runVMActuatorin isolated/constant mode, which installs a snapshot thatVMConfig.current()prefers over the global one; an audit of all test-sideTransactionContext/RuntimeImpl/VMActuatorconstruction found these are the only two unbalanced writers. Victims:AllowTvmLondonTest#testBaseFee,AllowTvmLondonTest#testStartWithEF, andValidateMultiSignContractTest#testTip854RejectsMalformedCalldata— the three tests that first-failed in 5/5 identical baseline CI runs and only passed via retry.ConfigLoader.disableleak (writer-side). What:IstanbulTestandAllowTvmLondonTestnow restoreConfigLoader.disablein@After, matching the convention used by eleven other test classes. How: the flag makesConfigLoader.load()a no-op, freezingVMConfigfor every later DPS-driven test in the same worker JVM. Victim: any subsequent DPS-driven VM test — proven with an ordered suite using a synthetic DPS-only London victim (polluted order failed 3/3; cleanup, reverse, and victim-only controls passed);HistoryBlockHashVmTestandBlockEventGetTestalready carry defensive resets for exactly this leak.DPS fork-flag leaks (writer-side). What:
UnfreezeBalanceActuatorTest,Create2Test, andTransferFailedEnergyTestnow snapshot in@Beforeand restore in@Afteronly the DPS flags they modify (allowTvmConstantinople,allowTvmSolidity059,allowTvmIstanbul,allowTvmTransferTrc10). How: their unrestored writes became live input to later VM executions once defect 4 was fixed.BandWidthRuntimeTestwas the initially observed victim; commit435e40e759and verified commit96d5c35d43removed its three explicit proposal initializations, so BandWidth no longer has defensive initialization. The latest three retry=0 rounds prove the writer-side snapshot/restore fix is sufficient.allowShieldedTransactionhygiene (writer-side). What:SendCoinShieldTestandShieldedReceiveTestnow snapshot and restore theallowShieldedTransactionDPS flag. No victim is confirmed — this is shared-state hygiene, not the anchor-race cause below.Shielded consensus lifecycle (writer and victim are the same class). What:
ShieldedReceiveTestno longer runs a class-wide consensus producer; only the two tests that need an initialized witness schedule start and stop consensus, via a synchronized balancedstart()/stop()helper, and the reflection-basedDposTaskrestart workaround is removed. How: background block production could advance the head and roll back the snapshot between a test's Merkle anchor write and transaction validation. Victims: its own methods —testSignWithoutFromAddress,testSignWithoutToAmount,testMemoNotEnough,testSameOutputCm, andtestIsolateSignaturefailed intermittently withRt is invalid.across CI runs.testStoptimeout (victim-side). What:ConditionallyStopTest#testStop's JUnit timeout changes from 30 s to 45 s; test behavior and logic remain unchanged. The test still generates and signs the real 512+1 blocks. Reason: measured durations on loaded GitHub free shared runners reached 32.6 s, so 30 s was below the observed runtime rather than a sign of a defect in the test logic.System.outleak (writer-side). What:BroadcastServletTestandGetTransactionByIdSolidityServletTestnow restore the process-wideSystem.outstream after every test. How: each class snapshots the originalPrintStreamin@Beforeand restores it at the beginning of@After, before teardown logging. No failing victim is confirmed; however, leaving the capture stream installed can affect every later test in the same worker JVM, andKeystoreFactoryDeprecationTestcan propagate it by saving the already-polluted stream as its own "original" stream.PeerManagerprocess-wide static state (infrastructure-side reset). What: a new test utilityPeerManagerStateResetterreturnsPeerManager's statics to a cold-JVM state before p2p tests — it clears the raw peer list (including disconnected and null-channel phantoms invisible togetPeers()), resets the active/passive counters, and rebuilds the scheduled executor only when it is null or already shut down. How: wired broadly intoBaseTest/BaseMethodTest@Before, covering subclasses that reuse Spring contexts or the JVM, plus@BeforeClassin the five standalone p2p test classes that bypass those bases (WalletApiTest,HandShakeServiceTest,MessageHandlerTest,PbftMsgHandlerTest,PeerManagerTest); static reflection is localized insidePeerManagerStateResetter, and sharedReflectUtilsremains unchanged. Why: broad wiring protects against unknown preceding process-wide pollution. For tests that do not usePeerManager, reset is idempotent and low-impact — typically clearing an empty list and zeroing counters, with executor replacement only when dead or null and threads created on demand. The wiring may be narrowed later if evidence supports it, but no narrowing is promised here. Victims were confirmed by fault-injection suites that poison exactly one mechanism per JVM:MetricsApiServiceTest#testProcessMessagehitRejectedExecutionExceptionafter executor shutdown;PeerStatusCheckTest,HandShakeServiceTest,MessageHandlerTest,PbftMsgHandlerTest, andResilienceServiceTestfailed on residual peers/counters;MessageHandlerTest,PbftMsgHandlerTest, andNodeInfoServiceTestthrew NPEs on null-channel peers.Why are these changes required?
First-attempt failures hidden by retry are real signal: the leaked thread-local snapshot changes which production branches execute (e.g. London-dependent validation), so test outcomes and JaCoCo counters varied with worker assignment.
ConfigLoader.disableand unrestored DPS flags are process-wide state that silently affects every later VM test in the same worker. The Shielded race was confirmed directly: instrumentation showed the anchor present right afterputbut absent before validation while manager/store identities stayed the same and the head/snapshot advanced; with the producer stopped the failure did not occur. Finally,testStopintentionally does expensive real work, and 30 s is below its observed runtime under shared-runner load, so a bounded timeout increase is preferable to weakening the test.This PR has been tested by:
maxParallelForks/forkEvery: verifier commit96d5c35d43, run31467609469, completed three independent fullclean build→:framework:testWithRocksDb→jacocoTestReportchains successfully, including the localizedPeerManagerreflection adjustment.PeerManagerexecutor/peer/null-channel victims; focused reruns of every touched class pass; thetestStopdurations were 24.9 s, 28.2 s, and 32.6 s.Follow up
PeerManager.close()/init()lifecycle soclose()clears raw peers and counters, andinit()safely rebuilds or restarts an executor after shutdown. After validating production semantics and concurrency, remove or significantly narrowPeerManagerStateResetter.Extra details
No production code is changed; all modifications are test code under
framework/src/test/**. This PR does not change any CI configuration — the existing retry settings stay untouched; whether to disable retry in production CI is a separate decision. What this PR delivers is the prerequisite: a test suite whose first-attempt results are trustworthy, verified by running the full CI test chain with retry disabled, so future first-attempt failures stay visible instead of being masked by retry.