19
19
20
20
package org .elasticsearch .test ;
21
21
22
- import org .elasticsearch .Version ;
23
- import org .elasticsearch .common .Booleans ;
24
- import org .elasticsearch .common .Nullable ;
25
- import org .elasticsearch .common .collect .Tuple ;
26
-
27
- import java .lang .reflect .Field ;
28
- import java .lang .reflect .Modifier ;
29
22
import java .util .ArrayList ;
30
- import java .util .Arrays ;
31
23
import java .util .Collections ;
32
24
import java .util .List ;
25
+ import java .util .Locale ;
26
+ import java .util .Map ;
33
27
import java .util .Optional ;
34
28
import java .util .Random ;
29
+ import java .util .SortedSet ;
30
+ import java .util .TreeSet ;
35
31
import java .util .stream .Collectors ;
32
+ import java .util .stream .Stream ;
36
33
37
- import static java .util .Collections .singletonList ;
38
- import static java .util .Collections .unmodifiableList ;
34
+ import org .elasticsearch .Version ;
35
+ import org .elasticsearch .common .Nullable ;
36
+ import org .elasticsearch .common .collect .Tuple ;
39
37
40
38
/** Utilities for selecting versions in tests */
41
39
public class VersionUtils {
40
+
42
41
/**
43
42
* Sort versions that have backwards compatibility guarantees from
44
43
* those that don't. Doesn't actually check whether or not the versions
@@ -50,73 +49,65 @@ public class VersionUtils {
50
49
* guarantees in v1 and versions without the guranteees in v2
51
50
*/
52
51
static Tuple <List <Version >, List <Version >> resolveReleasedVersions (Version current , Class <?> versionClass ) {
53
- List <Version > versions = Version .getDeclaredVersions (versionClass );
54
-
55
- Version last = versions .remove (versions .size () - 1 );
56
- assert last .equals (current ) : "The highest version must be the current one "
57
- + "but was [" + versions .get (versions .size () - 1 ) + "] and current was [" + current + "]" ;
58
-
59
- if (current .revision != 0 ) {
60
- /* If we are in a stable branch there should be no unreleased version constants
61
- * because we don't expect to release any new versions in older branches. If there
62
- * are extra constants then gradle will yell about it. */
63
- return new Tuple <>(unmodifiableList (versions ), singletonList (current ));
52
+ // group versions into major version
53
+ Map <Integer , List <Version >> majorVersions = Version .getDeclaredVersions (versionClass ).stream ()
54
+ .collect (Collectors .groupingBy (v -> (int )v .major ));
55
+ // this breaks b/c 5.x is still in version list but master doesn't care about it!
56
+ //assert majorVersions.size() == 2;
57
+ // TODO: remove oldVersions, we should only ever have 2 majors in Version
58
+ List <Version > oldVersions = majorVersions .getOrDefault ((int )current .major - 2 , Collections .emptyList ());
59
+ List <List <Version >> previousMajor = splitByMinor (majorVersions .get ((int )current .major - 1 ));
60
+ List <List <Version >> currentMajor = splitByMinor (majorVersions .get ((int )current .major ));
61
+
62
+ List <Version > unreleasedVersions = new ArrayList <>();
63
+ final List <List <Version >> stableVersions ;
64
+ if (currentMajor .size () == 1 ) {
65
+ // on master branch
66
+ stableVersions = previousMajor ;
67
+ // remove current
68
+ moveLastToUnreleased (currentMajor , unreleasedVersions );
69
+ } else {
70
+ // on a stable or release branch, ie N.x
71
+ stableVersions = currentMajor ;
72
+ // remove the next maintenance bugfix
73
+ moveLastToUnreleased (previousMajor , unreleasedVersions );
64
74
}
65
75
66
- /* If we are on a patch release then we know that at least the version before the
67
- * current one is unreleased. If it is released then gradle would be complaining. */
68
- int unreleasedIndex = versions .size () - 1 ;
69
- while (true ) {
70
- if (unreleasedIndex < 0 ) {
71
- throw new IllegalArgumentException ("Couldn't find first non-alpha release" );
72
- }
73
- /* We don't support backwards compatibility for alphas, betas, and rcs. But
74
- * they were released so we add them to the released list. Usually this doesn't
75
- * matter to consumers, but consumers that do care should filter non-release
76
- * versions. */
77
- if (versions .get (unreleasedIndex ).isRelease ()) {
78
- break ;
76
+ // remove next minor
77
+ Version lastMinor = moveLastToUnreleased (stableVersions , unreleasedVersions );
78
+ if (lastMinor .revision == 0 ) {
79
+ if (stableVersions .get (stableVersions .size () - 1 ).size () == 1 ) {
80
+ // a minor is being staged, which is also unreleased
81
+ moveLastToUnreleased (stableVersions , unreleasedVersions );
79
82
}
80
- unreleasedIndex --;
83
+ // remove the next bugfix
84
+ moveLastToUnreleased (stableVersions , unreleasedVersions );
81
85
}
82
86
83
- Version unreleased = versions .remove (unreleasedIndex );
84
- if (unreleased .revision == 0 ) {
85
- /*
86
- * If the last unreleased version is itself a patch release then Gradle enforces that there is yet another unreleased version
87
- * before that. However, we have to skip alpha/betas/RCs too (e.g., consider when the version constants are ..., 5.6.3, 5.6.4,
88
- * 6.0.0-alpha1, ..., 6.0.0-rc1, 6.0.0-rc2, 6.0.0, 6.1.0 on the 6.x branch. In this case, we will have pruned 6.0.0 and 6.1.0 as
89
- * unreleased versions, but we also need to prune 5.6.4. At this point though, unreleasedIndex will be pointing to 6.0.0-rc2, so
90
- * we have to skip backwards until we find a non-alpha/beta/RC again. Then we can prune that version as an unreleased version
91
- * too.
92
- */
93
- do {
94
- unreleasedIndex --;
95
- } while (versions .get (unreleasedIndex ).isRelease () == false );
96
- Version earlierUnreleased = versions .remove (unreleasedIndex );
97
-
98
- // This earlierUnreleased is either the snapshot on the minor branch lower, or its possible its a staged release. If it is a
99
- // staged release, remove it and return it in unreleased as well.
100
- if (earlierUnreleased .revision == 0 ) {
101
- unreleasedIndex --;
102
- Version actualUnreleasedPreviousMinor = versions .remove (unreleasedIndex );
103
- return new Tuple <>(unmodifiableList (versions ), unmodifiableList (Arrays .asList (actualUnreleasedPreviousMinor ,
104
- earlierUnreleased , unreleased , current )));
105
- }
87
+ List <Version > releasedVersions = Stream .concat (oldVersions .stream (),
88
+ Stream .concat (previousMajor .stream (), currentMajor .stream ()).flatMap (List ::stream ))
89
+ .collect (Collectors .toList ());
90
+ Collections .sort (unreleasedVersions ); // we add unreleased out of order, so need to sort here
91
+ return new Tuple <>(Collections .unmodifiableList (releasedVersions ), Collections .unmodifiableList (unreleasedVersions ));
92
+ }
106
93
107
- return new Tuple <>(unmodifiableList (versions ), unmodifiableList (Arrays .asList (earlierUnreleased , unreleased , current )));
108
- } else if (unreleased .major == current .major ) {
109
- // need to remove one more of the last major's minor set
110
- do {
111
- unreleasedIndex --;
112
- } while (unreleasedIndex > 0 && versions .get (unreleasedIndex ).major == current .major );
113
- if (unreleasedIndex > 0 ) {
114
- // some of the test cases return very small lists, so its possible this is just the end of the list, if so, dont include it
115
- Version earlierMajorsMinor = versions .remove (unreleasedIndex );
116
- return new Tuple <>(unmodifiableList (versions ), unmodifiableList (Arrays .asList (earlierMajorsMinor , unreleased , current )));
117
- }
94
+ // split the given versions into sub lists grouped by minor version
95
+ private static List <List <Version >> splitByMinor (List <Version > versions ) {
96
+ Map <Integer , List <Version >> byMinor = versions .stream ().collect (Collectors .groupingBy (v -> (int )v .minor ));
97
+ return byMinor .entrySet ().stream ().sorted (Map .Entry .comparingByKey ()).map (Map .Entry ::getValue ).collect (Collectors .toList ());
98
+ }
99
+
100
+ // move the last version of the last minor in versions to the unreleased versions
101
+ private static Version moveLastToUnreleased (List <List <Version >> versions , List <Version > unreleasedVersions ) {
102
+ List <Version > lastMinor = new ArrayList <>(versions .get (versions .size () - 1 ));
103
+ Version lastVersion = lastMinor .remove (lastMinor .size () - 1 );
104
+ if (lastMinor .isEmpty ()) {
105
+ versions .remove (versions .size () - 1 );
106
+ } else {
107
+ versions .set (versions .size () - 1 , lastMinor );
118
108
}
119
- return new Tuple <>(unmodifiableList (versions ), unmodifiableList (Arrays .asList (unreleased , current )));
109
+ unreleasedVersions .add (lastVersion );
110
+ return lastVersion ;
120
111
}
121
112
122
113
private static final List <Version > RELEASED_VERSIONS ;
@@ -131,7 +122,7 @@ static Tuple<List<Version>, List<Version>> resolveReleasedVersions(Version curre
131
122
allVersions .addAll (RELEASED_VERSIONS );
132
123
allVersions .addAll (UNRELEASED_VERSIONS );
133
124
Collections .sort (allVersions );
134
- ALL_VERSIONS = unmodifiableList (allVersions );
125
+ ALL_VERSIONS = Collections . unmodifiableList (allVersions );
135
126
}
136
127
137
128
/**
@@ -244,5 +235,4 @@ public static Version maxCompatibleVersion(Version version) {
244
235
assert compatible .size () > 0 ;
245
236
return compatible .get (compatible .size () - 1 );
246
237
}
247
-
248
238
}
0 commit comments