Skip to content

Speed up integration tests and fix amopAsyncSubTest silent timeout - #963

Open
morebtcg wants to merge 3 commits into
FISCO-BCOS:masterfrom
morebtcg:it_change
Open

Speed up integration tests and fix amopAsyncSubTest silent timeout#963
morebtcg wants to merge 3 commits into
FISCO-BCOS:masterfrom
morebtcg:it_change

Conversation

@morebtcg

Copy link
Copy Markdown
Member

Motivation

The FISCO-BCOS CI step Integration test - Air runs this repo's integrationTest suite three times (non-sm / sm / baseline), ~146s each. Two kinds of waste were found by analyzing the CI logs and reproducing locally:

  1. amopAsyncSubTest always wastes ~10s and can never fail. It broadcasts 5 messages immediately after start, but the subscriber's topic subscription is pushed to the node asynchronously — early broadcasts are silently dropped (verified in the node log: broadcast arrived 6ms before the subscription took effect). The subscriber loop then re-subscribes the same topic 5 times, and the last iteration(s) block on future.get(10s), throwing a TimeoutException that is caught and only printed. The test passes no matter what, burns 10s per run, and prints a misleading exception into CI logs.
  2. Stress loops and fixed sleeps. test51SyncCRUDService/test52AsyncCRUDService each fire 300 transactions; several tests use fixed sleeps where a deterministic wait works.

Control experiment: when the subscription is given time to propagate before broadcasting, 5/5 broadcasts are delivered — the AMOP delivery path (node + cpp-sdk + JNI) is fine; the problem is purely in the test.

Changes

  • AmopTest.amopAsyncSubTest: subscribe once, wait 3s for the subscription to propagate, then broadcast; collect results in a CountDownLatch and fail the test if not all 5 broadcasts arrive. No more swallowed TimeoutException.
  • AmopTest (other cases): shorten the subscription-propagation sleeps from 2s to 1s.
  • PrecompiledTest.test51SyncCRUDService / test52AsyncCRUDService: 100 → 20 iterations (300 → 60 txs); poll async receipts every 100ms with a 60s deadline and assert the count — the old code would hang forever if a callback was lost.
  • AssembleTransactionProcessorTest.test11HelloWorldAsync / AssembleTransactionWithRemoteSignProcessorTest.test2HelloWorldAsync: replace fixed 1s end-of-test sleeps with CompletableFuture.get() + status assertions.

Measured impact

Local run against a single-node air chain (FISCO-BCOS 3.18.0):

before after
integrationTest total (57 tests) 217.0s 151.5s (-30%)
test52AsyncCRUDService 24.6s 2.9s
test51SyncCRUDService 23.0s 3.9s
amopAsyncSubTest 15.5s (always passes) 9.4s (can actually fail)

All 57 tests pass with zero failures. Since the suite runs 3 times per FISCO-BCOS CI job, this should save roughly 1.5-2 minutes per Integration test - Air step and remove the spurious TimeoutException from the logs.

amopAsyncSubTest: subscribe once and wait for the subscription to
propagate before broadcasting, then assert on a CountDownLatch. The old
test re-subscribed the same topic in a loop and swallowed the resulting
TimeoutException, so it always passed while wasting ~10s per run; the
first broadcasts were also dropped silently because they were sent
before the subscription reached the node.

PrecompiledTest: reduce the CRUD stress loops from 100 to 20 iterations
(300 -> 60 transactions), poll async receipts every 100ms with a 60s
deadline, and assert the received receipt count instead of hanging
forever on failure.

AssembleTransactionProcessorTest / AssembleTransactionWithRemoteSignProcessorTest:
replace the fixed 1s end-of-test sleeps with deterministic
CompletableFuture.get() waits.

AmopTest: shorten the subscription-propagation waits from 2s to 1s.

Measured locally against a single-node air chain: total integrationTest
time drops from 217s to 152s (-30%), all 57 tests pass.
FakeTransactionCallback counted every onResponse as a sealed tx, so
error responses (e.g. client-side timeouts under load) made the
receipt-count wait pass while the on-chain tx count assertion failed
with no diagnostics. Count only successful receipts and log the error
code/message otherwise.
The old test fired asyncInsert + asyncUpdate + asyncRemove for the same
key simultaneously, so update/remove routinely landed before the insert
and failed with -51507/-51508; the callback also treated every response
as success, hiding those failures completely.

Chain the three calls per key through the callbacks (the next call is
submitted to the test thread pool, since resolving the table address is
a blocking call that must not run on the sdk callback thread), count
receipts by receipt status (a successful CRUD retCode carries the
affected row count, e.g. 1, not 0), and keep the 60s deadline so a lost
callback fails the test instead of hanging.
@sonarqubecloud

Copy link
Copy Markdown

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.

1 participant