-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
Read the full REST spec from a common directory #51890
Conversation
This commit changes where the REST API specs are read. The REST API spec is required to run the REST YAML tests and are currently copied to every project that has REST YAML tests. The REST API specs are now copied to the build directory of the root gradle project. Since each module or plugin (including all x-pack plugins) can contribute to the REST API spec, they too are copied to the common directory. The result is a single directory created during the build which includes the full REST API spec. Configuration is added to each project that has a RestIntegTestTask to enable ensure that the common directory is created when needed. The numerous places where this spec was copied around has now been removed in favor of the new common directory, which is the full spec and is part of the test classpath. Additionally, to enable plugin developers, a new plugin copy-rest-api-spec has been introduced that allows the specs to be copied locally from the jar. This is plugin is also used for the BWC tests which need to copy the tests for the spec to the local resource directory.
Pinging @elastic/es-core-infra (:Core/Infra/Build) |
working through the test failures they are mostly just need finish wiring up the spec dependencies |
/** | ||
* Copies the core REST specs to the local resource directory for the REST YAML tests. | ||
*/ | ||
class CopyRestApiSpecPlugin implements Plugin<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.
We still have a few places where we need the specs copied to the local resources. Notably the examples so that they can rely on the release jar. There are few others projects where it is easier to copy them locally then run from the global dir. However, I believe all (but 1) of the modules, plugins, and x-pack plugins REST Yaml tests run from the global dir.
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.
It's not clear to me what the difference is between just putting them on the test runtime classpath, and copying them to the resources output directory. Either way, we are just throwing these files on the classpath.
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 think I may have mis-attributed "easier", I will re-visit the usage of this. However, this is still required for the examples project.
@elasticmachine update branch |
//copy the rest api spec to a global location and add to the test classpath | ||
project.tasks.withType(RestIntegTestTask) { | ||
configurations { | ||
copyRestApiSpecGlobal |
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 consuming project doesn't need to create this configuration. When we mention this configuration below in the dependency notation, we are referring to the configuration on the root project.
@@ -138,6 +141,15 @@ subprojects { | |||
precommit.dependsOn 'spotlessJavaCheck' | |||
} | |||
} | |||
//copy the rest api spec to a global location and add to the test classpath | |||
project.tasks.withType(RestIntegTestTask) { |
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 think this logic should move to the existing RestTestPlugin
rather than shove it in a withType()
block. This has the side effect of creating this dependency multiple times, once for each instance of that task type. This is benign, but also unnecessary.
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 RestTestPlugin
creates a integTest
task of type RestIntegTestTask
task. But so does the PluginBuildPlugin
(esplugin) (not sure why it explicitly creates it instead of applying the RestTestPlugin
).
Additionally, many of the projects create custom tasks of type RestIntegTestTask
. The requirement for the RestTestRunnerTask
which is created by the RestIntegTestTask
.
Actually, I think this should actually be withType(RestTestRunnerTask)
since a couple project create that 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.
We aren't configuring the task, we are adding a testRuntime
dependency to the project. All test tasks inherit that classpath so there is no need to couple this to the existence of a RestIntegTestTask
.
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.
Based on your comment below
We should put the reliance on rest specs in an explicit plugin so that if you are using YAML tests and need those specs, you must apply the plugin.
I can move this to the RestTestPlugin
* Copies all of the REST api specs (including core, modules, plugins, and x-pack) to common location for the REST YAML test. | ||
* This plugin is expected to only be applied to applied to the root project. | ||
*/ | ||
File rootBuildDir = rootProject.buildDir |
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.
Ok, so I think we decided against centralizing all specs because I came late to the party with the whole cache hit issue. Sorry about that. Given that then the only common specs are those in :rest-api-spec
, let's just add this logic to that project, exposing it's specs as a build artifact. Kinda what we already do
} | ||
} | ||
|
||
tasks.create("copyModulesRestSpecGlobal", Copy) { |
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.
So essentially this is the stuff you ripped out of RestIntegTestTask
. I think that's still the right thing to do, but let's instead move it to RestTestPlugin
. So the plugin sets up the specs on the classpath instead of the task constructor.
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.
As mentioned above, there are many usages of RestIntegTestTask
outside of the RestTestPlugin
, so I can't move this to RestTestPlugin
. I'll look into moving this back to the RestIntegTestTask
, but not sure if that will just put us back to where we started.
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 all RestIntegTestTasks
require the rest specs though, that's the difference. We use those task for Java tests as well. We should put the reliance on rest specs in an explicit plugin so that if you are using YAML tests and need those specs, you must apply the plugin. Otherwise we are adding the core rest specs to the classpath unnecessarily for many tasks, again, negatively affecting cacheability.
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.
That makes sense... However, I would like to also remove the integTest
from the esplugin
(here) to help enforce this. I haven't checked yet, but for any esplugin that has REST tests, but does not have YAML based rest tests would need to include the specs unnecessarily or explicitly create the integTest
task. I think this is pretty rare, so either option probably not much of an issue.
Thoughts on removing integTest
from the esplugin
to enforce the inclusion of RestTestPlugin
for projects that have Rest tests ? This is technically a breaking change for plugin devs. (I am only targeting 8.0 anyway)
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 am only targeting 8.0 anyway)
We'll want to backport this to 7.x
so I don't think we can safely make this change.
I haven't checked yet, but for any esplugin that has REST tests, but does not have YAML based rest tests would need to include the specs unnecessarily or explicitly create the integTest task. I think this is pretty rare, so either option probably not much of an issue.
I don't think so. There are a number of plugins that don't use YAML tests.
I think the problem is when we say "rest tests" we actually mean a few things. This includes both Java-based tests that target an external cluster and YAML tests. We only need the specs for the latter, but we group them together as a single thing. We need to tease these apart.
Not all projects that execute tests against an external cluster (i.e. have a RestIntegTesttask
) utilize YAML tests. Pulling the copy rest spec stuff out of that task constructor is the first start. The question remains, where do we now put that logic, such that it get's applied to the appropriate projects. Moving it to RestTestPlugin
actually wouldn't be correct, as this would apply again, to all projects. I suggest we create a new YamlRestTestPlugin
that does all the spec copying and wiring and we apply this plugin explicitly to projects that leverage YAML tests.
/** | ||
* Copies the core REST specs to the local resource directory for the REST YAML tests. | ||
*/ | ||
class CopyRestApiSpecPlugin implements Plugin<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.
It's not clear to me what the difference is between just putting them on the test runtime classpath, and copying them to the resources output directory. Either way, we are just throwing these files on the classpath.
I took this refactor a slightly different direction due that the potential to make the cache hits worse. So instead of trying to central all of the tests, I introduced a new plugin that still allows us to remove the logic from the integTest task, centralizes the copying, and provides more control over what is copied. Sorry (again) for the new PR, but given the change of direction it feels cleaner for a fresh start. replaced by: #52114 |
This commit changes where the REST API specs are read. The REST API
spec is required to run the REST YAML tests and are currently copied
to every project that has REST YAML tests.
The REST API specs are now copied to the build directory of the root
gradle project. Since each module or plugin (including all x-pack plugins)
can contribute to the REST API spec, they too are copied to the common
directory. The result is a single directory created during the build which
includes the full REST API spec. Configuration is added to each project
that has a RestIntegTestTask to enable ensure that the common directory is
created when needed.
The numerous places where this spec was copied around has now been removed
in favor of the new common directory, which is the full spec and is part
of the test classpath.
Additionally, to enable plugin developers, a new plugin copy-rest-api-spec
has been introduced that allows the specs to be copied locally
from the jar. This is plugin is also used for the BWC tests which need
to copy the tests for the spec to the local resource directory.
Note - this review supersedes #51794