Flaky test: HttpTransportTests.testAccessTokenAuth / testBearerTokenAuth bind a random fixed port and fail with FatalStartupException
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
調査の方向性
client-v2/src/test/java/com/clickhouse/client/HttpTransportTests.java を開き、1307 行付近の testBearerTokenAuth と 1385 行付近の testAccessTokenAuth を調べます。これらの WireMock の設定を、ファイル内の他の .dynamicPort() の使用箇所と比較し、issue の認証テスト用 Maven コマンドを実行します。完了の条件は、両方のテストが空いている動的ポートを取得し、ポート競合がある場合でも bind エラーなしで成功することです。
索引モデルが issue の本文から書いたものです。
説明
Description
HttpTransportTests.testAccessTokenAuth and HttpTransportTests.testBearerTokenAuth
(module client-v2) start their WireMock server on a randomly chosen fixed port:
int randomPort = ThreadLocalRandom.current().nextInt(3000, 65535);
WireMockServer mockServer = new WireMockServer(WireMockConfiguration
.options().port(randomPort).notifier(new ConsoleNotifier(false)));
mockServer.start();
client-v2/src/test/java/com/clickhouse/client/HttpTransportTests.java:1307 (testBearerTokenAuth)
and :1385 (testAccessTokenAuth).
If that port is already taken, mockServer.start() throws immediately and the test fails.
There is no retry and no fallback. The chosen range (3000-65535) overlaps the Linux
ephemeral port range (/proc/sys/net/ipv4/ip_local_port_range = 32768-60999 on the CI
runners), so any outbound socket held by a concurrently running test, by Maven, or by
another job on the same runner can take the port.
Every other WireMock server in the same file already uses .dynamicPort() (about 20
occurrences, e.g. lines 895, 1465, 1854). Only these two tests use the fixed-port form.
Steps to reproduce
- Occupy an arbitrary subset of TCP ports in 3000-65535 on the machine (this simulates a
loaded CI runner). For the numbers below, 29768 ports (3000-32767, 47.6% of the range)
were held by a helper process; the ephemeral range was left free so outbound
connections still worked. - Run the test repeatedly:
mvn -B -pl client-v2 -DskipUTs=true -Dit.test=HttpTransportTests#testAccessTokenAuth -Dfailsafe.failIfNoSpecifiedTests=false -DfailIfNoTests=false verify - The test fails on roughly the fraction of the range that is occupied.
Observed: 4 failures out of 12 runs (33%, expected ~48%), each with the same signature
as CI but a different port each time:
run 1: PASS
run 2: FAIL -> Failed to bind to /0.0.0.0:10117
run 3: FAIL -> Failed to bind to /0.0.0.0:15282
run 4: PASS
run 5: FAIL -> Failed to bind to /0.0.0.0:18977
run 6..9: PASS
run 10: FAIL -> Failed to bind to /0.0.0.0:14457
run 11..12: PASS
Contrast: HttpTransportTests#testSessionSettingsClientAndOperationLevels, which uses
.dynamicPort(), passed 6/6 under exactly the same port contention.
Error Log or Exception StackTrace
Verbatim from CI (amazon JDK 17 / "Test all modules",
https://github.com/ClickHouse/clickhouse-java/actions/runs/32807717786/job/97681145686):
[ERROR] com.clickhouse.client.HttpTransportTests.testAccessTokenAuth -- Time elapsed: 0.005 s <<< FAILURE!
com.github.tomakehurst.wiremock.common.FatalStartupException: java.io.IOException: Failed to bind to /0.0.0.0:32783
[ERROR] HttpTransportTests.testAccessTokenAuth:1388 » FatalStartup ... Failed to bind to /0.0.0.0:32783
[ERROR] Tests run: 897, Failures: 1, Errors: 0, Skipped: 3
Note 32783 is inside the OS ephemeral range. The other 34 legs of the same matrix passed
on the same commit, and the change under test touched only client-v2 metadata handling -
nothing in the auth path - so the failure is not attributable to the code under test.
Expected Behaviour
The test binds a free port and never fails because of port allocation. The Client.Builder
already receives the port from mockServer.port() after start, so nothing needs the port
value in advance.
Code Example
Suggested fix - use the same form as the rest of the file, at both sites:
WireMockServer mockServer = new WireMockServer(WireMockConfiguration
.options().dynamicPort().notifier(new ConsoleNotifier(false)));
mockServer.start();
.dynamicPort() binds port 0, so the kernel picks a port that is guaranteed free, and
mockServer.port() (already used throughout both tests) returns the actual port. The
randomPort local becomes unused and can be dropped, together with the now-unneeded
ThreadLocalRandom usage if no other test needs it.
Please do not fix this with a retry loop or a narrower random range - both leave the race
in place. There is no product-code race here; the defect is entirely in the test fixture.
Configuration
Environment
- Cloud
- Client version:
main@667cbe90b - Language version: OpenJDK 17.0.18
- OS: Ubuntu 24.04 (container), also seen on the
amazon JDK 17CI runner
ClickHouse Server
- ClickHouse Server version: not relevant - the test uses a mocked WireMock server and
returns early whenisCloud().
Found by our PR monitor: the failure was seen on unrelated PRs whose changes do not touch
the auth path, and it is already tracked internally as a known non-routing flake. Verified
here by reproducing the bind failure locally under port contention, not by inspection only.
- 主要言語
- Java
- スター
- 1.6k
- フォーク
- 638
- 平均マージ
- 2日 14時間
- マージ済み PR(30日)
- 44
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
ClickHouse/clickhouse-java のほかの issue
-
[examples] Remove old Spring example対応中かも @polyglotAI-bot が 10 日前に担当しました。 オープン
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
ClickHouse/clickhouse-java#3111 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
area:sql-parser bug client-v1
難易度 1/5 1〜3時間 初心者へのやさしさ 92/100
ClickHouse/clickhouse-java#3066 ·
メンテナーはふだん 1 日以内に返信
-
bug client-api-v2 jdbc-v2
難易度 1/5 1〜3時間 初心者へのやさしさ 78/100
ClickHouse/clickhouse-java#2957 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
bug client-v1 wontfix
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
ClickHouse/clickhouse-java#2895 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
area:docs jdbc jdbc-v2
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
ClickHouse/clickhouse-java#2892 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
ClickHouse/clickhouse-java の issue をすべて見る
似ている issue
-
new feature
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
apache/rocketmq-dashboard#5594 ·
メンテナーはふだん 3 日以内に返信
-
bug pkg:sdk
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
aws/aws-durable-execution-sdk-java#773 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
PCL-Community/PCL-CE#3652 ·
メンテナーはふだん 1 日以内に返信
-
TaskSecret.vue: replace explicit `any` with real types対応中かも @prayas-bit が今日担当しました。 オープンarea/frontend good first issue kind/cooldown
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
kestra-io/kestra#20352 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信