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"
20 func TestProvisioningController(t *testing.T) {
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"
32 // Create Fake baremetalhost
33 bmhList := newBMList()
35 // Create Fake Provisioning CR
36 provisioning := newBPA(bpaName1, namespace, clusterName, macAddress1)
37 provisioning2 := newBPA(bpaName2, namespace, clusterName2, macAddress2)
39 // Objects to track in the fake Client
40 objs := []runtime.Object{provisioning, provisioning2}
42 // Register operator types with the runtime scheme
45 sc.AddKnownTypes(bpav1alpha1.SchemeGroupVersion, provisioning, provisioning2)
47 // Create Fake Clients and Clientset
48 fakeClient := fake.NewFakeClient(objs...)
49 fakeDyn := fakedynamic.NewSimpleDynamicClient(sc, bmhList)
50 fakeClientSet := fakeclientset.NewSimpleClientset()
52 r := &ReconcileProvisioning{client: fakeClient, scheme: sc, clientset: fakeClientSet, bmhClient: fakeDyn}
54 // Mock request to simulate Reconcile() being called on an event for a watched resource
55 req := simulateRequest(provisioning)
56 _, err := r.Reconcile(req)
58 t.Fatalf("reconcile: (%v)", err)
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{})
66 t.Fatalf("Error occured while getting job: (%v)", err)
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")
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)
83 // Delete cluster directories
84 err = os.RemoveAll("/multi-cluster/" + clusterName)
86 t.Logf("\nUnable to delete cluster directory %s\n", clusterName)
88 err = os.RemoveAll("/multi-cluster/" + clusterName2)
90 t.Logf("\nUnable to delete cluster directory %s\n", clusterName2)
92 err = os.RemoveAll("/multi-cluster/" + clusterName3)
94 t.Logf("\nUnable to delete cluster directory %s\n", clusterName3)
99 func simulateRequest(bpaCR *bpav1alpha1.Provisioning) reconcile.Request {
100 namespacedName := types.NamespacedName{
101 Name: bpaCR.ObjectMeta.Name,
102 Namespace: bpaCR.ObjectMeta.Namespace,
104 return reconcile.Request{NamespacedName: namespacedName}
107 func newBPA(name, namespace, clusterName, macAddress string) *bpav1alpha1.Provisioning {
109 provisioningCR := &bpav1alpha1.Provisioning{
110 ObjectMeta: metav1.ObjectMeta{
112 Namespace: namespace,
113 Labels: map[string]string{
114 "cluster": clusterName,
117 Spec: bpav1alpha1.ProvisioningSpec{
118 Masters: []map[string]bpav1alpha1.Master{
119 map[string]bpav1alpha1.Master{
120 "test-master": bpav1alpha1.Master{
121 MACaddress: macAddress,
127 return provisioningCR
130 func newBMList() *unstructured.UnstructuredList {
132 bmMap := map[string]interface{}{
133 "apiVersion": "metal3.io/v1alpha1",
134 "kind": "BareMetalHostList",
135 "metaData": map[string]interface{}{
137 "resourceVersion": "11830058",
138 "selfLink": "/apis/metal3.io/v1alpha1/baremetalhosts",
142 metaData := map[string]interface{}{
143 "creationTimestamp": "2019-10-24T04:51:15Z",
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",
152 nicMap1 := map[string]interface{}{
153 "ip": "192.168.50.63",
154 "mac": "08:00:27:00:ab:2c",
155 "model": "0x8086 0x1572",
162 nicMap2 := map[string]interface{}{
163 "ip": "192.168.60.73",
164 "mac": "08:00:27:00:ab:1c",
165 "model": "0x8086 0x1572",
172 specMap := map[string]interface{}{
173 "bootMACAddress": "08:00:27:00:ab:2c",
176 statusMap := map[string]interface{}{
178 "hardware": map[string]interface{}{
179 "nics": []interface{}{
186 itemMap := map[string]interface{}{
187 "apiVersion": "metal3.io/v1alpha1",
188 "kind": "BareMetalHost",
189 "metadata": metaData,
193 itemU := unstructured.Unstructured{
197 itemsList := []unstructured.Unstructured{itemU}
199 bmhList := &unstructured.UnstructuredList{