Skip to content
Merged
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
32 changes: 32 additions & 0 deletions java-reporter-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,26 @@
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.8.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.8.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<distributionManagement>
Expand All @@ -93,6 +113,18 @@
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
<configuration>
<includes>
<include>**/*Test.java</include>
<include>**/*Tests.java</include>
</includes>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
* Manages batch processing of test results for efficient API reporting.
* Collects test results in batches and periodically flushes them to Testomat.io.
* Provides automatic retry mechanism and graceful shutdown handling.
*
* <p>Thread-safe for concurrent test execution with configurable batch size and flush intervals.
*/
public class BatchResultManager {

Expand All @@ -40,7 +42,6 @@ public class BatchResultManager {
*
* @param apiClient API client for reporting test results
* @param runUid unique identifier of the test run
* @throws NumberFormatException if batch size or flush interval properties are invalid
*/
public BatchResultManager(ApiInterface apiClient, String runUid) {
this.apiClient = apiClient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,46 @@
import java.util.List;

/**
* API interface for interacting with Testomat.io platform.
* Provides methods for test run lifecycle management and result reporting.
* Primary interface for Testomat.io API operations.
* Defines the contract for test run lifecycle management and result reporting.
* Thread-safe implementations should support concurrent test execution scenarios.
*/
public interface ApiInterface {

/**
* Creates new test run.
* Creates a new test run in Testomat.io.
*
* @param title test run title
* @return unique test run identifier
* @throws IOException if API request fails
* @param title descriptive title for the test run
* @return unique test run identifier (UID) for subsequent operations
* @throws IOException if network request fails or API returns error
*/
String createRun(String title) throws IOException;

/**
* Reports single test result.
* Reports a single test result to the specified test run.
*
* @param uid test run identifier
* @param result test result to report
* @throws IOException if API request fails
* @param uid test run identifier from {@link #createRun(String)}
* @param result test execution result with status and metadata
* @throws IOException if network request fails or API returns error
*/
void reportTest(String uid, TestResult result) throws IOException;

/**
* Reports multiple test results in batch.
* Reports multiple test results in a single batch operation.
* More efficient than individual calls for large test suites.
*
* @param uid test run identifier
* @param results test results to report
* @throws IOException if API request fails
* @param uid test run identifier from {@link #createRun(String)}
* @param results collection of test execution results
* @throws IOException if network request fails or API returns error
*/
void reportTests(String uid, List<TestResult> results) throws IOException;

/**
* Marks test run as finished.
* Finalizes the test run and marks it as completed.
*
* @param uid test run identifier
* @param duration test run duration in seconds
* @throws IOException if API request fails
* @param uid test run identifier from {@link #createRun(String)}
* @param duration total test run duration in seconds
* @throws IOException if network request fails or API returns error
*/
void finishTestRun(String uid, float duration) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package io.testomat.core.client;

/**
* Factory for creating API client instances.
* Abstract factory for creating {@link ApiInterface} implementations.
* Provides a pluggable mechanism for different API client configurations.
*/
public interface ClientFactory {

/**
* Creates configured API client instance.
* Creates a fully configured API client instance.
* Implementation should handle all necessary initialization including
* authentication, HTTP client setup, and request/response handling.
*
* @return API client implementation
* @return ready-to-use API client implementation
*/
ApiInterface createClient();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
import static io.testomat.core.constants.CommonConstants.RESPONSE_UID_KEY;

/**
* HTTP client for Testomat.io API operations.
* Handles test run lifecycle and result reporting with proper error handling.
* Default HTTP-based implementation of {@link ApiInterface}.
* Handles test run lifecycle and result reporting with comprehensive error handling
* and automatic URL/request body construction for Testomat.io API endpoints.
*/
public class NativeApiClient implements ApiInterface {
private static final Logger log = LoggerFactory.getLogger(NativeApiClient.class);
Expand All @@ -32,11 +33,12 @@ public class NativeApiClient implements ApiInterface {
private final RequestBodyBuilder requestBodyBuilder;

/**
* Creates API client with custom dependencies for testing.
* Creates API client with injectable dependencies.
* Primarily used for testing with mock implementations.
*
* @param apiKey API key for authentication
* @param client HTTP client implementation
* @param requestBodyBuilder request body builder for JSON payloads
* @param apiKey Testomat.io API key for authentication
* @param client HTTP client implementation for network requests
* @param requestBodyBuilder builder for creating JSON request payloads
*/
public NativeApiClient(String apiKey,
CustomHttpClient client,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
import org.slf4j.LoggerFactory;

/**
* Singleton factory for creating Testomat.io API client instances.
* Loads API key from properties and creates configured client.
* Default implementation of {@link ClientFactory} for Testomat.io API clients.
* Singleton factory that loads API key from properties and creates production-ready
* clients with native HTTP implementation and standard request builders.
*/
public class TestomatClientFactory implements ClientFactory {
private static final PropertyProvider propertyProvider =
Expand All @@ -24,9 +25,10 @@ private TestomatClientFactory() {
}

/**
* Returns singleton factory instance.
* Returns the singleton factory instance.
* Thread-safe lazy initialization of factory.
*
* @return ClientFactory instance
* @return configured ClientFactory instance
*/
public static ClientFactory getClientFactory() {
if (instance == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,32 @@
import java.io.IOException;

/**
* HTTP client abstraction for making API requests.
* HTTP client abstraction for Testomat.io API communication.
* Provides type-safe request/response handling with JSON serialization support.
*/
public interface CustomHttpClient {

/**
* Executes HTTP POST request with JSON body.
* Executes HTTP POST request with JSON payload.
*
* @param url target URL
* @param requestBody JSON request body
* @param responseType expected response type class
* @param <T> response type
* @return deserialized response object or null if no response expected
* @throws IOException if request fails or response cannot be processed
* @param url endpoint URL for the request
* @param requestBody JSON-formatted request payload
* @param responseType expected response class for deserialization, or null if no response needed
* @param <T> response object type
* @return deserialized response object, or null if responseType is null
* @throws IOException if network request fails or JSON processing fails
*/
<T> T post(String url, String requestBody, Class<T> responseType) throws IOException;

/**
* Executes HTTP PUT request with JSON body.
* Executes HTTP PUT request with JSON payload.
*
* @param url target URL
* @param requestBody JSON request body
* @param responseType expected response type class
* @param <T> response type
* @return deserialized response object or null if no response expected
* @throws IOException if request fails or response cannot be processed
* @param url endpoint URL for the request
* @param requestBody JSON-formatted request payload
* @param responseType expected response class for deserialization, or null if no response needed
* @param <T> response object type
* @return deserialized response object, or null if responseType is null
* @throws IOException if network request fails or JSON processing fails
*/
<T> T put(String url, String requestBody, Class<T> responseType) throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Production HTTP client implementation using Java 11+ HttpClient.
* Provides robust request execution with automatic retries, connection pooling,
* and configurable timeouts for reliable Testomat.io API communication.
*/
public class NativeHttpClient implements CustomHttpClient {
private static final String HEADER_CONTENT_NAME = "Content-Type";
private static final String HEADER_CONTENT_VALUE = "application/json";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Default implementation of retry logic for HTTP requests.
* Provides exponential backoff with configurable retry attempts for transient failures
* including network timeouts, connection errors, and specific server error status codes.
*/
public class NativeRetryableRequestExecutor implements RetryableRequestExecutor {

private static final Logger log = LoggerFactory.getLogger(NativeRetryableRequestExecutor.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
package io.testomat.core.client.http.retryable;

import io.testomat.core.exception.RequestExecutionFailedException;
import io.testomat.core.exception.RequestStatusNotSuccessException;
import io.testomat.core.exception.RequestTimeoutException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

/**
* Strategy interface for executing HTTP requests with retry logic.
* Handles transient failures and implements backoff strategies for reliable API communication.
*/
public interface RetryableRequestExecutor {

/**
* Executes HTTP request with automatic retry on failures.
* Implements retry logic for transient errors like timeouts and server errors.
*
* @param request HTTP request to execute
* @param client HTTP client to use for execution
* @return successful HTTP response
* @throws RequestExecutionFailedException if all retry attempts fail
* @throws RequestTimeoutException if request times out on all attempts
* @throws RequestStatusNotSuccessException if server returns non-success status
*/
HttpResponse<String> executeRetryable(HttpRequest request, HttpClient client);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,27 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.testomat.core.exception.ResponseJsonParsingException;

/**
* Utility class for JSON response deserialization.
* Provides centralized JSON processing with pre-configured ObjectMapper
* for consistent response handling across all HTTP operations.
*/
public class JsonResponseMapperUtil {
private static final ObjectMapper objectMapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true);

/**
* Deserializes JSON response body to specified type.
* Handles null response types gracefully and provides meaningful error messages
* with truncated response bodies for debugging.
*
* @param responseBody JSON response string from HTTP request
* @param responseType target class for deserialization, null if no response expected
* @param <T> response object type
* @return deserialized response object, or null if responseType is null
* @throws ResponseJsonParsingException if JSON parsing fails
*/
public static <T> T mapJsonResponse(String responseBody, Class<T> responseType) {
if (responseType == null) {
return null;
Expand Down
Loading