Skip to content

Convert testclusters to use distro download plugin #44253

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

Merged
merged 7 commits into from
Jul 15, 2019

Conversation

rjernst
Copy link
Member

@rjernst rjernst commented Jul 12, 2019

Test clusters currently has its own set of logic for dealing with
finding different versions of Elasticsearch, downloading them, and
extracting them. This commit converts testclusters to use the
DistributionDownloadPlugin.

Test clusters currently has its own set of logic for dealing with
finding different versions of Elasticsearch, downloading them, and
extracting them. This commit converts testclusters to use the
DistributionDownloadPlugin.
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@rjernst rjernst requested review from alpar-t and mark-vieira July 12, 2019 03:31
Copy link
Contributor

@alpar-t alpar-t left a comment

Choose a reason for hiding this comment

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

Looks great!

I have one major concern as it seems we are loosing an important optimization with this change.

@@ -338,9 +339,9 @@ public boolean isProcessAlive() {
return nodes.stream().noneMatch(node -> node.isProcessAlive() == false);
}

void eachVersionedDistribution(BiConsumer<String, Distribution> consumer) {
void eachVersionedDistribution(BiConsumer<Version, TestDistribution> consumer) {
Copy link
Contributor

Choose a reason for hiding this comment

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

not 100% sure but this might no longer be used now

Copy link
Contributor

Choose a reason for hiding this comment

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

You're right. This can now be removed.


project.getPlugins().apply(DistributionDownloadPlugin.class);
@SuppressWarnings("unchecked")
NamedDomainObjectContainer<ElasticsearchDistribution> distros =
Copy link
Contributor

Choose a reason for hiding this comment

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

I was thinking of suggesting a ElasticsearchDistributionContainer type so that we can get this by type, but I don't think Gradle offers a way to construct that. Maybe @mark-vieira knows of a way.

Copy link
Contributor

Choose a reason for hiding this comment

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

You can. You have to extend AbstractNamedDomainObjectContainer which is technically internal but it's not an uncommon thing to do. The other option is to just create a default container, and delegate to it from your custom one. This is cumbersome in Java but could be done easily w/o boilderplate if the implementation was Groovy using something like @Delegate.

@@ -60,22 +60,23 @@
private final String clusterName;
private final NamedDomainObjectContainer<ElasticsearchNode> nodes;
private final File workingDirBase;
private final File artifactsExtractDir;
private final Function<Integer, ElasticsearchDistribution> distributionFactory;
Copy link
Contributor

Choose a reason for hiding this comment

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

I added a comment here previously which seems to have vanished.

It seems that we are generating a distribution per node, defeating the purpose of syncWithLinks.
This optimization is important both in terms of disk space and time the build takes and I would prefer we don't merge this without it.

It might make more sense to have this optimization in the distribution downloaded plugin trough and have test cluusters use the extracted distro dirs directly.

Copy link
Member Author

Choose a reason for hiding this comment

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

The distribution download plugin already optimizes by only doing a single extraction for a given set of distribution properties. While we create a unique ElasticsearchDistribution object per node here, the underlying extracted dir will just exist once, in the root project.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks, got it, we only use the index because we need unique names for the domain object container.
I wonder if we should be concerned about name clashes here ? In theory other uses of the distribution download plugin could use the same name as testclusters even trough unlikely.

Copy link
Contributor

Choose a reason for hiding this comment

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

Clashes are possible but will result in an obvious error. I don't think we need to be too concerned about it.

@@ -60,22 +60,23 @@
private final String clusterName;
private final NamedDomainObjectContainer<ElasticsearchNode> nodes;
private final File workingDirBase;
private final File artifactsExtractDir;
private final Function<Integer, ElasticsearchDistribution> distributionFactory;
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks, got it, we only use the index because we need unique names for the domain object container.
I wonder if we should be concerned about name clashes here ? In theory other uses of the distribution download plugin could use the same name as testclusters even trough unlikely.

Copy link
Contributor

@mark-vieira mark-vieira left a comment

Choose a reason for hiding this comment

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

Few comments, otherwise this looks great! Running tests that only use the integ-test distro are much faster now and overall this PR remove more code than it added which is always a step in the right direction.

return files;
private Iterable<File> getDistributionClasspath() {
FileTree jarFiles = distribution.getExtracted().getFileTree(project).matching(filter -> filter.include("**/*.jar"));
return () -> {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is very clever 👍. Thing is, it doesn't actually do what we want, lol. So my intuition was incorrect and returning an Iterable doesn't actually defer anything at task graph calculation time. That's because this iterable could be some other Buildable type, Gradle has to iterate this collection and add each entry as input. Due to type erasure we have no idea at runtime what this is a collection of, so we have to rip through it.

The interesting thing here though is that our assumption that calling getSingleFile() would cause resolution is actually incorrect. This doesn't actually trigger any work. It just returns a path to the empty directory as we are just resolving the configuration, but not it's artifacts. So all this effort to defer that was in vain 🤦‍♂ .

With that knowledge in hand we might be able to simplify some of this logic now that we knowing calling getSingleFile() on a configuration which includes a single directory artifact is fine.

}

private NamedDomainObjectContainer<ElasticsearchCluster> createTestClustersContainerExtension(Project project) {

project.getPlugins().apply(DistributionDownloadPlugin.class);
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd move this up to the first line of the plugin apply() method. It makes it very obvious that this other plugin is a "dependency" of this plugin.

@@ -338,9 +339,9 @@ public boolean isProcessAlive() {
return nodes.stream().noneMatch(node -> node.isProcessAlive() == false);
}

void eachVersionedDistribution(BiConsumer<String, Distribution> consumer) {
void eachVersionedDistribution(BiConsumer<Version, TestDistribution> consumer) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You're right. This can now be removed.

@rjernst
Copy link
Member Author

rjernst commented Jul 13, 2019

@mark-vieira @atorok I think I have addressed all your feedback. One small change I had to make was to move how the test distribution is defaulted. Before this happened inside RestIntegTestTask. However, that required using an afterEvaluate to set it for qa tests, which use the oss distro (and have a sysprop to change it for all qa tests). Using the integ test zip by default is now done directly within ElasticsearchNode (see https://github.com/elastic/elasticsearch/pull/44253/files#diff-a704b6e9e08a9ccfcc05e2ae59844495R163).

@rjernst
Copy link
Member Author

rjernst commented Jul 14, 2019

@elasticmachine run elasticsearch-ci/2

@rjernst
Copy link
Member Author

rjernst commented Jul 14, 2019

@elasticmachine run elasticsearch-ci/bwc

1 similar comment
@rjernst
Copy link
Member Author

rjernst commented Jul 14, 2019

@elasticmachine run elasticsearch-ci/bwc

Copy link
Contributor

@alpar-t alpar-t left a comment

Choose a reason for hiding this comment

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

LGTM

@rjernst rjernst merged commit 7e87c41 into elastic:master Jul 15, 2019
@rjernst rjernst deleted the distro_tests13 branch July 15, 2019 17:39
rjernst added a commit to rjernst/elasticsearch that referenced this pull request Jul 15, 2019
Test clusters currently has its own set of logic for dealing with
finding different versions of Elasticsearch, downloading them, and
extracting them. This commit converts testclusters to use the
DistributionDownloadPlugin.
rjernst added a commit that referenced this pull request Jul 16, 2019
Test clusters currently has its own set of logic for dealing with
finding different versions of Elasticsearch, downloading them, and
extracting them. This commit converts testclusters to use the
DistributionDownloadPlugin.
@mark-vieira mark-vieira added the Team:Delivery Meta label for Delivery team label Nov 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Delivery/Build Build or test infrastructure >refactoring Team:Delivery Meta label for Delivery team v7.4.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants