Skip to content

Commit 959b713

Browse files
committed
Merge remote-tracking branch 'upstream/main' into fix_testProcessMultipleChunks
2 parents fc08a60 + eceb178 commit 959b713

File tree

928 files changed

+8856
-5512
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

928 files changed

+8856
-5512
lines changed

REST_API_COMPATIBILITY.md

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,11 @@ if (request.getRestApiVersion() == RestApiVersion.V_7 && request.hasParam("limit
154154

155155
The above code checks the request's compatible version and if the request has the parameter in question. In this case the deprecation warning is not automatic and requires the developer to manually log the warning. `request.param` is also required since it consumes the value as to avoid the error of unconsumed parameters.
156156

157-
### Testing
157+
### Testing Backwards Compatibility
158158

159-
The primary means of testing compatibility is via the prior major version's YAML REST tests. The build system will download the latest prior version of the YAML rest tests and execute them against the current cluster version. Prior to execution the tests will be transformed by injecting the correct headers to enable compatibility as well as other custom changes to the tests to allow the tests to pass. These customizations are configured via the build.gradle and happen just prior to test execution. Since the compatibility tests are manipulated version of the tests stored in Github (via the past major version), it is important to find the local (on disk) version for troubleshooting compatibility tests.
159+
The primary means of testing compatibility is via the prior major version's YAML REST tests. The build system will download the latest prior version of the YAML rest tests and execute them against the current cluster version. For example if you are testing main versioned as 9.0.0 the build system will download the yaml tests in the 8.x branch and execute those against the current cluster version for 9.0.0.
160+
161+
Prior to execution the tests will be transformed by injecting the correct headers to enable compatibility as well as other custom changes to the tests to allow the tests to pass. These customizations are configured via the build.gradle and happen just prior to test execution. Since the compatibility tests are manipulated version of the tests stored in Github (via the past major version), it is important to find the local (on disk) version for troubleshooting compatibility tests.
160162

161163
The tests are wired into the `check` task, so that is the easiest way to test locally prior to committing. More specifically the task is called `yamlRestCompatTest`. These behave nearly identical to it's non-compat `yamlRestTest` task. The only variance is that the tests are sourced from the prior version branch and the tests go through a transformation phase before execution. The transformation task is `yamlRestCompatTestTransform`.
162164

@@ -170,6 +172,36 @@ Since these are a variation of backward compatibility testing, the entire suite
170172

171173
In some cases the prior version of the YAML REST tests are not sufficient to fully test changes. This can happen when the prior version has insufficient test coverage. In those cases, you can simply add more testing to the prior version or you can add custom REST tests that will run along side of the other compatibility tests. These custom tests can be found in the `yamlRestCompatTest` sourceset. Custom REST tests for compatibility will not be modified prior to execution, so the correct headers need to be manually added.
172174

175+
#### Breaking Changes
176+
177+
It is possible to be in a state where you have intentionally made a breaking change and the compatibility tests will fail irrespective of checks for `skip` or `requires` cluster or test features in the current version such as 9.0.0. In this state, assuming the breaking changes are reasonable and agreed upon by the breaking change committee, the correct behavior is to skip the test in the `build.gradle` in 9.0.0. For example, if you make a breaking change that causes the `range/20_synthetic_source/Date range` to break then this test can be disabled temporarily in this file `rest-api-spec/build.gradle` like within this snippet:
178+
179+
```groovy
180+
tasks.named("yamlRestCompatTestTransform").configure({task ->
181+
task.skipTest("range/20_synthetic_source/Date range", "date range breaking change causes tests to produce incorrect values for compatibility")
182+
task.skipTest("indices.sort/10_basic/Index Sort", "warning does not exist for compatibility")
183+
task.skipTest("search/330_fetch_fields/Test search rewrite", "warning does not exist for compatibility")
184+
task.skipTestsByFilePattern("indices.create/synthetic_source*.yml", "@UpdateForV9 -> tests do not pass after bumping API version to 9 [ES-9597]")
185+
})
186+
```
187+
188+
When skipping a test temporarily in 9.0.0, we have to implement the proper `skip` and `requires` conditions to previous branches, such as 8.latest. After these conditions are implemented in 8.latest, you can re-enable the test in 9.0.0 by removing the `skipTest` condition.
189+
190+
The team implementing the changes can decide how to clean up or modify tests based on how breaking changes were backported. e.g.:
191+
192+
In 8.latest:
193+
194+
* Add `skip` / `requires` conditions to existing tests that check the old behavior. This prevents those tests from failing during backward compatibility or upgrade testing from 8.latest to 9.0.0
195+
196+
In 9.0.0:
197+
198+
* Add `requires` conditions for new tests that validate the updated API or output format
199+
* Add `skip` conditions for older tests that would break in 9.0.0
200+
201+
#### Test Features
202+
203+
Both cluster and test features exist. Cluster features are meant for new capability and test features can specifically be used to gate and manage `skip` and `requires` yaml test operations. For more information, see [Versioning.md](docs/internal/Versioning.md#cluster-features). When backporting and using these features they can not overlap in name and must be consistent when backported so that clusters built with these features are compatible.
204+
173205
### Developer's workflow
174206

175207
There should not be much, if any, deviation in a developers normal workflow to introduce and back-port changes. Changes should be applied in main, then back ported as needed.

benchmarks/src/main/java/org/elasticsearch/benchmark/compute/operator/EvalBenchmark.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.elasticsearch.compute.data.DoubleVector;
2525
import org.elasticsearch.compute.data.LongBlock;
2626
import org.elasticsearch.compute.data.LongVector;
27+
import org.elasticsearch.compute.data.OrdinalBytesRefVector;
2728
import org.elasticsearch.compute.data.Page;
2829
import org.elasticsearch.compute.operator.DriverContext;
2930
import org.elasticsearch.compute.operator.EvalOperator;
@@ -127,7 +128,9 @@ static void selfTest() {
127128
"mv_min_ascending",
128129
"rlike",
129130
"to_lower",
130-
"to_upper" }
131+
"to_lower_ords",
132+
"to_upper",
133+
"to_upper_ords" }
131134
)
132135
public String operation;
133136

@@ -235,12 +238,12 @@ private static EvalOperator.ExpressionEvaluator evaluator(String operation) {
235238
RLike rlike = new RLike(Source.EMPTY, keywordField, new RLikePattern(".ar"));
236239
yield EvalMapper.toEvaluator(FOLD_CONTEXT, rlike, layout(keywordField)).get(driverContext);
237240
}
238-
case "to_lower" -> {
241+
case "to_lower", "to_lower_ords" -> {
239242
FieldAttribute keywordField = keywordField();
240243
ToLower toLower = new ToLower(Source.EMPTY, keywordField, configuration());
241244
yield EvalMapper.toEvaluator(FOLD_CONTEXT, toLower, layout(keywordField)).get(driverContext);
242245
}
243-
case "to_upper" -> {
246+
case "to_upper", "to_upper_ords" -> {
244247
FieldAttribute keywordField = keywordField();
245248
ToUpper toUpper = new ToUpper(Source.EMPTY, keywordField, configuration());
246249
yield EvalMapper.toEvaluator(FOLD_CONTEXT, toUpper, layout(keywordField)).get(driverContext);
@@ -414,13 +417,15 @@ private static void checkExpected(String operation, Page actual) {
414417
}
415418
}
416419
}
417-
case "to_lower" -> checkBytes(operation, actual, new BytesRef[] { new BytesRef("foo"), new BytesRef("bar") });
418-
case "to_upper" -> checkBytes(operation, actual, new BytesRef[] { new BytesRef("FOO"), new BytesRef("BAR") });
420+
case "to_lower" -> checkBytes(operation, actual, false, new BytesRef[] { new BytesRef("foo"), new BytesRef("bar") });
421+
case "to_lower_ords" -> checkBytes(operation, actual, true, new BytesRef[] { new BytesRef("foo"), new BytesRef("bar") });
422+
case "to_upper" -> checkBytes(operation, actual, false, new BytesRef[] { new BytesRef("FOO"), new BytesRef("BAR") });
423+
case "to_upper_ords" -> checkBytes(operation, actual, true, new BytesRef[] { new BytesRef("FOO"), new BytesRef("BAR") });
419424
default -> throw new UnsupportedOperationException(operation);
420425
}
421426
}
422427

423-
private static void checkBytes(String operation, Page actual, BytesRef[] expectedVals) {
428+
private static void checkBytes(String operation, Page actual, boolean expectOrds, BytesRef[] expectedVals) {
424429
BytesRef scratch = new BytesRef();
425430
BytesRefVector v = actual.<BytesRefBlock>getBlock(1).asVector();
426431
for (int i = 0; i < BLOCK_LENGTH; i++) {
@@ -430,6 +435,15 @@ private static void checkBytes(String operation, Page actual, BytesRef[] expecte
430435
throw new AssertionError("[" + operation + "] expected [" + expected + "] but was [" + b + "]");
431436
}
432437
}
438+
if (expectOrds) {
439+
if (v.asOrdinals() == null) {
440+
throw new IllegalArgumentException("expected ords but got " + v);
441+
}
442+
} else {
443+
if (v.asOrdinals() != null) {
444+
throw new IllegalArgumentException("expected non-ords but got " + v);
445+
}
446+
}
433447
}
434448

435449
private static Page page(String operation) {
@@ -510,6 +524,16 @@ private static Page page(String operation) {
510524
}
511525
yield new Page(builder.build().asBlock());
512526
}
527+
case "to_lower_ords", "to_upper_ords" -> {
528+
var bytes = blockFactory.newBytesRefVectorBuilder(BLOCK_LENGTH);
529+
bytes.appendBytesRef(new BytesRef("foo"));
530+
bytes.appendBytesRef(new BytesRef("bar"));
531+
var ordinals = blockFactory.newIntVectorFixedBuilder(BLOCK_LENGTH);
532+
for (int i = 0; i < BLOCK_LENGTH; i++) {
533+
ordinals.appendInt(i % 2);
534+
}
535+
yield new Page(new OrdinalBytesRefVector(ordinals.build(), bytes.build()).asBlock());
536+
}
513537
default -> throw new UnsupportedOperationException();
514538
};
515539
}

