CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-elasticsearch--elasticsearch-test-framework

Test framework library for Elasticsearch providing comprehensive testing utilities, base test classes, cluster management, and assertion helpers for unit and integration testing of Elasticsearch plugins and applications

Pending
Overview
Eval results
Files

specialized-testing.mddocs/

Specialized Testing

The Elasticsearch test framework provides specialized testing utilities for specific domains including XContent serialization, query validation, REST API testing, and disruption simulation. These utilities enable comprehensive testing of Elasticsearch's specialized functionality.

XContent Testing

XContent testing utilities for JSON/XML serialization, deserialization, and content validation.

AbstractXContentTestCase

Base class for testing XContent serialization and deserialization of domain objects.

package org.elasticsearch.test;

import org.elasticsearch.xcontent.ToXContent;
import org.elasticsearch.xcontent.XContent;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentType;

/**
 * Abstract base class for testing XContent serialization/deserialization of objects.
 * Provides comprehensive testing of JSON/XML round-trip conversion and parsing.
 * 
 * @param <T> the type being tested for XContent compatibility
 */
public abstract class AbstractXContentTestCase<T extends ToXContent> extends ESTestCase {
    
    /**
     * Creates a random test instance of the object being tested.
     * Subclasses must implement this to provide random test data.
     * 
     * @return random instance for testing
     */
    protected abstract T createTestInstance();
    
    /**
     * Parses an object from XContent. Subclasses must implement this
     * to provide parsing logic for their specific type.
     * 
     * @param parser XContent parser positioned at object start
     * @return parsed object instance
     */
    protected abstract T doParseInstance(XContentParser parser) throws IOException;
    
    /**
     * Tests round-trip serialization and deserialization across all XContent types.
     * Verifies that objects can be serialized to XContent and parsed back 
     * to equivalent objects.
     */
    public final void testFromXContent() throws IOException;
    
    /**
     * Tests serialization to XContent produces expected output format.
     */
    public final void testToXContent() throws IOException;
    
    /**
     * Tests parsing with additional random fields to ensure forward compatibility.
     */
    public final void testToXContentWithRandomFields() throws IOException;
    
    /**
     * Indicates whether the test should insert random fields during parsing tests.
     * Override to return false if your type doesn't support unknown fields.
     * 
     * @return true if random fields should be inserted, false otherwise
     */
    protected boolean supportsUnknownFields();
    
    /**
     * Returns XContent types to test. Override to limit testing to specific types.
     * 
     * @return array of XContent types to test
     */
    protected XContentType[] getSupportedXContentTypes();
    
    /**
     * Returns ToXContent parameters to use during serialization testing.
     * 
     * @return ToXContent.Params for serialization
     */
    protected ToXContent.Params getToXContentParams();
    
    /**
     * Predicate to determine which fields should have random content inserted.
     * 
     * @param field field path to check
     * @return true if random content can be inserted at this field
     */
    protected Predicate<String> getRandomFieldsExcludeFilter();
    
    /**
     * Assertion method to verify two instances are equivalent after round-trip.
     * Override to provide custom equality checking logic.
     * 
     * @param expected original instance
     * @param actual parsed instance
     */
    protected void assertEqualInstances(T expected, T actual);
    
    /**
     * Creates a mutated version of the instance for inequality testing.
     * 
     * @param instance original instance to mutate
     * @return mutated instance that should not be equal to original
     */
    protected T mutateInstance(T instance);
}

XContentTestUtils

Utility methods for XContent testing scenarios.

package org.elasticsearch.test;

import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentType;

/**
 * Utility methods for XContent testing including field insertion, 
 * content manipulation, and parsing verification.
 */
public class XContentTestUtils {
    
    /**
     * Inserts random fields into XContent to test forward compatibility.
     * 
     * @param builder XContent builder to insert fields into
     * @param value object to serialize with random fields
     * @param excludeFilter predicate to exclude certain field paths
     * @param xContentType XContent type being used
     * @return XContent with random fields inserted
     */
    public static BytesReference insertRandomFields(XContentBuilder builder,
                                                   Object value,
                                                   Predicate<String> excludeFilter,
                                                   XContentType xContentType) throws IOException;
    
    /**
     * Shuffles XContent field order to test order independence.
     * 
     * @param original original XContent
     * @param xContentType XContent type
     * @return XContent with shuffled field order
     */
    public static BytesReference shuffle(BytesReference original, 
                                       XContentType xContentType) throws IOException;
    
    /**
     * Compares two XContent objects for semantic equality, ignoring field order.
     * 
     * @param expected expected XContent
     * @param actual actual XContent  
     * @param xContentType XContent type
     * @return true if content is semantically equal
     */
    public static boolean equivalentXContent(BytesReference expected,
                                           BytesReference actual,
                                           XContentType xContentType) throws IOException;
    
    /**
     * Creates a random XContent object with specified depth and field count.
     * 
     * @param xContentType XContent type to generate
     * @param maxDepth maximum nesting depth
     * @param maxFields maximum fields per object
     * @return random XContent for testing
     */
    public static BytesReference randomXContent(XContentType xContentType,
                                              int maxDepth,
                                              int maxFields) throws IOException;
    
    /**
     * Validates that XContent can be parsed without errors.
     * 
     * @param content XContent to validate
     * @param xContentType XContent type
     * @return true if content is valid and parseable
     */
    public static boolean isValidXContent(BytesReference content, 
                                        XContentType xContentType);
}

XContent Testing Examples

import org.elasticsearch.test.AbstractXContentTestCase;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentType;

public class MyObjectXContentTest extends AbstractXContentTestCase<MyObject> {
    
    @Override
    protected MyObject createTestInstance() {
        return new MyObject(
            randomAlphaOfLength(10),
            randomIntBetween(1, 100),
            randomBoolean(),
            randomFrom("type1", "type2", "type3")
        );
    }
    
    @Override  
    protected MyObject doParseInstance(XContentParser parser) throws IOException {
        return MyObject.fromXContent(parser);
    }
    
    @Override
    protected boolean supportsUnknownFields() {
        return true; // MyObject can handle unknown fields gracefully
    }
    
    @Override
    protected Predicate<String> getRandomFieldsExcludeFilter() {
        // Exclude fields that have strict parsing requirements
        return field -> field.equals("metadata.config");
    }
    
    public void testSpecificXContentScenarios() throws IOException {
        MyObject original = createTestInstance();
        
        // Test all supported XContent types
        for (XContentType xContentType : XContentType.values()) {
            if (xContentType == XContentType.SMILE || xContentType == XContentType.CBOR) {
                continue; // Skip binary formats for this example
            }
            
            // Serialize to XContent
            XContentBuilder builder = XContentBuilder.builder(xContentType.xContent());
            original.toXContent(builder, ToXContent.EMPTY_PARAMS);
            BytesReference serialized = BytesReference.bytes(builder);
            
            // Parse back and verify
            XContentParser parser = createParser(xContentType.xContent(), serialized);
            MyObject parsed = doParseInstance(parser);
            
            assertEqualInstances(original, parsed);
        }
    }
}

Query Testing

Specialized testing utilities for Elasticsearch query builders and query validation.

AbstractQueryTestCase

Base class for testing query builders with comprehensive validation.

package org.elasticsearch.test;

import org.apache.lucene.search.Query;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.SearchExecutionContext;

/**
 * Abstract base class for testing QueryBuilder implementations.
 * Provides comprehensive testing of query serialization, parsing,
 * Lucene query generation, and caching behavior.
 * 
 * @param <QB> the QueryBuilder type being tested
 */
public abstract class AbstractQueryTestCase<QB extends QueryBuilder> extends AbstractXContentTestCase<QB> {
    
    /**
     * Creates a random query builder instance for testing.
     * 
     * @return random query builder
     */
    protected abstract QB doCreateTestQueryBuilder();
    
    /**
     * Tests that the query builder can be converted to a Lucene Query.
     */
    public void testToQuery() throws IOException;
    
    /**
     * Tests query builder caching behavior.
     */
    public void testCacheable() throws IOException;
    
    /**
     * Tests that malformed queries are rejected during parsing.
     */
    public void testMalformedQueries() throws IOException;
    
    /**
     * Tests query builder equality and hashCode implementation.
     */
    public void testQueryBuilderEquality();
    
    /**
     * Performs assertions on the generated Lucene query.
     * Override to provide query-specific validation.
     * 
     * @param query generated Lucene query
     * @param queryBuilder original query builder
     */
    protected void doAssertLuceneQuery(Query query, QB queryBuilder, SearchExecutionContext context);
    
    /**
     * Creates a SearchExecutionContext for query testing.
     * 
     * @return configured search execution context
     */
    protected SearchExecutionContext createSearchExecutionContext();
    
    /**
     * Returns field names that should be mapped in the test index.
     * 
     * @return collection of field names
     */
    protected Collection<String> getMappedFieldNames();
    
    /**
     * Returns the mapping configuration for test fields.
     * 
     * @return mapping as XContent string
     */
    protected String getMappingForTest();
    
    /**
     * Indicates if this query type supports caching.
     * 
     * @return true if query is cacheable
     */
    protected boolean isCacheable(QB queryBuilder);
    
    /**
     * Creates alternative query builders that should not be equal to the main one.
     * 
     * @param original original query builder
     * @return list of non-equal query builders
     */
    protected List<QB> getAlternativeQueryBuilders(QB original);
}

Query Builder Testing Examples

import org.elasticsearch.test.AbstractQueryTestCase;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.apache.lucene.search.TermQuery;

public class TermQueryBuilderTest extends AbstractQueryTestCase<TermQueryBuilder> {
    
    @Override
    protected TermQueryBuilder doCreateTestQueryBuilder() {
        String fieldName = randomFrom(MAPPED_FIELD_NAMES);
        Object value = getRandomValueForFieldName(fieldName);
        TermQueryBuilder query = new TermQueryBuilder(fieldName, value);
        
        if (randomBoolean()) {
            query.boost(randomFloat());
        }
        if (randomBoolean()) {
            query.queryName(randomAlphaOfLength(8));
        }
        
        return query;
    }
    
    @Override
    protected void doAssertLuceneQuery(Query query, 
                                     TermQueryBuilder queryBuilder, 
                                     SearchExecutionContext context) {
        assertThat(query, instanceOf(TermQuery.class));
        
        TermQuery termQuery = (TermQuery) query;
        assertThat(termQuery.getTerm().field(), equalTo(queryBuilder.fieldName()));
        
        // Verify boost is applied correctly
        if (queryBuilder.boost() != AbstractQueryBuilder.DEFAULT_BOOST) {
            assertThat(query.getBoost(), equalTo(queryBuilder.boost()));
        }
    }
    
    @Override
    protected String getMappingForTest() {
        return """
            {
                "properties": {
                    "text_field": {"type": "text"},
                    "keyword_field": {"type": "keyword"},
                    "number_field": {"type": "integer"},
                    "date_field": {"type": "date"}
                }
            }""";
    }
    
    public void testInvalidFieldName() {
        IllegalArgumentException e = expectThrows(IllegalArgumentException.class, 
            () -> new TermQueryBuilder(null, "value"));
        
        assertThat(e.getMessage(), containsString("field name cannot be null"));
    }
    
    public void testTermQueryWithNumberField() throws IOException {
        TermQueryBuilder query = new TermQueryBuilder("number_field", 42);
        Query luceneQuery = query.toQuery(createSearchExecutionContext());
        
        assertThat(luceneQuery, instanceOf(TermQuery.class));
        // Additional number-specific assertions...
    }
}

REST Testing Framework

Comprehensive framework for testing Elasticsearch REST APIs.

ESRestTestCase

Base class for REST API integration testing.

package org.elasticsearch.test.rest;

import org.apache.http.HttpEntity;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;

/**
 * Base class for REST API integration tests. Provides REST client management,
 * request/response utilities, and cluster lifecycle for REST endpoint testing.
 */
public abstract class ESRestTestCase extends ESTestCase {
    
    /**
     * Returns the REST client for making HTTP requests to Elasticsearch.
     * 
     * @return configured RestClient
     */
    protected static RestClient client();
    
    /**
     * Returns an admin-level REST client with elevated privileges.
     * 
     * @return admin RestClient
     */
    protected static RestClient adminClient();
    
    /**
     * Performs a REST request and returns the response.
     * 
     * @param request HTTP request to execute
     * @return HTTP response
     * @throws IOException on request failure
     */
    protected Response performRequest(Request request) throws IOException;
    
    /**
     * Performs a REST request with the specified method and endpoint.
     * 
     * @param method HTTP method (GET, POST, PUT, DELETE)
     * @param endpoint REST endpoint path
     * @return HTTP response
     * @throws IOException on request failure
     */
    protected Response performRequest(String method, String endpoint) throws IOException;
    
