@@ -17,7 +17,9 @@ limitations under the License.
17
17
package machineset
18
18
19
19
import (
20
+ "context"
20
21
"fmt"
22
+ "strings"
21
23
"testing"
22
24
"time"
23
25
@@ -26,11 +28,13 @@ import (
26
28
apierrors "k8s.io/apimachinery/pkg/api/errors"
27
29
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28
30
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
31
+ "k8s.io/apimachinery/pkg/runtime/schema"
29
32
"k8s.io/apimachinery/pkg/util/intstr"
30
33
"k8s.io/client-go/tools/record"
31
34
"k8s.io/utils/ptr"
32
35
"sigs.k8s.io/controller-runtime/pkg/client"
33
36
"sigs.k8s.io/controller-runtime/pkg/client/fake"
37
+ "sigs.k8s.io/controller-runtime/pkg/client/interceptor"
34
38
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
35
39
"sigs.k8s.io/controller-runtime/pkg/reconcile"
36
40
@@ -2346,6 +2350,157 @@ func TestMachineSetReconciler_syncReplicas(t *testing.T) {
2346
2350
})
2347
2351
}
2348
2352
2353
+ func TestMachineSetReconciler_syncReplicas_WithErrors (t * testing.T ) {
2354
+ t .Run ("should hold off on sync replicas when create Infrastructure of machine failed " , func (t * testing.T ) {
2355
+ g := NewWithT (t )
2356
+ fakeClient := fake .NewClientBuilder ().WithObjects ().WithInterceptorFuncs (interceptor.Funcs {
2357
+ Create : func (ctx context.Context , client client.WithWatch , obj client.Object , opts ... client.CreateOption ) error {
2358
+ // simulate scenarios where infra object creation fails
2359
+ if obj .GetObjectKind ().GroupVersionKind ().Kind == "GenericInfrastructureMachine" {
2360
+ return fmt .Errorf ("inject error for create machineInfrastructure" )
2361
+ }
2362
+ return client .Create (ctx , obj , opts ... )
2363
+ },
2364
+ }).Build ()
2365
+
2366
+ r := & Reconciler {
2367
+ Client : fakeClient ,
2368
+ }
2369
+ testCluster := & clusterv1.Cluster {}
2370
+ testCluster .Namespace = "default"
2371
+ testCluster .Name = "test-cluster"
2372
+ version := "v1.14.2"
2373
+ duration10m := & metav1.Duration {Duration : 10 * time .Minute }
2374
+ machineSet := & clusterv1.MachineSet {
2375
+ ObjectMeta : metav1.ObjectMeta {
2376
+ Name : "machineset1" ,
2377
+ Namespace : metav1 .NamespaceDefault ,
2378
+ Finalizers : []string {"block-deletion" },
2379
+ },
2380
+ Spec : clusterv1.MachineSetSpec {
2381
+ Replicas : ptr.To [int32 ](1 ),
2382
+ ClusterName : "test-cluster" ,
2383
+ Template : clusterv1.MachineTemplateSpec {
2384
+ Spec : clusterv1.MachineSpec {
2385
+ ClusterName : testCluster .Name ,
2386
+ Version : & version ,
2387
+ Bootstrap : clusterv1.Bootstrap {
2388
+ ConfigRef : & corev1.ObjectReference {
2389
+ APIVersion : "bootstrap.cluster.x-k8s.io/v1beta1" ,
2390
+ Kind : "GenericBootstrapConfigTemplate" ,
2391
+ Name : "ms-template" ,
2392
+ Namespace : metav1 .NamespaceDefault ,
2393
+ },
2394
+ },
2395
+ InfrastructureRef : corev1.ObjectReference {
2396
+ APIVersion : "infrastructure.cluster.x-k8s.io/v1beta1" ,
2397
+ Kind : "GenericInfrastructureMachineTemplate" ,
2398
+ Name : "ms-template" ,
2399
+ Namespace : metav1 .NamespaceDefault ,
2400
+ },
2401
+ NodeDrainTimeout : duration10m ,
2402
+ NodeDeletionTimeout : duration10m ,
2403
+ NodeVolumeDetachTimeout : duration10m ,
2404
+ },
2405
+ },
2406
+ },
2407
+ }
2408
+
2409
+ // Create bootstrap template resource.
2410
+ bootstrapResource := map [string ]interface {}{
2411
+ "kind" : "GenericBootstrapConfig" ,
2412
+ "apiVersion" : "bootstrap.cluster.x-k8s.io/v1beta1" ,
2413
+ "metadata" : map [string ]interface {}{
2414
+ "annotations" : map [string ]interface {}{
2415
+ "precedence" : "GenericBootstrapConfig" ,
2416
+ },
2417
+ },
2418
+ }
2419
+ bootstrapTmpl := & unstructured.Unstructured {
2420
+ Object : map [string ]interface {}{
2421
+ "spec" : map [string ]interface {}{
2422
+ "template" : bootstrapResource ,
2423
+ },
2424
+ },
2425
+ }
2426
+ bootstrapTmpl .SetKind ("GenericBootstrapConfigTemplate" )
2427
+ bootstrapTmpl .SetAPIVersion ("bootstrap.cluster.x-k8s.io/v1beta1" )
2428
+ bootstrapTmpl .SetName ("ms-template" )
2429
+ bootstrapTmpl .SetNamespace (metav1 .NamespaceDefault )
2430
+ g .Expect (r .Client .Create (context .TODO (), bootstrapTmpl )).To (Succeed ())
2431
+
2432
+ // Create infrastructure template resource.
2433
+ infraResource := map [string ]interface {}{
2434
+ "kind" : "GenericInfrastructureMachine" ,
2435
+ "apiVersion" : "infrastructure.cluster.x-k8s.io/v1beta1" ,
2436
+ "metadata" : map [string ]interface {}{
2437
+ "annotations" : map [string ]interface {}{
2438
+ "precedence" : "GenericInfrastructureMachineTemplate" ,
2439
+ },
2440
+ },
2441
+ "spec" : map [string ]interface {}{
2442
+ "size" : "3xlarge" ,
2443
+ },
2444
+ }
2445
+ infraTmpl := & unstructured.Unstructured {
2446
+ Object : map [string ]interface {}{
2447
+ "spec" : map [string ]interface {}{
2448
+ "template" : infraResource ,
2449
+ },
2450
+ },
2451
+ }
2452
+ infraTmpl .SetKind ("GenericInfrastructureMachineTemplate" )
2453
+ infraTmpl .SetAPIVersion ("infrastructure.cluster.x-k8s.io/v1beta1" )
2454
+ infraTmpl .SetName ("ms-template" )
2455
+ infraTmpl .SetNamespace (metav1 .NamespaceDefault )
2456
+ g .Expect (r .Client .Create (context .TODO (), infraTmpl )).To (Succeed ())
2457
+
2458
+ s := & scope {
2459
+ cluster : testCluster ,
2460
+ machineSet : machineSet ,
2461
+ machines : []* clusterv1.Machine {},
2462
+ getAndAdoptMachinesForMachineSetSucceeded : true ,
2463
+ }
2464
+ _ , err := r .syncReplicas (ctx , s )
2465
+ g .Expect (err ).To (HaveOccurred ())
2466
+
2467
+ // Verify the proper condition is set on the MachineSet.
2468
+ condition := clusterv1 .MachinesCreatedCondition
2469
+ g .Expect (conditions .Has (machineSet , condition )).To (BeTrue (), "MachineSet should have the %s condition set" , condition )
2470
+
2471
+ machinesCreatedCondition := conditions .Get (machineSet , condition )
2472
+ g .Expect (machinesCreatedCondition .Status ).
2473
+ To (Equal (corev1 .ConditionFalse ), "%s condition status should be %s" , condition , corev1 .ConditionFalse )
2474
+ g .Expect (machinesCreatedCondition .Reason ).
2475
+ To (Equal (clusterv1 .InfrastructureTemplateCloningFailedReason ), "%s condition reason should be %s" , condition , clusterv1 .InfrastructureTemplateCloningFailedReason )
2476
+
2477
+ // Verify no new Machines are created.
2478
+ machineList := & clusterv1.MachineList {}
2479
+ g .Expect (r .Client .List (ctx , machineList )).To (Succeed ())
2480
+ g .Expect (machineList .Items ).To (BeEmpty (), "There should not be any machines" )
2481
+
2482
+ // Verify no boostrap object created
2483
+ bootstrapList := & unstructured.UnstructuredList {}
2484
+ bootstrapList .SetGroupVersionKind (schema.GroupVersionKind {
2485
+ Group : bootstrapTmpl .GetObjectKind ().GroupVersionKind ().Group ,
2486
+ Version : bootstrapTmpl .GetObjectKind ().GroupVersionKind ().Version ,
2487
+ Kind : strings .TrimSuffix (bootstrapTmpl .GetObjectKind ().GroupVersionKind ().Kind , clusterv1 .TemplateSuffix ),
2488
+ })
2489
+ g .Expect (r .Client .List (ctx , bootstrapList )).To (Succeed ())
2490
+ g .Expect (bootstrapList .Items ).To (BeEmpty (), "There should not be any bootstrap object" )
2491
+
2492
+ // Verify no infra object created
2493
+ infraList := & unstructured.UnstructuredList {}
2494
+ infraList .SetGroupVersionKind (schema.GroupVersionKind {
2495
+ Group : infraTmpl .GetObjectKind ().GroupVersionKind ().Group ,
2496
+ Version : infraTmpl .GetObjectKind ().GroupVersionKind ().Version ,
2497
+ Kind : strings .TrimSuffix (infraTmpl .GetObjectKind ().GroupVersionKind ().Kind , clusterv1 .TemplateSuffix ),
2498
+ })
2499
+ g .Expect (r .Client .List (ctx , infraList )).To (Succeed ())
2500
+ g .Expect (infraList .Items ).To (BeEmpty (), "There should not be any infra object" )
2501
+ })
2502
+ }
2503
+
2349
2504
func TestComputeDesiredMachine (t * testing.T ) {
2350
2505
duration5s := & metav1.Duration {Duration : 5 * time .Second }
2351
2506
duration10s := & metav1.Duration {Duration : 10 * time .Second }
0 commit comments