Skip to content

Commit 8f3f027

Browse files
committed
add tests
Signed-off-by: Pavel Tishkov <[email protected]>
1 parent 919a8cc commit 8f3f027

File tree

2 files changed

+157
-7
lines changed

2 files changed

+157
-7
lines changed

images/hooks/cmd/cleanup-labels/main.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ import (
3434
)
3535

3636
const (
37-
nodesSnapshot = "virthandler-nodes"
38-
virtHandlerLabel = "kubevirt.internal.virtualization.deckhouse.io/schedulable"
39-
labelPattern = "virtualization.deckhouse.io"
40-
nodeJQFilter = `{
37+
nodesSnapshot = "virthandler-nodes"
38+
virtHandlerLabel = "kubevirt.internal.virtualization.deckhouse.io/schedulable"
39+
labelPattern = "virtualization.deckhouse.io"
40+
logMessageTemplate = "Removing %d label(s) contains %s from node %s"
41+
nodeJQFilter = `{
4142
"name": .metadata.name,
4243
"labels": .metadata.labels,
4344
}`
@@ -48,7 +49,7 @@ type NodeInfo struct {
4849
Labels map[string]string `json:"labels"`
4950
}
5051

51-
var _ = registry.RegisterFunc(configDiscoveryService, cleanUpNodeLabels)
52+
var _ = registry.RegisterFunc(configDiscoveryService, handleCleanUpNodeLabels)
5253

5354
var configDiscoveryService = &pkg.HookConfig{
5455
OnAfterDeleteHelm: &pkg.OrderedConfig{Order: 5},
@@ -74,7 +75,7 @@ var configDiscoveryService = &pkg.HookConfig{
7475
Queue: fmt.Sprintf("modules/%s", common.MODULE_NAME),
7576
}
7677

77-
func cleanUpNodeLabels(_ context.Context, input *pkg.HookInput) error {
78+
func handleCleanUpNodeLabels(_ context.Context, input *pkg.HookInput) error {
7879
input.Logger.Info("Start.")
7980

8081
nodes := input.Snapshots.Get(nodesSnapshot)
@@ -103,7 +104,7 @@ func cleanUpNodeLabels(_ context.Context, input *pkg.HookInput) error {
103104
if len(patches) == 0 {
104105
continue
105106
} else {
106-
input.Logger.Info(fmt.Sprintf("Removing %d labels contains %s from node %s", len(patches), labelPattern, nodeInfo.Name))
107+
input.Logger.Info(fmt.Sprintf(logMessageTemplate, len(patches), labelPattern, nodeInfo.Name))
107108
}
108109

109110
input.PatchCollector.PatchWithJSON(patches, "v1", "Node", "", nodeInfo.Name)
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
Copyright 2025 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 main
18+
19+
import (
20+
"bytes"
21+
"context"
22+
"fmt"
23+
"testing"
24+
"time"
25+
26+
"github.com/deckhouse/deckhouse/pkg/log"
27+
"github.com/deckhouse/module-sdk/pkg"
28+
"github.com/deckhouse/module-sdk/testing/mock"
29+
. "github.com/onsi/ginkgo/v2"
30+
. "github.com/onsi/gomega"
31+
)
32+
33+
func createSnapshotMock(nodeInfo NodeInfo) pkg.Snapshot {
34+
m := mock.NewSnapshotMock(GinkgoT())
35+
m.UnmarshalToMock.Set(func(v any) error {
36+
target, ok := v.(*NodeInfo)
37+
if !ok {
38+
return fmt.Errorf("expected *NodeInfo, got %T", v)
39+
}
40+
*target = nodeInfo
41+
return nil
42+
})
43+
return m
44+
}
45+
46+
func TestCleanUpVirtHandlerNodeLabels(t *testing.T) {
47+
RegisterFailHandler(Fail)
48+
RunSpecs(t, "Cleanup virtHandler node labels Suite")
49+
}
50+
51+
var _ = Describe("Cleanup virtHandler node labels", func() {
52+
var (
53+
snapshots *mock.SnapshotsMock
54+
values *mock.PatchableValuesCollectorMock
55+
patchCollector *mock.PatchCollectorMock
56+
input *pkg.HookInput
57+
buf *bytes.Buffer
58+
)
59+
60+
BeforeEach(func() {
61+
snapshots = mock.NewSnapshotsMock(GinkgoT())
62+
values = mock.NewPatchableValuesCollectorMock(GinkgoT())
63+
patchCollector = mock.NewPatchCollectorMock(GinkgoT())
64+
65+
buf = bytes.NewBuffer([]byte{})
66+
67+
input = &pkg.HookInput{
68+
Values: values,
69+
Snapshots: snapshots,
70+
Logger: log.NewLogger(log.Options{
71+
Level: log.LevelDebug.Level(),
72+
Output: buf,
73+
TimeFunc: func(_ time.Time) time.Time {
74+
parsedTime, err := time.Parse(time.DateTime, "2006-01-02 15:04:05")
75+
Expect(err).ShouldNot(HaveOccurred())
76+
return parsedTime
77+
},
78+
}),
79+
PatchCollector: patchCollector,
80+
}
81+
})
82+
83+
Context("Empty cluster", func() {
84+
It("Hook must execute successfully", func() {
85+
snapshots.GetMock.When(nodesSnapshot).Then(
86+
[]pkg.Snapshot{},
87+
)
88+
err := handleCleanUpNodeLabels(context.Background(), input)
89+
Expect(err).ShouldNot(HaveOccurred())
90+
})
91+
})
92+
93+
Context("Nodes should be patched.", func() {
94+
It("Hook must execute successfully", func() {
95+
expectedNodes := map[string]interface{}{
96+
"node1": []map[string]string{
97+
map[string]string{
98+
"op": "remove",
99+
"path": "/metadata/labels/kubevirt.internal.virtualization.deckhouse.io~1schedulable",
100+
},
101+
},
102+
"node2": []map[string]string{
103+
{
104+
"op": "remove",
105+
"path": "/metadata/labels/kubevirt.internal.virtualization.deckhouse.io~1schedulable",
106+
},
107+
map[string]string{
108+
"op": "remove",
109+
"path": "/metadata/labels/virtualization.deckhouse.io~1kvm-enabled",
110+
},
111+
},
112+
}
113+
114+
snapshots.GetMock.When(nodesSnapshot).Then([]pkg.Snapshot{
115+
// should be patched
116+
createSnapshotMock(NodeInfo{
117+
Name: "node1",
118+
Labels: map[string]string{
119+
"kubevirt.internal.virtualization.deckhouse.io/schedulable": "true",
120+
},
121+
}),
122+
// should be patched
123+
createSnapshotMock(NodeInfo{
124+
Name: "node2",
125+
Labels: map[string]string{
126+
"kubevirt.internal.virtualization.deckhouse.io/schedulable": "true",
127+
"virtualization.deckhouse.io/kvm-enabled": "true",
128+
},
129+
}),
130+
})
131+
132+
patchCollector.PatchWithJSONMock.Set(func(patch any, apiVersion, kind, namespace, name string, opts ...pkg.PatchCollectorOption) {
133+
p, ok := patch.([]map[string]string)
134+
Expect(ok).To(BeTrue())
135+
Expect(expectedNodes).To(HaveKey(name))
136+
Expect(p).To(Equal(expectedNodes[name]))
137+
delete(expectedNodes, name)
138+
})
139+
140+
err := handleCleanUpNodeLabels(context.Background(), input)
141+
Expect(err).ShouldNot(HaveOccurred())
142+
143+
Expect(buf.String()).To(ContainSubstring(fmt.Sprintf(logMessageTemplate, 1, labelPattern, "node1")))
144+
Expect(buf.String()).To(ContainSubstring(fmt.Sprintf(logMessageTemplate, 2, labelPattern, "node2")))
145+
146+
Expect(expectedNodes).To(HaveLen(0))
147+
})
148+
})
149+
})

0 commit comments

Comments
 (0)