Skip to content

Commit

Permalink
[TEST] Cover custom sorting and routing in randomized testing (#120584)
Browse files Browse the repository at this point in the history
* Cover custom sorting and routing in randomized testing

* [CI] Auto commit changes from spotless

* fix reindex tests

* fix reindex tests

* refactor classes

* comment

* more refactoring

* more refactoring

* restore tests with static mappings

* reduce diff

* reduce diff

* Restore single-element array removal in synthetic source

* Revert "Restore single-element array removal in synthetic source"

This reverts commit e8e99e1.

* [CI] Auto commit changes from spotless

---------

Co-authored-by: elasticsearchmachine <[email protected]>
  • Loading branch information
kkrik-es and elasticsearchmachine authored Jan 27, 2025
1 parent 2ca2bbf commit 695bf75
Show file tree
Hide file tree
Showing 8 changed files with 279 additions and 223 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.core.CheckedConsumer;
import org.elasticsearch.core.Tuple;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.test.cluster.ElasticsearchCluster;
Expand Down Expand Up @@ -221,44 +220,16 @@ private XContentBuilder createContenderMappings() throws IOException {

public abstract void contenderMappings(XContentBuilder builder) throws IOException;

public void baselineSettings(Settings.Builder builder) {}
public abstract void baselineSettings(Settings.Builder builder);

public void contenderSettings(Settings.Builder builder) {}
public abstract void contenderSettings(Settings.Builder builder);

public void commonSettings(Settings.Builder builder) {}

private Response indexDocuments(
final String dataStreamName,
final CheckedSupplier<List<XContentBuilder>, IOException> documentsSupplier
) throws IOException {
final StringBuilder sb = new StringBuilder();
int id = 0;
for (var document : documentsSupplier.get()) {
sb.append(Strings.format("{ \"create\": { \"_id\" : \"%d\" } }", id)).append("\n");
sb.append(Strings.toString(document)).append("\n");
id++;
}
var request = new Request("POST", "/" + dataStreamName + "/_bulk");
request.setJsonEntity(sb.toString());
request.addParameter("refresh", "true");
return client.performRequest(request);
}

public Response indexBaselineDocuments(final CheckedSupplier<List<XContentBuilder>, IOException> documentsSupplier) throws IOException {
return indexDocuments(getBaselineDataStreamName(), documentsSupplier);
}

public Response indexContenderDocuments(final CheckedSupplier<List<XContentBuilder>, IOException> documentsSupplier)
throws IOException {
return indexDocuments(getContenderDataStreamName(), documentsSupplier);
}

public Tuple<Response, Response> indexDocuments(
final CheckedSupplier<List<XContentBuilder>, IOException> baselineSupplier,
final CheckedSupplier<List<XContentBuilder>, IOException> contenderSupplier
) throws IOException {
return new Tuple<>(indexBaselineDocuments(baselineSupplier), indexContenderDocuments(contenderSupplier));
}
public abstract void indexDocuments(
CheckedSupplier<List<XContentBuilder>, IOException> baselineSupplier,
CheckedSupplier<List<XContentBuilder>, IOException> contenderSupplier
) throws IOException;

public Response queryBaseline(final SearchSourceBuilder search) throws IOException {
return query(search, this::getBaselineDataStreamName);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.logsdb.qa;

import org.elasticsearch.common.CheckedSupplier;
import org.elasticsearch.common.Strings;
import org.elasticsearch.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
* Challenge test that uses bulk indexing for both baseline and contender sides.
* We index same documents into an index with standard index mode and an index with logsdb index mode.
* Then we verify that results of common operations are the same modulo knows differences like synthetic source
* modifications.
*/
public class BulkChallengeRestIT extends StandardVersusLogsIndexModeChallengeRestIT {

public BulkChallengeRestIT() {}

protected BulkChallengeRestIT(DataGenerationHelper dataGenerationHelper) {
super(dataGenerationHelper);
}

@Override
public void indexDocuments(
final CheckedSupplier<List<XContentBuilder>, IOException> baselineSupplier,
final CheckedSupplier<List<XContentBuilder>, IOException> contenderSupplier
) throws IOException {
var contenderResponseEntity = indexContenderDocuments(contenderSupplier);
indexBaselineDocuments(baselineSupplier, contenderResponseEntity);
}

private Map<String, Object> indexContenderDocuments(final CheckedSupplier<List<XContentBuilder>, IOException> documentsSupplier)
throws IOException {
final StringBuilder sb = new StringBuilder();
int id = 0;
for (var document : documentsSupplier.get()) {
if (autoGenerateId()) {
sb.append("{ \"create\": { } }\n");
} else {
sb.append(Strings.format("{ \"create\": { \"_id\" : \"%d\" } }\n", id));
}
sb.append(Strings.toString(document)).append("\n");
id++;
}
return performBulkRequest(sb.toString(), false);
}

@SuppressWarnings("unchecked")
private void indexBaselineDocuments(
final CheckedSupplier<List<XContentBuilder>, IOException> documentsSupplier,
final Map<String, Object> contenderResponseEntity
) throws IOException {
final StringBuilder sb = new StringBuilder();
int id = 0;
final List<Map<String, Object>> items = (List<Map<String, Object>>) contenderResponseEntity.get("items");
for (var document : documentsSupplier.get()) {
if (autoGenerateId()) {
var contenderId = ((Map<String, Object>) items.get(id).get("create")).get("_id");
sb.append(Strings.format("{ \"create\": { \"_id\" : \"%s\" } }\n", contenderId));
} else {
sb.append(Strings.format("{ \"create\": { \"_id\" : \"%d\" } }\n", id));
}
sb.append(Strings.toString(document)).append("\n");
id++;
}
performBulkRequest(sb.toString(), true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@

import org.elasticsearch.common.settings.Settings;

public class StandardVersusLogsIndexModeRandomDataDynamicMappingChallengeRestIT extends
StandardVersusLogsIndexModeRandomDataChallengeRestIT {
public StandardVersusLogsIndexModeRandomDataDynamicMappingChallengeRestIT() {
public class BulkDynamicMappingChallengeRestIT extends BulkChallengeRestIT {
public BulkDynamicMappingChallengeRestIT() {
super(new DataGenerationHelper(builder -> builder.withFullyDynamicMapping(true)));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.logsdb.qa;

import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.FormatNames;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentFactory;

import java.io.IOException;
import java.time.Instant;

/**
* This test uses simple mapping and document structure in order to allow easier debugging of the test itself.
*/
public class BulkStaticMappingChallengeRestIT extends BulkChallengeRestIT {
public BulkStaticMappingChallengeRestIT() {}

@Override
public void baselineMappings(XContentBuilder builder) throws IOException {
if (fullyDynamicMapping == false) {
builder.startObject()
.startObject("properties")

.startObject("@timestamp")
.field("type", "date")
.endObject()

.startObject("host.name")
.field("type", "keyword")
.field("ignore_above", randomIntBetween(1000, 1200))
.endObject()

.startObject("message")
.field("type", "keyword")
.field("ignore_above", randomIntBetween(1000, 1200))
.endObject()

.startObject("method")
.field("type", "keyword")
.field("ignore_above", randomIntBetween(1000, 1200))
.endObject()

.startObject("memory_usage_bytes")
.field("type", "long")
.field("ignore_malformed", randomBoolean())
.endObject()

.endObject()

.endObject();
} else {
// We want dynamic mapping, but we need host.name to be a keyword instead of text to support aggregations.
builder.startObject()
.startObject("properties")

.startObject("host.name")
.field("type", "keyword")
.field("ignore_above", randomIntBetween(1000, 1200))
.endObject()

.endObject()
.endObject();
}
}

@Override
public void contenderMappings(XContentBuilder builder) throws IOException {
builder.startObject();
builder.field("subobjects", false);

if (fullyDynamicMapping == false) {
builder.startObject("properties")

.startObject("@timestamp")
.field("type", "date")
.endObject()

.startObject("host.name")
.field("type", "keyword")
.field("ignore_above", randomIntBetween(1000, 1200))
.endObject()

.startObject("message")
.field("type", "keyword")
.field("ignore_above", randomIntBetween(1000, 1200))
.endObject()

.startObject("method")
.field("type", "keyword")
.field("ignore_above", randomIntBetween(1000, 1200))
.endObject()

.startObject("memory_usage_bytes")
.field("type", "long")
.field("ignore_malformed", randomBoolean())
.endObject()

.endObject();
}

builder.endObject();
}

@Override
protected XContentBuilder generateDocument(final Instant timestamp) throws IOException {
return XContentFactory.jsonBuilder()
.startObject()
.field("@timestamp", DateFormatter.forPattern(FormatNames.STRICT_DATE_OPTIONAL_TIME.getName()).format(timestamp))
.field("host.name", randomFrom("foo", "bar", "baz"))
.field("message", randomFrom("a message", "another message", "still another message", "one more message"))
.field("method", randomFrom("put", "post", "get"))
.field("memory_usage_bytes", randomLongBetween(1000, 2000))
.endObject();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* This test compares behavior of a standard mode data stream and a logsdb data stream using stored source.
* There should be no differences between such two data streams.
*/
public class StandardVersusLogsStoredSourceChallengeRestIT extends StandardVersusLogsIndexModeRandomDataChallengeRestIT {
public class BulkStoredSourceChallengeRestIT extends BulkChallengeRestIT {
@Override
public void contenderSettings(Settings.Builder builder) {
super.contenderSettings(builder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
package org.elasticsearch.xpack.logsdb.qa;

import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.common.CheckedSupplier;
import org.elasticsearch.common.Strings;
import org.elasticsearch.xcontent.XContentBuilder;

import java.io.IOException;
Expand All @@ -18,9 +18,29 @@

import static org.hamcrest.Matchers.equalTo;

public abstract class ReindexChallengeRestIT extends StandardVersusLogsIndexModeRandomDataChallengeRestIT {
public abstract class ReindexChallengeRestIT extends StandardVersusLogsIndexModeChallengeRestIT {

@Override
public Response indexContenderDocuments(CheckedSupplier<List<XContentBuilder>, IOException> documentsSupplier) throws IOException {
public void indexDocuments(
final CheckedSupplier<List<XContentBuilder>, IOException> baselineSupplier,
final CheckedSupplier<List<XContentBuilder>, IOException> contencontenderSupplierderSupplier
) throws IOException {
indexBaselineDocuments(baselineSupplier);
indexContenderDocuments();
}

private void indexBaselineDocuments(final CheckedSupplier<List<XContentBuilder>, IOException> documentsSupplier) throws IOException {
final StringBuilder sb = new StringBuilder();
int id = 0;
for (var document : documentsSupplier.get()) {
sb.append(Strings.format("{ \"create\": { \"_id\" : \"%d\" } }\n", id));
sb.append(Strings.toString(document)).append("\n");
id++;
}
performBulkRequest(sb.toString(), true);
}

private void indexContenderDocuments() throws IOException {
var reindexRequest = new Request("POST", "/_reindex?refresh=true");
reindexRequest.setJsonEntity(String.format(Locale.ROOT, """
{
Expand All @@ -38,7 +58,5 @@ public Response indexContenderDocuments(CheckedSupplier<List<XContentBuilder>, I

var body = entityAsMap(response);
assertThat("encountered failures when performing reindex:\n " + body, body.get("failures"), equalTo(List.of()));

return response;
}
}
Loading

0 comments on commit 695bf75

Please sign in to comment.