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

Read the full REST spec from a common directory #51890

Closed

Conversation

jakelandis
Copy link
Contributor

@jakelandis jakelandis commented Feb 4, 2020

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

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.
@jakelandis jakelandis marked this pull request as ready for review February 4, 2020 21:13
@jakelandis jakelandis added :Delivery/Build Build or test infrastructure >refactoring v8.0.0 labels Feb 4, 2020
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (:Core/Infra/Build)

@jakelandis
Copy link
Contributor Author

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> {
Copy link
Contributor Author

@jakelandis jakelandis Feb 4, 2020

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

@jakelandis
Copy link
Contributor Author

@elasticmachine update branch

//copy the rest api spec to a global location and add to the test classpath
project.tasks.withType(RestIntegTestTask) {
configurations {
copyRestApiSpecGlobal
Copy link
Contributor

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) {
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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
Copy link
Contributor

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) {
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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)

Copy link
Contributor

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> {
Copy link
Contributor

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.

@jakelandis
Copy link
Contributor Author

Ok, so I think we decided against centralizing all specs because I came late to the party with the whole cache hit issue

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

@jakelandis jakelandis closed this Feb 9, 2020
@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 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants