-
Notifications
You must be signed in to change notification settings - Fork 25.2k
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
Conversation
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.
Pinging @elastic/es-core-infra |
There was a problem hiding this 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) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 = |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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.
There was a problem hiding this 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 () -> { |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
@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). |
@elasticmachine run elasticsearch-ci/2 |
@elasticmachine run elasticsearch-ci/bwc |
1 similar comment
@elasticmachine run elasticsearch-ci/bwc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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.