Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / pkg / controller / provisioning / provisioning_controller_test.go
1 package provisioning
2
3 import (
4         "os"
5         "testing"
6
7         bpav1alpha1 "github.com/bpa-operator/pkg/apis/bpa/v1alpha1"
8         metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9         "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
10         "k8s.io/apimachinery/pkg/runtime"
11         "k8s.io/apimachinery/pkg/types"
12         fakedynamic "k8s.io/client-go/dynamic/fake"
13         fakeclientset "k8s.io/client-go/kubernetes/fake"
14         "k8s.io/client-go/kubernetes/scheme"
15         "sigs.k8s.io/controller-runtime/pkg/client/fake"
16         "sigs.k8s.io/controller-runtime/pkg/reconcile"
17         logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
18 )
19
20 func TestProvisioningController(t *testing.T) {
21
22         logf.SetLogger(logf.ZapLogger(true))
23         bpaName1 := "bpa-test-cr"
24         bpaName2 := "bpa-test-2"
25         namespace := "default"
26         clusterName := "test-cluster"
27         clusterName2 := "test-cluster-2"
28         clusterName3 := "test-cluster-3"
29         macAddress1 := "08:00:27:00:ab:2c"
30         macAddress2 := "08:00:27:00:ab:3d"
31
32         // Create Fake baremetalhost
33         bmhList := newBMList()
34
35         // Create Fake Provisioning CR
36         provisioning := newBPA(bpaName1, namespace, clusterName, macAddress1)
37         provisioning2 := newBPA(bpaName2, namespace, clusterName2, macAddress2)
38
39         // Objects to track in the fake Client
40         objs := []runtime.Object{provisioning, provisioning2}
41
42         // Register operator types with the runtime scheme
43         sc := scheme.Scheme
44
45         sc.AddKnownTypes(bpav1alpha1.SchemeGroupVersion, provisioning, provisioning2)
46
47         // Create Fake Clients and Clientset
48         fakeClient := fake.NewFakeClient(objs...)
49         fakeDyn := fakedynamic.NewSimpleDynamicClient(sc, bmhList)
50         fakeClientSet := fakeclientset.NewSimpleClientset()
51
52         r := &ReconcileProvisioning{client: fakeClient, scheme: sc, clientset: fakeClientSet, bmhClient: fakeDyn}
53
54         // Mock request to simulate Reconcile() being called on an event for a watched resource
55         req := simulateRequest(provisioning)
56         _, err := r.Reconcile(req)
57         if err != nil {
58                 t.Fatalf("reconcile: (%v)", err)
59         }
60
61         // Test 1: Check the job was created with the expected name
62         jobClient := r.clientset.BatchV1().Jobs(namespace)
63         job, err := jobClient.Get("kud-test-cluster", metav1.GetOptions{})
64
65         if err != nil {
66                 t.Fatalf("Error occured while getting job: (%v)", err)
67         }
68
69         // Test 2: Check that cluster name metadata in job is the expected cluster name
70         jobClusterName := job.Labels["cluster"]
71         if jobClusterName != clusterName {
72                 t.Fatalf("Job cluster Name is wrong")
73         }
74
75         // Test 3: Check that the right error is produced when host with MAC address does not exist
76         req = simulateRequest(provisioning2)
77         _, err = r.Reconcile(req)
78         expectedErr := "Host with MAC Address " + macAddress2 + " not found\n"
79         if err.Error() != expectedErr {
80                 t.Fatalf("Failed, Unexpected error occured %v\n", err)
81         }
82
83         // Delete cluster directories
84         err = os.RemoveAll("/multi-cluster/" + clusterName)
85         if err != nil {
86                 t.Logf("\nUnable to delete cluster directory %s\n", clusterName)
87         }
88         err = os.RemoveAll("/multi-cluster/" + clusterName2)
89         if err != nil {
90                 t.Logf("\nUnable to delete cluster directory %s\n", clusterName2)
91         }
92         err = os.RemoveAll("/multi-cluster/" + clusterName3)
93         if err != nil {
94                 t.Logf("\nUnable to delete cluster directory %s\n", clusterName3)
95         }
96
97 }
98
99 func simulateRequest(bpaCR *bpav1alpha1.Provisioning) reconcile.Request {
100         namespacedName := types.NamespacedName{
101                 Name:      bpaCR.ObjectMeta.Name,
102                 Namespace: bpaCR.ObjectMeta.Namespace,
103         }
104         return reconcile.Request{NamespacedName: namespacedName}
105 }
106
107 func newBPA(name, namespace, clusterName, macAddress string) *bpav1alpha1.Provisioning {
108
109         provisioningCR := &bpav1alpha1.Provisioning{
110                 ObjectMeta: metav1.ObjectMeta{
111                         Name:      name,
112                         Namespace: namespace,
113                         Labels: map[string]string{
114                                 "cluster": clusterName,
115                         },
116                 },
117                 Spec: bpav1alpha1.ProvisioningSpec{
118                         Masters: []map[string]bpav1alpha1.Master{
119                                 map[string]bpav1alpha1.Master{
120                                         "test-master": bpav1alpha1.Master{
121                                                 MACaddress: macAddress,
122                                         },
123                                 },
124                         },
125                 },
126         }
127         return provisioningCR
128 }
129
130 func newBMList() *unstructured.UnstructuredList {
131
132         bmMap := map[string]interface{}{
133                 "apiVersion": "metal3.io/v1alpha1",
134                 "kind":       "BareMetalHostList",
135                 "metaData": map[string]interface{}{
136                         "continue":        "",
137                         "resourceVersion": "11830058",
138                         "selfLink":        "/apis/metal3.io/v1alpha1/baremetalhosts",
139                 },
140         }
141
142         metaData := map[string]interface{}{
143                 "creationTimestamp": "2019-10-24T04:51:15Z",
144                 "generation":        "1",
145                 "name":              "fake-test-bmh",
146                 "namespace":         "default",
147                 "resourceVersion":   "11829263",
148                 "selfLink":          "/apis/metal3.io/v1alpha1/namespaces/default/baremetalhosts/bpa-test-bmh",
149                 "uid":               "e92cb312-f619-11e9-90bc-00219ba0c77a",
150         }
151
152         nicMap1 := map[string]interface{}{
153                 "ip":        "192.168.50.63",
154                 "mac":       "08:00:27:00:ab:2c",
155                 "model":     "0x8086 0x1572",
156                 "name":      "eth3",
157                 "pxe":       "false",
158                 "speedGbps": "0",
159                 "vlanId":    "0",
160         }
161
162         nicMap2 := map[string]interface{}{
163                 "ip":        "192.168.60.73",
164                 "mac":       "08:00:27:00:ab:1c",
165                 "model":     "0x8086 0x1572",
166                 "name":      "eth4",
167                 "pxe":       "false",
168                 "speedGbps": "0",
169                 "vlanId":    "0",
170         }
171
172         specMap := map[string]interface{}{
173                 "bootMACAddress": "08:00:27:00:ab:2c",
174         }
175
176         statusMap := map[string]interface{}{
177                 "errorMessage": "",
178                 "hardware": map[string]interface{}{
179                         "nics": []interface{}{
180                                 nicMap1,
181                                 nicMap2,
182                         },
183                 },
184         }
185
186         itemMap := map[string]interface{}{
187                 "apiVersion": "metal3.io/v1alpha1",
188                 "kind":       "BareMetalHost",
189                 "metadata":   metaData,
190                 "spec":       specMap,
191                 "status":     statusMap,
192         }
193         itemU := unstructured.Unstructured{
194                 Object: itemMap,
195         }
196
197         itemsList := []unstructured.Unstructured{itemU}
198
199         bmhList := &unstructured.UnstructuredList{
200                 Object: bmMap,
201                 Items:  itemsList,
202         }
203
204         return bmhList
205 }