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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃尡 Add e2e tests for sample external plugin #3419

Merged
merged 2 commits into from
May 31, 2023

Conversation

Eileen-Yu
Copy link
Member

Description:

Add e2e tests for sample external plugin

Motivation:

Validate the functionality and the behavior of the sample external plugin.

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels May 18, 2023
@k8s-ci-robot
Copy link
Contributor

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 /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

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.

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label May 18, 2023
@Eileen-Yu Eileen-Yu force-pushed the external-plugin-e2e branch 2 times, most recently from 1e971df to 7c65085 Compare May 19, 2023 00:14
@everettraven
Copy link
Contributor

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels May 19, 2023
Copy link
Contributor

@everettraven everettraven left a 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:

test/e2e/externalplugin/generate_test.go Outdated Show resolved Hide resolved
test/e2e/externalplugin/generate_test.go Outdated Show resolved Hide resolved
test/e2e/externalplugin/generate_test.go Outdated Show resolved Hide resolved
test/e2e/externalplugin/e2e_suite_test.go Show resolved Hide resolved
test/e2e/externalplugin/generate_test.go Show resolved Hide resolved
test/e2e/externalplugin/generate_test.go Outdated Show resolved Hide resolved
@rashmigottipati
Copy link
Contributor

/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)`
Copy link
Member

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

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 is still needed. IIUC, just the execution of the go tests were added in the Prow configuration

Copy link
Member

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

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Member

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

Copy link
Contributor

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

Copy link
Contributor

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.

Copy link
Member

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)

Copy link
Member Author

@Eileen-Yu Eileen-Yu May 24, 2023

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")
Copy link
Member

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

Copy link
Contributor

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.

Copy link
Member

@camilamacedo86 camilamacedo86 May 24, 2023

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

Copy link
Contributor

@Kavinjsir Kavinjsir May 24, 2023

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:

  1. those single files such as local.sh, setup.sh are used to provide the general environment for e2e testing
  2. 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:

  1. At the very beginning in the ginkgo context, use go code to build and configure external-plugin
  2. 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"
Copy link
Contributor

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:

  1. We remove this line and don't test that kubebuilder can initialize with this plugin as part of building the plugin
  2. We build a local version of the kubebuilder binary from source to use for testing this as part of this script

Copy link
Contributor

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:

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Comment on lines 19 to 20
# TODO: Dynamically set exteranl plugin destination based on OS platform
EXTERNAL_PLUGIN_DESTINATION_PREFIX="${HOME}/Library/Application Support/kubebuilder/plugins"
Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Contributor

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

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.

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 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:

build_kb
fetch_tools
install_kind

My recommendation would be that we try to follow the existing pattern as much as possible

Copy link
Contributor

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"
Copy link
Member

@camilamacedo86 camilamacedo86 May 26, 2023

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

@Kavinjsir Kavinjsir left a 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.

Copy link
Contributor

@everettraven everettraven left a 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

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 31, 2023
Copy link
Contributor

@rashmigottipati rashmigottipati left a 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

Copy link
Member

@camilamacedo86 camilamacedo86 left a 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

@k8s-ci-robot
Copy link
Contributor

[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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 31, 2023
@k8s-ci-robot k8s-ci-robot merged commit 40ec611 into kubernetes-sigs:master May 31, 2023
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants