Skip to content

Unit tests for TLS protocol validation#1898

Open
shreyabiradar07 wants to merge 12 commits into
kruize:mvp_demofrom
shreyabiradar07:tls_unit_tests
Open

Unit tests for TLS protocol validation#1898
shreyabiradar07 wants to merge 12 commits into
kruize:mvp_demofrom
shreyabiradar07:tls_unit_tests

Conversation

@shreyabiradar07
Copy link
Copy Markdown
Contributor

@shreyabiradar07 shreyabiradar07 commented May 7, 2026

Description

Add unit tests GenericRestApiClientTLSTest.java for TLS protocol validation in GenericRestApiClient to ensure secure communication standards.

  • Updates HttpResponseWrapper to a static inner class.

  • Tests use real SSLSocket instances (not mocks) configured with system default protocols to validate that: modern TLS is enabled, legacy TLS is excluded, and handshake simulations confirm protocol mismatch scenarios. This mirrors the production code's approach of passing null for protocols to delegate to JVM system defaults.

Test Cases:

  • TLS 1.1 handshake rejection with SSLHandshakeException
  • TLS 1.0 handshake rejection with SSLHandshakeException
  • TLS 1.3 acceptance via client configuration
  • TLS 1.2 acceptance via client configuration
  • TLS 1.1 rejection through system defaults
  • TLS 1.0 rejection through system defaults
  • TLS 1.3 preference validation
  • Legacy SSL (SSLv3/SSLv2) exclusion
  • Protocol version error handling

Unit tests output:

[INFO] Running com.autotune.utils.GenericRestApiClientTLSTest
2026-05-1318:12:50.835 INFO [main][GenericRestApiClientTLSTest.java(173)]-Testing TLS 1.0 handshake rejection
2026-05-1318:12:50.940 INFO [main][GenericRestApiClientTLSTest.java(213)]-Verified: TLS 1.0 handshake would fail - no common protocol
2026-05-1318:12:50.949 INFO [main][GenericRestApiClientTLSTest.java(244)]-Testing TLS 1.2 acceptance via system defaults
2026-05-1318:12:50.950 INFO [main][GenericRestApiClientTLSTest.java(281)]-Verified: TLS 1.2 enabled by system defaults
2026-05-1318:12:50.952 INFO [main][GenericRestApiClientTLSTest.java(305)]-Testing TLS 1.1 rejection via system defaults
2026-05-1318:12:50.952 INFO [main][GenericRestApiClientTLSTest.java(338)]-Verified: TLS 1.1 properly blocked by system defaults
2026-05-1318:12:50.954 INFO [main][GenericRestApiClientTLSTest.java(173)]-Testing TLS 1.1 handshake rejection
2026-05-1318:12:50.954 INFO [main][GenericRestApiClientTLSTest.java(213)]-Verified: TLS 1.1 handshake would fail - no common protocol
2026-05-1318:12:50.956 INFO [main][GenericRestApiClientTLSTest.java(435)]-Testing legacy SSL version exclusion
2026-05-1318:12:50.957 INFO [main][GenericRestApiClientTLSTest.java(450)]-Verified: No legacy SSL versions enabled
2026-05-1318:12:50.958 INFO [main][GenericRestApiClientTLSTest.java(244)]-Testing TLS 1.3 acceptance via system defaults
2026-05-1318:12:50.958 INFO [main][GenericRestApiClientTLSTest.java(281)]-Verified: TLS 1.3 enabled by system defaults
2026-05-1318:12:50.960 INFO [main][GenericRestApiClientTLSTest.java(395)]-Testing TLS version preference in system defaults
2026-05-1318:12:50.960 INFO [main][GenericRestApiClientTLSTest.java(418)]-Verified: TLS 1.3 preferred over TLS 1.2
2026-05-1318:12:50.961 INFO [main][GenericRestApiClientTLSTest.java(458)]-Testing protocol version error handling for legacy TLS
2026-05-1318:12:50.962 INFO [main][GenericRestApiClientTLSTest.java(496)]-Verified: Legacy TLS clients would receive protocol_version error
2026-05-1318:12:50.963 INFO [main][GenericRestApiClientTLSTest.java(350)]-Testing TLS 1.0 rejection via system defaults
2026-05-1318:12:50.964 INFO [main][GenericRestApiClientTLSTest.java(383)]-Verified: TLS 1.0 properly blocked by system defaults
[INFO] Tests run: 9, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.490 s -- in com.autotune.utils.GenericRestApiClientTLSTest

Fixes # (issue)

Type of change

  • Bug fix
  • New feature
  • Docs update
  • Breaking change (What changes might users need to make in their application due to this PR?)
  • Requires DB changes

How has this been tested?

Please describe the tests that were run to verify your changes and steps to reproduce. Please specify any test configuration required.

  • New Test X
  • Functional testsuite

Test Configuration

mvn test -Dtest=GenericRestApiClientTLSTest

Checklist 🎯

  • Followed coding guidelines
  • Comments added
  • Dependent changes merged
  • Documentation updated
  • Tests added or updated

Additional information

Include any additional information such as links, test results, screenshots here

Summary by Sourcery

Tests:

  • Introduce GenericRestApiClientTLSTest to cover acceptance of TLS 1.2/1.3, rejection of TLS 1.0/1.1 with SSLHandshakeException, system default protocol usage, null-parameter behavior, protocol_version error handling, TLS 1.3 preference, and exclusion of SSLv2/SSLv3.

Summary by Sourcery

Add TLS protocol validation coverage for GenericRestApiClient and adjust response wrapper accessibility to support the new tests.

New Features:

  • Introduce GenericRestApiClientTLSTest to validate TLS 1.2/1.3 acceptance, TLS 1.0/1.1 rejection, and protocol preference using the client’s TLS configuration pattern.

Enhancements:

  • Make HttpResponseWrapper a static inner class to allow usage without an instance of GenericRestApiClient, enabling improved testability.

Tests:

  • Add unit tests ensuring GenericRestApiClient delegates to secure system default TLS protocols, excludes legacy SSL/TLS versions, and correctly identifies protocol_version errors.

Summary by Sourcery

Add TLS protocol validation tests for GenericRestApiClient to ensure it relies on secure system default TLS settings and rejects legacy protocols.

Enhancements:

  • Make HttpResponseWrapper a static inner class to allow it to be used independently of GenericRestApiClient instances and improve testability.

Tests:

  • Introduce GenericRestApiClientTLSTest to validate acceptance of TLS 1.2/1.3, rejection of TLS 1.0/1.1, exclusion of legacy SSL versions, TLS 1.3 preference, and correct handling of protocol version handshake errors when using system default TLS configuration.

Signed-off-by: Shreya Biradar <shbirada@ibm.com>
@shreyabiradar07 shreyabiradar07 self-assigned this May 7, 2026
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 7, 2026

Reviewer's Guide

Adds a comprehensive TLS protocol validation test suite for GenericRestApiClient using real SSLSocket/SSLContext configurations and adjusts HttpResponseWrapper to be a static inner class to support testability and independent usage.

Sequence diagram for TLS handshake validation with system defaults

sequenceDiagram
    actor Test as GenericRestApiClientTLSTest
    participant SSLContext
    participant SSLSocket
    participant JVMSystemDefaults

    Test->>SSLContext: getDefault()
    SSLContext-->>Test: SSLContext
    Test->>SSLContext: createSSLSocket()
    SSLContext-->>Test: SSLSocket

    Test->>SSLSocket: setEnabledProtocols(clientProtocols)
    Test->>SSLSocket: startHandshake()

    alt [no common protocol]
        SSLSocket-->>Test: SSLHandshakeException
    else [TLSv1_2 or TLSv1_3]
        SSLSocket-->>Test: handshake success
    end

    Note over JVMSystemDefaults,SSLSocket: Null protocols delegate to JVMSystemDefaults enabled TLS versions
Loading

File-Level Changes

Change Details Files
Enable HttpResponseWrapper to be instantiated independently of GenericRestApiClient for improved testability.
  • Change HttpResponseWrapper from a non-static to a static inner class so it no longer requires an outer GenericRestApiClient instance.
  • Preserve existing fields and behavior of HttpResponseWrapper while only modifying its declaration.
src/main/java/com/autotune/utils/GenericRestApiClient.java
Add TLS protocol validation tests that mirror the production client’s SSL configuration and system default behavior.
  • Introduce GenericRestApiClientTLSTest to construct real SSLContext/SSLSocket instances using Apache SSLContexts with a trust-all material for controlled TLS scenarios.
  • Implement helper methods to create sockets with system defaults, restrict sockets to a specific protocol, and compute protocol overlap to simulate handshake outcomes without real network I/O.
  • Add shared test helpers to validate legacy TLS (1.0/1.1) rejection with simulated SSLHandshakeException conditions due to protocol mismatch.
  • Verify that passing null protocol configuration (system defaults) enables TLS 1.2/1.3, disables TLS 1.0/1.1 when supported by the JDK, and excludes SSLv2/SSLv3 from enabled protocols.
  • Assert that TLS 1.3 is preferred over TLS 1.2 when available and that protocol_version-style failures would occur for legacy clients, aligning with GenericRestApiClient’s expected security posture.
src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • Several tests (e.g., shouldAcceptTLS13, shouldAcceptTLS12, shouldHandleProtocolVersionError) only assert on mocked socket state or hard-coded strings and never exercise GenericRestApiClient; consider refactoring them to go through the client API so they validate actual production behavior rather than mock setup.
  • The shouldCreateSSLConnectionSocketFactoryWithNullProtocols test currently just asserts true, which doesn't validate any behavior; either remove it or replace it with an assertion that inspects the factory/protocols actually created by GenericRestApiClient when passing null.
  • In the test setup you create mockDataSourceInfo, mockSSLContext, and mockSSLSocketFactory, but they are not used beyond basic stubbing; if they are not needed to verify behavior, simplify the setup to only keep necessary mocks to reduce noise and improve maintainability.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Several tests (e.g., `shouldAcceptTLS13`, `shouldAcceptTLS12`, `shouldHandleProtocolVersionError`) only assert on mocked socket state or hard-coded strings and never exercise `GenericRestApiClient`; consider refactoring them to go through the client API so they validate actual production behavior rather than mock setup.
- The `shouldCreateSSLConnectionSocketFactoryWithNullProtocols` test currently just asserts `true`, which doesn't validate any behavior; either remove it or replace it with an assertion that inspects the factory/protocols actually created by `GenericRestApiClient` when passing null.
- In the test setup you create `mockDataSourceInfo`, `mockSSLContext`, and `mockSSLSocketFactory`, but they are not used beyond basic stubbing; if they are not needed to verify behavior, simplify the setup to only keep necessary mocks to reduce noise and improve maintainability.

## Individual Comments

### Comment 1
<location path="src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java" line_range="85-94" />
<code_context>
+        assertEquals("TLSv1.2", protocols[1], "TLS 1.2 should be second");
+    }
+
+    @Test
+    @DisplayName("Should not include SSLv3 in supported protocols")
+    void shouldNotSupportSSLv3() {
+        // Given: System default protocols
+        String[] systemProtocols = {"TLSv1.3", "TLSv1.2"};
+        
+        when(mockSSLSocket.getEnabledProtocols()).thenReturn(systemProtocols);
+        
+        // When: Check enabled protocols
+        String[] protocols = mockSSLSocket.getEnabledProtocols();
+        
+        // Then: SSLv3 should not be present
+        assertNotNull(protocols);
+        assertFalse(Arrays.asList(protocols).contains("SSLv3"),
+                "SSLv3 should never be enabled");
+        assertFalse(Arrays.asList(protocols).contains("SSLv2"),
+                "SSLv2 should never be enabled");
+    }
+}
</code_context>
<issue_to_address>
**issue (testing):** TLS 1.3/1.2 tests never exercise GenericRestApiClient, they only assert on a standalone mock socket

