Skip to content
Open
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
2 changes: 1 addition & 1 deletion hack/go-unit-tests-vpa.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ set -o nounset
CONTRIB_ROOT="$(dirname ${BASH_SOURCE})/.."

pushd ${CONTRIB_ROOT}/vertical-pod-autoscaler
go test -count=1 -race $(go list ./... | grep -v /vendor/ | grep -v vertical-pod-autoscaler/e2e)
go test -count=1 -race $(go list ./... | grep -v /vendor/ | grep -v vertical-pod-autoscaler/e2e | grep -v vertical-pod-autoscaler/integration)
popd
pushd ${CONTRIB_ROOT}/vertical-pod-autoscaler/e2e
go test -run=None ./...
Expand Down
34 changes: 27 additions & 7 deletions vertical-pod-autoscaler/common/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,38 @@ type CommonFlags struct {
IgnoredVpaObjectNamespaces string
}

// DefaultCommonConfig returns the default values for common flags
func DefaultCommonConfig() *CommonFlags {
return &CommonFlags{
KubeConfig: "",
KubeApiQps: 50.0,
KubeApiBurst: 100.0,
EnableProfiling: false,
VpaObjectNamespace: apiv1.NamespaceAll,
IgnoredVpaObjectNamespaces: "",
}
}

// InitCommonFlags initializes the common flags
func InitCommonFlags() *CommonFlags {
cf := &CommonFlags{}
flag.StringVar(&cf.KubeConfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
flag.Float64Var(&cf.KubeApiQps, "kube-api-qps", 50.0, "QPS limit when making requests to Kubernetes apiserver")
flag.Float64Var(&cf.KubeApiBurst, "kube-api-burst", 100.0, "QPS burst limit when making requests to Kubernetes apiserver")
flag.BoolVar(&cf.EnableProfiling, "profiling", false, "Is debug/pprof endpoint enabled")
flag.StringVar(&cf.VpaObjectNamespace, "vpa-object-namespace", apiv1.NamespaceAll, "Specifies the namespace to search for VPA objects. Leave empty to include all namespaces. If provided, the garbage collector will only clean this namespace.")
flag.StringVar(&cf.IgnoredVpaObjectNamespaces, "ignored-vpa-object-namespaces", "", "A comma-separated list of namespaces to ignore when searching for VPA objects. Leave empty to avoid ignoring any namespaces. These namespaces will not be cleaned by the garbage collector.")
cf := DefaultCommonConfig()
flag.StringVar(&cf.KubeConfig, "kubeconfig", cf.KubeConfig, "Path to a kubeconfig. Only required if out-of-cluster.")
flag.Float64Var(&cf.KubeApiQps, "kube-api-qps", cf.KubeApiQps, "QPS limit when making requests to Kubernetes apiserver")
flag.Float64Var(&cf.KubeApiBurst, "kube-api-burst", cf.KubeApiBurst, "QPS burst limit when making requests to Kubernetes apiserver")
flag.BoolVar(&cf.EnableProfiling, "profiling", cf.EnableProfiling, "Is debug/pprof endpoint enabled")
flag.StringVar(&cf.VpaObjectNamespace, "vpa-object-namespace", cf.VpaObjectNamespace, "Specifies the namespace to search for VPA objects. Leave empty to include all namespaces. If provided, the garbage collector will only clean this namespace.")
flag.StringVar(&cf.IgnoredVpaObjectNamespaces, "ignored-vpa-object-namespaces", cf.IgnoredVpaObjectNamespaces, "A comma-separated list of namespaces to ignore when searching for VPA objects. Leave empty to avoid ignoring any namespaces. These namespaces will not be cleaned by the garbage collector.")
return cf
}

// ValidateCommonConfig performs validation of the common flags
func ValidateCommonConfig(config *CommonFlags) {
Copy link
Member

Choose a reason for hiding this comment

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

This seems to be only used in the admission controller right now.

if len(config.VpaObjectNamespace) > 0 && len(config.IgnoredVpaObjectNamespaces) > 0 {
klog.ErrorS(nil, "--vpa-object-namespace and --ignored-vpa-object-namespaces are mutually exclusive and can't be set together.")
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
}
}

// InitLoggingFlags initializes the logging flags
func InitLoggingFlags() {
// Set the default log level to 4 (info)
Expand Down
29 changes: 29 additions & 0 deletions vertical-pod-autoscaler/docs/development-and-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<!-- toc -->
- [Introduction](#introduction)
- [Running integration tests](#running-integration-tests)
- [Running e2e tests](#running-e2e-tests)
- [Feature gates](#feature-gates)
- [Parallelism](#parallelism)
Expand All @@ -14,6 +15,34 @@

This project contains various scripts and tools to aid in the development of the three VPA components.

## Running integration tests

The VPA contains integration tests that test individual components in isolation using [controller-runtime's envtest](https://github.com/kubernetes-sigs/controller-runtime/tree/main/tools/setup-envtest) environment.

They can be run using the `./hack/run-integration-tests.sh` helper script. This script automatically downloads and manages the required Kubernetes API server and etcd binaries for testing.

Integration tests are faster than e2e tests and do not require a full Kubernetes cluster. They are suitable for testing:

- Component-specific behavior and logic
- Configuration handling
- API object validation
- Resource filtering and selection logic

**Example usage:**

```bash
# Run all integration tests
./hack/run-integration-tests.sh

# Run a specific test
./hack/run-integration-tests.sh -run TestRecommenderWithNamespaceFiltering

# Run tests with custom parallelism
./hack/run-integration-tests.sh -parallel 8
```

By default, integration tests run with 4 parallel workers.

## Running e2e tests

The VPA contains some e2e tests that test how each component interacts with Pods and VPA resources inside a real Kubernetes cluster.
Expand Down
2 changes: 1 addition & 1 deletion vertical-pod-autoscaler/docs/flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ This document is auto-generated from the flag definitions in the VPA updater cod
| `alsologtostderr` | | | log to standard error as well as files (no effect when -logtostderr=true) |
| `evict-after-oom-threshold` | | 10m0s | duration Evict pod that has OOMed in less than evict-after-oom-threshold since start. |
| `eviction-rate-burst` | int | 1 | Burst of pods that can be evicted. |
| `eviction-rate-limit` | float | | Number of pods that can be evicted per seconds. A rate limit set to 0 or -1 will disable<br>the rate limiter. (default -1) |
| `eviction-rate-limit` | float | -1 | Number of pods that can be evicted per seconds. A rate limit set to 0 or -1 will disable the rate limiter. |
| `eviction-tolerance` | float | 0.5 | Fraction of replica count that can be evicted for update, if more than one pod can be evicted. |
| `feature-gates` | mapStringBool | | A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:<br>AllAlpha=true\|false (ALPHA - default=false)<br>AllBeta=true\|false (BETA - default=false)<br>PerVPAConfig=true\|false (ALPHA - default=false) |
| `ignored-vpa-object-namespaces` | string | | A comma-separated list of namespaces to ignore when searching for VPA objects. Leave empty to avoid ignoring any namespaces. These namespaces will not be cleaned by the garbage collector. |
Expand Down
4 changes: 2 additions & 2 deletions vertical-pod-autoscaler/e2e/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ require (
k8s.io/apiserver v0.35.0
k8s.io/autoscaler/vertical-pod-autoscaler v1.5.1
k8s.io/client-go v0.35.0
k8s.io/component-base v0.35.0
k8s.io/klog/v2 v2.130.1
k8s.io/kubernetes v1.35.0
k8s.io/pod-security-admission v0.35.0
Expand Down Expand Up @@ -162,6 +161,7 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.35.0 // indirect
k8s.io/cloud-provider v0.35.0 // indirect
k8s.io/component-base v0.35.0 // indirect
k8s.io/component-helpers v0.35.0 // indirect
k8s.io/controller-manager v0.35.0 // indirect
k8s.io/cri-api v0.35.0 // indirect
Expand All @@ -177,7 +177,7 @@ require (
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)

Expand Down
4 changes: 2 additions & 2 deletions vertical-pod-autoscaler/e2e/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A
sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E=
sigs.k8s.io/structured-merge-diff/v6 v6.3.1/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs=
sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
4 changes: 2 additions & 2 deletions vertical-pod-autoscaler/e2e/integration/recommender.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func testIncludedAndIgnoredNamespaces(f *framework.Framework, vpaClientSet vpa_c
ignoredVpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(ignoredNamespace).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(container1Name).
WithScalingMode(container1Name, vpa_types.ContainerScalingModeOff).
WithContainer(container2Name).
Expand All @@ -113,7 +113,7 @@ func testIncludedAndIgnoredNamespaces(f *framework.Framework, vpaClientSet vpa_c
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(includedNamespace).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(container1Name).
WithScalingMode(container1Name, vpa_types.ContainerScalingModeOff).
WithContainer(container2Name).
Expand Down
7 changes: 0 additions & 7 deletions vertical-pod-autoscaler/e2e/utils/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,6 @@ func init() {
}
}

// HamsterTargetRef is CrossVersionObjectReference of hamster app
var HamsterTargetRef = &autoscaling.CrossVersionObjectReference{
APIVersion: "apps/v1",
Kind: "Deployment",
Name: "hamster-deployment",
}
Comment on lines -71 to -76
Copy link
Member Author

Choose a reason for hiding this comment

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

This is moved out of the e2e directory.
I didn't want to give the integration tests its own go.mod file, and I didn't want to make the VPA depend on things inside the e2e tests, so handle that, I moved this out of e2e so that it could be used in the integration tests.


// RecommenderLabels are labels of VPA recommender
var RecommenderLabels = map[string]string{"app": "vpa-recommender"}

Expand Down
26 changes: 13 additions & 13 deletions vertical-pod-autoscaler/e2e/v1/actuation.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithUpdateMode(vpa_types.UpdateModeInPlaceOrRecreate).
WithContainer(containerName).
AppendRecommendation(
Expand Down Expand Up @@ -126,7 +126,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(container1Name).
WithContainer(container2Name).
WithUpdateMode(vpa_types.UpdateModeInPlaceOrRecreate).
Expand Down Expand Up @@ -189,7 +189,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(containerName).
WithUpdateMode(vpa_types.UpdateModeInPlaceOrRecreate).
AppendRecommendation(
Expand Down Expand Up @@ -231,7 +231,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(containerName).
WithUpdateMode(vpa_types.UpdateModeInPlaceOrRecreate).
AppendRecommendation(
Expand Down Expand Up @@ -293,7 +293,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(containerName).
AppendRecommendation(
test.Recommendation().
Expand Down Expand Up @@ -325,7 +325,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithUpdateMode(vpa_types.UpdateModeOff).
WithContainer(containerName).
AppendRecommendation(
Expand Down Expand Up @@ -363,7 +363,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithUpdateMode(vpa_types.UpdateModeInitial).
WithContainer(containerName).
AppendRecommendation(
Expand Down Expand Up @@ -475,7 +475,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(containerName).
AppendRecommendation(
test.Recommendation().
Expand Down Expand Up @@ -534,7 +534,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(containerName).
AppendRecommendation(
test.Recommendation().
Expand Down Expand Up @@ -568,7 +568,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(containerName).
AppendRecommendation(
test.Recommendation().
Expand Down Expand Up @@ -605,7 +605,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(container1Name).
AppendRecommendation(
test.Recommendation().
Expand Down Expand Up @@ -650,7 +650,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(container1Name).
AppendRecommendation(
test.Recommendation().
Expand Down Expand Up @@ -715,7 +715,7 @@ var _ = ActuationSuiteE2eDescribe("Actuation", func() {
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(utils.HamsterTargetRef).
WithTargetRef(test.HamsterTargetRef).
WithContainer(container1Name).
AppendRecommendation(
test.Recommendation().
Expand Down
Loading