Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the need for _UNRELEASED suffix in versions #24798

Merged
merged 17 commits into from
May 26, 2017

Conversation

nik9000
Copy link
Member

@nik9000 nik9000 commented May 19, 2017

Before this change we used the name of the constant to check if a version was released or not. Versions ending in _UNRELEASED were considered unreleased and other versions were considered released. The trouble with this is that we'd often forget to switch a version from unreleased to released. That is a problem because unreleased versions don't get backwards compatibility tests. This changes the logic so that the released versions are inferred from the current version using the following rules:

  1. If the current version is a bug fix release all other versions are released.
  2. Otherwise, the version constant before the current version and before all the alphas is considered unreleased.
  3. If that unreleased version is itself a bug fix release then that is the only unreleased version.
  4. Otherwise, the version before it is unreleased.

Some examples:

  • Right now in master the current version is 6.0.0-alpha2 which means that the last non-alpha in the list is unreleased. That version is 5.5.0. Because that is a .0 release the version before that is also considered unreleased. So in master 5.5.0 and 5.4.1 are both considered unreleased.
  • Right now in 5.x the current version is 5.5.0 which means that that last non-alpha in the list is unreleased. That version is 5.4.1. It isn't a .0 release, so the only unreleased version is 5.4.1.
  • Right now in 5.4 the current version is 5.4.1. Since that isn't a .0 release there are no unreleased versions.

This logic is mirrored in both VersionUtils.java and in build.gradle so that gradle can run the appropriate backwards compatibility tests, some of which are already written.

A secondary goal with removing the _UNRELEASED suffix is to one day be able to use a script to add the new version constant.

It is also important to note that gradle already has a test that verifies that the list of released versions is correct according to maven central. This means that we won't be able to forget to add a version constant.

Closes #24768

nik9000 added 5 commits May 19, 2017 09:37
Attempts to detect if we're missing any `_UNRELEASED` versions
from `Version.java`. This is important because this is how we
trigger backwards compatibility testing for the HEAD of that
branch. If we're building a release with a version number like
`x.y.0` then it makes sure that the last version constant is
`_UNRELEASED`. Because we validate that the constants are sorted,
should work. If that version constant is of the for `x.y.0`
then it also checks that there is an `_UNRELEASED` constant
before that.

Concretely, on master this fails the build unless there is a
constant for 5.5.0 and 5.4.1 or just 5.4.1. On 5.x this requires
a constant for 5.4.1 only. On 5.4 this doesn't require a constant
at all.

TODO entirely rework this comment

Can't do that

Be careful with alphas

Oh boy
.collect { it.toString() })

// TODO this is almost certainly going to fail on 5.4 when we release 5.5.0
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to deal with this in a followup. This change is big enough as is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "fail on 5.4"? The 5.4 branch? I think we need to filter the actualVersions for things less than the current version?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe so. I added this here because I noticed it here. I think it'd be nice to fix it in a separate PR though because it isn't really related to this.

@@ -74,15 +74,17 @@
public static final Version V_5_3_2 = new Version(V_5_3_2_ID, org.apache.lucene.util.Version.LUCENE_6_4_2);
public static final int V_5_4_0_ID = 5040099;
public static final Version V_5_4_0 = new Version(V_5_4_0_ID, org.apache.lucene.util.Version.LUCENE_6_5_0);
public static final int V_5_5_0_ID_UNRELEASED = 5050099;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I almost certainly should have waited to make this change as a purely mechanical followup. It nasty to backport. But I already bit this pill so I feel like I have to swallow it now....

@@ -308,7 +308,7 @@ public void readFrom(StreamInput in) throws IOException {
indicesOptions = IndicesOptions.readIndicesOptions(in);
type = in.readOptionalString();
source = in.readString();
if (in.getVersion().before(Version.V_6_0_0_alpha1_UNRELEASED)) { // TODO change to V_5_3 once backported
if (in.getVersion().before(Version.V_6_0_0_alpha1)) { // TODO change to V_5_3 once backported
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This TODO worries me some....

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaymode, should this change?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it should change. I'll open a PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #24835 for both

@@ -487,7 +487,7 @@ public void readFrom(StreamInput in) throws IOException {
for (int i = 0; i < size; i++) {
final String type = in.readString();
String mappingSource = in.readString();
if (in.getVersion().before(Version.V_6_0_0_alpha1_UNRELEASED)) { // TODO change to V_5_3_0 once backported
if (in.getVersion().before(Version.V_6_0_0_alpha1)) { // TODO change to V_5_3_0 once backported
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jaymode here too?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And maybe we're missing something in a mixed cluster test? Maybe we just aren't running it yet.....

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also change. We do not catch this in our BWC/mixed cluster tests since these checks just guard the need to do content type auto-detection. In versions > 5.3.0 we always send JSON so we do not need to autodetect, but this check being wrong kept the auto detection in place when it wasn't necessary.


/** Utilities for selecting versions in tests */
public class VersionUtils {
/**
* Matches names of versions that we process. Intentionally skips things like CURRENT.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I think about it, maybe I should just skip CURRENT and drop the regex entirely.

}
}

public void testRandomVersionBetween() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just moved this test and the one above it. They were in the org.elasticsearch.test.test package which would have forced me to make VersionUtils. resolveReleasedVersions public and that seemed wrong.

assertEquals(got, Version.CURRENT);
}

static class TestPatchBranch {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really wanted to have tests of this logic on the types of versions that we expect to see. This is kind of like the current state of the 5.4 branch.

assertEquals(emptyList(), unreleased);
}

static class TestMinorBranch {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this one is kind of like 5.x.

assertEquals(singletonList(TestMinorBranch.V_5_3_2), unreleased);
}

static class TestNextBranch {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is what I imagine 5.x looked like right after we forked the 5.4 branch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename this TestStableBranch?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure!

}

static class TestAlphaBranch {
public static final Version V_5_3_0 = Version.fromId(Version.V_5_3_0_ID);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this one is pretty much like master.

Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments.

.collect { it.toString() })

// TODO this is almost certainly going to fail on 5.4 when we release 5.5.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "fail on 5.4"? The 5.4 branch? I think we need to filter the actualVersions for things less than the current version?

* 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 is does in {@code :core:verifyVersions}. So long as the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: is -> it

@@ -290,7 +290,7 @@ task('verifyVersions') {
}
Set<String> knownVersions = new TreeSet<>(xml.versioning.versions.version.collect { it.text() }.findAll { it ==~ /\d\.\d\.\d/ })

// Limit the known versions to those that should be wire compatible
// Limit the known versions to those that should be index compatible
String currentVersion = versions.elasticsearch.minus('-SNAPSHOT')
int prevMajor = Integer.parseInt(currentVersion.split('\\.')[0]) - 1
if (prevMajor == 4) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic only needs to exist on the 5.x branches.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I figure it helps to keep them in sync so backporting is easier.

@@ -290,7 +290,7 @@ task('verifyVersions') {
}
Set<String> knownVersions = new TreeSet<>(xml.versioning.versions.version.collect { it.text() }.findAll { it ==~ /\d\.\d\.\d/ })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is weird to me this task is on core. Could it just be in the root project? And create a precommit task there which depends on this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be easy enough to just move the whole thing into the root project. Is that what you'd prefer?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rereading, yes, that looks like what you'd prefer. I'll do that now.

* If there are, gradle will yell about it. */
return new Tuple<>(unmodifiableList(versions), emptyList());
}
/* If we are on a patch release then we know that at least the version before the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

patch release -> stable branch?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. That is more descriptive.

}

static class TestPatchBranch {
public static final Version V_5_3_0 = Version.fromId(Version.V_5_3_0_ID);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using constants from Version makes removing old constants time consuming. Can you use Version.fromString throughout these tests?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that is better.

assertEquals(singletonList(TestMinorBranch.V_5_3_2), unreleased);
}

static class TestNextBranch {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename this TestStableBranch?

assertEquals(got, Version.CURRENT);
}

static class TestPatchBranch {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename this TestReleaseBranch?

assertEquals(Arrays.asList(TestNextBranch.V_5_3_2, Version.V_5_4_0), unreleased);
}

static class TestAlphaBranch {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename this TestUnstableBranch?

* constant and it should be upgraded by hand. Take this opportunity to
* make sure that it lines up with reality.
*/
public void testUnreleaseCurrent() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should have a test that fails every time we create a new version; that makes automating version bumping more difficult. Can we instead test that CURRENT is equal to the last unreleased version?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll drop it. I had thought it'd be a nice reminder for the next few releases until we automate the version bumping.

jaymode added a commit to jaymode/elasticsearch that referenced this pull request May 23, 2017
…ction for 5.3.0+

This change cleans up some missed TODOs for content type detection on the source of put mapping and
put index template requests. In 5.3.0 and newer versions, the source is always JSON so the content
type detection is not needed. The TODOs were missed after the change was backported to master.

Relates elastic#24798
@nik9000
Copy link
Member Author

nik9000 commented May 23, 2017

@rjernst I think this should be ready for another round.

nik9000 added a commit to nik9000/elasticsearch that referenced this pull request May 24, 2017
Adds the `:distribution:bwc-stable` project which builds the previous
stable branch when `:distribution:bwc` is building an unreleased
branch. When `:distribution:bwc` builds a released branch then
`:distribution:bwc-stable` is an empty build, not used or depended
on by anything.

Relates to elastic#24798
@rjernst
Copy link
Member

rjernst commented May 25, 2017

The changes look fine, but I still see the old test class names? I think we should keep with consistent naming, meaning using unstable for master, stable for N.x, and release (no d on the end like I see in one of the class names) for N.M. Albeit I am copying this naming from Lucene, but I have personally used this terminology to talk about ES branching to other engineers at elastic since I've been here, so I think we standardize on it if there is any actual question about it?

jaymode added a commit that referenced this pull request May 25, 2017
…ction for 5.3.0+ (#24835)

This change cleans up some missed TODOs for content type detection on the source of put mapping and
put index template requests. In 5.3.0 and newer versions, the source is always JSON so the content
type detection is not needed. The TODOs were missed after the change was backported to 5.3.

Relates #24798
@nik9000
Copy link
Member Author

nik9000 commented May 26, 2017

Ok. I understand the naming convention now. I like it. I'll switch.

Lucene has a standard for branch names and it makes sense, we may
as well use that standard when talking about our own branches.
@nik9000
Copy link
Member Author

nik9000 commented May 26, 2017

@rjernst renamed.

Copy link
Member

@rjernst rjernst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the naming! I left one last minor comment.

assertEquals(Arrays.asList(TestUnstableBranch.V_5_3_2, Version.V_5_4_0), unreleased);
}

static class TestUnstableBranchWithAlphas {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this needs "WithAlphas", because the unstable branch always has alphas (when we switch to beta, we cut a new stable branch).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think I should drop the test without alphas then? Or rename it? I'd kind of like to keep it because it is telling is only one of the two tests fails.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should only have one unstable test, and that should be how the unstable branch Version class always looks, ie with CURRENT being an alpha. I'm not sure I understand the testing concern, you have tests here for each of the patterns we handle on each branch, so we should be covered?

@nik9000 nik9000 removed the v5.5.0 label May 26, 2017
@nik9000 nik9000 merged commit 5da8ce8 into elastic:master May 26, 2017
jasontedor added a commit to mashudong/elasticsearch that referenced this pull request May 28, 2017
* master: (38 commits)
  Fix Lucene version expectation
  Verify Lucene version constants
  Avoid double decrement on current query counter
  Remove the need for _UNRELEASED suffix in versions (elastic#24798)
  Adjust available and free bytes to be non-negative on huge FSes
  Begin replacing static index tests with full restart tests (elastic#24846)
  Fix plugin docs for using custom config dir
  Update context-suggest.asciidoc
  Move BWC version to 5.5 after backport
  Support Multiple Collapse Inner Hits
  Scripting: Rename CompiledType to FactoryType in ScriptContext (elastic#24897)
  Scripting: Make contexts available to ScriptEngine construction (elastic#24896)
  Mute index and relocate concurrently
  Build: Add back explicit exclusions and remove gradle exclusions (elastic#24879)
  Scripting: Move context definitions to instance type classes (elastic#24883)
  Build: Fix hadoop integ test error on windows (elastic#24885)
  Put mapping and index template requests do not need content type detection for 5.3.0+ (elastic#24835)
  Add the ability to store objects with a ScrollContext (elastic#24777)
  add docs example for Ingest scripts manipulating document metadata (elastic#24875)
  Fix error message if an incompatible node connects (elastic#24884)
  ...
nik9000 added a commit to nik9000/elasticsearch that referenced this pull request May 29, 2017
Both gradle and java code attempt to infer the type of a each
Version constant in Version.java. It is super important that
they infer that each constant has the same type. If they disagree
we might accidentally not be testing backwards compatibility for
some version.

This adds a test to make sure that they agree, modulo known and
accepted differences (mostly around alphas). It also changes the
minimum wire compatible version from the released 5.4.0 to the
unreleased 5.5.0 as that lines up with the gradle logic.

Relates to elastic#24798
nik9000 added a commit that referenced this pull request Jun 3, 2017
Both gradle and java code attempt to infer the type of a each
Version constant in Version.java. It is super important that
they infer that each constant has the same type. If they disagree
we might accidentally not be testing backwards compatibility for
some version.

This adds a test to make sure that they agree, modulo known and
accepted differences (mostly around alphas). It also changes the
minimum wire compatible version from the released 5.4.0 to the
unreleased 5.5.0 as that lines up with the gradle logic.

Relates to #24798 

Note that the gradle and java version logic doesn't actually match so
this contains a hack to make it *look* like it matches. Since this is a
start, I'm merging it and going to work on some followups to make the
logic actually match.....
@nik9000 nik9000 deleted the version_check_some_more branch June 7, 2017 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Ensure Version#CURRENT is not _UNRELEASED if we are on a release branch
4 participants