From c401aca16e8f49e6daa7a2283dcc373bbd27fdb8 Mon Sep 17 00:00:00 2001 From: Kezhu Wang Date: Wed, 27 Aug 2025 03:11:03 +0800 Subject: [PATCH] ZOOKEEPER-4972: Fix flaky tests in PrometheusMetricsProviderConfigTest Those tests use hard written ports to listen. ``` org.apache.zookeeper.metrics.MetricsProviderLifeCycleException: java.io.IOException: Failed to bind to /0.0.0.0:50512 at org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider.start(PrometheusMetricsProvider.java:213) at org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProviderConfigTest.testValidHttpsAndHttpConfig(PrometheusMetricsProviderConfigTest.java:88) ``` --- .../zookeeper-prometheus-metrics/pom.xml | 6 ++++ .../prometheus/PrometheusMetricsProvider.java | 35 ++++++++++++------- .../PrometheusMetricsProviderConfigTest.java | 8 ++--- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/pom.xml b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/pom.xml index 2d8e48656b6..4b13fa6adfb 100644 --- a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/pom.xml +++ b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/pom.xml @@ -69,6 +69,12 @@ jetty-servlet provided + + ch.qos.logback + logback-classic + runtime + true + org.mockito mockito-core diff --git a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java index cae081f2697..e9bc72ec52b 100644 --- a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java +++ b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java @@ -23,7 +23,6 @@ import io.prometheus.client.exporter.MetricsServlet; import io.prometheus.client.hotspot.DefaultExports; import java.io.IOException; -import java.net.InetSocketAddress; import java.util.Enumeration; import java.util.Objects; import java.util.Optional; @@ -170,28 +169,32 @@ public void configure(Properties configuration) throws MetricsProviderLifeCycleE public void start() throws MetricsProviderLifeCycleException { this.executorOptional = createExecutor(); try { - LOG.info("Starting /metrics {} endpoint at HTTP port: {}, HTTPS port: {}, exportJvmInfo: {}", - httpPort > 0 ? httpPort : "disabled", - httpsPort > 0 ? httpsPort : "disabled", + LOG.info("Starting /metrics endpoint at HTTP port: {}, HTTPS port: {}, exportJvmInfo: {}", + httpPort >= 0 ? httpPort : "disabled", + httpsPort >= 0 ? httpsPort : "disabled", exportJvmInfo); if (exportJvmInfo) { DefaultExports.initialize(); } - if (httpPort == -1) { - server = new Server(); - } else { - server = new Server(new InetSocketAddress(host, httpPort)); + server = new Server(); + ServerConnector httpConnector = null; + ServerConnector httpsConnector = null; + if (httpPort >= 0) { + httpConnector = new ServerConnector(server); + httpConnector.setHost(host); + httpConnector.setPort(httpPort); + server.addConnector(httpConnector); } - if (httpsPort != -1) { + if (httpsPort >= 0) { SslContextFactory sslServerContextFactory = new SslContextFactory.Server(); configureSslContextFactory(sslServerContextFactory); KeyStoreScanner keystoreScanner = new KeyStoreScanner(sslServerContextFactory); keystoreScanner.setScanInterval(SCAN_INTERVAL); server.addBean(keystoreScanner); - ServerConnector connector = new ServerConnector(server, sslServerContextFactory); - connector.setPort(httpsPort); - connector.setHost(host); - server.addConnector(connector); + httpsConnector = new ServerConnector(server, sslServerContextFactory); + httpsConnector.setHost(host); + httpsConnector.setPort(httpsPort); + server.addConnector(httpsConnector); } ServletContextHandler context = new ServletContextHandler(); context.setContextPath("/"); @@ -199,6 +202,12 @@ public void start() throws MetricsProviderLifeCycleException { server.setHandler(context); context.addServlet(new ServletHolder(servlet), "/metrics"); server.start(); + if (httpPort == 0) { + LOG.info("Bound /metrics endpoint to HTTP port: {}", httpConnector.getLocalPort()); + } + if (httpsPort == 0) { + LOG.info("Bound /metrics endpoint to HTTPS port: {}", httpsConnector.getLocalPort()); + } } catch (Exception err) { LOG.error("Cannot start /metrics server", err); if (server != null) { diff --git a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderConfigTest.java b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderConfigTest.java index 6ff0da5e204..aa9cd2c7170 100644 --- a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderConfigTest.java +++ b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderConfigTest.java @@ -64,7 +64,7 @@ public void testValidSslConfig() throws MetricsProviderLifeCycleException { Properties configuration = new Properties(); String testDataPath = System.getProperty("test.data.dir", "src/test/resources/data"); configuration.setProperty("httpHost", "127.0.0.1"); - configuration.setProperty("httpsPort", "50511"); + configuration.setProperty("httpsPort", "0"); configuration.setProperty("ssl.keyStore.location", testDataPath + "/ssl/server_keystore.jks"); configuration.setProperty("ssl.keyStore.password", "testpass"); configuration.setProperty("ssl.trustStore.location", testDataPath + "/ssl/server_truststore.jks"); @@ -78,8 +78,8 @@ public void testValidHttpsAndHttpConfig() throws MetricsProviderLifeCycleExcepti PrometheusMetricsProvider provider = new PrometheusMetricsProvider(); Properties configuration = new Properties(); String testDataPath = System.getProperty("test.data.dir", "src/test/resources/data"); - configuration.setProperty("httpPort", "50512"); - configuration.setProperty("httpsPort", "50513"); + configuration.setProperty("httpPort", "0"); + configuration.setProperty("httpsPort", "0"); configuration.setProperty("ssl.keyStore.location", testDataPath + "/ssl/server_keystore.jks"); configuration.setProperty("ssl.keyStore.password", "testpass"); configuration.setProperty("ssl.trustStore.location", testDataPath + "/ssl/server_truststore.jks"); @@ -95,7 +95,7 @@ public void testInvalidSslConfig() throws MetricsProviderLifeCycleException { PrometheusMetricsProvider provider = new PrometheusMetricsProvider(); Properties configuration = new Properties(); String testDataPath = System.getProperty("test.data.dir", "src/test/resources/data"); - configuration.setProperty("httpsPort", "50514"); + configuration.setProperty("httpsPort", "0"); //keystore missing configuration.setProperty("ssl.keyStore.password", "testpass"); configuration.setProperty("ssl.trustStore.location", testDataPath + "/ssl/server_truststore.jks");