Skip to content

Commit db470ef

Browse files
committed
test(e2e): add precheck for affinity and toleration e2e
Signed-off-by: Dmitry Lopatin <dmitry.lopatin@flant.com>
1 parent a01cf49 commit db470ef

3 files changed

Lines changed: 112 additions & 1 deletion

File tree

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
Copyright 2026 Flant JSC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package precheck
18+
19+
import (
20+
"context"
21+
"fmt"
22+
23+
"github.com/deckhouse/virtualization/test/e2e/internal/framework"
24+
. "github.com/onsi/ginkgo/v2"
25+
corev1 "k8s.io/api/core/v1"
26+
crclient "sigs.k8s.io/controller-runtime/pkg/client"
27+
)
28+
29+
const (
30+
affinityTolerationPrecheckEnvName = "AFFINITY_TOLERATION_PRECHECK"
31+
affinityTolerationNodeGroupLabelKey = "node.deckhouse.io/group"
32+
affinityTolerationKVMLabelKey = "virtualization.deckhouse.io/kvm-enabled"
33+
34+
minReadyKVMNodes = 2
35+
minReadyKVMMasterNodes = 1
36+
minReadyKVMWorkerNodes = 2
37+
)
38+
39+
// affinityTolerationPrecheck implements Precheck interface for VM affinity/toleration test cluster requirements.
40+
type affinityTolerationPrecheck struct{}
41+
42+
func (a *affinityTolerationPrecheck) Label() string {
43+
return PrecheckAffinityToleration
44+
}
45+
46+
func (a *affinityTolerationPrecheck) Run(ctx context.Context, f *framework.Framework) error {
47+
if !isCheckEnabled(affinityTolerationPrecheckEnvName) {
48+
_, _ = GinkgoWriter.Write([]byte("Affinity/toleration precheck is disabled.\n"))
49+
return nil
50+
}
51+
52+
kvmNodes, err := listReadyNodesByLabels(ctx, f, map[string]string{affinityTolerationKVMLabelKey: "true"})
53+
if err != nil {
54+
return fmt.Errorf("%s=no to disable this precheck: failed to list ready KVM-enabled nodes: %w", affinityTolerationPrecheckEnvName, err)
55+
}
56+
if len(kvmNodes) < minReadyKVMNodes {
57+
return fmt.Errorf("%s=no to disable this precheck: at least %d ready KVM-enabled nodes are required, got %d", affinityTolerationPrecheckEnvName, minReadyKVMNodes, len(kvmNodes))
58+
}
59+
60+
masterNodes, err := listReadyNodesByLabels(ctx, f, map[string]string{
61+
affinityTolerationKVMLabelKey: "true",
62+
affinityTolerationNodeGroupLabelKey: "master",
63+
})
64+
if err != nil {
65+
return fmt.Errorf("%s=no to disable this precheck: failed to list ready KVM-enabled master nodes: %w", affinityTolerationPrecheckEnvName, err)
66+
}
67+
if len(masterNodes) < minReadyKVMMasterNodes {
68+
return fmt.Errorf("%s=no to disable this precheck: at least %d ready KVM-enabled master node is required, got %d", affinityTolerationPrecheckEnvName, minReadyKVMMasterNodes, len(masterNodes))
69+
}
70+
71+
workerNodes, err := listReadyNodesByLabels(ctx, f, map[string]string{
72+
affinityTolerationKVMLabelKey: "true",
73+
affinityTolerationNodeGroupLabelKey: "worker",
74+
})
75+
if err != nil {
76+
return fmt.Errorf("%s=no to disable this precheck: failed to list ready KVM-enabled worker nodes: %w", affinityTolerationPrecheckEnvName, err)
77+
}
78+
if len(workerNodes) < minReadyKVMWorkerNodes {
79+
return fmt.Errorf("%s=no to disable this precheck: at least %d ready KVM-enabled worker nodes are required, got %d", affinityTolerationPrecheckEnvName, minReadyKVMWorkerNodes, len(workerNodes))
80+
}
81+
82+
return nil
83+
}
84+
85+
func listReadyNodesByLabels(ctx context.Context, f *framework.Framework, labels map[string]string) ([]corev1.Node, error) {
86+
nodes := &corev1.NodeList{}
87+
err := f.GenericClient().List(ctx, nodes, crclient.MatchingLabels(labels))
88+
if err != nil {
89+
return nil, err
90+
}
91+
92+
readyNodes := make([]corev1.Node, 0, len(nodes.Items))
93+
for _, node := range nodes.Items {
94+
for _, condition := range node.Status.Conditions {
95+
if condition.Type == corev1.NodeReady && condition.Status == corev1.ConditionTrue {
96+
readyNodes = append(readyNodes, node)
97+
break
98+
}
99+
}
100+
}
101+
102+
return readyNodes, nil
103+
}
104+
105+
func init() {
106+
RegisterPrecheck(&affinityTolerationPrecheck{}, false)
107+
}

test/e2e/internal/precheck/labels.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ const (
4545
// PrecheckUSB - test requires USB device with dummy_hcd to be configured.
4646
PrecheckUSB = "usb-precheck"
4747

48+
// PrecheckAffinityToleration - test requires enough ready KVM-enabled master/worker nodes.
49+
PrecheckAffinityToleration = "affinity-toleration-precheck"
50+
4851
// PrecheckPostCleanup - test requires postcleanup to be configured.
4952
PrecheckPostCleanup = "postcleanup-precheck"
5053

@@ -68,6 +71,7 @@ func KnownPrecheckLabels() []string {
6871
PrecheckSnapshot,
6972
PrecheckVirtualization,
7073
PrecheckUSB,
74+
PrecheckAffinityToleration,
7175
PrecheckPostCleanup,
7276
PrecheckPrecreatedCVI,
7377
NoPrecheck,

test/e2e/vm/affinity_toleration.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const (
5555
migrationTargetMustDiffer
5656
)
5757

58-
var _ = Describe("VirtualMachineAffinityAndToleration", Ordered, Label(precheck.NoPrecheck), func() {
58+
var _ = Describe("VirtualMachineAffinityAndToleration", Ordered, Label(precheck.PrecheckAffinityToleration), func() {
5959
var (
6060
f *framework.Framework
6161
ctx context.Context

0 commit comments

Comments
 (0)