Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d88615a
feat(sim): Update framework to set variables as part of BeforeSuite
takoverflow Jul 31, 2026
e632571
Add simulated provider for IT testing without CSP
takoverflow Jul 31, 2026
910f655
Update go mod, run tidy
takoverflow Jul 31, 2026
c0a5e99
Update CICD test script to also run IT
takoverflow Jul 31, 2026
ca03db8
fix: Poll for machineclass secret in IT fwk
takoverflow Jul 31, 2026
53a2f0c
Fix linter failures (docstring and reduced file permissions on write)
takoverflow Jul 31, 2026
b3e29a4
Address Review Comments
takoverflow Aug 6, 2026
97f7a81
Switch the managedNodes to have only required info as map value
takoverflow Aug 13, 2026
fc99aeb
Remove mutex from the simulated driver (not needed with sync.Map)
takoverflow Aug 14, 2026
410efa6
On clusterEnv creation, update context with the cluster name
takoverflow Aug 22, 2026
e649eca
Check for nil nodetemplate before building a node
takoverflow Aug 22, 2026
7d4a186
Fix the machine class name in managedNodes
takoverflow Aug 25, 2026
ce03c80
Add note on running IT with simulated provider
takoverflow Aug 26, 2026
249cf2e
Address review comments
takoverflow Sep 3, 2026
910e9f7
Appease the linter: docstrings for CRD objects
takoverflow Sep 3, 2026
283727c
Specify kwok version when creating the cluster
takoverflow Sep 4, 2026
ffe4afd
Update IT VAP to block node ready updates
takoverflow Sep 10, 2026
09368d8
Update kwok config to use kcm, explicit addition of stage
takoverflow Sep 10, 2026
2b92d67
Update node on VAP removal to trigger recovery
takoverflow Sep 10, 2026
3a36d58
Wait for all preserved machines to either be removed or recover
takoverflow Sep 10, 2026
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
15 changes: 11 additions & 4 deletions .ci/test
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ function test_with_coverage() {
local output_dir=test/output
local coverprofile_file=coverprofile.out
mkdir -p test/output
ginkgo $GINKGO_COMMON_FLAGS --coverprofile ${coverprofile_file} -covermode=set -output-dir ${output_dir} ${TEST_PACKAGES}
ginkgo $GINKGO_COMMON_FLAGS \
--coverprofile ${coverprofile_file} -covermode=set \
--skip-package ${SKIP_PACKAGES} \
-output-dir ${output_dir} ${TEST_PACKAGES}

sed -i -e '/mode: set/d' ${output_dir}/${coverprofile_file}
{( echo "mode: set"; cat ${output_dir}/${coverprofile_file} )} > ${output_dir}/${coverprofile_file}.temp
Expand All @@ -47,18 +50,22 @@ function test_with_coverage() {
###############################################################################

if [[ "${SKIP_UNIT_TESTS}" != "" ]]; then
echo ">>>>>Skipping unit tests"
echo ">>>>> Skipping unit tests"
else
echo ">>>>> Invoking unit tests"
TEST_PACKAGES="cmd pkg"
GINKGO_COMMON_FLAGS="-r -timeout=1h0m0s --randomize-all --randomize-suites --fail-on-pending --show-node-events"
SKIP_PACKAGES="simulatedprovider/test/integration"
GINKGO_COMMON_FLAGS="-r -timeout=1h0m0s --randomize-all --randomize-suites --fail-on-pending --show-node-events --poll-progress-after=300s --poll-progress-interval=60s"
test_with_coverage
echo ">>>>> Finished executing unit tests"
fi

# Integration tests here will always be skipped.
if [[ "${SKIP_INTEGRATION_TESTS}" != "" ]]; then
echo ">>>>> Skipping integration tests"
else
echo ">>>>> Invoking integration tests with the simulated provider"
ginkgo -v --show-node-events --poll-progress-after=300s --poll-progress-interval=60s pkg/simulatedprovider/test/integration/controller
echo ">>>>> Finished executing integration tests"
fi

#TODO: return success failure properly
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/test
/logs
/hack/tools/bin
/pkg/simulatedprovider/bin

*.html
.vscode
Expand All @@ -20,12 +21,17 @@ kubectl
.cache_ggshield

# Binary files of MCM
./machine-controller
./machine-controller-manager
./managevm

# Output of the go coverage tool, specifically when used with LiteIDE
*coverprofile.out*

# Output of MCM IT logs
**/*.log
**/*.log.*

# Autogen tags
tags

Expand Down
14 changes: 13 additions & 1 deletion docs/development/integration_tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,19 @@ Integration tests for `machine-controller-manager-provider-{provider-name}` can
- In case of non-gardener setup (control cluster is not a gardener seed), the name of the machineclass must be `test-mc-v1` and the value of `providerSpec.secretRef.name` should be `test-mc-secret`.
- In case of azure, `TARGET_CLUSTER_NAME` must be same as the name of the Azure ResourceGroup for the cluster.
- If you are deploying the secret manually, a `Secret` named `test-mc-secret` (that contains the provider secret and cloud-config) in the `default` namespace of the Control Cluster should be created.
3. The controllers log files (`mcm_process.log` and `mc_process.log`) are stored in `.ci/controllers-test/logs` repo and can be used later.
3. The controllers log files (`mcm_process.log` and `mc_process.log`) are stored in `.ci/controllers-test/logs` directory and can be used later.

### With the Simulated Provider

Before running the simulated provider, please ensure that there's no old `kwokctl` versions present on your system since the cluster creation installs the required version. But that only happens if there's no existing installation present.

To run the integration tests against the simulated provider, rather than running the `test-integration` target from the provider repository, just run it on the project root.
That is, `machine-controller-manager/Makefile` provides the same helper target that runs IT with the simulated provider.
```
make test-integration
Comment thread
takoverflow marked this conversation as resolved.
```
No additional inputs are required. The logs are stored in `pkg/simulatedprovider/test/integration/controller/logs` directory.

## Adding Integration Tests for new providers

For a new provider, Running Integration tests works with no changes. But for the orphan resource test cases to work correctly, the provider-specific API calls and the Resource Tracker Interface (RTI) should be implemented. Please check [`machine-controller-manager-provider-aws`](https://github.com/gardener/machine-controller-manager-provider-aws/blob/master/test/integration/provider/) for reference.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.66.1 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns
github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
Expand Down
44 changes: 44 additions & 0 deletions kubernetes/crds.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Gardener contributors
//
// SPDX-License-Identifier: Apache-2.0

package kubernetes

import (
_ "embed"

apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
sigyaml "sigs.k8s.io/yaml"
)

func mustUnmarshal(raw []byte) *apiextensionsv1.CustomResourceDefinition {
t := new(apiextensionsv1.CustomResourceDefinition)
err := sigyaml.Unmarshal(raw, &t)
if err != nil {
panic(err)
}
return t
}

var (
//go:embed crds/machine.sapcloud.io_machineclasses.yaml
// MachineClassCRD represents the raw bytes for MachineClass resource.
MachineClassCRD []byte
//go:embed crds/machine.sapcloud.io_machinedeployments.yaml
// MachineDeploymentCRD represents the raw bytes for MachineDeployment resource.
MachineDeploymentCRD []byte
//go:embed crds/machine.sapcloud.io_machinesets.yaml
// MachineSetCRD represents the raw bytes for MachineSet resource.
MachineSetCRD []byte
//go:embed crds/machine.sapcloud.io_machines.yaml
// MachineCRD represents the raw bytes for Machine resource.
MachineCRD []byte

// CRDs is a list of all machine-controller-manager CRDs.
CRDs = []*apiextensionsv1.CustomResourceDefinition{
mustUnmarshal(MachineClassCRD),
mustUnmarshal(MachineDeploymentCRD),
mustUnmarshal(MachineSetCRD),
mustUnmarshal(MachineCRD),
}
)
49 changes: 49 additions & 0 deletions pkg/simulatedprovider/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and Gardener contributors
#
# SPDX-License-Identifier: Apache-2.0

PKG_ROOT := $(shell dirname "$(realpath $(lastword $(MAKEFILE_LIST)))")
PKG_DIR := $(shell dirname "$(PKG_ROOT)")
REPO_ROOT := $(shell dirname "$(PKG_DIR)")
TOOLS_BIN_DIR := $(REPO_ROOT)/hack/tools/bin

KWOKCTL ?= $(TOOLS_BIN_DIR)/kwokctl
KWOK_VERSION ?= v0.8.0

$(KWOKCTL): $(TOOLS_BIN_DIR)
GOBIN=$(abspath $(TOOLS_BIN_DIR)) go install sigs.k8s.io/kwok/cmd/{kwok,kwokctl}@$(KWOK_VERSION)


.PHONY: build
build:
@mkdir -p bin
go build -v -o bin/machine-controller cmd/machine-controller/main.go

.PHONY: start
start:
@GO111MODULE=on go run \
cmd/machine-controller/main.go \
--control-kubeconfig=$(CONTROL_KUBECONFIG) \
--target-kubeconfig=$(TARGET_KUBECONFIG) \
--namespace=$(CONTROL_NAMESPACE) \
--machine-creation-timeout=20m \
--machine-drain-timeout=5m \
--machine-health-timeout=10m \
--machine-pv-detach-timeout=2m \
--machine-safety-apiserver-statuscheck-timeout=30s \
--machine-safety-apiserver-statuscheck-period=1m \
--machine-safety-orphan-vms-period=30m \
--leader-elect=$(LEADER_ELECT) \
--v=3

.PHONY: start-simulated-cluster
start-simulated-cluster: $(KWOKCTL)
$(KWOKCTL) create cluster --name "test-cluster" --config ./cluster/kwok-config.yaml

.PHONY: stop-simulated-cluster
stop-simulated-cluster: $(KWOKCTL)
$(KWOKCTL) delete cluster --name "test-cluster"

.PHONY: test-integration
test-integration:
@(cd test/integration/controller; ginkgo -v --show-node-events --poll-progress-after=300s --poll-progress-interval=60s)
Loading
Loading