Skip to content

test: EventTestRunner.throwException times out during cancellation #11069

Description

@wuhuizuo

1. Minimal reproduce step

This was found while validating the TiFlash Jenkins job migration in PingCAP-QE/ci#5062.

  1. Run TiFlash pull unit tests for pingcap/tiflash#10981, commit e8b2ad95dd6a58f079ac6b086b8aa5a183c794e3.
  2. Run gtests_dbms, or specifically EventTestRunner.throwException, on an 8-vCPU Jenkins worker.
  3. Observe the test timeout while the test is waiting for pipeline tasks to drain.

Relevant test source:

2. What did you expect to see?

EventTestRunner.throwException should finish successfully after the deliberate exception is propagated and the executor is cancelled. The test should not depend on the worker having a particular CPU count.

3. What did you see instead?

The test failed after waiting 15 seconds for active tasks to drain:

[FAILED] EventTestRunner.throwException
DB::Exception: error with timeout
FAILED TESTS (1/3430):
  /tiflash/gtests_dbms EventTestRunner.throwException

The failing staging build is pull_unit_test #12, and the migration verifier result is shown here.

The same TiFlash commit passed the original Jenkins job in pull_unit_test #234. The two logs show different worker sizes:

  • staging worker: 8 online CPUs
  • original worker: 16 online CPUs

Both jobs requested 6 CPUs and used the same TiFlash builder image. This is evidence that worker scheduling/resources expose the problem, but it does not prove that CPU count alone is the root cause.

Root cause analysis

The test creates a default PipelineExecutorContext, whose query_id is empty:

It then schedules 100 DeadLoopEvent instances, each creating 10 tasks that continuously return RUNNING. When ThrowExceptionEvent raises the deliberate exception, PipelineExecutorContext::cancel() only forwards cancellation to TaskScheduler when query_id is non-empty:

Because this test context has an empty query ID, the scheduler cancellation path is skipped. The dead-loop tasks remain active, active_ref_count does not reach zero, and the test's 15-second waitFor() timeout is triggered:

4. What is your TiFlash version?

This is a unit-test issue in the TiFlash source at commit e8b2ad95dd6a58f079ac6b086b8aa5a183c794e3, from pingcap/tiflash#10981. It was observed in the TiFlash builder image ghcr.io/pingcap-qe/cd/builders/tiflash:v2025.4.15-rocky8-llvm-17.0.6-v2.

Proposed fix

The preferred fix is to make the test use a non-empty query ID, so cancellation is routed through the scheduler and reaches the tasks created by this executor context. For example:

- PipelineExecutorContext exec_context;
+ PipelineExecutorContext exec_context{"event-test", "", nullptr};

Please verify that all tasks created by the test inherit this query ID and that the test reliably drains on both 8-vCPU and 16-vCPU workers.

In addition, please consider:

  1. Adding a regression assertion for cancellation and task draining when an exception is raised.
  2. Reviewing whether the unit-test cancellation path should support empty query IDs, and adding coverage if that behavior is intended.
  3. Reducing the number of infinite DeadLoopTask instances or otherwise making the test less scheduling-sensitive. Simply increasing the timeout would only mask the issue.
  4. Treating a worker with at least 16 vCPUs as an infrastructure mitigation, not as the code fix.

A related but distinct production cancellation issue is #11059.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions