Skip to content

RunExampleTool: fail fast when a --script-inputs port is in use - #5280

Open
dsmiley wants to merge 1 commit into
apache:mainfrom
dsmiley:run-example-port-robustness
Open

dsmiley wants to merge 1 commit into
apache:mainfrom
dsmiley:run-example-port-robustness

Conversation

@dsmiley

@dsmiley dsmiley commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

🤖 TestSolrCLIRunExample.testSolrCloudExampleWithScriptInputs failed on a busy CI worker with a misleading "collection not found" error, and the cause was in the tool, not only the test.

Failure chain

  1. The test picks a free port by opening and closing a ServerSocket(0).
  2. Before RunExampleTool probes it, another process takes that port. This is a race that only shows on a busy machine, such as a 96-core CI worker.
  3. The tool prints "port N is already being used" and re-prompts.
  4. --script-inputs is a fixed ordered list, so the retry consumes the next scripted answers (the collection name, then numShards) as ports.
  5. isPortAvailable(2) hits the test security policy's SocketPermission denial, the tool aborts with exit 1, and Solr never starts.
  6. The test ignored the exit code, so it failed later with "collection not found", hiding the real error.

Changes

  • RunExampleTool: with --script-inputs, a port that is already in use now throws immediately with a clear message. A retry can't recover, since it would read the next scripted value.
  • TestSolrCLIRunExample: testSolrCloudExampleWithScriptInputs asserts the tool's exit code, so a failure shows the tool's error. A new testScriptInputsPortInUse holds a port open and expects exit code 1.

Not changed
The test still picks a port, releases it, and uses it later, so it can still lose that race. It now fails with a clear message. The failExecuteScript access-denied output in the same log comes from the unrelated testFailExecuteScript, which expects it.

Testing
gradlew :solr:core:test --tests "org.apache.solr.cli.TestSolrCLIRunExample" passes (7 tests).

Related

🤖 Generated with Claude Code

A retry would consume the next scripted answer as the port. Also assert the tool's exit code in testSolrCloudExampleWithScriptInputs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@epugh epugh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM.

Locale.ROOT, "Please enter the port for node%d [%d]: ", (n + 1), cloudPorts[n]);
int port = promptForPort(readInput, n + 1, promptMsg, cloudPorts[n]);
while (!isPortAvailable(port)) {
if (usingScriptInputs) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That's gnarly bug. Though the fix is good, both for making CI easier but also locally. I've been bit by running a script not realizing I had a zombied solr on port 8984 or was already running it in docker on 8983... and then getting my scripted run blows up obsucrely...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants