Repository navigation
AsyncAPI 3.x: the kill switch is off by default for message-driven services - #1868
Open
LautaroPetaccio wants to merge 1 commit into
Open
LautaroPetaccio wants to merge 1 commit into
LautaroPetaccio wants to merge 1 commit into
Conversation
…rvices The kill switch stops SUT code that is still running once the coverage of a test has been collected. It assumes a request handled on a thread of its own. A message-driven service consumes on long-lived threads instead: the first line probe executed by a raw consumer loop inside that window throws, the thread dies, and every later message goes unanswered. A Spring Kafka listener container survives, but the records that arrive inside the window are retried while the switch is still on and then dropped. So far every AsyncAPI E2E had to pass --killSwitch false to get anything done. For AsyncAPI the switch is off unless the user set it explicitly. Two things make this less direct than flipping a default: - problemType may still be DEFAULT when the options are checked, and only become ASYNCAPI once resolved from the driver in Main. So the option itself is never changed; EMConfig.isKillSwitchOn() decides when asked, and that is what the core sends to the driver with every coverage fetch. - A boolean option has no sentinel value, so EMConfig keeps the options set on the command line or in the configuration file, as properties, accumulated over every updateProperties call. They were computed already, for the experimental-settings warning and the dependency checks, but after the multi-field checks and then discarded. RemoteControllerImplementation.getTestResults is the only place in the core that reads the option. Schedule tasks never send it. EMConfigTest covers the default and the explicit cases, with the problem type given on the command line, resolved later as Main does it, and the switch set in a configuration file. NcsKafkaEMTest drops --killSwitch false. No change for any other problem type: isKillSwitchOn() is the option itself there.
LautaroPetaccio
force-pushed
the
feature/asyncapi-kill-switch
branch
from
October 12, 2026 02:54
0074e97 to
cf91e01
Compare
jgaleotti
approved these changes
Oct 13, 2026
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.
First in the AsyncAPI white-box stack, on top of #1810. It makes a white-box run of a message-driven service work without
--killSwitch false.Why
The kill switch stops SUT code that is still running once the coverage of a test has been collected. It assumes a request handled on a thread of its own. A message-driven service consumes on long-lived threads instead. In NCS, the first line probe of the raw consumer loop inside that window throws
KillSwitchException, the thread dies, and every later message goes unanswered. A Spring Kafka listener container survives, since its poll loop is not instrumented, but the records that arrive inside the window are retried by the default error handler while the switch is still on, and then dropped. Every AsyncAPI E2E so far had to pass--killSwitch false.What it changes
For
--problemType ASYNCAPIthe kill switch is off unless the user set it explicitly, on the command line or in the configuration file. Every other problem type is unchanged.EMConfig.isKillSwitchOn()decides, and is whatRemoteControllerImplementation.getTestResultssends to the driver. That is the only place in the core that reads the option: schedule tasks never send it.EMConfig.explicitlySetOptionskeeps the options the user set, as properties, accumulated over every call toupdateProperties. The modified options were computed there already, for the experimental-settings warning and the dependency checks, but aftercheckMultiFieldConstraints()and then discarded. They are computed just before it and kept.@Cfgtext ofkillSwitchsays it is off by default for AsyncAPI;docs/options.mdis regenerated.NcsKafkaEMTestdrops--killSwitch falsefrom its three runs.The one decision: decide when asked, not while checking
The obvious place for a per-problem-type default is
checkMultiFieldConstraints(), where DEFAULT enums are resolved. It does not work here, for two reasons:problemTypemay still beDEFAULTwhile the options are checked. In white-box mode it is resolved from the driver later, inMain, which is exactly what the E2E does.trueis the user's choice or the default.So the option itself is never changed.
isKillSwitchOn()iskillSwitch && (problemType != ASYNCAPI || EMConfig::killSwitch in explicitlySetOptions), evaluated each time the core talks to the driver. A value assigned toconfig.killSwitchdirectly in code, rather than through an option, does not count as explicit; the KDoc says so.What this changes outside AsyncAPI
EMConfig.updatePropertiescomputes the modified options a few lines earlier than before and keeps the matching properties. Their other uses (experimental and internal-settings warnings,checkDependsOn) get the same map as before.RemoteControllerImplementationreadsisKillSwitchOn(), which equalskillSwitchfor every other problem type.Not here
Black-box AsyncAPI runs still ask the driver for coverage, and with it for the kill switch; the next PR stops that.
Testing
EMConfigTest, 3 new tests: the default for REST and AsyncAPI;--killSwitch trueandfalsegiven explicitly for AsyncAPI and REST, andtruegiven in a configuration file; and the problem type resolved after the options were checked, asMaindoes it, with and without an explicit--killSwitch true.NcsKafkaEMTest(Docker): 3 tests, 0 failures, without--killSwitch false.AsyncApi*Test,EMConfigTest,ConfigToMarkdownTest,ConfigPathCheckTest,ConfigUtilTest): 276 tests, 0 failures.