    /**
     * Performs a REST request with method, endpoint, and request body.
     * 
     * @param method HTTP method
     * @param endpoint REST endpoint path
     * @param entity HTTP request body
     * @return HTTP response
     * @throws IOException on request failure
     */
    protected Response performRequest(String method, 
                                    String endpoint, 
                                    HttpEntity entity) throws IOException;
    
    /**
     * Asserts that a REST response has the expected status code.
     * 
     * @param response HTTP response to check
     * @param expectedStatus expected HTTP status code
     */
    protected static void assertResponseStatus(Response response, int expectedStatus);
    
    /**
     * Asserts that a response body contains the expected JSON content.
     * 
     * @param response HTTP response
     * @param expectedContent expected JSON content as map
     */
    protected static void assertResponseContent(Response response, 
                                              Map<String, Object> expectedContent);
    
    /**
     * Parses response body as JSON and returns as Map.
     * 
     * @param response HTTP response with JSON body
     * @return parsed JSON as Map
     * @throws IOException on parsing failure
     */
    protected static Map<String, Object> responseAsMap(Response response) throws IOException;
    
    /**
     * Waits for cluster to reach specified health status via REST API.
     * 
     * @param status health status to wait for ("green", "yellow", "red")
     * @param timeout maximum time to wait
     * @throws IOException on request failure
     */
    protected void ensureHealth(String status, TimeValue timeout) throws IOException;
    
    /**
     * Creates an index via REST API.
     * 
     * @param name index name
     * @throws IOException on request failure
     */
    protected void createIndex(String name) throws IOException;
    
    /**
     * Creates an index with settings and mappings via REST API.
     * 
     * @param name index name
     * @param settings index settings as JSON string
     * @param mappings index mappings as JSON string
     * @throws IOException on request failure
     */
    protected void createIndex(String name, String settings, String mappings) throws IOException;
    
    /**
     * Deletes an index via REST API.
     * 
     * @param name index name
     * @throws IOException on request failure
     */
    protected void deleteIndex(String name) throws IOException;
    
    /**
     * Indexes a document via REST API.
     * 
     * @param index index name
     * @param id document ID
     * @param source document source as JSON string
     * @return indexing response as Map
     * @throws IOException on request failure
     */
    protected Map<String, Object> indexDocument(String index, 
                                               String id, 
                                               String source) throws IOException;
    
    /**
     * Searches for documents via REST API.
     * 
     * @param index index name
     * @param query search query as JSON string
     * @return search response as Map
     * @throws IOException on request failure
     */
    protected Map<String, Object> search(String index, String query) throws IOException;
}

ObjectPath

Utility for navigating JSON response structures in REST tests.

package org.elasticsearch.test.rest;

import java.util.List;
import java.util.Map;

/**
 * Utility for navigating and extracting values from nested JSON structures
 * in REST API responses. Supports dot notation path traversal.
 */
public class ObjectPath {
    
    /**
     * Creates an ObjectPath from a response Map.
     * 
     * @param response parsed JSON response as Map
     * @return ObjectPath for navigation
     */
    public static ObjectPath createFromResponse(Map<String, Object> response);
    
    /**
     * Evaluates a path expression and returns the value.
     * 
     * @param path dot-notation path (e.g., "hits.hits.0._source.title")
     * @return value at the specified path
     * @throws IllegalArgumentException if path doesn't exist
     */
    public <T> T evaluate(String path);
    
    /**
     * Evaluates a path and returns the value, or default if path doesn't exist.
     * 
     * @param path dot-notation path
     * @param defaultValue default value to return if path missing
     * @return value at path or default value
     */
    public <T> T evaluate(String path, T defaultValue);
    
    /**
     * Checks if a path exists in the object structure.
     * 
     * @param path dot-notation path to check
     * @return true if path exists, false otherwise
     */
    public boolean exists(String path);
    
    /**
     * Evaluates a path that should return a List.
     * 
     * @param path dot-notation path
     * @return List value at the specified path
     */
    public List<Object> evaluateArraySize(String path);
    
    /**
     * Gets the size of an array at the specified path.
     * 
     * @param path path to array
     * @return array size
     */
    public int getArraySize(String path);
    
    /**
     * Evaluates multiple paths and returns a Map of path->value.
     * 
     * @param paths array of paths to evaluate
     * @return Map of path to evaluated value
     */
    public Map<String, Object> evaluateMultiple(String... paths);
}

REST Testing Examples

import org.elasticsearch.test.rest.ESRestTestCase;
import org.elasticsearch.test.rest.ObjectPath;

public class MyRestApiTest extends ESRestTestCase {
    
    public void testIndexCreationAndSearch() throws IOException {
        // Create index with custom settings
        String settings = """
            {
                "settings": {
                    "number_of_shards": 1,
                    "number_of_replicas": 0
                },
                "mappings": {
                    "properties": {
                        "title": {"type": "text"},
                        "category": {"type": "keyword"}
                    }
                }
            }""";
            
        Request createRequest = new Request("PUT", "/my-index");
        createRequest.setJsonEntity(settings);
        Response createResponse = performRequest(createRequest);
        assertResponseStatus(createResponse, 200);
        
        // Index a document
        String doc = """
            {
                "title": "Sample Document",
                "category": "test",
                "timestamp": "2023-01-01T00:00:00Z"
            }""";
            
        Map<String, Object> indexResponse = indexDocument("my-index", "1", doc);
        assertEquals("created", indexResponse.get("result"));
        
        // Refresh index
        performRequest("POST", "/my-index/_refresh");
        
        // Search for the document
        String searchQuery = """
            {
                "query": {
                    "match": {
                        "title": "Sample"
                    }
                }
            }""";
            
        Map<String, Object> searchResponse = search("my-index", searchQuery);
        
        // Use ObjectPath to navigate response
        ObjectPath path = ObjectPath.createFromResponse(searchResponse);
        
        assertEquals(1, path.evaluate("hits.total.value"));
        assertEquals("1", path.evaluate("hits.hits.0._id"));
        assertEquals("Sample Document", path.evaluate("hits.hits.0._source.title"));
        assertTrue(path.exists("hits.hits.0._score"));
    }
    
    public void testClusterHealth() throws IOException {
        Response healthResponse = performRequest("GET", "/_cluster/health");
        assertResponseStatus(healthResponse, 200);
        
        Map<String, Object> health = responseAsMap(healthResponse);
        ObjectPath healthPath = ObjectPath.createFromResponse(health);
        
        String status = healthPath.evaluate("status");
        assertThat(status, anyOf(equalTo("green"), equalTo("yellow")));
        
        int numberOfNodes = healthPath.evaluate("number_of_nodes");
        assertThat(numberOfNodes, greaterThan(0));
    }
    
    public void testBulkIndexing() throws IOException {
        String bulkBody = """
            {"index":{"_index":"bulk-test","_id":"1"}}
            {"title":"First Document","value":10}
            {"index":{"_index":"bulk-test","_id":"2"}}
            {"title":"Second Document","value":20}
            """;
            
        Request bulkRequest = new Request("POST", "/_bulk");
        bulkRequest.setJsonEntity(bulkBody);
        bulkRequest.addParameter("refresh", "true");
        
        Response bulkResponse = performRequest(bulkRequest);
        assertResponseStatus(bulkResponse, 200);
        
        Map<String, Object> bulk = responseAsMap(bulkResponse);
        ObjectPath bulkPath = ObjectPath.createFromResponse(bulk);
        
        assertFalse("Bulk should not have errors", bulkPath.evaluate("errors"));
        assertEquals(2, bulkPath.getArraySize("items"));
    }
}

Disruption Testing

Framework for simulating network partitions, service disruptions, and failure scenarios.

NetworkDisruption

Simulation of network failures and partitions.

package org.elasticsearch.test.disruption;

import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.unit.TimeValue;

/**
 * Simulates network disruptions between cluster nodes including
 * partitions, delays, and connection failures.
 */
public class NetworkDisruption implements ServiceDisruptionScheme {
    
    /**
     * Creates a network partition that isolates the specified node.
     * 
     * @param isolatedNode node to isolate from the cluster
     * @param duration duration of the isolation
     */
    public NetworkDisruption(DiscoveryNode isolatedNode, TimeValue duration);
    
    /**
     * Creates a network partition between two sets of nodes.
     * 
     * @param nodeSetA first set of nodes
     * @param nodeSetB second set of nodes  
     * @param duration duration of the partition
     */
    public NetworkDisruption(Set<DiscoveryNode> nodeSetA, 
                           Set<DiscoveryNode> nodeSetB,
                           TimeValue duration);
    
