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

Add tests for k0scontrolplane controller #806

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ func main() {

if err = (&controlplane.K0sController{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
ClientSet: clientSet,
RESTConfig: restConfig,
}).SetupWithManager(mgr); err != nil {
Expand Down
70 changes: 11 additions & 59 deletions docs/contributing/contribute-testing.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,22 @@
# Testing guidelines

k0smotron uses GitHub actions to run automated tests on all pull requests prior to merging.
Pull request will not be reviewed before all tests are green,
so to save time and prevent your Pull request from going stale,
it is best to test it before submitting the pull request.
K0smotron follows a comprehensive testing strategy that includes unit, integration, and e2e testing to ensure the reliability and robustness of the system.

## Run local verifications
All unit, integration, and e2e tests are executed automatically on pull requests that are intended to be merged, ensuring that changes are thoroughly validated before integration into the main codebase. These tests are executed using [GitHub Actions](https://docs.github.com/en/actions), which provides a seamless and automated way to validate proposed changes. This layered approach ensures that proposed changes are both correct and meet the expected quality standards.

Run the following style and formatting commands to fix or check-in the changes:
For details on the contribution process, including how to follow the GitHub workflow and ensure your changes pass all necessary validations, please refer to the [Contributing Workflow](contribute-workflow.md).

1. Verify code style using [`golangci-lint`](https://golangci-lint.run/). In the root directory of the repository run:
## Unit and Integration Testing

```shell
make lint
```
In k0smotron project, tests are prioritized to execute quickly in order to maintain a fast feedback loop, ensuring efficient and agile development.

The build system automatically installs `golangci-lint`.
K0smotron uses [go test](https://pkg.go.dev/testing) as the foundation for all our tests, combined with the [testify](https://pkg.go.dev/github.com/stretchr/testify) library to simplify assertions and improve test readability and reliability. Both unit and integration tests rely on this approach to ensure consistency and ease of development.

2. Format Go source code using the `go fmt` command:
- **Unit Testing**: Focused on isolated components, unit tests validate the correctness of individual functions or methods in a controlled environment, ensuring they behave as expected.

- **Integration Testing**: For integration testing, k0smotron uses [envtest](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/envtest), which provides a lightweight Kubernetes control plane with the essential components needed to test interactions between the code and Kubernetes API. This approach allows us to validate the behavior of our controllers and other Kubernetes integrations in a reproducible and efficient manner without requiring a full cluster.

```shell
go fmt ./...
```
Following the best practices suggested in the [Cluster API documentation](https://cluster-api.sigs.k8s.io/developer/core/testing), integration tests are written using [**generic infrastructure providers**](https://cluster-api.sigs.k8s.io/developer/core/testing#generic-providers) rather than a specific provider. This ensures that tests remain agnostic and reusable across different infrastructures, fostering better maintainability and adaptability.

3. Check documentation.
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 all this should be in contribute workflow instead testing so I moved it there


The Dockerized setup is used to locally perform documentation tests.
Run `make docs-serve-dev` to build documentation on http://localhost:8000.

If your port `8000` is busy, run `make docs-serve-dev DOCS_DEV_PORT=9999`.
The documentation page will be available on http://localhost:9999.

4. Pre-submit flight checks.

In the repository root directory, ensure that the following commands are successfully run:

* `make build && git diff --exit-code`
This command verifies that the build is working
and that the generated source code matches the code checked into source control.
* `make test`
This command verifies that all the unit tests pass.

Once all tests have passed, you can open a pull request upstream.

## Open pull request

### Draft mode

If you open a pull request in draft mode, it will only go through the automated testing.
Once you decide the PR is ready for review, transition it out of draft mode to notify the k0smotron team.

### Pre-requisites for merge

In order for a pull request to be merged, the following conditions should be met:

1. The PR has passed all the automated tests (style, build and conformance tests).
1. All the PR commits have been signed with the `--signoff` option.
1. The PR has been reviewed and approved by a code owner.
1. The PR has been rebased against upstream main branch.

## Cleanup local workspace

Run `make clean` to remove all the intermediate files and directories created
locally during the k0smotron build.
You cannot use `git clean -X` or `rm -rf`, since the Go modules
cache sets all of its subdirectories to read-only.
If you encounter problems during a deletion process,
run `chmod -R u+w /path/to/workspace && rm -rf /path/to/workspace`.
## E2E testing
TBD
58 changes: 58 additions & 0 deletions docs/contributing/contribute-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,41 @@ Create pull requests to contribute to [k0smotron GitHub repository](http://githu
Too many commits make the history messy and violate the principle
that commits ought to be individually understandable and useful.

## Run local verifications

Run the following style and formatting commands to fix or check-in the changes:

1. Verify code style using [`golangci-lint`](https://golangci-lint.run/). In the root directory of the repository run:
```shell
make lint
```
The build system automatically installs `golangci-lint`.

2. Format Go source code using the `go fmt` command:
```shell
go fmt ./...
```

3. Check documentation.

The Dockerized setup is used to locally perform documentation tests.
Run `make docs-serve-dev` to build documentation on http://localhost:8000.

If your port `8000` is busy, run `make docs-serve-dev DOCS_DEV_PORT=9999`.
The documentation page will be available on http://localhost:9999.

4. Pre-submit flight checks.

In the repository root directory, ensure that the following commands are successfully run:

* `make build && git diff --exit-code`
This command verifies that the build is working
and that the generated source code matches the code checked into source control.
* `make test`
This command verifies that all the unit tests pass.

Once all tests have passed, you can open a pull request upstream.

## Commit and push

Commit and sign your changes:
Expand Down Expand Up @@ -104,6 +139,20 @@ git push --set-upstream my_fork my_feature_branch

Refer to the official GitHub documentation [Creating a pull request from a fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork).

### Draft mode

If you open a pull request in draft mode, it will only go through the automated testing.
Once you decide the PR is ready for review, transition it out of draft mode to notify the k0smotron team.

### Pre-requisites for merge

In order for a pull request to be merged, the following conditions should be met:

1. The PR has passed all the automated tests (style, build and conformance tests).
1. All the PR commits have been signed with the `--signoff` option.
1. The PR has been reviewed and approved by a code owner.
1. The PR has been rebased against upstream main branch.

### Wait for code review

The k0smotron team will review your pull request and leave comments.
Expand All @@ -127,3 +176,12 @@ git push --force
```

If necessary, you can run multiple iteration of `rebase`/`push -f`.

## Cleanup local workspace

Run `make clean` to remove all the intermediate files and directories created
locally during the k0smotron build.
You cannot use `git clean -X` or `rm -rf`, since the Go modules
cache sets all of its subdirectories to read-only.
If you encounter problems during a deletion process,
run `chmod -R u+w /path/to/workspace && rm -rf /path/to/workspace`.
10 changes: 6 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.22.0
require (
github.com/cloudflare/cfssl v1.6.4
github.com/go-logr/logr v1.4.2
github.com/gobuffalo/flect v1.0.2
github.com/google/uuid v1.6.0
github.com/imdario/mergo v0.3.16
github.com/k0sproject/k0s v1.27.2-0.20230504131248-94378e521a29
Expand All @@ -16,8 +17,11 @@ require (
github.com/stretchr/testify v1.9.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.30.3
k8s.io/apiextensions-apiserver v0.30.3
k8s.io/apimachinery v0.30.3
k8s.io/client-go v0.30.3
k8s.io/klog/v2 v2.120.1
k8s.io/kubectl v0.30.3
k8s.io/kubernetes v1.30.3
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0
sigs.k8s.io/controller-runtime v0.18.5
Expand Down Expand Up @@ -57,7 +61,7 @@ require (
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
golang.org/x/crypto v0.27.0
golang.org/x/sync v0.8.0 // indirect
golang.org/x/tools v0.24.0 // indirect
golang.org/x/tools v0.24.0
gotest.tools/v3 v3.4.0 // indirect
helm.sh/helm/v3 v3.11.3 // indirect
k8s.io/kube-aggregator v0.27.2 // indirect
Expand Down Expand Up @@ -90,7 +94,6 @@ require (
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/gobuffalo/flect v1.0.2 // indirect
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
Expand Down Expand Up @@ -152,6 +155,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/oauth2 v0.21.0 // indirect
golang.org/x/sys v0.25.0 // indirect
Expand All @@ -166,14 +170,12 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/apiextensions-apiserver v0.30.3 // indirect
k8s.io/apiserver v0.30.3 // indirect
k8s.io/cloud-provider v0.27.1 // indirect
k8s.io/cluster-bootstrap v0.30.3 // indirect
k8s.io/component-base v0.30.3 // indirect
k8s.io/component-helpers v0.30.3 // indirect
k8s.io/controller-manager v0.30.3 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/kms v0.30.3 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/kubelet v0.27.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,8 @@ k8s.io/kube-aggregator v0.30.3 h1:hy5zfQ7p6BuJgc/XtGp3GBh2MPfOj6b1n3raKKMHOQE=
k8s.io/kube-aggregator v0.30.3/go.mod h1:2SP0IckvQoOwwZN8lmtWUnTZTgIpwOWvidWtxyqLwuk=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
k8s.io/kubectl v0.30.3 h1:YIBBvMdTW0xcDpmrOBzcpUVsn+zOgjMYIu7kAq+yqiI=
k8s.io/kubectl v0.30.3/go.mod h1:IcR0I9RN2+zzTRUa1BzZCm4oM0NLOawE6RzlDvd1Fpo=
k8s.io/kubelet v0.30.3 h1:KvGWDdhzD0vEyDyGTCjsDc8D+0+lwRMw3fJbfQgF7ys=
k8s.io/kubelet v0.30.3/go.mod h1:D9or45Vkzcqg55CEiqZ8dVbwP3Ksj7DruEVRS9oq3Ys=
k8s.io/kubernetes v1.30.3 h1:A0qoXI1YQNzrQZiff33y5zWxYHFT/HeZRK98/sRDJI0=
Expand Down
8 changes: 6 additions & 2 deletions internal/controller/controlplane/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (c *K0sController) createMachine(ctx context.Context, name string, cluster
if err != nil {
return nil, fmt.Errorf("error generating machine: %w", err)
}
_ = ctrl.SetControllerReference(kcp, machine, c.Scheme)
_ = ctrl.SetControllerReference(kcp, machine, c.Client.Scheme())
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of curiosity, why do we change it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

writing tests for the controller I saw that we access the schema at this point and I thought about refactoring it using the client schema directly and remove K0scontroller.Scheme field. Both are obtained from manager.Manager so I thought it was safe to make this change


err = c.Client.Patch(ctx, machine, client.Apply, &client.PatchOptions{
FieldManager: "k0smotron",
Expand Down Expand Up @@ -226,7 +226,11 @@ func (c *K0sController) generateMachineFromTemplate(ctx context.Context, name st
return nil, err
}

_ = ctrl.SetControllerReference(kcp, infraMachineTemplate, c.Scheme)
_ = ctrl.SetControllerReference(cluster, infraMachineTemplate, c.Client.Scheme())
err = c.Client.Patch(ctx, infraMachineTemplate, client.Merge, &client.PatchOptions{FieldManager: "k0smotron"})
if err != nil {
return nil, err
}

template, found, err := unstructured.NestedMap(infraMachineTemplate.UnstructuredContent(), "spec", "template")
if !found {
Expand Down
Loading
Loading