Skip to content

[IT] Read the address column of lsof when checking port occupation - #19070

Open
chrisdutz wants to merge 1 commit into
masterfrom
fix/it-lsof-port-column
Open

chrisdutz wants to merge 1 commit into
masterfrom
fix/it-lsof-port-column

Conversation

@chrisdutz

Copy link
Copy Markdown
Contributor

Description

Problem

On Linux and macOS, the IT framework never detects ports that are already in use. EnvUtils.searchAvailablePorts() then hands out ports another process listens on, and a node fails to start:

StartupException: Failed to start [Config Node service], because [IoTDB: failed to start Config Node service,
because Could not create ServerSocket on address /127.0.0.1:16490.]
java.net.BindException: Address already in use

The test then fails in setUp with "After 30 times retry, the cluster status check failed: ... Empty configNode set". On my machine this hit two ITs in one SimpleIT/TableSimpleIT run, because another local process was listening on 127.0.0.1:16490.

Cause

listPortOccupationUnix() parses lsof -iTCP -sTCP:LISTEN,TIME_WAIT -P -n and takes the local address from column 9. A line splits into 10 columns, and column 9 is the state:

java 1234 user 77u IPv6 0x1a2b 0t0 TCP 127.0.0.1:6667 (LISTEN)
0    1    2    3   4    5      6   7   8              9

"(LISTEN)".endsWith(":" + port) is never true, so the method always returns an empty map. This also disables the PORT_OCCUPIED handling in AbstractEnv.handleProcessStatus(), which uses the same method to find and restart a node that holds a port.

Fix

Read the address from column 8. The Windows variant (netstat -aon -p tcp, address in column 1) was already correct. A Javadoc line shows the column layout.

Verification

  • The layout is the same on both platforms:

    • macOS 27, lsof 4.91: ... TCP 127.0.0.1:16490 (LISTEN), 10 columns.
    • Ubuntu 26.04, lsof 4.99.4: ... TCP 127.0.0.1:6667 (LISTEN) and ... TCP [::1]:6668 (LISTEN), 10 columns, address in column 8.
  • Called EnvUtils.listPortOccupationUnix(...) directly on macOS, on master and with this change:

    Port Before After
    16490 (held by another process) {} {16490=<pid>}
    15292 (held by another process) {} {15292=<pid>}
    16491 (free) {} {}
  • spotless:check passes for integration-test.

  • IT runs with this change, on macOS: EdgeIT (7 tests) and IoTDBWithoutNullAllFilterIT (SimpleIT, 11 tests, 5 skipped) pass.


This PR has:

  • been self-reviewed.
  • added comments explaining the "why" and the intent of the code wherever would not be obvious for an unfamiliar reader.

Key changed/added classes (or packages if there are too many classes) in this PR
  • integration-test/src/main/java/org/apache/iotdb/it/env/cluster/EnvUtils.java

🤖 Generated with Claude Code

EnvUtils.listPortOccupationUnix() parses the output of
"lsof -iTCP -sTCP:LISTEN,TIME_WAIT -P -n" and took the local address
from column 9. A line splits into 10 columns, though, and column 9 is
the state, e.g. "(LISTEN)":

  java 1234 user 77u IPv6 0x1a2b 0t0 TCP 127.0.0.1:6667 (LISTEN)
  0    1    2    3   4    5      6   7   8              9

So no line ever matched, and the method always returned an empty map
on Linux and macOS. As a result:

- searchAvailablePorts() handed out ports that another process was
  already listening on, and the node failed to start with
  "Could not create ServerSocket ... Address already in use";
- the PORT_OCCUPIED handling in AbstractEnv.handleProcessStatus() never
  found the node holding a port, so it never restarted it.

Read the address from column 8. The Windows variant (netstat) was
already correct.
@sonarqubecloud

sonarqubecloud Bot commented Nov 1, 2026

Copy link
Copy Markdown

@codecov

codecov Bot commented Nov 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 48.05%. Comparing base (8a5e5ca) to head (8627538).

Additional details and impacted files
@@             Coverage Diff              @@
##             master   #19070      +/-   ##
============================================
- Coverage     48.05%   48.05%   -0.01%     
  Complexity      604      604              
============================================
  Files          5572     5572              
  Lines        410195   410195              
  Branches      54112    54112              
============================================
- Hits         197124   197112      -12     
- Misses       213071   213083      +12     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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