@@ -17,7 +17,11 @@ limitations under the License.
17
17
package machineset
18
18
19
19
import (
20
+ "context"
20
21
"fmt"
22
+ "k8s.io/apimachinery/pkg/runtime/schema"
23
+ "sigs.k8s.io/controller-runtime/pkg/client/interceptor"
24
+ "strings"
21
25
"testing"
22
26
"time"
23
27
@@ -1969,6 +1973,149 @@ func TestMachineSetReconciler_syncReplicas(t *testing.T) {
1969
1973
})
1970
1974
}
1971
1975
1976
+ func TestMachineSetReconciler_syncReplicas_WithErrors (t * testing.T ) {
1977
+ t .Run ("should hold off on sync replicas when create Infrastructure of machine failed " , func (t * testing.T ) {
1978
+ g := NewWithT (t )
1979
+ fakeClient := fake .NewClientBuilder ().WithObjects ().WithInterceptorFuncs (interceptor.Funcs {
1980
+ Create : func (ctx context.Context , client client.WithWatch , obj client.Object , opts ... client.CreateOption ) error {
1981
+ // simulate scenarios where infra object creation fails
1982
+ if obj .GetObjectKind ().GroupVersionKind ().Kind == "GenericInfrastructureMachine" {
1983
+ return fmt .Errorf ("inject error for create machineInfrastructure" )
1984
+ }
1985
+ return client .Create (ctx , obj , opts ... )
1986
+ },
1987
+ }).Build ()
1988
+
1989
+ r := & Reconciler {
1990
+ Client : fakeClient ,
1991
+ }
1992
+ testCluster := & clusterv1.Cluster {}
1993
+ testCluster .Namespace = "default"
1994
+ testCluster .Name = "test-cluster"
1995
+ version := "v1.14.2"
1996
+ duration10m := & metav1.Duration {Duration : 10 * time .Minute }
1997
+ machineSet := & clusterv1.MachineSet {
1998
+ ObjectMeta : metav1.ObjectMeta {
1999
+ Name : "machineset1" ,
2000
+ Namespace : metav1 .NamespaceDefault ,
2001
+ Finalizers : []string {"block-deletion" },
2002
+ },
2003
+ Spec : clusterv1.MachineSetSpec {
2004
+ Replicas : ptr.To [int32 ](1 ),
2005
+ ClusterName : "test-cluster" ,
2006
+ Template : clusterv1.MachineTemplateSpec {
2007
+ Spec : clusterv1.MachineSpec {
2008
+ ClusterName : testCluster .Name ,
2009
+ Version : & version ,
2010
+ Bootstrap : clusterv1.Bootstrap {
2011
+ ConfigRef : & corev1.ObjectReference {
2012
+ APIVersion : "bootstrap.cluster.x-k8s.io/v1beta1" ,
2013
+ Kind : "GenericBootstrapConfigTemplate" ,
2014
+ Name : "ms-template" ,
2015
+ },
2016
+ },
2017
+ InfrastructureRef : corev1.ObjectReference {
2018
+ APIVersion : "infrastructure.cluster.x-k8s.io/v1beta1" ,
2019
+ Kind : "GenericInfrastructureMachineTemplate" ,
2020
+ Name : "ms-template" ,
2021
+ },
2022
+ NodeDrainTimeout : duration10m ,
2023
+ NodeDeletionTimeout : duration10m ,
2024
+ NodeVolumeDetachTimeout : duration10m ,
2025
+ },
2026
+ },
2027
+ },
2028
+ }
2029
+
2030
+ // Create bootstrap template resource.
2031
+ bootstrapResource := map [string ]interface {}{
2032
+ "kind" : "GenericBootstrapConfig" ,
2033
+ "apiVersion" : "bootstrap.cluster.x-k8s.io/v1beta1" ,
2034
+ "metadata" : map [string ]interface {}{
2035
+ "annotations" : map [string ]interface {}{
2036
+ "precedence" : "GenericBootstrapConfig" ,
2037
+ },
2038
+ },
2039
+ }
2040
+ bootstrapTmpl := & unstructured.Unstructured {
2041
+ Object : map [string ]interface {}{
2042
+ "spec" : map [string ]interface {}{
2043
+ "template" : bootstrapResource ,
2044
+ },
2045
+ },
2046
+ }
2047
+ bootstrapTmpl .SetKind ("GenericBootstrapConfigTemplate" )
2048
+ bootstrapTmpl .SetAPIVersion ("bootstrap.cluster.x-k8s.io/v1beta1" )
2049
+ bootstrapTmpl .SetName ("ms-template" )
2050
+ bootstrapTmpl .SetNamespace (metav1 .NamespaceDefault )
2051
+ g .Expect (r .Client .Create (context .TODO (), bootstrapTmpl )).To (Succeed ())
2052
+
2053
+ // Create infrastructure template resource.
2054
+ infraResource := map [string ]interface {}{
2055
+ "kind" : "GenericInfrastructureMachine" ,
2056
+ "apiVersion" : "infrastructure.cluster.x-k8s.io/v1beta1" ,
2057
+ "metadata" : map [string ]interface {}{
2058
+ "annotations" : map [string ]interface {}{
2059
+ "precedence" : "GenericInfrastructureMachineTemplate" ,
2060
+ },
2061
+ },
2062
+ "spec" : map [string ]interface {}{
2063
+ "size" : "3xlarge" ,
2064
+ },
2065
+ }
2066
+ infraTmpl := & unstructured.Unstructured {
2067
+ Object : map [string ]interface {}{
2068
+ "spec" : map [string ]interface {}{
2069
+ "template" : infraResource ,
2070
+ },
2071
+ },
2072
+ }
2073
+ infraTmpl .SetKind ("GenericInfrastructureMachineTemplate" )
2074
+ infraTmpl .SetAPIVersion ("infrastructure.cluster.x-k8s.io/v1beta1" )
2075
+ infraTmpl .SetName ("ms-template" )
2076
+ infraTmpl .SetNamespace (metav1 .NamespaceDefault )
2077
+ g .Expect (r .Client .Create (context .TODO (), infraTmpl )).To (Succeed ())
2078
+
2079
+ _ , err := r .syncReplicas (ctx , testCluster , machineSet , nil )
2080
+ g .Expect (err ).To (HaveOccurred ())
2081
+
2082
+ // Verify the proper condition is set on the MachineSet.
2083
+ condition := clusterv1 .MachinesCreatedCondition
2084
+ g .Expect (conditions .Has (machineSet , condition )).To (BeTrue (), "MachineSet should have the %s condition set" , condition )
2085
+
2086
+ machinesCreatedCondition := conditions .Get (machineSet , condition )
2087
+ g .Expect (machinesCreatedCondition .Status ).
2088
+ To (Equal (corev1 .ConditionFalse ), "%s condition status should be %s" , condition , corev1 .ConditionFalse )
2089
+ g .Expect (machinesCreatedCondition .Reason ).
2090
+ To (Equal (clusterv1 .InfrastructureTemplateCloningFailedReason ), "%s condition reason should be %s" , condition , clusterv1 .InfrastructureTemplateCloningFailedReason )
2091
+
2092
+ // Verify no new Machines are created.
2093
+ machineList := & clusterv1.MachineList {}
2094
+ g .Expect (r .Client .List (ctx , machineList )).To (Succeed ())
2095
+ g .Expect (machineList .Items ).To (BeEmpty (), "There should not be any machines" )
2096
+
2097
+ // Verify no boostrap object created
2098
+ bootstrapList := & unstructured.UnstructuredList {}
2099
+ bootstrapList .SetGroupVersionKind (schema.GroupVersionKind {
2100
+ Group : bootstrapTmpl .GetObjectKind ().GroupVersionKind ().Group ,
2101
+ Version : bootstrapTmpl .GetObjectKind ().GroupVersionKind ().Version ,
2102
+ Kind : strings .TrimSuffix (bootstrapTmpl .GetObjectKind ().GroupVersionKind ().Kind , clusterv1 .TemplateSuffix ),
2103
+ })
2104
+ g .Expect (r .Client .List (ctx , bootstrapList )).To (Succeed ())
2105
+ g .Expect (len (bootstrapList .Items )).To (BeEmpty (), "There should not be any bootstrap object" )
2106
+
2107
+ // Verify no infra object created
2108
+ infraList := & unstructured.UnstructuredList {}
2109
+ infraList .SetGroupVersionKind (schema.GroupVersionKind {
2110
+ Group : infraTmpl .GetObjectKind ().GroupVersionKind ().Group ,
2111
+ Version : infraTmpl .GetObjectKind ().GroupVersionKind ().Version ,
2112
+ Kind : strings .TrimSuffix (infraTmpl .GetObjectKind ().GroupVersionKind ().Kind , clusterv1 .TemplateSuffix ),
2113
+ })
2114
+ g .Expect (r .Client .List (ctx , infraList )).To (Succeed ())
2115
+ g .Expect (len (infraList .Items )).To (BeEmpty (), "There should not be any infra object" )
2116
+ })
2117
+ }
2118
+
1972
2119
func TestComputeDesiredMachine (t * testing.T ) {
1973
2120
duration5s := & metav1.Duration {Duration : 5 * time .Second }
1974
2121
duration10s := & metav1.Duration {Duration : 10 * time .Second }
0 commit comments