Skip to content

Commit 5058474

Browse files
authored
test: refactor sizing policy e2e test (#1734)
Signed-off-by: Valeriy Khorunzhin <[email protected]>
1 parent f0d47a5 commit 5058474

File tree

21 files changed

+349
-585
lines changed

21 files changed

+349
-585
lines changed

test/e2e/e2e_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121

2222
. "github.com/onsi/ginkgo/v2"
2323
. "github.com/onsi/gomega"
24+
"sigs.k8s.io/controller-runtime/pkg/log"
25+
"sigs.k8s.io/controller-runtime/pkg/log/zap"
2426

2527
_ "github.com/deckhouse/virtualization/test/e2e/blockdevice"
2628
"github.com/deckhouse/virtualization/test/e2e/controller"
@@ -29,6 +31,7 @@ import (
2931
)
3032

3133
func TestE2E(t *testing.T) {
34+
log.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
3235
RegisterFailHandler(Fail)
3336
RunSpecs(t, "Tests")
3437
}

test/e2e/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ require (
3030
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
3131
github.com/go-errors/errors v1.4.2 // indirect
3232
github.com/go-logr/logr v1.4.2 // indirect
33+
github.com/go-logr/zapr v1.3.0 // indirect
3334
github.com/go-openapi/jsonpointer v0.21.0 // indirect
3435
github.com/go-openapi/jsonreference v0.20.2 // indirect
3536
github.com/go-openapi/swag v0.23.0 // indirect
@@ -60,6 +61,8 @@ require (
6061
github.com/spf13/pflag v1.0.7 // indirect
6162
github.com/x448/float16 v0.8.4 // indirect
6263
github.com/xlab/treeprint v1.2.0 // indirect
64+
go.uber.org/multierr v1.11.0 // indirect
65+
go.uber.org/zap v1.27.0 // indirect
6366
go.yaml.in/yaml/v2 v2.4.2 // indirect
6467
go.yaml.in/yaml/v3 v3.0.3 // indirect
6568
golang.org/x/oauth2 v0.27.0 // indirect

test/e2e/internal/config/config.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ type TestData struct {
8383
AffinityToleration string `yaml:"affinityToleration"`
8484
ComplexTest string `yaml:"complexTest"`
8585
DiskResizing string `yaml:"diskResizing"`
86-
SizingPolicy string `yaml:"sizingPolicy"`
8786
ImageHotplug string `yaml:"imageHotplug"`
8887
VMConfiguration string `yaml:"vmConfiguration"`
8988
VMLabelAnnotation string `yaml:"vmLabelAnnotation"`

test/e2e/internal/framework/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828

2929
"github.com/deckhouse/virtualization/api/client/kubeclient"
3030
"github.com/deckhouse/virtualization/api/core/v1alpha2"
31+
"github.com/deckhouse/virtualization/api/core/v1alpha3"
3132
dv1alpha1 "github.com/deckhouse/virtualization/test/e2e/internal/api/deckhouse/v1alpha1"
3233
dv1alpha2 "github.com/deckhouse/virtualization/test/e2e/internal/api/deckhouse/v1alpha2"
3334
"github.com/deckhouse/virtualization/test/e2e/internal/d8"
@@ -114,6 +115,7 @@ func init() {
114115
// use dynamic client for get kubevirt types
115116
for _, f := range []func(*apiruntime.Scheme) error{
116117
v1alpha2.AddToScheme,
118+
v1alpha3.AddToScheme,
117119
clientgoscheme.AddToScheme,
118120
dv1alpha1.AddToScheme,
119121
dv1alpha2.AddToScheme,

test/e2e/internal/util/until.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,112 @@ func UntilObjectPhase(expectedPhase string, timeout time.Duration, objs ...clien
4040
untilObjectField("status.phase", expectedPhase, timeout, objs...)
4141
}
4242

43+
// UntilConditionReason waits for the specified conditionType in status.conditions to have the given reason value for all provided objects.
44+
func UntilConditionReason(conditionType, expectedReason string, timeout time.Duration, objs ...client.Object) {
45+
UntilConditionState(conditionType, timeout, struct {
46+
Reason string
47+
Status string
48+
Message string
49+
CheckReason bool
50+
CheckStatus bool
51+
CheckMessage bool
52+
}{
53+
Reason: expectedReason,
54+
CheckReason: true,
55+
}, objs...)
56+
}
57+
58+
// UntilConditionStatus waits for the specified conditionType in status.conditions to have the given status value for all provided objects.
59+
func UntilConditionStatus(conditionType, expectedStatus string, timeout time.Duration, objs ...client.Object) {
60+
UntilConditionState(conditionType, timeout, struct {
61+
Reason string
62+
Status string
63+
Message string
64+
CheckReason bool
65+
CheckStatus bool
66+
CheckMessage bool
67+
}{
68+
Status: expectedStatus,
69+
CheckStatus: true,
70+
}, objs...)
71+
}
72+
73+
// UntilConditionState generalizes condition field checks ("reason", "status", "message") for the specified conditionType.
74+
// You can specify which fields to check by setting the corresponding flags to true and providing their expected values.
75+
func UntilConditionState(
76+
conditionType string,
77+
timeout time.Duration,
78+
checkOptions struct {
79+
Reason string
80+
Status string
81+
Message string
82+
CheckReason bool
83+
CheckStatus bool
84+
CheckMessage bool
85+
},
86+
objs ...client.Object,
87+
) {
88+
GinkgoHelper()
89+
Eventually(func(g Gomega) {
90+
for _, obj := range objs {
91+
key := client.ObjectKeyFromObject(obj)
92+
u := getTemplateUnstructured(obj).DeepCopy()
93+
err := framework.GetClients().GenericClient().Get(context.Background(), key, u)
94+
g.Expect(err).ShouldNot(HaveOccurred())
95+
96+
conditions, found, err := unstructured.NestedSlice(u.Object, "status", "conditions")
97+
g.Expect(err).ShouldNot(HaveOccurred(), "failed to access status.conditions of %s/%s", u.GetNamespace(), u.GetName())
98+
g.Expect(found).Should(BeTrue(), "no status.conditions found in %s/%s", u.GetNamespace(), u.GetName())
99+
100+
var actualReason, actualStatus, actualMessage string
101+
condFound := false
102+
103+
for _, c := range conditions {
104+
m, ok := c.(map[string]interface{})
105+
if !ok {
106+
continue
107+
}
108+
if t, ok := m["type"].(string); ok && t == conditionType {
109+
condFound = true
110+
if s, ok := m["reason"].(string); ok {
111+
actualReason = s
112+
} else {
113+
actualReason = "Unknown"
114+
}
115+
if s, ok := m["status"].(string); ok {
116+
actualStatus = s
117+
} else {
118+
actualStatus = "Unknown"
119+
}
120+
if s, ok := m["message"].(string); ok {
121+
actualMessage = s
122+
} else {
123+
actualMessage = ""
124+
}
125+
break
126+
}
127+
}
128+
g.Expect(condFound).To(BeTrue(), "object %s/%s: condition %s not found", u.GetNamespace(), u.GetName(), conditionType)
129+
130+
if checkOptions.CheckReason {
131+
g.Expect(actualReason).To(Equal(checkOptions.Reason),
132+
"object %s/%s: condition %s reason is %q, expected %q",
133+
u.GetNamespace(), u.GetName(), conditionType, actualReason, checkOptions.Reason)
134+
}
135+
if checkOptions.CheckStatus {
136+
g.Expect(actualStatus).To(Equal(checkOptions.Status),
137+
"object %s/%s: condition %s status is %q, expected %q",
138+
u.GetNamespace(), u.GetName(), conditionType, actualStatus, checkOptions.Status)
139+
}
140+
if checkOptions.CheckMessage {
141+
g.Expect(actualMessage).To(Equal(checkOptions.Message),
142+
"object %s/%s: condition %s message is %q, expected %q",
143+
u.GetNamespace(), u.GetName(), conditionType, actualMessage, checkOptions.Message)
144+
}
145+
}
146+
}).WithTimeout(timeout).WithPolling(time.Second).Should(Succeed())
147+
}
148+
43149
// UntilObjectState waits for an object to reach the specified state.
44150
// It accepts a runtime.Object (which serves as a template with name and namespace),
45151
// expected state string, and timeout duration.

0 commit comments

Comments
 (0)