1
16
17 package app
18
19 import (
20 "context"
21 "testing"
22 "time"
23
24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 "k8s.io/client-go/discovery"
26 fakediscovery "k8s.io/client-go/discovery/fake"
27 "k8s.io/client-go/informers"
28 clientset "k8s.io/client-go/kubernetes"
29 fakeclientset "k8s.io/client-go/kubernetes/fake"
30 restclient "k8s.io/client-go/rest"
31 )
32
33
34 type TestClientBuilder struct {
35 clientset clientset.Interface
36 }
37
38 func (TestClientBuilder) Config(name string) (*restclient.Config, error) { return nil, nil }
39 func (TestClientBuilder) ConfigOrDie(name string) *restclient.Config {
40 return &restclient.Config{}
41 }
42
43 func (TestClientBuilder) Client(name string) (clientset.Interface, error) { return nil, nil }
44 func (m TestClientBuilder) ClientOrDie(name string) clientset.Interface {
45 return m.clientset
46 }
47
48 func (m TestClientBuilder) DiscoveryClient(name string) (discovery.DiscoveryInterface, error) {
49 return m.clientset.Discovery(), nil
50 }
51 func (m TestClientBuilder) DiscoveryClientOrDie(name string) discovery.DiscoveryInterface {
52 ret, err := m.DiscoveryClient(name)
53 if err != nil {
54 panic(err)
55 }
56 return ret
57 }
58
59
60 type FakeDiscoveryWithError struct {
61 fakediscovery.FakeDiscovery
62 PossibleResources []*metav1.APIResourceList
63 Err error
64 }
65
66 func (d FakeDiscoveryWithError) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
67 return d.PossibleResources, d.Err
68 }
69
70
71 type FakeClientSet struct {
72 fakeclientset.Clientset
73 DiscoveryObj *FakeDiscoveryWithError
74 }
75
76 func (c *FakeClientSet) Discovery() discovery.DiscoveryInterface {
77 return c.DiscoveryObj
78 }
79
80 func (c *FakeClientSet) GetPossibleResources() []*metav1.APIResourceList {
81 return c.DiscoveryObj.PossibleResources
82 }
83
84
85 func NewFakeClientset(fakeDiscovery FakeDiscoveryWithError) *FakeClientSet {
86 cs := &FakeClientSet{}
87 cs.DiscoveryObj = &fakeDiscovery
88 return cs
89 }
90
91 func possibleDiscoveryResource() []*metav1.APIResourceList {
92 return []*metav1.APIResourceList{
93 {
94 GroupVersion: "create/v1",
95 APIResources: []metav1.APIResource{
96 {
97 Name: "jobs",
98 Verbs: []string{"create", "list", "watch", "delete"},
99 ShortNames: []string{"jz"},
100 Categories: []string{"all"},
101 },
102 },
103 },
104 }
105 }
106
107 func TestController_DiscoveryError(t *testing.T) {
108 controllerDescriptorMap := map[string]*ControllerDescriptor{
109 "ResourceQuotaController": newResourceQuotaControllerDescriptor(),
110 "GarbageCollectorController": newGarbageCollectorControllerDescriptor(),
111 "EndpointSliceController": newEndpointSliceControllerDescriptor(),
112 "EndpointSliceMirroringController": newEndpointSliceMirroringControllerDescriptor(),
113 "PodDisruptionBudgetController": newDisruptionControllerDescriptor(),
114 }
115
116 tcs := map[string]struct {
117 discoveryError error
118 expectedErr bool
119 possibleResources []*metav1.APIResourceList
120 }{
121 "No Discovery Error": {
122 discoveryError: nil,
123 possibleResources: possibleDiscoveryResource(),
124 expectedErr: false,
125 },
126 "Discovery Calls Partially Failed": {
127 discoveryError: new(discovery.ErrGroupDiscoveryFailed),
128 possibleResources: possibleDiscoveryResource(),
129 expectedErr: false,
130 },
131 }
132 for name, test := range tcs {
133 testDiscovery := FakeDiscoveryWithError{Err: test.discoveryError, PossibleResources: test.possibleResources}
134 testClientset := NewFakeClientset(testDiscovery)
135 testClientBuilder := TestClientBuilder{clientset: testClientset}
136 testInformerFactory := informers.NewSharedInformerFactoryWithOptions(testClientset, time.Duration(1))
137 ctx := ControllerContext{
138 ClientBuilder: testClientBuilder,
139 InformerFactory: testInformerFactory,
140 ObjectOrMetadataInformerFactory: testInformerFactory,
141 InformersStarted: make(chan struct{}),
142 }
143 for controllerName, controllerDesc := range controllerDescriptorMap {
144 _, _, err := controllerDesc.GetInitFunc()(context.TODO(), ctx, controllerName)
145 if test.expectedErr != (err != nil) {
146 t.Errorf("%v test failed for use case: %v", controllerName, name)
147 }
148 }
149 _, _, err := startModifiedNamespaceController(
150 context.TODO(), ctx, testClientset, testClientBuilder.ConfigOrDie("namespace-controller"))
151 if test.expectedErr != (err != nil) {
152 t.Errorf("Namespace Controller test failed for use case: %v", name)
153 }
154 }
155 }
156
View as plain text