Because these tests only stub and assert on `mockSSLSocket.getEnabledProtocols()`, they never verify how `GenericRestApiClient` actually configures TLS. To make them meaningful, have the mocked `SSLContext`/`SSLSocketFactory` used by a `GenericRestApiClient` instance (or a spy), trigger a real client call or the internal TLS factory builder, and assert the enabled protocols on the socket created by the client. This ensures regressions in client TLS configuration are caught, not just behavior of a standalone mock.
</issue_to_address>

### Comment 2
<location path="src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java" line_range="63-72" />
<code_context>
+    private SSLSocketFactory mockSSLSocketFactory;
+    private SSLSocket mockSSLSocket;
+
+    @BeforeEach
+    void setup() throws Exception {
+        // Create mock objects
+        mockDataSourceInfo = mock(DataSourceInfo.class);
+        mockSSLContext = mock(SSLContext.class);
+        mockSSLSocketFactory = mock(SSLSocketFactory.class);
+        mockSSLSocket = mock(SSLSocket.class);
+
+        // Setup basic mock behavior
+        when(mockSSLContext.getSocketFactory()).thenReturn(mockSSLSocketFactory);
+        when(mockSSLSocketFactory.createSocket()).thenReturn(mockSSLSocket);
+        
+        // Initialize client
+        client = new GenericRestApiClient();
+        client.setBaseURL("https://test-prometheus.example.com:9090");
+    }
+
</code_context>
<issue_to_address>
**suggestion (testing):** Several mocks set up in @BeforeEach are unused and can be removed or actually wired into the client

In `setup()`, these mocks are created and partially configured but never used by `GenericRestApiClient`, which adds noise and can mislead readers about what’s actually under test. Either wire these mocks into the client and assert its TLS behavior (e.g., enabled protocols), or remove them and keep the setup focused on protocol list testing. Wiring them in would also improve coverage of the client’s TLS handling.

Suggested implementation:

```java
class GenericRestApiClientTLSTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(GenericRestApiClientTLSTest.class);

    private GenericRestApiClient client;
    private DataSourceInfo mockDataSourceInfo;

```

```java

```

1. In the same file, simplify the `setup()` method so it only creates the `mockDataSourceInfo` and initializes the `GenericRestApiClient`, removing the unused TLS-related mocks and their stubbing. For example:
   @BeforeEach
   void setup() throws Exception {
       mockDataSourceInfo = mock(DataSourceInfo.class);
       client = new GenericRestApiClient();
       client.setBaseURL("https://test-prometheus.example.com:9090");
   }
2. Remove now-unused imports such as `javax.net.ssl.SSLContext`, `javax.net.ssl.SSLSocketFactory`, and `javax.net.ssl.SSLSocket` if they are no longer referenced anywhere in the test.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java Outdated
Comment thread src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java Outdated
Signed-off-by: Shreya Biradar <shbirada@ibm.com>
@shreyabiradar07 shreyabiradar07 added this to the Kruize 0.11.0 Release milestone May 11, 2026
@shreyabiradar07 shreyabiradar07 moved this to In Progress in Monitoring May 11, 2026
Signed-off-by: Shreya Biradar <shbirada@ibm.com>
Signed-off-by: Shreya Biradar <shbirada@ibm.com>
@shreyabiradar07
Copy link
Copy Markdown
Contributor Author

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 3 issues, and left some high level feedback:

  • Most tests repeat the same reflection-based setup (obtaining setupHttpClient, building SSLContext, creating factory/socket); consider extracting this into shared helper methods or a setup utility to reduce duplication and make the tests easier to maintain.
  • The tests assert specific system default TLS protocols (e.g., absence of TLSv1.0/1.1, ordering of TLSv1.3) which may vary by JDK/security policy; you may want to relax or parameterize these assertions to avoid brittleness across different runtime environments.
  • Several tests create an SSLConnectionSocketFactory instance (createTestFactory) but never use the factory; either use it to exercise the behavior under test or remove it to avoid dead code and clarify what is actually being validated.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Most tests repeat the same reflection-based setup (obtaining setupHttpClient, building SSLContext, creating factory/socket); consider extracting this into shared helper methods or a setup utility to reduce duplication and make the tests easier to maintain.
- The tests assert specific system default TLS protocols (e.g., absence of TLSv1.0/1.1, ordering of TLSv1.3) which may vary by JDK/security policy; you may want to relax or parameterize these assertions to avoid brittleness across different runtime environments.
- Several tests create an SSLConnectionSocketFactory instance (createTestFactory) but never use the factory; either use it to exercise the behavior under test or remove it to avoid dead code and clarify what is actually being validated.

## Individual Comments

### Comment 1
<location path="src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java" line_range="83-92" />
<code_context>
+        httpClient.close();
+    }
+
+    @Test
+    @DisplayName("Should handle protocol_version error for legacy TLS")
+    void shouldHandleProtocolVersionError() {
+        LOGGER.info("=== Testing Protocol Version Error Handling ===");
+        
+        String errorMessage = "Received fatal alert: protocol_version";
+        boolean isProtocolVersionError = errorMessage.contains("protocol_version");
+        
+        assertTrue(isProtocolVersionError,
+                "Error message should indicate protocol version mismatch");
+        
+        LOGGER.info("Protocol version error correctly identified");
+    }
+}
</code_context>
<issue_to_address>
**suggestion (testing):** TLS 1.0/1.1 tests don't validate the advertised SSLHandshakeException behavior

The tests `shouldRejectTLS11ThroughSystemDefaults` and `shouldRejectTLS10ThroughSystemDefaults` only assert that TLS 1.0/1.1 are absent from `getEnabledProtocols()`, which verifies JVM defaults but not `GenericRestApiClient`’s behavior during a real handshake.

Please add at least one test that performs an actual HTTPS call via `GenericRestApiClient` against a TLS 1.0/1.1-only endpoint (or equivalent setup using an `SSLSocket` configured with `TLSv1`/`TLSv1.1`) and asserts that the handshake fails with `SSLHandshakeException`. This will align the tests with the described behavior and catch regressions in handshake handling.

Suggested implementation:

```java
    @Test
    @DisplayName("Should handle protocol_version error for legacy TLS")
    void shouldHandleProtocolVersionError() {
        LOGGER.info("=== Testing Protocol Version Error Handling ===");

        String errorMessage = "Received fatal alert: protocol_version";
        boolean isProtocolVersionError = errorMessage.contains("protocol_version");

        assertTrue(isProtocolVersionError,
                "Error message should indicate protocol version mismatch");

        LOGGER.info("Protocol version error correctly identified");
    }

    /**
     * Validates that a real TLS handshake against a TLS 1.0–only endpoint fails with
     * SSLHandshakeException when using system-default client protocols (which exclude TLS 1.0/1.1).
     *
     * This goes beyond inspecting enabled protocols and exercises the actual handshake path.
     */
    @Test
    @DisplayName("Should fail handshake against TLS 1.0-only endpoint with SSLHandshakeException")
    void shouldFailHandshakeAgainstTls10OnlyEndpoint() throws Exception {
        LOGGER.info("=== Testing handshake failure against TLS 1.0-only endpoint ===");

        // Start a local TLS 1.0-only SSL server socket on an ephemeral port
        SSLContext legacyTlsContext = createLegacyTls10ServerContext();
        SSLServerSocketFactory serverSocketFactory = legacyTlsContext.getServerSocketFactory();

        try (SSLServerSocket serverSocket = (SSLServerSocket) serverSocketFactory.createServerSocket(0)) {
            serverSocket.setEnabledProtocols(new String[]{"TLSv1"});

            final int port = serverSocket.getLocalPort();
            LOGGER.info("Started TLS 1.0-only test server on port {}", port);

            // Accept connections in a background thread; the handshake is expected to fail
            ExecutorService executor = Executors.newSingleThreadExecutor();
            Future<?> serverFuture = executor.submit(() -> {
                try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
                    socket.startHandshake();
                } catch (Exception e) {
                    // Handshake is expected to fail with protocol_version, so swallow exceptions here
                    LOGGER.debug("Expected exception during legacy TLS server handshake", e);
                }
            });

            try {
                // Use system-default SSLContext for the client side, which should not include TLS 1.0/1.1
                SSLContext clientContext = SSLContext.getDefault();
                SSLSocketFactory clientSocketFactory = clientContext.getSocketFactory();

                SSLHandshakeException handshakeException = assertThrows(
                        SSLHandshakeException.class,
                        () -> {
                            try (SSLSocket clientSocket = (SSLSocket) clientSocketFactory.createSocket("localhost", port)) {
                                clientSocket.startHandshake();
                            }
                        },
                        "Handshake against TLS 1.0-only endpoint should fail with SSLHandshakeException"
                );

                LOGGER.info("Handshake failed as expected with message: {}", handshakeException.getMessage());
                assertTrue(
                        handshakeException.getMessage() == null
                                || handshakeException.getMessage().contains("protocol_version"),
                        "Handshake failure should indicate a protocol version mismatch"
                );
            } finally {
                serverFuture.cancel(true);
                executor.shutdownNow();
            }
        }
    }

    /**
     * Creates an SSLContext configured with a server key/certificate for a TLS 1.0-only endpoint.
     *
     * The keystore is loaded from a classpath resource so that we can run a real SSLServerSocket
     * bound to TLSv1. System-default client settings should then fail to negotiate.
     */
    private SSLContext createLegacyTls10ServerContext() throws Exception {
        // The project should provide a test keystore containing a server certificate for localhost.
        // This method intentionally uses a classpath resource so that the keystore can be managed
        // alongside other test resources.
        char[] password = "changeit".toCharArray();

        try (InputStream keystoreStream =
                     GenericRestApiClientTLSTest.class.getResourceAsStream("/tls/legacy-tls-keystore.jks")) {

            // If the keystore is not present, skip the test rather than failing the build
            Assumptions.assumeTrue(
                    keystoreStream != null,
                    "Test keystore /tls/legacy-tls-keystore.jks is required for legacy TLS handshake tests"
            );

            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(keystoreStream, password);

            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(keyStore, password);

            SSLContext sslContext = SSLContext.getInstance("TLSv1");
            sslContext.init(kmf.getKeyManagers(), null, null);
            return sslContext;
        }
    }
}

```

1. Ensure the following imports are present at the top of `GenericRestApiClientTLSTest.java`:
   - `import javax.net.ssl.SSLContext;`
   - `import javax.net.ssl.SSLServerSocket;`
   - `import javax.net.ssl.SSLServerSocketFactory;`
   - `import javax.net.ssl.SSLSocket;`
   - `import javax.net.ssl.SSLSocketFactory;`
   - `import javax.net.ssl.SSLHandshakeException;`
   - `import java.io.InputStream;`
   - `import java.security.KeyStore;`
   - `import javax.net.ssl.KeyManagerFactory;`
   - `import java.util.concurrent.ExecutorService;`
   - `import java.util.concurrent.Executors;`
   - `import java.util.concurrent.Future;`
   - `import org.junit.jupiter.api.Assumptions;`
