@@ -17,6 +17,8 @@ limitations under the License.
17
17
package controllers
18
18
19
19
import (
20
+ "context"
21
+ "fmt"
20
22
"testing"
21
23
"time"
22
24
@@ -27,6 +29,7 @@ import (
27
29
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28
30
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
29
31
"k8s.io/client-go/kubernetes/scheme"
32
+ "k8s.io/client-go/tools/record"
30
33
"k8s.io/utils/pointer"
31
34
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
32
35
"sigs.k8s.io/cluster-api/controllers/remote"
@@ -36,6 +39,7 @@ import (
36
39
"sigs.k8s.io/cluster-api/util/patch"
37
40
ctrl "sigs.k8s.io/controller-runtime"
38
41
"sigs.k8s.io/controller-runtime/pkg/client"
42
+ "sigs.k8s.io/controller-runtime/pkg/client/apiutil"
39
43
"sigs.k8s.io/controller-runtime/pkg/client/fake"
40
44
"sigs.k8s.io/controller-runtime/pkg/log"
41
45
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -1855,6 +1859,139 @@ func TestNodeToMachine(t *testing.T) {
1855
1859
}
1856
1860
}
1857
1861
1862
+ type fakeClientWithNodeDeletionErr struct {
1863
+ client.Client
1864
+ }
1865
+
1866
+ func (fc fakeClientWithNodeDeletionErr ) Delete (ctx context.Context , obj client.Object , opts ... client.DeleteOption ) error {
1867
+ gvk , err := apiutil .GVKForObject (obj , fakeScheme )
1868
+ if err == nil && gvk .Kind == "Node" {
1869
+ return fmt .Errorf ("fake error" )
1870
+ }
1871
+ return fc .Client .Delete (ctx , obj , opts ... )
1872
+ }
1873
+
1874
+ func TestNodeDeletion (t * testing.T ) {
1875
+ g := NewWithT (t )
1876
+
1877
+ deletionTime := metav1 .Now ()
1878
+
1879
+ testCluster := clusterv1.Cluster {
1880
+ ObjectMeta : metav1.ObjectMeta {
1881
+ Name : "test-cluster" ,
1882
+ Namespace : metav1 .NamespaceDefault ,
1883
+ },
1884
+ }
1885
+
1886
+ node := & corev1.Node {
1887
+ ObjectMeta : metav1.ObjectMeta {
1888
+ Name : "test" ,
1889
+ },
1890
+ Spec : corev1.NodeSpec {ProviderID : "test://id-1" },
1891
+ }
1892
+
1893
+ testMachine := clusterv1.Machine {
1894
+ ObjectMeta : metav1.ObjectMeta {
1895
+ Name : "test" ,
1896
+ Namespace : metav1 .NamespaceDefault ,
1897
+ Labels : map [string ]string {
1898
+ clusterv1 .MachineControlPlaneLabelName : "" ,
1899
+ },
1900
+ Annotations : map [string ]string {
1901
+ "machine.cluster.x-k8s.io/exclude-node-draining" : "" ,
1902
+ },
1903
+ Finalizers : []string {clusterv1 .MachineFinalizer },
1904
+ DeletionTimestamp : & deletionTime ,
1905
+ },
1906
+ Spec : clusterv1.MachineSpec {
1907
+ ClusterName : "test-cluster" ,
1908
+ InfrastructureRef : corev1.ObjectReference {
1909
+ APIVersion : "infrastructure.cluster.x-k8s.io/v1beta1" ,
1910
+ Kind : "GenericInfrastructureMachine" ,
1911
+ Name : "infra-config1" ,
1912
+ },
1913
+ Bootstrap : clusterv1.Bootstrap {DataSecretName : pointer .StringPtr ("data" )},
1914
+ },
1915
+ Status : clusterv1.MachineStatus {
1916
+ NodeRef : & corev1.ObjectReference {
1917
+ Name : "test" ,
1918
+ },
1919
+ },
1920
+ }
1921
+
1922
+ cpmachine1 := & clusterv1.Machine {
1923
+ ObjectMeta : metav1.ObjectMeta {
1924
+ Name : "cp1" ,
1925
+ Namespace : metav1 .NamespaceDefault ,
1926
+ Labels : map [string ]string {
1927
+ clusterv1 .ClusterLabelName : "test-cluster" ,
1928
+ clusterv1 .MachineControlPlaneLabelName : "" ,
1929
+ },
1930
+ Finalizers : []string {clusterv1 .MachineFinalizer },
1931
+ },
1932
+ Spec : clusterv1.MachineSpec {
1933
+ ClusterName : "test-cluster" ,
1934
+ InfrastructureRef : corev1.ObjectReference {},
1935
+ Bootstrap : clusterv1.Bootstrap {DataSecretName : pointer .StringPtr ("data" )},
1936
+ },
1937
+ Status : clusterv1.MachineStatus {
1938
+ NodeRef : & corev1.ObjectReference {
1939
+ Name : "cp1" ,
1940
+ },
1941
+ },
1942
+ }
1943
+
1944
+ testCases := []struct {
1945
+ deletionTimeout time.Duration
1946
+ resultErr bool
1947
+ createFakeClient func (... client.Object ) client.Client
1948
+ }{
1949
+ {
1950
+ deletionTimeout : time .Second ,
1951
+ resultErr : false ,
1952
+ createFakeClient : func (initObjs ... client.Object ) client.Client {
1953
+ return fake .NewClientBuilder ().
1954
+ WithObjects (initObjs ... ).
1955
+ Build ()
1956
+ },
1957
+ },
1958
+ {
1959
+ deletionTimeout : 10 * time .Millisecond ,
1960
+ resultErr : true ,
1961
+ createFakeClient : func (initObjs ... client.Object ) client.Client {
1962
+ fc := fake .NewClientBuilder ().
1963
+ WithObjects (initObjs ... ).
1964
+ Build ()
1965
+ return fakeClientWithNodeDeletionErr {fc }
1966
+ },
1967
+ },
1968
+ }
1969
+
1970
+ for _ , tc := range testCases {
1971
+ m := testMachine .DeepCopy ()
1972
+ m .Spec .NodeDeletionTimeout = & metav1.Duration {Duration : tc .deletionTimeout }
1973
+
1974
+ fakeClient := tc .createFakeClient (node , m , cpmachine1 )
1975
+ tracker := remote .NewTestClusterCacheTracker (ctrl .Log , fakeClient , fakeScheme , client .ObjectKeyFromObject (& testCluster ))
1976
+
1977
+ r := & MachineReconciler {
1978
+ Client : fakeClient ,
1979
+ Tracker : tracker ,
1980
+ recorder : record .NewFakeRecorder (10 ),
1981
+ }
1982
+
1983
+ _ , err := r .reconcileDelete (context .Background (), & testCluster , m )
1984
+
1985
+ if tc .resultErr {
1986
+ g .Expect (err ).To (HaveOccurred ())
1987
+ } else {
1988
+ g .Expect (err ).NotTo (HaveOccurred ())
1989
+ n := & corev1.Node {}
1990
+ g .Expect (fakeClient .Get (context .Background (), client .ObjectKeyFromObject (node ), n )).NotTo (Succeed ())
1991
+ }
1992
+ }
1993
+ }
1994
+
1858
1995
// adds a condition list to an external object.
1859
1996
func addConditionsToExternal (u * unstructured.Unstructured , newConditions clusterv1.Conditions ) {
1860
1997
existingConditions := clusterv1.Conditions {}
0 commit comments