Replace heavy weight build-tools integ tests with a simple unit test.#44056
Replace heavy weight build-tools integ tests with a simple unit test.#44056alpar-t merged 9 commits intoelastic:masterfrom
Conversation
- Moves the example project builds into their own project - switch to doing an assemble only rather than a full check - Remove most of testclusters IT - this is a central piece of test infrastructure now widely use we would for sure catch any fallout in all the other tests. Closes elastic#41256 elastic#41256
|
Pinging @elastic/es-core-infra |
|
An alternative I taught about is to separate the examples completely from the build, |
buildSrc/build.gradle
Outdated
| } | ||
|
|
||
| task integTest(type: Test) { | ||
| inputs.dir(file("src/testKit")) |
There was a problem hiding this comment.
We should add a property name (so this doesn't show in scan comparison as $1 or similar) and explicit path sensitivity so we get good cache reuse. We can also directly pass a path to dir() no need to convert to a file.
inputs.dir("src/testKit").withPropertyName("testKitDir").withPathSensitivity(PathSensitivity.RELATIVE)
| } | ||
| project.dependencies { | ||
| restSpec project.project(':rest-api-spec') | ||
| if (ClasspathUtils.isElasticsearchProject()) { |
There was a problem hiding this comment.
I don't think this will work when running tests via the :build-tools project as this will be considered "external". This will only be true in build logic, or when running the task in :buildSrc. We'll need to either explicitly add the buildSrc maker file to the test classpath here, or include some other flag to tell this utility it's running within the Elasticsearch build.
| import java.util.Arrays; | ||
|
|
||
| @Ignore("https://github.com/elastic/elasticsearch/issues/42453") | ||
| public class TestClustersPluginIT extends GradleIntegrationTestCase { |
There was a problem hiding this comment.
The usefulness of this test is pretty questionable at this point. I'd be more inclined to completely remove it.
| FileCollection examplesToTest = files( | ||
| project(':example-plugins').subprojects.collect { it.projectDir } | ||
| ) | ||
| inputs.files(examplesToTest.sort()) |
There was a problem hiding this comment.
File order doesn't matter here (only for classpaths). We should declare relative path sensitivity though.
| } | ||
| } | ||
|
|
||
| task integTest(type: Test) { |
There was a problem hiding this comment.
The main issue with moving these tests to their own project outside of buildSrc is now we are not tracking the build logic as an input in any way. So we'll continue to use cached results pretty much indefinitely until the sample projects themselves change. Alos, these tests are going to resolve the build-tools JAR "externally" now. So a breaking change in buildSrc will only manifest when the new JAR is pulled down, not on the build that included the breaking change.
Due to the issues above and the complexity involved in fixing them I think I'm inclined to leave this stuff part of buildSrc for simplicity. Essentially, these tests are to ensure changes in buildSrc have not caused a regression. For that reason, I think that is where the tests should live, not in a separate project.
There was a problem hiding this comment.
That's only part of the picture. Changes in build-tools is one thing, but more often some dependency is added, e.x. a new library but publishing for it is not configured for it.
This was meant for a way to also test that we are publishing everything we need to, and eventually change the release manager so that we can generate it's configuration from Gradle instead of having a hard-coded list so that we could generate a configuration to publish everything that has publishing configured.
One way to solve this is to add the local repo as input, but that would void the cache most of the time, but It might be the only correct way, as some project might change and have it's publication removed, so the artifact will no longer be there.
There was a problem hiding this comment.
but more often some dependency is added, e.x. a new library but publishing for it is not configured for it.
Under what scenario would this happen? The buildSrc project cannot depend on any other project, since it's needed at build time. So it's only dependencies would be other third-party libraries that will be available in public repos. If we want better isolation here we should do as you recommend and remove the example projects from the root project completely so that they have to get everything as a binary dependency.
One way to solve this is to add the local repo as input, but that would void the cache most of the time, but It might be the only correct way
We can just as easily just add :build-tools to the test classpath here. This is just as correct.
That said, I still don't quite see the benefits of this being a separate project. It doesn't buy us any additional coverage, but creates additional complexity. What we are testing is build-tools so I think these tests should really live there. None of the issues we had with example project testing was caused by the tests being part of the build-tools project.
IMO we should defer any significant refactoring here until we tackle the larger issues of third-party plugin development being basically undocumented, our buildSrc being littered with loads of internal stuff never intended to be used outside of the elasticsearch project, and our funky quasi-compatibility with Java 8.
There was a problem hiding this comment.
By "significant refactoring" I mean just the addition of the separate project for example build testing.
There was a problem hiding this comment.
We agreed with @rjernst a long time ago that we would move these to their own project, the main motivation is that it created a lot of confusion when these broke due to unpublished dependencies. A failure in build-tools didn't make it obvious at all what was going on.
Note that the integ tests are being ran as part of build-tools not buildSrc.
That being said I agree that we need to do all those things, but we should not hold up running these tests until all of that happens.
There was a problem hiding this comment.
We agreed with @rjernst a long time ago that we would move these to their own project, the main motivation is that it created a lot of confusion when these broke due to unpublished dependencies.
By "own project" I just meant a separate CI build. The concern at the time was performance.
In any case, I still contend that there's no need to move these to a separate project to test dependency isolation. Simply using a GradleRunner and not passing withPluginClasspath() would have the same effect w/o the need for another project.
If we want to keep the separate QA project that's fine, we just need to track build-tools as an input. Let's not try to factor in all the other dependencies the build might use. We weren't testing that before so that hasn't changed. We are only doing assembly here so we don't actually care about the runtime behavior of those JARs, only that they exist.
|
@atorok FYI I'm moving it to 7.4 since 7.3 is now feature frozen. |
|
This was discussed and we decided that :
|
|
@elasticmachine run elasticsearch-ci/1 |
|
@mark-vieira this is ready for review now. I added a simple unit test as discussed. |
The test is meant to catch configuration that are not applicable when applying on a stand alone project.
| extension.setDescription("just a test"); | ||
| extension.setClassname(getClass().getName()); | ||
|
|
||
| PluginBuildPlugin.configureAfterEvaluate(project); |
There was a problem hiding this comment.
I think the better thing to do here is simply call Project.evaluate(). It more accurately represents what will happen and will also trigger other afterEvaluate code that we haven't explicitly refactored in this way.
There was a problem hiding this comment.
There is no (longer) such method. I tried calling it with reflection too.
Method evaluate = project.getClass().getDeclaredMethod("evaluate");
evaluate.invoke(project);
There was a problem hiding this comment.
You'll have to cast it to ProjectInternal.
There was a problem hiding this comment.
The cast works but then leads to a very strange cast exception down the road: https://gradle-enterprise.elastic.co/s/jjbp3xhyh3pvc/tests/td2ppmui4dyvs-7dxeqxtgf7z3g?openStackTraces=WzJd
There was a problem hiding this comment.
I suspect what is happening here is that actually evaluating the project is exposing some weird behavior. Probably because we have some dependencies between plugins that aren't being well defined. Sounds like the nebula InfoJavaPlugin is doing something weird.
|
I bumped the version of the plugin and it works now. |
|
@mark-vieira ready for another review |
mark-vieira
left a comment
There was a problem hiding this comment.
I think we could probably improve some of the assertions here but this is still better coverage than we had before. At least once we're able to reenable these tests.
Remove heavy build-tool integ test.
Add a unit test for the plugin builder plugin.
Closes #41256 #41256