-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontroller_test.go
152 lines (139 loc) · 4.23 KB
/
controller_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
//TODO(i-prudnikov): Add unit tests for reconciler object methods
// Test_Reconcile is overall test of reconciliation logic for deployment and daemonset
// Based on this, we can extend testing to cover various errors. This is not included here
// for the sake of simplicity.
// From the home exercise perspective, I'm aiming to show general approach only
func Test_Reconcile(t *testing.T) {
// Fake client is buggy, and it looks like it more or less works for very basic and simple scenarios
// https://github.com/kubernetes-sigs/controller-runtime/issues/348
fakeClientBuilder := fake.NewClientBuilder()
//mock registry
mockRegistry := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Fake registry")
}))
defer mockRegistry.Close()
u,_ := url.Parse(mockRegistry.URL)
reconc := reconciler{
client: nil,
ignoredNamespaces: map[string]struct{}{"kube-system": {}},
backupRegistry: u.Host+"/namespace/backup",
}
tests := []struct {
// test case short title
title string
objects []client.Object
expetedImage string
expectError bool
}{
{
title: "reconcile deployment",
expetedImage: reconc.getTargetImage(u.Host+"/nginx:latest"),
objects: []client.Object{
&appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "server",
Namespace: "test",
},
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"deployment": "test" + "-deployment"},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": "test" + "-deployment"}},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "nginx",
Image: u.Host+"/nginx:latest",
},
},
},
},
},
},
},
},
{
title: "reconcile daemonset",
expetedImage: reconc.getTargetImage(u.Host+"/nginx:latest"),
objects: []client.Object{
&appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: "server",
Namespace: "test",
},
Spec: appsv1.DaemonSetSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"deployment": "test" + "-deployment"},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"deployment": "test" + "-deployment"}},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "nginx",
Image: u.Host+"/nginx:latest",
},
},
},
},
},
},
},
},
}
for _, test := range tests {
t.Run(test.title, func(t *testing.T) {
//Put mock objects to fake client
fakeClientBuilder.WithObjects(test.objects...)
//Set fake client to reconciler
reconc.client = fakeClientBuilder.Build()
for _, o := range test.objects {
kind := ""
if _, isDeployment := o.(*appsv1.Deployment); isDeployment {
kind = "Deployment"
}else {
kind = "DaemonSet"
}
r := reconcile.Request{NamespacedName: types.NamespacedName{
Namespace: o.GetNamespace(),
Name: fmt.Sprintf("%s:%s", kind, o.GetName()),
}}
_, e := reconc.Reconcile(context.Background(), r)
require.Nil(t, e)
//Checking if reconciled object has the right image
key := types.NamespacedName{
Name: o.GetName(),
Namespace: o.GetNamespace(),
}
switch kind {
case "Deployment":
dp := appsv1.Deployment{}
reconc.client.Get(context.Background(),key,&dp)
require.Equal(t,dp.Spec.Template.Spec.Containers[0].Image,test.expetedImage)
case "DaemonSet":
ds := appsv1.DaemonSet{}
reconc.client.Get(context.Background(),key,&ds)
require.Equal(t,ds.Spec.Template.Spec.Containers[0].Image,test.expetedImage)
}
}
})
}
}