    /**
     * Starts the network disruption.
     */
    @Override
    public void startDisrupting();
    
    /**
     * Stops the network disruption and restores connectivity.
     */
    @Override  
    public void stopDisrupting();
    
    /**
     * Checks if the disruption is currently active.
     * 
     * @return true if disruption is active
     */
    @Override
    public boolean isDisrupting();
    
    /**
     * Sets the network delay to introduce latency.
     * 
     * @param delay network delay duration
     */
    public void setNetworkDelay(TimeValue delay);
    
    /**
     * Sets the packet loss rate for network simulation.
     * 
     * @param lossRate packet loss rate (0.0 to 1.0)
     */
    public void setPacketLossRate(double lossRate);
}

Disruption Testing Examples

import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.disruption.NetworkDisruption;

public class DisruptionTest extends ESIntegTestCase {
    
    public void testNetworkPartition() throws Exception {
        InternalTestCluster cluster = internalCluster();
        cluster.ensureAtLeastNumDataNodes(3);
        
        String masterNode = cluster.getMasterName();
        Set<String> otherNodes = cluster.getNodeNames()
            .stream()
            .filter(name -> !name.equals(masterNode))
            .collect(Collectors.toSet());
        
        // Create network partition isolating master
        NetworkDisruption disruption = new NetworkDisruption(
            cluster.clusterService(masterNode).localNode(),
            TimeValue.timeValueMinutes(1)
        );
        
        cluster.setDisruptionScheme(disruption);
        disruption.startDisrupting();
        
        try {
            // Verify cluster detects partition
            cluster.waitForState(state -> 
                state.nodes().getMasterNode() == null ||
                !state.nodes().getMasterNode().getName().equals(masterNode),
                TimeValue.timeValueSeconds(30)
            );
            
            // Verify operations still work on majority side
            String nonMasterNode = otherNodes.iterator().next();
            Client nonMasterClient = cluster.client(nonMasterNode);
            
            createIndex("partition-test");
            ensureGreen("partition-test");
            
        } finally {
            disruption.stopDisrupting();
            
            // Wait for cluster to recover
            cluster.waitForConsensus(TimeValue.timeValueMinutes(1));
            ensureGreen("partition-test");
        }
    }
    
    public void testSlowNetwork() throws Exception {
        NetworkDisruption disruption = new NetworkDisruption(
            Collections.emptySet(),
            Collections.emptySet(), 
            TimeValue.timeValueMinutes(5)
        );
        
        // Add network delay
        disruption.setNetworkDelay(TimeValue.timeValueSeconds(2));
        
        internalCluster().setDisruptionScheme(disruption);
        disruption.startDisrupting();
        
        try {
            // Operations should still work but be slower
            long startTime = System.currentTimeMillis();
            
            createIndex("slow-network-test");
            ensureYellow("slow-network-test");
            
            long duration = System.currentTimeMillis() - startTime;
            assertThat("Operations should be slower with network delay", 
                      duration, greaterThan(1000L));
                      
        } finally {
            disruption.stopDisrupting();
        }
    }
}

Best Practices

XContent Testing

  • Test all supported XContent formats (JSON, YAML, CBOR, SMILE)
  • Include unknown field testing for forward compatibility
  • Verify field order independence in parsing
  • Test edge cases like empty objects and null values

Query Testing

  • Test query builder serialization round-trips
  • Verify Lucene query generation for all query variants
  • Include malformed query rejection testing
  • Test caching behavior when applicable

REST Testing

  • Use ObjectPath for clean response navigation
  • Test both success and error response scenarios
  • Include proper HTTP status code validation
  • Test with various parameter combinations

Disruption Testing

  • Always restore normal operation in finally blocks
  • Test both partition detection and recovery scenarios
  • Use realistic disruption durations
  • Verify cluster remains functional during disruptions

These specialized testing utilities enable comprehensive validation of Elasticsearch's complex functionality while maintaining test reliability and readability.

Install with Tessl CLI

npx tessl i tessl/maven-org-elasticsearch--elasticsearch-test-framework

docs

assertions-matchers.md

cluster-management.md

core-testing.md

data-generation.md

index.md

mock-implementations.md

specialized-testing.md

tile.json