-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Ingest Manager] Use DockerServers service in integration tests. #69822
Conversation
x-pack/scripts/functional_tests.js
Outdated
@@ -52,6 +52,7 @@ const onlyNotInCoverageTests = [ | |||
require.resolve('../test/endpoint_api_integration_no_ingest/config.ts'), | |||
require.resolve('../test/reporting_api_integration/config.js'), | |||
require.resolve('../test/functional_embedded/config.ts'), | |||
require.resolve('../test/ingest_manager_api_integration'), |
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 for working on this Sonja! The endpoint team will also hopefully be able to pick up the docker registry changes in our tests too.
How is the package storage repo brought in with the registry? Or do we have to commit the packages to kibana that we want the registry to serve for the tests?
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.
Right now the docker container comes with a certain set of packages. I'm using a container from a specific PR (see here: https://github.com/elastic/kibana/pull/69822/files#diff-61a40c93b50ddc25b22ebb367b272aa9R21 ) but it's not very easy to find out what packages and versions are actually included in that build. I don't have a solution for that yet and am open to all suggestions.
In addition to that it is possible to mount a directory into the container and tell the package registry to serve packages from that in addition to those that are delivered with the container, so it will be possible to craft special packages to test specific corner cases. (Watch out for the next commits on this PR how this will work.)
The issue with that approach is that our production packages contain lots of small files, and I'm not comfortable with adding them to the test directory. If nothing else, it makes PRs unreadable (see spalger#34 for an example).
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.
Right now the docker container comes with a certain set of packages. I'm using a container from a specific PR
Are we able to override that package registry version when running the tests locally? If I understand correctly we can just set INGEST_MANAGEMENT_PACKAGE_REGISTRY_PORT
to the port of our locally running registry?
The issue with that approach is that our production packages contain lots of small files, and I'm not comfortable with adding them to the test directory. If nothing else, it makes PRs unreadable (see spalger#34 for an example).
Yeah I noticed that too. @ruflin I wonder if we could add functionality to the registry so it could decompress a tar.gz file to get extra packages. That way we could at least commit gzipped files here for tests. It still doesn't make it clear what packages are included until someone decompresses it but it makes it easier to review.
Another option is we could pull down a specific branch of the package storage repo but adding another external dependency might not be a good idea. Plus that might conflict with the proposed package release flow.
Also can we pin the registry to specific commits or is it just master
and specific PRs?
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.
Also can we pin the registry to specific commits or is it just master and specific PRs?
You can use anything that is available on https://container-library.elastic.co/r/package-registry/package-registry
@ruflin I wonder if we could add functionality to the registry so it could decompress a tar.gz file to get extra packages. That way we could at least commit gzipped files here for tests.
Seconded, that would make it easier to add extra packages for tests.
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.
Are we able to override that package registry version when running the tests locally?
The docker container that is configured in the config.{ts,js}
for your *_api_integration
directory is used for all the tests. It is currently not possible to start up a docker container per test. That means that all packages you need in addition to those in the container will need to be in one central place for all your tests.
If I understand correctly we can just set INGEST_MANAGEMENT_PACKAGE_REGISTRY_PORT to the port of our locally running registry?
No. This is an environment variable that will be set by CI tooling. The tests are run in a distributed way, and it is possible that one jenkins worker runs two sets of tests using docker at the same time. Therefore, all the ports that docker containers are mounted to need to be unter control of the CI environment to ensure there are no port conflicts.
When the tests are run locally, the presence of this environment variable indicates that the tests should be run at all. Leaving it out makes it possible to run the tests on a machine without docker. This all will be documented.
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.
Sounds good, thanks for the explanation!
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 adding files instead of tar.gz is a feature. If a package is changed for a test, the PR reviewer should also be able to review the package change. If it is in a .tar.gz, the user can't.
My expectation is that for the tests, we build very small packages dedicated to what we want to test. So the number of files will be low and once commited, from the on the diffs will only be on the changes. I don't expect us to push a new package version with all the files each time we update a package here.
If we want later to test across many packages I would rather have a testing distribution of the registry with these packages already inside instead of storing all the .tar.gz inside, but I think this is a different testing scenario.
d6a933e
to
536cc69
Compare
@paul-tavares This needs polishing but is probably worth a look 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.
This is AWSOME @skh 😃
Thanks for working on this. I left a minor comment that would assist with us being able to reuse the setup in our test.
return { | ||
testFiles: [require.resolve('./apis')], | ||
servers: xPackAPITestsConfig.get('servers'), | ||
dockerServers: defineDockerServersConfig({ |
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 for the endpoint functional tests (those that execute from here x-pack/test/security_solution_endpoint/config.ts
), we would need to add something similar to this (along with an endpoint package fixture), right?
Any chance this setup could be extracted into shared lib/module so that we can just re-use from our end, and thus ensure we're testing with the same setup?
I would prose adding a method to x-pack/test/common/services/ingest_manager.ts
that would return some of of this setup - example:
return {
async setup() {
//....
},
getPackageRegistryDockerConfig() {
return {
registry: {
enabled: !!registryPort,
image: 'docker.elastic.co/package-registry/package-registry:PR-539',
portInContainer: 8080,
port: registryPort,
args: [
'-v',
`${path.join(
path.dirname(__filename),
'./apis/fixtures/package_registry_config.yml'
)}:/registry/config.yml`,
'-v',
`${path.join(
path.dirname(__filename),
'./apis/fixtures/test_packages'
)}:/registry/packages/test-packages`,
],
waitForLogLine: 'package manifests loaded into memory',
},
}
}
};
We could then use the same setup, add in our package in the args
and enable this in our runs of Front-end functional tests (and maybe even our api integration tests as well).
//cc: @nnamdifrankie , @charlie-pichette , @jonathan-buttner FYI
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 like the idea. Let's add this after this PR has been reviewed and merged?
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.
sounds good @skh 👍
dockerServers: defineDockerServersConfig({ | ||
registry: { | ||
enabled: !!registryPort, | ||
image: 'docker.elastic.co/package-registry/package-registry:PR-539', |
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 might just be my ignorance on the subject of docker images 😬 - what is the PR-539
at the end? is that the ID of the package (which maybe is derived from the PR that created it?)
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 is the ID of the PR in elastic/package-registry
that the image was built from. We need a stable docker image, but it is not decided how we will keep track of the images used for these tests that is both trackable and at least somewhat understandable for the developer. I'm adding some documentation that addresses this, but: good catch.
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.
Oh, and we can use anything that is available on https://container-library.elastic.co/r/package-registry/package-registry , and the @elastic/observablt-robots team can help us put the containers there that we need. We "just" need to come up with a plan when to build a container to use for CI, from what branch and commit, and how to name it. (Cc: @ruflin )
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 was too noisy to publish the PR Docker images on the package-registry namespace, so we have changed the PR images to the observability-ci namespace(https://container-library.elastic.co/r/observability-ci/package-registry) we use the PR-XXXX and the SHA1 as tags, every green build deploy a Docker image.
If you need anything you just have to ping us someone will manage to help you.
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 for the explanation 😄
Pinging @elastic/ingest-management (Team:Ingest Management) |
@tylersmalley I'm waiting for CI to voice its opinion, but other than that this is ready for review. |
@elasticmachine merge upstream |
|
||
## How to run the tests locally | ||
|
||
In the `x-pack` directory, run: |
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 recently learned about some yarn scripts that I think are preferable using node scripts/*
For the two terminal approach listed shown here, in the kibana root,
- in one shell, run
yarn test:ftr:server --config x-pack/test/ingest_manager_api_integration/config.ts
- in another, run
yarn test:ftr:runner --config x-pack/test/ingest_manager_api_integration/config.ts
If you want to run everything in one go, this seems to work
yarn test:ftr --config x-pack/test/ingest_manager_api_integration/config.ts
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.
Thank you! I've updated the documentation accordingly.
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's cool. I wasn't aware of that either. 👍
const supertest = getService('supertest'); | ||
const dockerServers = getService('dockerServers'); | ||
|
||
const server = dockerServers.get('registry'); |
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.
🎉
const dockerServers = getService('dockerServers'); | ||
|
||
const server = dockerServers.get('registry'); | ||
// use function () {} and not () => {} here |
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.
Thank you so much for this note. I've "discovered" it a few times in my career. Thanks from Future Me for the found time and mental health.
@elasticmachine merge upstream |
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.
Changes on files under operations team code owners LGTM
💚 Build SucceededBuild metrics
History
To update your PR or re-run it, just comment with: |
👏 Really great to have this in. This will change the way we can test. |
…stic#69822) * Partially disable test files. * Use DockerServers in EPM tests. * Only run tests when DockerServers have been set up * Reenable ingest manager API integration tests * Pass new test_packages to registry container * Enable DockerServers tests in CI. * Correctly serve filetest package for file tests. * Add helper to skip test and log warning. * Reenable further file tests. * Add developer documentation about Docker in Kibana CI. * Document use of yarn test:ftr Co-authored-by: Elastic Machine <[email protected]> # Conflicts: # x-pack/scripts/functional_tests.js
) (#70197) * Partially disable test files. * Use DockerServers in EPM tests. * Only run tests when DockerServers have been set up * Reenable ingest manager API integration tests * Pass new test_packages to registry container * Enable DockerServers tests in CI. * Correctly serve filetest package for file tests. * Add helper to skip test and log warning. * Reenable further file tests. * Add developer documentation about Docker in Kibana CI. * Document use of yarn test:ftr Co-authored-by: Elastic Machine <[email protected]> # Conflicts: # x-pack/scripts/functional_tests.js
…stic#69822) * Partially disable test files. * Use DockerServers in EPM tests. * Only run tests when DockerServers have been set up * Reenable ingest manager API integration tests * Pass new test_packages to registry container * Enable DockerServers tests in CI. * Correctly serve filetest package for file tests. * Add helper to skip test and log warning. * Reenable further file tests. * Add developer documentation about Docker in Kibana CI. * Document use of yarn test:ftr Co-authored-by: Elastic Machine <[email protected]>
Summary
Implements #61699
Supersedes #68172
Documentation
(this is also part of this PR in
x-pack/plugins/ingest_manager/dev_docs/api_integration_tests.md
)Many API integration tests for Ingest Manager trigger at some point a connection to the package registry, and retrieval of some packages. If these connections are made to a package registry deployment outside of Kibana CI, these tests can fail at any time for two reasons:
For that reason, we run a dockerized version of the package registry in Kibana CI. For this to work, our tests must run against a custom test configuration and be kept in a custom directory,
x-pack/test/ingest_manager_api_integration
.How to run the tests locally
Usually, having the test server and the test runner in two different shells is most efficient, as it is possible to keep the server running and only rerun the test runner as often as needed. To do so, in one shell in the main
kibana
directory, run:In another shell in the same directory, run
However, it is also possible to alternatively run everything in one go, again from the main
kibana
directory:Port
12345
is used as an example here, it can be anything, but the environment variable has to be present for the tests to run at all.DockerServers service setup
We use the
DockerServers
service provided bykbn-test
. The documentation for this functionality can be found here:https://github.com/elastic/kibana/blob/master/packages/kbn-test/src/functional_test_runner/lib/docker_servers/README.md
The main configuration for the
DockerServers
service for our tests can be found inx-pack/test/ingest_manager_api_integration/config.ts
:Specify the arguments to pass to
docker run
:-v
mounts local paths into the docker image. The first one puts a custom configuration file into the correct place in the docker container, the second one mounts a directory containing additional packages.Specify the docker image to use
This image contains the content of
docker.elastic.co/package-registry/package-registry:master
on June 26 2020. The image used here should be stable, i.e. usingmaster
would defeat the purpose of having a stable set of packages to be used in Kibana CI.Packages available for testing
The containerized package registry contains a set of packages which should be sufficient to run tests against all parts of Ingest Manager. The list of the packages are logged to the console when the docker container is initialized during testing, or when the container is started manually with
Additional packages for testing certain corner cases or error conditions can be put into
x-pack/test/ingest_manager_api_integration/apis/fixtures/test_packages
. A packagefiletest
has been added there as an example.Some DockerServers background
For the
DockerServers
servers to run correctly in CI, theINGEST_MANAGEMENT_PACKAGE_REGISTRY_PORT
environment variable needs to be under control of the CI environment. The reason behind this: it is possible that several versions of our tests are run in parallel on the same worker in Jenkins, and if we used a hard-coded port number here, those tests would run into port conflicts. (This is also the case for a few other ports, and the setup happens invars/kibanaPipeline.groovy
).Also, not every developer has
docker
installed on their workstation, so it must be possible to run the testsuite as a whole withoutdocker
, and preferably this should be the default behaviour. Therefore, ourDockerServers
service is only enabled whenINGEST_MANAGEMENT_PACKAGE_REGISTRY_PORT
is set. This needs to be checked in every test like this:If the tests are skipped in this way, they are marked in the test summary as
pending
and a warning is logged:Known issues
Not all tests in
ingest_manager_api_integration
have been re-enabled. Those that remain need to be changed to work withv2
index templates, which is beyond the scope of this PR.