diff --git a/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/transport/TransportVersionValidationFuncTest.groovy b/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/transport/TransportVersionValidationFuncTest.groovy index 3778ea3e62914..36be4c4d94bff 100644 --- a/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/transport/TransportVersionValidationFuncTest.groovy +++ b/build-tools-internal/src/integTest/groovy/org/elasticsearch/gradle/internal/transport/TransportVersionValidationFuncTest.groovy @@ -223,10 +223,33 @@ class TransportVersionValidationFuncTest extends AbstractTransportVersionFuncTes def "unreferable definitions can have primary ids that are patches"() { given: - unreferableTransportVersion("initial_10.0.1", "10000001") + unreferableTransportVersion("initial_7.0.1", "7000001") when: def result = gradleRunner(":myserver:validateTransportVersionResources").build() then: result.task(":myserver:validateTransportVersionResources").outcome == TaskOutcome.SUCCESS } + + def "highest id in an referable definition should exist in an upper bounds file"() { + given: + referableAndReferencedTransportVersion("some_tv", "10000000") + when: + def result = validateResourcesFails() + then: + assertValidateResourcesFailure(result, "Transport version definition file " + + "[myserver/src/main/resources/transport/definitions/referable/some_tv.csv] " + + "has the highest transport version id [10000000] but is not present in any upper bounds files") + } + + def "highest id in an unreferable definition should exist in an upper bounds file"() { + given: + unreferableTransportVersion("initial_10.0.0", "10000000") + when: + def result = validateResourcesFails() + then: + // TODO: this should be _unreferable_ in the error message, but will require some rework + assertValidateResourcesFailure(result, "Transport version definition file " + + "[myserver/src/main/resources/transport/definitions/referable/initial_10.0.0.csv] " + + "has the highest transport version id [10000000] but is not present in any upper bounds files") + } } diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/transport/ValidateTransportVersionResourcesTask.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/transport/ValidateTransportVersionResourcesTask.java index 44e9bde8352f2..222683d4514e5 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/transport/ValidateTransportVersionResourcesTask.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/transport/ValidateTransportVersionResourcesTask.java @@ -83,6 +83,8 @@ public void validateTransportVersions() throws IOException { for (var upperBound : upperBounds.values()) { validateUpperBound(upperBound, allDefinitions, idsByBase); } + + validateLargestIdIsUsed(upperBounds, allDefinitions); } private Map collectAllDefinitions( @@ -253,6 +255,27 @@ private void validateBase(int base, List ids) { } } + private void validateLargestIdIsUsed( + Map upperBounds, + Map allDefinitions + ) { + // first id is always the highest within a definition, and validated earlier + // note we use min instead of max because the id comparator is in descending order + var highestDefinition = allDefinitions.values().stream().min(Comparator.comparing(d -> d.ids().get(0))).get(); + var highestId = highestDefinition.ids().get(0); + + for (var upperBound : upperBounds.values()) { + if (upperBound.id().equals(highestId)) { + return; + } + } + + throwDefinitionFailure( + highestDefinition, + "has the highest transport version id [" + highestId + "] but is not present in any upper bounds files" + ); + } + private void throwDefinitionFailure(TransportVersionDefinition definition, String message) { Path relativePath = getResources().get().getReferableDefinitionRepositoryPath(definition); throw new IllegalStateException("Transport version definition file [" + relativePath + "] " + message);