-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
馃尡 Add e2e tests for sample external plugin #3419
馃尡 Add e2e tests for sample external plugin #3419
Conversation
Hi @Eileen-Yu. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
1e971df
to
7c65085
Compare
/ok-to-test |
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 @Eileen-Yu for putting this together! For the most part it looks good - great work!
There are just a few nits and a couple more things that I think need to be done to ensure we are including these tests in CI:
5a28069
to
81980a5
Compare
/retest |
Makefile
Outdated
## To keep the same kind cluster between test runs, use `SKIP_KIND_CLEANUP=1 make test-e2e-local` | ||
./test/e2e/local.sh | ||
|
||
.PHONY: test-e2e-ci | ||
test-e2e-ci: ## Run the end-to-end tests (used in the CI)` | ||
test-e2e-ci: build-external-plugin ## Run the end-to-end tests (used in the CI)` |
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.
Revert this change you added it in the prow already
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 is still needed. IIUC, just the execution of the go tests were added in the Prow configuration
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 prow setup is done in this one: https://github.com/kubernetes-sigs/kubebuilder/blob/master/test/e2e/setup.sh#L56-L67
We do not call any of our tests in this way, so why we would need to have this new target and call in the test-e2e-ci?
if [ $? -eq 0 ]; then | ||
echo "External plugin is built at: $EXTERNAL_PLUGIN_DESTINATION" | ||
else | ||
echo "FAIL to build external plugin" |
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 would be nice to echo the exact error message as well, with which init
command has failed.
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.
+1
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.
IMO, ideally, we need to keep all in Go.
Why? It makes it easier for us to keep the project maintained.
- See that using an IDE, we can trigger the tests directly, which means the sh would not be executed.
- Also, it makes it more intuitive since all the required steps to do the tests are placed together.
- By leasing, keeping it in Go with the test help us to troubleshot since we can add breakpoints to verify each step
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.
@camilamacedo86 I don't disagree that it is ideal but I think we already have precedence for building the binaries for testing purposes in shell scripts. I think for now we should follow the pre-existing pattern and we can make an issue to convert the e2e shell scripts to Go
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 @everettraven idea to keep the pattern consistent in this PR.
Other than that, it feels like this is something suitable in the scope of the external plugin project itself.
Such as a make target in the sample external plugin folder.
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.
If we want to keep the pattern consistent accross the project then we should not add what is required to be build in the tests in shell. Note that today we can run the e2e tests locally for dev purposes without any shell. We just run the suite in go. So that will broke the current behaviour
See: #3419 (comment)
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 agree it is a good practice to follow the current pattern, which lets Ginkgo do all e2e related tasks, instead of having an additional script. By doing this we wish to keep consistency and benefit from Ginkgo's feature.
The current script may be a reference to put in the docs to provide users info about how to install their external plugin.
func GenerateProject(kbc *utils.TestContext) { | ||
var err error | ||
|
||
By("initializing a 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.
See that before init you need to ensure that the plugin was built.
It is not better build the plugin here instead of create the sh?
Could we not move the code to here and to do that in go so that is easier to keep maintained as well?
See that you can run it locally either if you move all to here by just trigging the tests from your IDE
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 don't disagree that it might be easier to maintain, but I think there is a lot of precedence to build stuff in a shell script for the e2e tests. IMO we shouldn't try to reinvent the wheel by adding this to the go code and follow the existing pattern for building and configuring e2e tests with shell scripts.
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.
Hi @everettraven,
but I think there is a lot of precedence to build stuff in a shell script for the e2e tests.
We currently do not utilize any shell scripting to accomplish the tasks required for our end-to-end (e2e) tests. It's important to note that these tests can be executed locally as long as you have a functional Kubernetes cluster. However, after this PR is merged, this functionality will likely be disrupted and might no longer be possible.
To elaborate, introducing shell scripting for e2e tests as we are doing here will break the development environment. This is contrary to our current setup. The shells scripts in place are Optional to setup the k8s locally either and btw I never used them or to call the test on prow.
Nonetheless, if @Eileen-Yu is able to successfully integrate shell scripting without compromising the functionality (despite my concerns that it will negatively affect the ability to run e2e tests in a development environment), I'm open to having this PR merged and making necessary changes in a follow-up. Please note, however, that it appears these tests are currently failing due to the lack of the necessary steps within the e2e test environment. Therefore, when the init command is called, it results in a failure. See the following for more details:"
s: "kubebuilder init --plugins sampleexternalplugin/v1 --domain sample.domain.com failed with error: (exit status 1) Error: no plugin could be resolved with key \"sampleexternalplugin/v1\"\nUsage:\n kubebuilder [flags]\n\nExamples:\nThe first step is to initialize your project:\n kubebuilder init [--plugins=<PLUGIN KEYS> [--project-version=<PROJECT VERSION>]]\n\n<PLUGIN KEYS> is a comma-separated list of plugin keys from the following table\nand <PROJECT VERSION> a supported project version for these plugins.\n\n Plugin keys | Supported project versions\n-----------------------------------------+----------------------------\n base.go.kubebuilder.io/v3 | 3\n base.go.kubebuilder.io/v4 | 3\n declarative.go.kubebuilder.io/v1 | 2, 3\n deploy-image.go.kubebuilder.io/v1-alpha | 3\n go.kubebuilder.io/v2 | 2, 3\n go.kubebuilder.io/v3 | 3\n go.kubebuilder.io/v4 | 3\n grafana.kubebuilder.io/v1-alpha | 3\n kustomize.common.kubebuilder.io/v1 | 3\n kustomize.common.kubebuilder.io/v2 | 3\n\nFor more specific help for the init command of a certain plugins and project version\nconfiguration please run:\n kubebuilder init --help --plugins=<PLUGIN KEYS> [--project-version=<PROJECT VERSION>]\n\nDefault plugin keys: \"go.kubebuilder.io/v4\"\nDefault project version: \"3\"\n\n\nFlags:\n -h, --help help for kubebuilder\n --plugins strings plugin keys to be used for this subcommand execution\n --project-version string project version (default \"3\")\n\n2023/05/24 13:03:58 no plugin could be resolved with key \"sampleexternalplugin/v1\"\n",
}
occurred
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.
Hey @camilamacedo86 , I'm trying to follow your idea:
Since test/e2e/utils
provides context to bring rich prerequisites, including k8s cluster
, kubectl
, kubebuilder
.
That is how e2e tests get performed for internal plugins.
So, it is not necessary/consistent to deal with prerequisites on a different pattern, such as running a new script.
Is that something you mentioned of and such external-plugin should NOT break?
We currently do not utilize any shell scripting to accomplish the tasks required for our end-to-end (e2e) tests.
Here is my opinion:
We have a well-structured directory under test/e2e
:
- those single files such as
local.sh
,setup.sh
are used to provide the general environment for e2e testing - plugin related stuff are put into separate files such as
v4
,deployimage
To maintain that way, when we create a new e2e test suite for external-plugin, it is not necessary/recommended to touch those public files in 1
.
Then, if building and configuring external-plugin is needed, we can follow what we did to other plugins:
- At the very beginning in the ginkgo context, use go code to build and configure external-plugin
- At the end of the ginkgo context, delete the temporary asset for external-plugin
SOURCE_DIR="./docs/book/src/simple-external-plugin-tutorial/testdata/sampleexternalplugin/v1" | ||
cd $SOURCE_DIR && go build -o $PLUGIN_NAME && mv $PLUGIN_NAME "$EXTERNAL_PLUGIN_PATH" | ||
|
||
kubebuilder init --plugins="${PLUGIN_NAME}/${PLUGIN_VERSION}" --help | grep --quiet "$PLUGIN_NAME" |
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.
Nice touch, but this introduces a dependency on the kubebuilder
binary being in your PATH when you run this script. Ideally the build script will not use something in the PATH but rather a location we can control during the build. There are a couple options here:
- We remove this line and don't test that kubebuilder can initialize with this plugin as part of building the plugin
- We build a local version of the kubebuilder binary from source to use for testing this as part of this script
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 like we already have a shell function for building kubebuilder here:
Line 104 in 804fed4
function build_kb { |
Makefile
Outdated
## To keep the same kind cluster between test runs, use `SKIP_KIND_CLEANUP=1 make test-e2e-local` | ||
./test/e2e/local.sh | ||
|
||
.PHONY: test-e2e-ci | ||
test-e2e-ci: ## Run the end-to-end tests (used in the CI)` | ||
test-e2e-ci: build-external-plugin ## Run the end-to-end tests (used in the CI)` |
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 is still needed. IIUC, just the execution of the go tests were added in the Prow configuration
if [ $? -eq 0 ]; then | ||
echo "External plugin is built at: $EXTERNAL_PLUGIN_DESTINATION" | ||
else | ||
echo "FAIL to build external plugin" |
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.
+1
# TODO: Dynamically set exteranl plugin destination based on OS platform | ||
EXTERNAL_PLUGIN_DESTINATION_PREFIX="${HOME}/Library/Application Support/kubebuilder/plugins" |
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 making me wonder if it would be worth implementing the functionality to configure where kubebuilder should search for external plugins sooner rather than later. I'm not a huge fan of having e2e tests making modifications to a HOME directory.
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 completely agree with your assessment.
Modifying the HOME directory during e2e testing is indeed not an ideal scenario, and it may lead to unforeseen issues or conflicts.
I think allowing users to configure the path for searching external plugins would significantly increase the flexibility and control over the system.
Wondering if it's possible to read a configuration file or an environment variable provided by the user, to specify the desired path for the plugin search? Hope in this way we could avoid making assumptions about the user's directory structure or enforcing unnecessary constraints.
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.
One approach maybe:
Introduce an env var KB_PLUGIN_PATH
when executing the kb command to tell the path of the external plugin.
KB_PLUGIN_PATH="/opt/app/kubebuilder/plugin" \
kubebuilder create api --plugins=myexternalplugin/v1
If such env does not exist, fall back to the default (currently used) path.
func GenerateProject(kbc *utils.TestContext) { | ||
var err error | ||
|
||
By("initializing a 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.
I don't disagree that it might be easier to maintain, but I think there is a lot of precedence to build stuff in a shell script for the e2e tests. IMO we shouldn't try to reinvent the wheel by adding this to the go code and follow the existing pattern for building and configuring e2e tests with shell scripts.
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 the shell script approach is good, however I'm not sure this needs its own shell script. Taking a look at the overall test/
directory, there is a common.sh file that contains a bunch of shell functions to build and configure things for e2e tests and then are used like:
Lines 17 to 19 in 804fed4
build_kb | |
fetch_tools | |
install_kind |
My recommendation would be that we try to follow the existing pattern as much as possible
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.
For clarification, my recommendation is that we:
- Make this shell script a new function in the common.sh file
- call this function in the
test/e2e/setup.sh
script similar to the snippet I shared above
set -e | ||
|
||
# TODO: Dynamically set exteranl plugin destination based on OS platform | ||
EXTERNAL_PLUGIN_DESTINATION_PREFIX="${HOME}/Library/Application Support/kubebuilder/plugins" |
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.
@everettraven @rashmigottipati Will this path exist in the prow ?
I think we might need to put at in test/e2e/externalplugin/bin
Co-authored-by: Bryce Palmer <everettraven@gmail.com>
81980a5
to
78b7b50
Compare
78b7b50
to
926dd60
Compare
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
nits: better to set the external plugin path flexibly.
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 looks great! Awesome work @Eileen-Yu !
/lgtm
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.
Great work @Eileen-Yu,
/lgtm
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.
Great work 馃
We can improve it in follow ups.
That is a really amazing job
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: camilamacedo86, Eileen-Yu, everettraven, Kavinjsir, rashmigottipati The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Description:
Add e2e tests for sample external plugin
Motivation:
Validate the functionality and the behavior of the sample external plugin.