Skip to content

Commit

Permalink
Remove released vs unreleased distinction from VersionUtils
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-vieira committed Dec 5, 2024
1 parent fd81c51 commit 6764887
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 424 deletions.
41 changes: 2 additions & 39 deletions server/src/test/java/org/elasticsearch/VersionTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ public void testParseVersion() {
}

public void testAllVersionsMatchId() throws Exception {
final Set<Version> releasedVersions = new HashSet<>(VersionUtils.allReleasedVersions());
final Set<Version> unreleasedVersions = new HashSet<>(VersionUtils.allUnreleasedVersions());
final Set<Version> versions = new HashSet<>(VersionUtils.allVersions());
Map<String, Version> maxBranchVersions = new HashMap<>();
for (java.lang.reflect.Field field : Version.class.getFields()) {
if (field.getName().matches("_ID")) {
Expand All @@ -195,43 +194,15 @@ public void testAllVersionsMatchId() throws Exception {

Version v = (Version) versionConstant.get(null);
logger.debug("Checking {}", v);
if (field.getName().endsWith("_UNRELEASED")) {
assertTrue(unreleasedVersions.contains(v));
} else {
assertTrue(releasedVersions.contains(v));
}
assertTrue(versions.contains(v));
assertEquals("Version id " + field.getName() + " does not point to " + constantName, v, Version.fromId(versionId));
assertEquals("Version " + constantName + " does not have correct id", versionId, v.id);
String number = v.toString();
assertEquals("V_" + number.replace('.', '_'), constantName);

// only the latest version for a branch should be a snapshot (ie unreleased)
String branchName = "" + v.major + "." + v.minor;
Version maxBranchVersion = maxBranchVersions.get(branchName);
if (maxBranchVersion == null) {
maxBranchVersions.put(branchName, v);
} else if (v.after(maxBranchVersion)) {
if (v == Version.CURRENT) {
// Current is weird - it counts as released even though it shouldn't.
continue;
}
assertFalse(
"Version " + maxBranchVersion + " cannot be a snapshot because version " + v + " exists",
VersionUtils.allUnreleasedVersions().contains(maxBranchVersion)
);
maxBranchVersions.put(branchName, v);
}
}
}
}

public static void assertUnknownVersion(Version version) {
assertFalse(
"Version " + version + " has been releaed don't use a new instance of this version",
VersionUtils.allReleasedVersions().contains(version)
);
}

public void testIsCompatible() {
assertTrue(isCompatible(Version.CURRENT, Version.CURRENT.minimumCompatibilityVersion()));
assertFalse(isCompatible(Version.V_7_0_0, Version.V_8_0_0));
Expand Down Expand Up @@ -279,14 +250,6 @@ public boolean isCompatible(Version left, Version right) {
return result;
}

// This exists because 5.1.0 was never released due to a mistake in the release process.
// This verifies that we never declare the version as "released" accidentally.
// It would never pass qa tests later on, but those come very far in the build and this is quick to check now.
public void testUnreleasedVersion() {
Version VERSION_5_1_0_UNRELEASED = Version.fromString("5.1.0");
VersionTests.assertUnknownVersion(VERSION_5_1_0_UNRELEASED);
}

public void testIllegalMinorAndPatchNumbers() {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> Version.fromString("8.2.999"));
assertThat(
Expand Down
1 change: 0 additions & 1 deletion test/framework/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ tasks.named("thirdPartyAudit").configure {
tasks.named("test").configure {
systemProperty 'tests.gradle_index_compat_versions', buildParams.bwcVersions.indexCompatible.join(',')
systemProperty 'tests.gradle_wire_compat_versions', buildParams.bwcVersions.wireCompatible.join(',')
systemProperty 'tests.gradle_unreleased_versions', buildParams.bwcVersions.unreleased.join(',')
}

tasks.register("integTest", Test) {
Expand Down
139 changes: 11 additions & 128 deletions test/framework/src/main/java/org/elasticsearch/test/VersionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,132 +12,15 @@
import org.elasticsearch.Build;
import org.elasticsearch.Version;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.Tuple;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/** Utilities for selecting versions in tests */
public class VersionUtils {

/**
* Sort versions that have backwards compatibility guarantees from
* those that don't. Doesn't actually check whether or not the versions
* are released, instead it relies on gradle to have already checked
* this which it does in {@code :core:verifyVersions}. So long as the
* rules here match up with the rules in gradle then this should
* produce sensible results.
* @return a tuple containing versions with backwards compatibility
* guarantees in v1 and versions without the guranteees in v2
*/
static Tuple<List<Version>, List<Version>> resolveReleasedVersions(Version current, Class<?> versionClass) {
// group versions into major version
Map<Integer, List<Version>> majorVersions = Version.getDeclaredVersions(versionClass)
.stream()
.collect(Collectors.groupingBy(v -> (int) v.major));
// this breaks b/c 5.x is still in version list but master doesn't care about it!
// assert majorVersions.size() == 2;
// TODO: remove oldVersions, we should only ever have 2 majors in Version
List<List<Version>> oldVersions = splitByMinor(majorVersions.getOrDefault((int) current.major - 2, Collections.emptyList()));
List<List<Version>> previousMajor = splitByMinor(majorVersions.get((int) current.major - 1));
List<List<Version>> currentMajor = splitByMinor(majorVersions.get((int) current.major));

List<Version> unreleasedVersions = new ArrayList<>();
final List<List<Version>> stableVersions;
if (currentMajor.size() == 1) {
// on master branch
stableVersions = previousMajor;
// remove current
moveLastToUnreleased(currentMajor, unreleasedVersions);
} else {
// on a stable or release branch, ie N.x
stableVersions = currentMajor;
// remove the next maintenance bugfix
moveLastToUnreleased(previousMajor, unreleasedVersions);
}

// remove next minor
Version lastMinor = moveLastToUnreleased(stableVersions, unreleasedVersions);
if (lastMinor.revision == 0) {
if (stableVersions.get(stableVersions.size() - 1).size() == 1) {
// a minor is being staged, which is also unreleased
moveLastToUnreleased(stableVersions, unreleasedVersions);
}
// remove the next bugfix
if (stableVersions.isEmpty() == false) {
moveLastToUnreleased(stableVersions, unreleasedVersions);
}
}

// If none of the previous major was released, then the last minor and bugfix of the old version was not released either.
if (previousMajor.isEmpty()) {
assert currentMajor.isEmpty() : currentMajor;
// minor of the old version is being staged
moveLastToUnreleased(oldVersions, unreleasedVersions);
// bugix of the old version is also being staged
moveLastToUnreleased(oldVersions, unreleasedVersions);
}
List<Version> releasedVersions = Stream.of(oldVersions, previousMajor, currentMajor)
.flatMap(List::stream)
.flatMap(List::stream)
.collect(Collectors.toList());
Collections.sort(unreleasedVersions); // we add unreleased out of order, so need to sort here
return new Tuple<>(Collections.unmodifiableList(releasedVersions), Collections.unmodifiableList(unreleasedVersions));
}

// split the given versions into sub lists grouped by minor version
private static List<List<Version>> splitByMinor(List<Version> versions) {
Map<Integer, List<Version>> byMinor = versions.stream().collect(Collectors.groupingBy(v -> (int) v.minor));
return byMinor.entrySet().stream().sorted(Map.Entry.comparingByKey()).map(Map.Entry::getValue).collect(Collectors.toList());
}

// move the last version of the last minor in versions to the unreleased versions
private static Version moveLastToUnreleased(List<List<Version>> versions, List<Version> unreleasedVersions) {
List<Version> lastMinor = new ArrayList<>(versions.get(versions.size() - 1));
Version lastVersion = lastMinor.remove(lastMinor.size() - 1);
if (lastMinor.isEmpty()) {
versions.remove(versions.size() - 1);
} else {
versions.set(versions.size() - 1, lastMinor);
}
unreleasedVersions.add(lastVersion);
return lastVersion;
}

private static final List<Version> RELEASED_VERSIONS;
private static final List<Version> UNRELEASED_VERSIONS;
private static final List<Version> ALL_VERSIONS;

static {
Tuple<List<Version>, List<Version>> versions = resolveReleasedVersions(Version.CURRENT, Version.class);
RELEASED_VERSIONS = versions.v1();
UNRELEASED_VERSIONS = versions.v2();
List<Version> allVersions = new ArrayList<>(RELEASED_VERSIONS.size() + UNRELEASED_VERSIONS.size());
allVersions.addAll(RELEASED_VERSIONS);
allVersions.addAll(UNRELEASED_VERSIONS);
Collections.sort(allVersions);
ALL_VERSIONS = Collections.unmodifiableList(allVersions);
}

/**
* Returns an immutable, sorted list containing all released versions.
*/
public static List<Version> allReleasedVersions() {
return RELEASED_VERSIONS;
}

/**
* Returns an immutable, sorted list containing all unreleased versions.
*/
public static List<Version> allUnreleasedVersions() {
return UNRELEASED_VERSIONS;
}
private static final List<Version> ALL_VERSIONS = Version.getDeclaredVersions(Version.class);

/**
* Returns an immutable, sorted list containing all versions, both released and unreleased.
Expand All @@ -147,16 +30,16 @@ public static List<Version> allVersions() {
}

/**
* Get the released version before {@code version}.
* Get the version before {@code version}.
*/
public static Version getPreviousVersion(Version version) {
for (int i = RELEASED_VERSIONS.size() - 1; i >= 0; i--) {
Version v = RELEASED_VERSIONS.get(i);
for (int i = ALL_VERSIONS.size() - 1; i >= 0; i--) {
Version v = ALL_VERSIONS.get(i);
if (v.before(version)) {
return v;
}
}
throw new IllegalArgumentException("couldn't find any released versions before [" + version + "]");
throw new IllegalArgumentException("couldn't find any versions before [" + version + "]");
}

/**
Expand All @@ -169,22 +52,22 @@ public static Version getPreviousVersion() {
}

/**
* Returns the released {@link Version} before the {@link Version#CURRENT}
* Returns the {@link Version} before the {@link Version#CURRENT}
* where the minor version is less than the currents minor version.
*/
public static Version getPreviousMinorVersion() {
for (int i = RELEASED_VERSIONS.size() - 1; i >= 0; i--) {
Version v = RELEASED_VERSIONS.get(i);
for (int i = ALL_VERSIONS.size() - 1; i >= 0; i--) {
Version v = ALL_VERSIONS.get(i);
if (v.minor < Version.CURRENT.minor || v.major < Version.CURRENT.major) {
return v;
}
}
throw new IllegalArgumentException("couldn't find any released versions of the minor before [" + Build.current().version() + "]");
throw new IllegalArgumentException("couldn't find any versions of the minor before [" + Build.current().version() + "]");
}

/** Returns the oldest released {@link Version} */
/** Returns the oldest {@link Version} */
public static Version getFirstVersion() {
return RELEASED_VERSIONS.get(0);
return ALL_VERSIONS.get(0);
}

/** Returns a random {@link Version} from all available versions. */
Expand Down
Loading

0 comments on commit 6764887

Please sign in to comment.