2. Add the test keystore file `legacy-tls-keystore.jks` under `src/test/resources/tls/` (or adjust the resource path and filename in `createLegacyTls10ServerContext()` accordingly). The keystore should contain a server certificate for `localhost` with password `changeit`, or you can update the password in the code to match your keystore.
3. If your logging framework does not support parameterized messages with `{}` (e.g., if you are using a plain JDK logger instead of SLF4J), adjust the `LOGGER.info` and `LOGGER.debug` calls accordingly.
4. If you prefer to exercise `GenericRestApiClient` directly instead of using `SSLSocket`, you can reuse the `createLegacyTls10ServerContext()` and server setup but replace the client-side SSLSocket logic with a `GenericRestApiClient` call to `https://localhost:<port>/` and assert that it fails with `SSLHandshakeException`.
</issue_to_address>

### Comment 2
<location path="src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java" line_range="100" />
<code_context>
+                .loadTrustMaterial((chain, authType) -> true)
+                .build();
+        
+        SSLConnectionSocketFactory factory = createTestFactory(sslContext);
+        
+        // Create a socket using the same SSLContext to verify system defaults
</code_context>
<issue_to_address>
**suggestion (testing):** Tests don't verify the actual SSLConnectionSocketFactory used by GenericRestApiClient

The tests build an `SSLConnectionSocketFactory` via `createTestFactory(sslContext)` but never assert anything about the factory actually used by `GenericRestApiClient.setupHttpClient()`. Assertions only exercise an `SSLSocket` built directly from the `SSLContext`, so they primarily validate JVM TLS defaults rather than the client's configuration.

Either assert against the `SSLConnectionSocketFactory` actually installed in the HTTP client's connection manager (e.g. via reflection) to confirm it uses `null` protocols, or remove the unused `factory` variable and clarify in comments that the tests target system defaults instead of the client's factory configuration.

Suggested implementation:

```java
        assertNotNull(httpClient, "HTTP client should be created by GenericRestApiClient");

        // Then: Verify the HTTP client is configured with an SSLConnectionSocketFactory that relies on system default protocols (null)
        SSLConnectionSocketFactory httpsFactory = extractSslConnectionSocketFactory(httpClient);
        assertNotNull(httpsFactory, "HTTPS socket factory should be configured on the HTTP client's connection manager");

        String[] supportedProtocols = getSupportedProtocols(httpsFactory);
        assertNull(supportedProtocols, "Configured supported protocols should be null to indicate use of system defaults");

        // When: Test the same configuration pattern (null protocols) that GenericRestApiClient uses
        SSLContext sslContext = SSLContexts.custom()
                .loadTrustMaterial((chain, authType) -> true)
                .build();

        // Create a socket using the same SSLContext to verify system defaults
        SSLSocket socket = (SSLSocket) sslContext.getSocketFactory().createSocket();

        // Then: Verify system defaults provide secure TLS configuration
        String[] enabledProtocols = socket.getEnabledProtocols();

        LOGGER.info("System defaults with null protocols - Enabled: {}", Arrays.toString(enabledProtocols));

        assertNotNull(enabledProtocols);
        List<String> protocolList = Arrays.asList(enabledProtocols);
        assertTrue(protocolList.contains("TLSv1.3") || protocolList.contains("TLSv1.2"),

```

To fully implement the reflection-based assertions, you also need to:

1. **Add helper methods inside `GenericRestApiClientTLSTest` (or the relevant test class):**
   ```java
   private SSLConnectionSocketFactory extractSslConnectionSocketFactory(CloseableHttpClient httpClient) {
       try {
           // Most Apache HttpClient implementations in tests will be InternalHttpClient
           if (httpClient instanceof org.apache.http.impl.client.InternalHttpClient) {
               org.apache.http.impl.client.InternalHttpClient internal =
                       (org.apache.http.impl.client.InternalHttpClient) httpClient;

               org.apache.http.conn.HttpClientConnectionManager connectionManager = internal.getConnectionManager();
               if (connectionManager instanceof org.apache.http.impl.conn.PoolingHttpClientConnectionManager) {
                   org.apache.http.impl.conn.PoolingHttpClientConnectionManager poolingMgr =
                           (org.apache.http.impl.conn.PoolingHttpClientConnectionManager) connectionManager;

                   org.apache.http.config.Lookup<org.apache.http.conn.socket.ConnectionSocketFactory> registry =
                           poolingMgr.getSocketFactoryRegistry();
                   org.apache.http.conn.socket.ConnectionSocketFactory csf = registry.lookup("https");
                   if (csf instanceof SSLConnectionSocketFactory) {
                       return (SSLConnectionSocketFactory) csf;
                   }
               }
           }

           // Fallback via reflection for other CloseableHttpClient implementations
           java.lang.reflect.Field mgrField = httpClient.getClass().getDeclaredField("connManager");
           mgrField.setAccessible(true);
           Object manager = mgrField.get(httpClient);

           if (manager instanceof org.apache.http.impl.conn.PoolingHttpClientConnectionManager) {
               org.apache.http.impl.conn.PoolingHttpClientConnectionManager poolingMgr =
                       (org.apache.http.impl.conn.PoolingHttpClientConnectionManager) manager;

               org.apache.http.config.Lookup<org.apache.http.conn.socket.ConnectionSocketFactory> registry =
                       poolingMgr.getSocketFactoryRegistry();
               org.apache.http.conn.socket.ConnectionSocketFactory csf = registry.lookup("https");
               if (csf instanceof SSLConnectionSocketFactory) {
                   return (SSLConnectionSocketFactory) csf;
               }
           }

           return null;
       } catch (NoSuchFieldException | IllegalAccessException e) {
           fail("Failed to introspect HTTP client SSL configuration: " + e.getMessage());
           return null; // unreachable, fail() throws AssertionError
       }
   }

   private String[] getSupportedProtocols(SSLConnectionSocketFactory factory) {
       try {
           java.lang.reflect.Field field = SSLConnectionSocketFactory.class.getDeclaredField("supportedProtocols");
           field.setAccessible(true);
           return (String[]) field.get(factory);
       } catch (NoSuchFieldException | IllegalAccessException e) {
           fail("Failed to introspect SSLConnectionSocketFactory supportedProtocols: " + e.getMessage());
           return null; // unreachable, fail() throws AssertionError
       }
   }
   ```

2. **Ensure the following imports (or their equivalents) exist at the top of the test file:**
   ```java
   import org.apache.http.conn.HttpClientConnectionManager;
   import org.apache.http.conn.socket.ConnectionSocketFactory;
   import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
   import org.apache.http.impl.client.CloseableHttpClient;
   import org.apache.http.impl.client.InternalHttpClient;
   import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
   import org.apache.http.config.Lookup;

   import static org.junit.jupiter.api.Assertions.assertNull;
   import static org.junit.jupiter.api.Assertions.fail;
   ```

These changes make the tests assert against the actual `SSLConnectionSocketFactory` configured by `GenericRestApiClient.setupHttpClient()`, verifying that its protocols are `null` (system defaults), while retaining the existing checks that ensure the JVM's default TLS configuration remains secure.
</issue_to_address>

### Comment 3
<location path="src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java" line_range="88-97" />
<code_context>
+        // Given: Verify GenericRestApiClient.setupHttpClient() works
</code_context>
<issue_to_address>
**suggestion:** Repeated reflective setup and resource management could be centralized for clarity

Most tests duplicate the same reflective `setupHttpClient` call and manual closing of `CloseableHttpClient`/`SSLSocket`, which hurts maintainability and risks inconsistent cleanup.

Consider centralizing this by adding a helper (or `@BeforeEach`/`@AfterEach`) that handles client creation via reflection and guarantees proper teardown (e.g., via try-with-resources), so individual tests focus solely on their TLS assertions while setup/teardown stays consistent and easy to update if `GenericRestApiClient` initialization changes.

Suggested implementation:

```java
    @Test
    @DisplayName("Should accept TLS 1.3 connections using GenericRestApiClient's configuration pattern")
    void shouldAcceptTLS13ThroughClientConfiguration() throws Exception {
        LOGGER.info("=== Testing TLS 1.3 Acceptance via Client Configuration Pattern ===");

        // Given: Verify GenericRestApiClient.setupHttpClient() works via centralized helper
        CloseableHttpClient httpClient = getHttpClientViaSetup();

        // When: Test the same configuration pattern (null protocols) that GenericRestApiClient uses
        SSLContext sslContext = SSLContexts.custom()
                .loadTrustMaterial((chain, authType) -> true)
                .build();

```

To fully centralize the reflective setup and teardown as suggested, you should also:

1. Add centralized reflective setup for `CloseableHttpClient`:
   - Introduce a field in `GenericRestApiClientTLSTest`:
     - `private Method setupHttpClientMethod;`
     - `private CloseableHttpClient httpClient;`
   - Add a `@BeforeEach` method:
     ```java
     @BeforeEach
     void setUpHttpClient() throws Exception {
         setupHttpClientMethod = GenericRestApiClient.class.getDeclaredMethod("setupHttpClient");
         setupHttpClientMethod.setAccessible(true);
         httpClient = (CloseableHttpClient) setupHttpClientMethod.invoke(client);
         assertNotNull(httpClient, "HTTP client should be created by GenericRestApiClient");
     }
     ```
   - Implement the helper used in the edited test:
     ```java
     private CloseableHttpClient getHttpClientViaSetup() {
         assertNotNull(httpClient, "HTTP client should be initialized in setUpHttpClient()");
         return httpClient;
     }
     ```

2. Add centralized teardown guaranteeing proper cleanup:
   - Add a `@AfterEach` method:
     ```java
     @AfterEach
     void tearDownHttpClient() throws IOException {
         if (httpClient != null) {
             httpClient.close();
             httpClient = null;
         }
     }
     ```
   - If tests open `SSLSocket` instances directly, either:
     - Use try-with-resources in each test, or
     - Track them in a collection and close them in `@AfterEach`.

3. Update other tests in this class that currently:
   - Reflectively obtain `setupHttpClient` and/or manually close the returned `CloseableHttpClient`,
   - To instead use the shared `getHttpClientViaSetup()` helper and rely on `@AfterEach` for cleanup.

4. Ensure imports for lifecycle annotations if not already present:
   ```java
   import org.junit.jupiter.api.BeforeEach;
   import org.junit.jupiter.api.AfterEach;
   ```
These changes will remove duplicated reflective setup logic and ensure consistent resource management across all TLS tests.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java Outdated
Comment thread src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java Outdated
Comment thread src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java Outdated
Signed-off-by: Shreya Biradar <shbirada@ibm.com>
@shreyabiradar07
Copy link
Copy Markdown
Contributor Author

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 3 issues, and left some high level feedback:

  • The createTestFactory helper method in GenericRestApiClientTLSTest is never used; consider removing it or wiring it into the tests to avoid dead/unused code.
  • There is a lot of duplicated logic across the TLS 1.0/1.1 acceptance/rejection tests (socket setup, logging, assertions on enabled protocols); consider extracting common helpers or parameterizing the TLS version to make the tests shorter and easier to maintain.
  • Protocol names like "TLSv1", "TLSv1.1", and "TLSv1.3" are hard-coded in many places; consider centralizing them as constants to reduce typo risk and ease future changes if supported protocol sets evolve.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `createTestFactory` helper method in `GenericRestApiClientTLSTest` is never used; consider removing it or wiring it into the tests to avoid dead/unused code.
- There is a lot of duplicated logic across the TLS 1.0/1.1 acceptance/rejection tests (socket setup, logging, assertions on enabled protocols); consider extracting common helpers or parameterizing the TLS version to make the tests shorter and easier to maintain.
- Protocol names like `"TLSv1"`, `"TLSv1.1"`, and `"TLSv1.3"` are hard-coded in many places; consider centralizing them as constants to reduce typo risk and ease future changes if supported protocol sets evolve.

## Individual Comments

### Comment 1
<location path="src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java" line_range="397-271" />
<code_context>
+        SSLSocket socket = createSocketWithSystemDefaults(sslContext);
+        String[] protocols = socket.getEnabledProtocols();
+        
+        LOGGER.info("System default protocols: {}", Arrays.toString(protocols));
+        
+        // Then: Only modern TLS versions should be enabled
+        assertNotNull(protocols);
+        assertTrue(protocols.length >= 1, "Should have at least 1 protocol enabled");
+        
+        List<String> protocolList = Arrays.asList(protocols);
+        assertTrue(protocolList.contains("TLSv1.3") || protocolList.contains("TLSv1.2"),
+                "Modern TLS (1.3 or 1.2) should be enabled by system defaults");
+        assertFalse(protocolList.contains("TLSv1.1"),
+                "TLS 1.1 should not be enabled by system defaults");
+        assertFalse(protocolList.contains("TLSv1"),
+                "TLS 1.0 should not be enabled by system defaults");
+        
+        socket.close();
+        httpClient.close();
+    }
+
</code_context>
<issue_to_address>
**suggestion (testing):** Tests rely on specific system default protocol sets, which may cause brittleness across JDKs or environments.

These tests currently assert a specific TLS protocol set (no TLSv1/TLSv1.1, presence of TLSv1.2/1.3), which depends on the JDK version and local security configuration. On older or differently configured JVMs, they may fail even when `GenericRestApiClient` correctly defers to system defaults.

To reduce brittleness, consider:
- Relaxing expectations to focus on excluding legacy protocols only when the JDK supports doing so, or
- Guarding them with assumptions (e.g., Java version, security properties), or
- Asserting only that the client uses system defaults, without fixing the exact protocol list.

This keeps the tests portable while still validating the intended configuration behaviour.

Suggested implementation:

```java
        SSLSocket socket = createSocketWithSystemDefaults(sslContext);
        String[] enabledProtocols = socket.getEnabledProtocols();
        String[] supportedProtocols = socket.getSupportedProtocols();

        LOGGER.info("System default enabled protocols: {}", Arrays.toString(enabledProtocols));
        LOGGER.info("System supported protocols: {}", Arrays.toString(supportedProtocols));

        // Then: verify we have some protocols enabled and, where supported by the JDK, legacy
        // protocols are not enabled. This focuses on excluding legacy protocols without
        // asserting an exact modern TLS set, keeping the test portable across JDKs.
        assertNotNull(enabledProtocols);
        assertTrue(enabledProtocols.length >= 1, "Should have at least 1 protocol enabled");

        List<String> enabledList = Arrays.asList(enabledProtocols);
        List<String> supportedList = Arrays.asList(supportedProtocols);

        // Only assert on legacy protocols if the JVM actually supports them; this avoids
        // failures on JDKs where TLSv1/TLSv1.1 are fully disabled/removed.
        if (supportedList.contains("TLSv1") || supportedList.contains("TLSv1.1")) {
            assertFalse(enabledList.contains("TLSv1"),
                    "TLS 1.0 should not be enabled by system defaults when supported by the JDK");
            assertFalse(enabledList.contains("TLSv1.1"),
                    "TLS 1.1 should not be enabled by system defaults when supported by the JDK");
        }

        socket.close();
        httpClient.close();
    }

```

1. Ensure `java.util.Arrays` and `java.util.List` are imported at the top of the file (if not already present).
2. If there are other tests that assert specific TLS protocol sets, consider aligning them with this pattern (log enabled/supported protocols, assert basic non-emptiness, and conditionally exclude legacy protocols based on `getSupportedProtocols()`).
</issue_to_address>

### Comment 2
<location path="src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java" line_range="74-80" />
<code_context>
+     * This allows us to verify that the configuration approach used by the client results in
+     * secure TLS settings.
+     */
+    private SSLConnectionSocketFactory createTestFactory(SSLContext sslContext) {
+        return new SSLConnectionSocketFactory(
+                sslContext,
+                null,  // protocols - null delegates to system defaults (as GenericRestApiClient does)
+                null,  // cipher suites
+                NoopHostnameVerifier.INSTANCE
+        );
+    }
+
</code_context>
<issue_to_address>
**nitpick:** Unused helper method `createTestFactory` adds noise and can be removed or used.

Since this helper isn’t referenced, either refactor the tests to use it (to explicitly cover the `null` protocols case) or remove it to avoid dead code and keep the test intent clear.
</issue_to_address>

### Comment 3
<location path="src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java" line_range="90-95" />
<code_context>
+     * @return The CloseableHttpClient created by GenericRestApiClient
+     * @throws Exception if reflection or client setup fails
+     */
+    private CloseableHttpClient setupAndVerifyHttpClient() throws Exception {
+        Method setupMethod = GenericRestApiClient.class.getDeclaredMethod("setupHttpClient");
+        setupMethod.setAccessible(true);
+        CloseableHttpClient httpClient = (CloseableHttpClient) setupMethod.invoke(client);
+        assertNotNull(httpClient, "HTTP client should be created by GenericRestApiClient");
+        return httpClient;
+    }
+
</code_context>
<issue_to_address>
**suggestion (testing):** Reflective access to `setupHttpClient` makes tests tightly coupled to private implementation details.