build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/fixtures/AbstractGradleInternalPluginFuncTest.groovy

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,22 @@ abstract class AbstractGradleInternalPluginFuncTest extends AbstractJavaGradleFu
2020
plugins {
2121
id 'elasticsearch.java-toolchain'
2222
}
23+
24+
toolchainManagement {
25+
jvm {
26+
javaRepositories {
27+
repository('bundledOracleOpendJdk') {
28+
resolverClass = org.elasticsearch.gradle.internal.toolchain.OracleOpenJdkToolchainResolver
29+
}
30+
repository('adoptiumJdks') {
31+
resolverClass = org.elasticsearch.gradle.internal.toolchain.AdoptiumJdkToolchainResolver
32+
}
33+
repository('archivedOracleJdks') {
34+
resolverClass = org.elasticsearch.gradle.internal.toolchain.ArchivedOracleJdkToolchainResolver
35+
}
36+
}
37+
}
38+
}
2339
""" + settingsFile.text
2440

2541
buildFile << """

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ConcatFilesTask.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
*/
99
package org.elasticsearch.gradle.internal;
1010

11+
import com.google.common.collect.Iterables;
12+
1113
import org.gradle.api.DefaultTask;
1214
import org.gradle.api.file.FileCollection;
1315
import org.gradle.api.tasks.Input;
@@ -85,7 +87,7 @@ public void setAdditionalLines(List<String> additionalLines) {
8587
public void concatFiles() throws IOException {
8688
if (getHeaderLine() != null) {
8789
getTarget().getParentFile().mkdirs();
88-
Files.write(getTarget().toPath(), (getHeaderLine() + '\n').getBytes(StandardCharsets.UTF_8));
90+
Files.writeString(getTarget().toPath(), getHeaderLine() + '\n');
8991
}
9092

9193
// To remove duplicate lines
@@ -95,11 +97,12 @@ public void concatFiles() throws IOException {
9597
uniqueLines.addAll(Files.readAllLines(f.toPath(), StandardCharsets.UTF_8));
9698
}
9799
}
98-
Files.write(getTarget().toPath(), uniqueLines, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
99-
100-
for (String additionalLine : additionalLines) {
101-
Files.write(getTarget().toPath(), (additionalLine + '\n').getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
102-
}
100+
Files.write(
101+
getTarget().toPath(),
102+
Iterables.concat(uniqueLines, additionalLines),
103+
StandardCharsets.UTF_8,
104+
StandardOpenOption.APPEND
105+
);
103106
}
104107

105108
}

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DependenciesInfoTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public void generateDependenciesInfo() throws IOException {
155155
output.append(dep.getGroup() + ":" + dep.getName() + "," + dep.getVersion() + "," + url + "," + licenseType + "\n");
156156
}
157157

158-
Files.write(outputFile.toPath(), output.toString().getBytes("UTF-8"), StandardOpenOption.CREATE);
158+
Files.writeString(outputFile.toPath(), output.toString(), StandardOpenOption.CREATE);
159159
}
160160

161161
@Input

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/doc/RestTestsFromDocSnippetTask.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.io.File;
2525
import java.io.IOException;
2626
import java.io.PrintWriter;
27+
import java.nio.charset.StandardCharsets;
2728
import java.nio.file.Files;
2829
import java.nio.file.Path;
2930
import java.util.ArrayList;
@@ -440,7 +441,7 @@ private PrintWriter setupCurrent(Snippet test) {
440441
// Now setup the writer
441442
try {
442443
Files.createDirectories(dest.getParent());
443-
current = new PrintWriter(dest.toFile(), "UTF-8");
444+
current = new PrintWriter(dest.toFile(), StandardCharsets.UTF_8);
444445
return current;
445446
} catch (IOException e) {
446447
throw new RuntimeException(e);

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/FilePermissionsTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public void checkInvalidPermissions() throws IOException {
106106
}
107107

108108
outputMarker.getParentFile().mkdirs();
109-
Files.write(outputMarker.toPath(), "done".getBytes("UTF-8"));
109+
Files.writeString(outputMarker.toPath(), "done");
110110
}
111111

112112
@OutputFile

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ForbiddenPatternsTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public void checkInvalidPatterns() throws IOException {
135135

136136
File outputMarker = getOutputMarker();
137137
outputMarker.getParentFile().mkdirs();
138-
Files.write(outputMarker.toPath(), "done".getBytes(StandardCharsets.UTF_8));
138+
Files.writeString(outputMarker.toPath(), "done");
139139
}
140140

141141
@OutputFile

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ThirdPartyAuditTask.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ private String runForbiddenAPIsCli() throws IOException {
364364
}
365365
final String forbiddenApisOutput;
366366
try (ByteArrayOutputStream outputStream = errorOut) {
367-
forbiddenApisOutput = outputStream.toString(StandardCharsets.UTF_8.name());
367+
forbiddenApisOutput = outputStream.toString(StandardCharsets.UTF_8);
368368
}
369369
if (EXPECTED_EXIT_CODES.contains(result.getExitValue()) == false) {
370370
throw new IllegalStateException("Forbidden APIs cli failed: " + forbiddenApisOutput);
@@ -397,7 +397,7 @@ private Set<String> runJdkJarHellCheck() throws IOException {
397397
}
398398
final String jdkJarHellCheckList;
399399
try (ByteArrayOutputStream outputStream = standardOut) {
400-
jdkJarHellCheckList = outputStream.toString(StandardCharsets.UTF_8.name());
400+
jdkJarHellCheckList = outputStream.toString(StandardCharsets.UTF_8);
401401
}
402402
return new TreeSet<>(Arrays.asList(jdkJarHellCheckList.split("\\r?\\n")));
403403
}

build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/ConcatFilesTaskTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ public void testConcatenationWithUnique() throws IOException {
6060
file2.getParentFile().mkdirs();
6161
file1.createNewFile();
6262
file2.createNewFile();
63-
Files.write(file1.toPath(), ("Hello" + System.lineSeparator() + "Hello").getBytes(StandardCharsets.UTF_8));
64-
Files.write(file2.toPath(), ("Hello" + System.lineSeparator() + "नमस्ते").getBytes(StandardCharsets.UTF_8));
63+
Files.writeString(file1.toPath(), "Hello" + System.lineSeparator() + "Hello");
64+
Files.writeString(file2.toPath(), "Hello" + System.lineSeparator() + "नमस्ते");
6565

6666
concatFilesTask.setFiles(project.fileTree(file1.getParentFile().getParentFile()));
6767

0 commit comments

Comments
 (0)