Skip to content

Commit 6d3ec0f

Browse files
committed
Add fuzzy conversion tests for v1beta1 API types
Signed-off-by: Lennart Jern <lennart.jern@est.tech>
1 parent 8f3094c commit 6d3ec0f

File tree

2 files changed

+363
-28
lines changed

2 files changed

+363
-28
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
Copyright 2026 The Kubernetes Authors.
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 v1beta1_test
18+
19+
import (
20+
"slices"
21+
"strings"
22+
"testing"
23+
24+
"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
"k8s.io/apimachinery/pkg/runtime"
27+
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
28+
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
29+
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
30+
"sigs.k8s.io/controller-runtime/pkg/conversion"
31+
32+
infrav1beta1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
33+
infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta2"
34+
testhelpers "sigs.k8s.io/cluster-api-provider-openstack/test/helpers"
35+
)
36+
37+
// Setting this to false to avoid running tests in parallel. Only for use in development.
38+
const parallel = true
39+
40+
func runParallel(f func(t *testing.T)) func(t *testing.T) {
41+
if parallel {
42+
return func(t *testing.T) {
43+
t.Helper()
44+
t.Parallel()
45+
f(t)
46+
}
47+
}
48+
return f
49+
}
50+
51+
func TestFuzzyConversion(t *testing.T) {
52+
t.Helper()
53+
54+
scheme := runtime.NewScheme()
55+
if err := infrav1beta1.AddToScheme(scheme); err != nil {
56+
t.Fatal(err)
57+
}
58+
if err := infrav1.AddToScheme(scheme); err != nil {
59+
t.Fatal(err)
60+
}
61+
62+
fuzzerFuncs := func(_ runtimeserializer.CodecFactory) []interface{} {
63+
return slices.Concat(
64+
testhelpers.InfraV1beta1FuzzerFuncs(),
65+
testhelpers.InfraV1Beta2FuzzerFuncs(),
66+
)
67+
}
68+
69+
// ignoreDataAnnotation removes the data annotation that is added by
70+
// MarshalData during ConvertTo. The annotation is not present on the
71+
// original hub object, so it must be removed before comparison.
72+
ignoreDataAnnotation := func(hub conversion.Hub) {
73+
obj := hub.(metav1.Object)
74+
delete(obj.GetAnnotations(), utilconversion.DataAnnotation)
75+
}
76+
77+
// clusterHubAfterMutation removes the data annotation and sorts
78+
// FailureDomains by Name to normalize non-deterministic map iteration
79+
// order from the FailureDomains map↔slice conversion.
80+
clusterHubAfterMutation := func(hub conversion.Hub) {
81+
cluster := hub.(*infrav1.OpenStackCluster)
82+
delete(cluster.GetAnnotations(), utilconversion.DataAnnotation)
83+
slices.SortFunc(cluster.Status.FailureDomains, func(a, b clusterv1.FailureDomain) int {
84+
return strings.Compare(a.Name, b.Name)
85+
})
86+
}
87+
88+
t.Run("for OpenStackCluster", runParallel(utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
89+
Scheme: scheme,
90+
Hub: &infrav1.OpenStackCluster{},
91+
Spoke: &infrav1beta1.OpenStackCluster{},
92+
HubAfterMutation: clusterHubAfterMutation,
93+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
94+
})))
95+
96+
t.Run("for OpenStackCluster with mutate", runParallel(testhelpers.FuzzMutateTestFunc(testhelpers.FuzzMutateTestFuncInput{
97+
FuzzTestFuncInput: utilconversion.FuzzTestFuncInput{
98+
Scheme: scheme,
99+
Hub: &infrav1.OpenStackCluster{},
100+
Spoke: &infrav1beta1.OpenStackCluster{},
101+
HubAfterMutation: clusterHubAfterMutation,
102+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
103+
},
104+
MutateFuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
105+
})))
106+
107+
t.Run("for OpenStackClusterTemplate", runParallel(utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
108+
Scheme: scheme,
109+
Hub: &infrav1.OpenStackClusterTemplate{},
110+
Spoke: &infrav1beta1.OpenStackClusterTemplate{},
111+
HubAfterMutation: ignoreDataAnnotation,
112+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
113+
})))
114+
115+
t.Run("for OpenStackClusterTemplate with mutate", runParallel(testhelpers.FuzzMutateTestFunc(testhelpers.FuzzMutateTestFuncInput{
116+
FuzzTestFuncInput: utilconversion.FuzzTestFuncInput{
117+
Scheme: scheme,
118+
Hub: &infrav1.OpenStackClusterTemplate{},
119+
Spoke: &infrav1beta1.OpenStackClusterTemplate{},
120+
HubAfterMutation: ignoreDataAnnotation,
121+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
122+
},
123+
MutateFuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
124+
})))
125+
126+
t.Run("for OpenStackMachine", runParallel(utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
127+
Scheme: scheme,
128+
Hub: &infrav1.OpenStackMachine{},
129+
Spoke: &infrav1beta1.OpenStackMachine{},
130+
HubAfterMutation: ignoreDataAnnotation,
131+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
132+
})))
133+
134+
t.Run("for OpenStackMachine with mutate", runParallel(testhelpers.FuzzMutateTestFunc(testhelpers.FuzzMutateTestFuncInput{
135+
FuzzTestFuncInput: utilconversion.FuzzTestFuncInput{
136+
Scheme: scheme,
137+
Hub: &infrav1.OpenStackMachine{},
138+
Spoke: &infrav1beta1.OpenStackMachine{},
139+
HubAfterMutation: ignoreDataAnnotation,
140+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
141+
},
142+
MutateFuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
143+
})))
144+
145+
t.Run("for OpenStackMachineTemplate", runParallel(utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{
146+
Scheme: scheme,
147+
Hub: &infrav1.OpenStackMachineTemplate{},
148+
Spoke: &infrav1beta1.OpenStackMachineTemplate{},
149+
HubAfterMutation: ignoreDataAnnotation,
150+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
151+
})))
152+
153+
t.Run("for OpenStackMachineTemplate with mutate", runParallel(testhelpers.FuzzMutateTestFunc(testhelpers.FuzzMutateTestFuncInput{
154+
FuzzTestFuncInput: utilconversion.FuzzTestFuncInput{
155+
Scheme: scheme,
156+
Hub: &infrav1.OpenStackMachineTemplate{},
157+
Spoke: &infrav1beta1.OpenStackMachineTemplate{},
158+
HubAfterMutation: ignoreDataAnnotation,
159+
FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
160+
},
161+
MutateFuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzerFuncs},
162+
})))
163+
}

0 commit comments

Comments
 (0)