Using reflection here gives good coverage but also couples these tests to private internals, so minor refactors (renames, visibility or structural changes) may fail tests without changing behavior.

Consider either:
- Introducing a test seam (e.g., package-visible method, factory, or configuration hook), or
- Confining reflective usage to a small wiring-focused test, with other TLS tests exercising only public behavior.

This isn’t strictly blocking, but a change like this would improve long-term test maintainability as `GenericRestApiClient` evolves.

Suggested implementation:

```java

```

```java
import org.apache.http.conn.ssl.NoopHostnameVerifier;

```

1. Remove the `setupAndVerifyHttpClient()` helper method entirely from `GenericRestApiClientTLSTest` (its declaration and body), as it uses reflection on `setupHttpClient`.
2. Update any tests in this class that currently call `setupAndVerifyHttpClient()` to instead exercise only public behavior of `GenericRestApiClient` (e.g., by performing actual requests or inspecting TLS-related configuration exposed through public APIs).
3. If you still want a wiring-level check for `setupHttpClient`, introduce a separate, focused test class (e.g., `GenericRestApiClientWiringTest`) that contains the reflective access, keeping this TLS-focused test decoupled from private implementation details.
4. Optionally, if you decide to introduce a test seam later (such as a package-visible factory or hook in `GenericRestApiClient`), you can refactor the TLS tests to use that seam instead of reflection, but that would require changes in the production code as well.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java Outdated
Comment thread src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java Outdated
Comment thread src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java Outdated
Signed-off-by: Shreya Biradar <shbirada@ibm.com>
Signed-off-by: Shreya Biradar <shbirada@ibm.com>
@shreyabiradar07
Copy link
Copy Markdown
Contributor Author

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • Some tests (e.g., shouldPreferTLS13OverTLS12InClient) make assumptions about protocol ordering (protocols[0] == TLSv1.3) that may not hold across JDKs or configurations; consider asserting presence and relative preference in a less brittle way (e.g., checking index order only if both are present, or just that TLS 1.3 is enabled).
  • Several tests still use hard-coded protocol strings like "TLSv1.1" and "TLSv1" instead of the defined constants (TLS_1_1, TLS_1_0); aligning all usages to the constants will avoid typos and make future updates easier.
  • The unit tests log a large amount of informational output for normal conditions; consider trimming logs or lowering log levels in non-failure cases to keep test output concise and focused on failures.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Some tests (e.g., `shouldPreferTLS13OverTLS12InClient`) make assumptions about protocol ordering (`protocols[0] == TLSv1.3`) that may not hold across JDKs or configurations; consider asserting presence and relative preference in a less brittle way (e.g., checking index order only if both are present, or just that TLS 1.3 is enabled).
- Several tests still use hard-coded protocol strings like "TLSv1.1" and "TLSv1" instead of the defined constants (`TLS_1_1`, `TLS_1_0`); aligning all usages to the constants will avoid typos and make future updates easier.
- The unit tests log a large amount of informational output for normal conditions; consider trimming logs or lowering log levels in non-failure cases to keep test output concise and focused on failures.

## Individual Comments

### Comment 1
<location path="src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java" line_range="165-168" />
<code_context>
+        LOGGER.info("JDK supported protocols: {}", Arrays.toString(supportedProtocols));
+        
+        // Only run this test if the protocol is supported by the JDK
+        if (!supportedList.contains(protocol)) {
+            LOGGER.info("{} not supported by JDK - skipping test as it's already disabled at JDK level",
+                    protocolDisplayName);
+            return;
+        }
+        
</code_context>
<issue_to_address>
**suggestion (testing):** Use JUnit assumptions to explicitly mark unsupported protocols as skipped rather than silently passing.

Right now, if the JDK doesn’t support a legacy protocol, the helper logs and returns, so the test appears to pass even though the scenario isn’t actually run. Prefer using `Assumptions.assumeTrue(supportedList.contains(protocol), ...)` here so these cases are marked as skipped rather than passing when TLS 1.0/1.1 isn’t available on the runtime.

Suggested implementation:

```java
        LOGGER.info("JDK supported protocols: {}", Arrays.toString(supportedProtocols));

        // Only run this test if the protocol is supported by the JDK
        Assumptions.assumeTrue(
                supportedList.contains(protocol),
                () -> protocolDisplayName + " not supported by JDK - skipping test as it's already disabled at JDK level"
        );

```

```java
import org.apache.http.ssl.SSLContexts;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;

```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/test/java/com/autotune/utils/GenericRestApiClientTLSTest.java Outdated
Signed-off-by: Shreya Biradar <shbirada@ibm.com>
Signed-off-by: Shreya Biradar <shbirada@ibm.com>
Signed-off-by: Shreya Biradar <shbirada@ibm.com>
Signed-off-by: Shreya Biradar <shbirada@ibm.com>
@shreyabiradar07
Copy link
Copy Markdown
Contributor Author

shreyabiradar07 commented May 14, 2026

@chandrams [Edit] All the unit tests are run with Docker build using command: RUN mvn -f pom.xml clean package and verified that the build fails if some error with tests.

Signed-off-by: Shreya Biradar <shbirada@ibm.com>
Copy link
Copy Markdown
Contributor

@chandrams chandrams left a comment

Choose a reason for hiding this comment

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

LGTM

@chandrams chandrams moved this from In Progress to Under Review in Monitoring May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request test

Projects

Status: Under Review

Development

Successfully merging this pull request may close these issues.

2 participants