Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Test Cases for JVM and metrics-httpasyncclient #4041

Open
wants to merge 7 commits into
base: release/4.2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions metrics-collectd/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,11 @@
<version>1.0.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.codahale.metrics.collectd;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

public class SecurityConfigurationTest {

private byte[] username;
private byte[] password;
private SecurityLevel securityLevel;

@BeforeEach
public void setUp() {
username = "admin".getBytes();
password = "password".getBytes();
securityLevel = SecurityLevel.SIGN;
}

/**
* Test the constructor and getters of the SecurityConfiguration class.
*/
@Test
public void testConstructorAndGetters() {
// When
SecurityConfiguration config = new SecurityConfiguration(username, password, securityLevel);

// Then
assertArrayEquals(username, config.getUsername(), "Username matched");
assertArrayEquals(password, config.getPassword(), "Password matched");
assertEquals(securityLevel, config.getSecurityLevel(), "Security level matched");
}

/**
* Test the none() factory method of SecurityConfiguration to ensure it creates
* a configuration with no security settings.
*/
@Test
public void testNoneSecurityConfiguration() {
// When
SecurityConfiguration config = SecurityConfiguration.none();

// Then
assertNull(config.getUsername(), "Username is null");
assertNull(config.getPassword(), "Password is null");
assertEquals(SecurityLevel.NONE, config.getSecurityLevel(), "Security level is NONE");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public HttpHost startServerWithGlobalRequestHandler(HttpRequestHandler handler)
return new HttpHost("localhost", address.getPort(), "http");
}



@After
public void tearDown() {
if (server != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,124 @@
import com.codahale.metrics.MetricRegistryListener;
import com.codahale.metrics.Timer;
import com.codahale.metrics.httpclient.HttpClientMetricNameStrategy;
import com.codahale.metrics.httpclient.InstrumentedHttpClients;
import org.apache.http.HttpRequest;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.nio.client.HttpAsyncClient;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.concurrent.ExecutionException;

import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;


/**
* Test class for {@link InstrumentedHttpClients}.
* This class tests the registration of expected metrics using various configurations of metric registries,
* metric name strategies, and HTTP clients.
*/
@RunWith(MockitoJUnitRunner.class)
public class InstrumentedHttpClientsTest extends HttpClientTestBase {

// Metric registry for testing
private final MetricRegistry metricRegistry = new MetricRegistry();


// HTTP client instance
private HttpAsyncClient asyncHttpClient;

// Mocked objects
@Mock
private HttpClientMetricNameStrategy metricNameStrategy;
@Mock
private MetricRegistryListener registryListener;

/**
* Test method to verify the registration of expected metrics using a given name strategy.
*
* @throws Exception if an error occurs during the test execution
*/
@Test
public void registersExpectedMetricsGivenNameStrategy() throws Exception {
// Arrange
HttpHost host = startServerWithGlobalRequestHandler(STATUS_OK);
final HttpGet get = new HttpGet("/q=anything");
final String metricName = MetricRegistry.name("some.made.up.metric.name");

when(metricNameStrategy.getNameFor(any(), any(HttpRequest.class)))
.thenReturn(metricName);
// Stubbing behavior of the metric name strategy
when(metricNameStrategy.getNameFor(any(), any(HttpRequest.class))).thenReturn(metricName);

// Act
asyncHttpClient.execute(host, get, null).get();

// Assert
verify(registryListener).onTimerAdded(eq(metricName), any(Timer.class));
}

/**
* Test method to verify the creation of a closeable HTTP async client with a metric registry and name strategy.
*/
@Test
public void testBuildWithMetricRegistryAndNameStrategy() {
// Arrange
InstrumentedNHttpClientBuilder builder = new InstrumentedNHttpClientBuilder(metricRegistry, metricNameStrategy, "test-client");

// Act
CloseableHttpAsyncClient client = builder.build();

// Assert
assertNotNull(client);
}

/**
* Test method to verify the registration of expected metrics using a name strategy with a built client.
*
* @throws Exception if an error occurs during the test execution
*/
@Ignore // Ignored due to incomplete test setup
@Test
public void testRegistersExpectedMetricsGivenNameStrategy() throws Exception {
// Arrange
InstrumentedNHttpClientBuilder builder = new InstrumentedNHttpClientBuilder(metricRegistry, metricNameStrategy);
CloseableHttpAsyncClient asyncHttpClient = builder.build();
asyncHttpClient.start();

HttpHost host = startServerWithGlobalRequestHandler(STATUS_OK);
HttpGet get = new HttpGet("/q=anything");
asyncHttpClient.execute(host, get, null).get();

ArgumentCaptor<String> metricNameCaptor = ArgumentCaptor.forClass(String.class);

// Act
verify(metricNameStrategy).getNameFor(any(), any(HttpRequest.class));
verify(registryListener).onTimerAdded(metricNameCaptor.capture(), any(Timer.class));
}

/**
* Set up method executed before each test case.
* Initializes the HTTP async client and adds a metric registry listener.
*
* @throws Exception if an error occurs during the setup
*/
@Before
public void setUp() throws Exception {
// Initialize the HTTP async client
CloseableHttpAsyncClient chac = new InstrumentedNHttpClientBuilder(metricRegistry, metricNameStrategy).build();
chac.start();
asyncHttpClient = chac;

// Add metric registry listener
metricRegistry.addListener(registryListener);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.nio.client.HttpAsyncClient;
import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
Expand All @@ -29,7 +33,7 @@
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
@Ignore("The tests are flaky")
//@Ignore("The tests are flaky")
public class InstrumentedHttpClientsTimerTest extends HttpClientTestBase {

private HttpAsyncClient asyncHttpClient;
Expand Down Expand Up @@ -101,6 +105,9 @@ public void timerIsStoppedCorrectlyWithProvidedFutureCallbackCompleted() throws
verify(context, timeout(200).times(1)).stop();
}




@Test
@SuppressWarnings("unchecked")
public void timerIsStoppedCorrectlyWithProvidedFutureCallbackFailed() throws Exception {
Expand Down Expand Up @@ -131,4 +138,97 @@ public void timerIsStoppedCorrectlyWithProvidedFutureCallbackFailed() throws Exc
verify(context, timeout(200).times(1)).stop();
}

/**
* Test method to verify that the timer is stopped correctly when multiple requests are executed concurrently.
*
* @throws Exception if an error occurs during the test execution
*/
@Test
public void timerIsStoppedCorrectlyWithConcurrentRequests() throws Exception {
HttpHost host = startServerWithGlobalRequestHandler(STATUS_OK);
HttpGet get = new HttpGet("/?q=concurrent");

// Timer hasn't been stopped prior to executing the requests
verify(context, never()).stop();

// Execute multiple requests concurrently
Future<HttpResponse> responseFuture1 = asyncHttpClient.execute(host, get, null);
Future<HttpResponse> responseFuture2 = asyncHttpClient.execute(host, get, null);

// Wait for both requests to complete
responseFuture1.get(20, TimeUnit.SECONDS);
responseFuture2.get(20, TimeUnit.SECONDS);

// After all computations are complete, the timer should be stopped
verify(context, timeout(200).times(2)).stop(); // Two requests were made
}

/**
* Test method to verify that the timer is stopped correctly when a request is cancelled using a provided future callback.
*
* @throws Exception if an error occurs during the test execution
*/
@Test
public void timerIsStoppedCorrectlyWithProvidedFutureCallbackCancelled() throws Exception {
HttpHost host = startServerWithGlobalRequestHandler(STATUS_OK);
HttpGet get = new HttpGet("/?q=cancelled");

FutureCallback<HttpResponse> futureCallback = mock(FutureCallback.class);

// Timer hasn't been stopped prior to executing the request
verify(context, never()).stop();

Future<HttpResponse> responseFuture = asyncHttpClient.execute(host, get, futureCallback);
responseFuture.cancel(true); // Cancel the future

// After the computation is cancelled, the timer must be stopped
verify(context, timeout(200).times(1)).stop();
}

/**
* Test method to verify that the timer is stopped correctly when a request fails using a provided future callback.
*
* @throws Exception if an error occurs during the test execution
*/
@Test
@SuppressWarnings("unchecked")
public void timerIsStoppedCorrectlyWithProvidedFutureCallbackAndFailure() throws Exception {
HttpHost host = startServerWithGlobalRequestHandler(STATUS_OK);
HttpGet get = new HttpGet("/?q=failure");

FutureCallback<HttpResponse> futureCallback = mock(FutureCallback.class);

// Timer hasn't been stopped prior to executing the request
verify(context, never()).stop();

Future<HttpResponse> responseFuture = asyncHttpClient.execute(host, get, futureCallback);
responseFuture.get(20, TimeUnit.SECONDS); // Wait for the request to complete

// After the computation fails, the timer must be stopped
verify(context, timeout(200).times(1)).stop();
}

/**
* Test method to verify that the timer is stopped correctly when an exception occurs during the future get operation.
*
* @throws Exception if an error occurs during the test execution
*/
@Test
public void timerIsStoppedCorrectlyWithExceptionInFutureGet() throws Exception {
HttpHost host = startServerWithGlobalRequestHandler(STATUS_OK);
HttpGet get = new HttpGet("/?q=exception");

// Timer hasn't been stopped prior to executing the request
verify(context, never()).stop();


Future<HttpResponse> responseFuture = asyncHttpClient.execute(host, get, null);
responseFuture.get(); // Let the future throw an exception

// After the computation throws an exception, the timer must be stopped
verify(context, timeout(200).times(1)).stop();
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.codahale.metrics.httpasyncclient;

import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import org.apache.http.config.Registry;
import org.apache.http.conn.DnsResolver;
import org.apache.http.conn.SchemePortResolver;
import org.apache.http.nio.conn.ManagedNHttpClientConnection;
import org.apache.http.nio.conn.NHttpConnectionFactory;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.reactor.ConnectingIOReactor;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.concurrent.TimeUnit;

import static org.mockito.Mockito.*;

public class InstrumentedNClientConnManagerTest {

@Mock
private MetricRegistry metricRegistry;

@Mock
private ConnectingIOReactor ioreactor;

@Mock
private NHttpConnectionFactory<ManagedNHttpClientConnection> connFactory;

@Mock
private Registry<SchemeIOSessionStrategy> iosessionFactoryRegistry;

@Mock
private SchemePortResolver schemePortResolver;

@Mock
private DnsResolver dnsResolver;

private InstrumentedNClientConnManager connManager;

@Before
public void setup() {
MockitoAnnotations.initMocks(this);

// Initialize the InstrumentedNClientConnManager instance
connManager = new InstrumentedNClientConnManager(
ioreactor, connFactory, schemePortResolver, metricRegistry,
iosessionFactoryRegistry, 100, TimeUnit.MILLISECONDS, dnsResolver, "test");
}

/**
* Test method to verify that metrics are registered correctly.
*/
@Test
public void testMetricsAreRegistered() {
// Verify that registerGauge is called for each metric
verify(metricRegistry, times(4)).registerGauge(anyString(), any(Gauge.class));
}
}
Loading