1
16
17 package testing
18
19 import (
20 "bytes"
21 "fmt"
22 "io"
23 "testing"
24
25 "k8s.io/apimachinery/pkg/runtime"
26 "k8s.io/apimachinery/pkg/runtime/schema"
27 )
28
29
30
31
32 type noncacheableTestObject struct {
33 gvk schema.GroupVersionKind
34 }
35
36
37 func (*noncacheableTestObject) MarshalJSON() ([]byte, error) {
38 return []byte("\"json-result\""), nil
39 }
40
41
42 func (*noncacheableTestObject) Marshal() ([]byte, error) {
43 return []byte("\"proto-result\""), nil
44 }
45
46
47 func (*noncacheableTestObject) DeepCopyObject() runtime.Object {
48 panic("DeepCopy unimplemented for noncacheableTestObject")
49 }
50
51
52 func (o *noncacheableTestObject) GetObjectKind() schema.ObjectKind {
53 return o
54 }
55
56
57 func (o *noncacheableTestObject) GroupVersionKind() schema.GroupVersionKind {
58 return o.gvk
59 }
60
61
62 func (o *noncacheableTestObject) SetGroupVersionKind(gvk schema.GroupVersionKind) {
63 o.gvk = gvk
64 }
65
66 var _ runtime.CacheableObject = &MockCacheableObject{}
67
68
69
70 type MockCacheableObject struct {
71 gvk schema.GroupVersionKind
72
73 t *testing.T
74
75 runEncode bool
76 returnSelf bool
77 expectedResult string
78 expectedError error
79
80 intercepted []runtime.Identifier
81 }
82
83
84 func (m *MockCacheableObject) DeepCopyObject() runtime.Object {
85 panic("DeepCopy unimplemented for MockCacheableObject")
86 }
87
88
89 func (m *MockCacheableObject) GetObjectKind() schema.ObjectKind {
90 return m
91 }
92
93
94 func (m *MockCacheableObject) GroupVersionKind() schema.GroupVersionKind {
95 return m.gvk
96 }
97
98
99 func (m *MockCacheableObject) SetGroupVersionKind(gvk schema.GroupVersionKind) {
100 m.gvk = gvk
101 }
102
103
104
105 func (*MockCacheableObject) Marshal() ([]byte, error) {
106 return []byte("\"proto-result\""), nil
107 }
108
109
110 func (m *MockCacheableObject) CacheEncode(id runtime.Identifier, encode func(runtime.Object, io.Writer) error, w io.Writer) error {
111 m.intercepted = append(m.intercepted, id)
112 if m.runEncode {
113 return encode(m.GetObject(), w)
114 }
115 if _, err := w.Write([]byte(m.expectedResult)); err != nil {
116 m.t.Errorf("couldn't write to io.Writer: %v", err)
117 }
118 return m.expectedError
119 }
120
121
122 func (m *MockCacheableObject) GetObject() runtime.Object {
123 if m.returnSelf {
124 return m
125 }
126 gvk := schema.GroupVersionKind{Group: "group", Version: "version", Kind: "noncacheableTestObject"}
127 return &noncacheableTestObject{gvk: gvk}
128 }
129
130 func (m *MockCacheableObject) interceptedCalls() []runtime.Identifier {
131 return m.intercepted
132 }
133
134 type testBuffer struct {
135 writer io.Writer
136 t *testing.T
137 object *MockCacheableObject
138 }
139
140
141 func (b *testBuffer) Write(p []byte) (int, error) {
142
143
144 if len(b.object.interceptedCalls()) == 0 {
145 b.t.Errorf("writing to buffer without handling MockCacheableObject")
146 }
147 return b.writer.Write(p)
148 }
149
150
151
152
153 func CacheableObjectTest(t *testing.T, e runtime.Encoder) {
154 gvk1 := schema.GroupVersionKind{Group: "group", Version: "version1", Kind: "MockCacheableObject"}
155
156 testCases := []struct {
157 desc string
158 runEncode bool
159 returnSelf bool
160 expectedResult string
161 expectedError error
162 }{
163 {
164 desc: "delegate",
165 runEncode: true,
166 },
167 {
168 desc: "delegate return self",
169 runEncode: true,
170 returnSelf: true,
171 },
172 {
173 desc: "cached success",
174 runEncode: false,
175 expectedResult: "result",
176 expectedError: nil,
177 },
178 {
179 desc: "cached failure",
180 runEncode: false,
181 expectedResult: "",
182 expectedError: fmt.Errorf("encoding error"),
183 },
184 }
185
186 for _, test := range testCases {
187 t.Run(test.desc, func(t *testing.T) {
188 obj := &MockCacheableObject{
189 gvk: gvk1,
190 t: t,
191 runEncode: test.runEncode,
192 returnSelf: test.returnSelf,
193 expectedResult: test.expectedResult,
194 expectedError: test.expectedError,
195 }
196 buffer := bytes.NewBuffer(nil)
197 w := &testBuffer{
198 writer: buffer,
199 t: t,
200 object: obj,
201 }
202
203 if err := e.Encode(obj, w); err != test.expectedError {
204 t.Errorf("unexpected error: %v, expected: %v", err, test.expectedError)
205 }
206 if !test.runEncode {
207 if result := buffer.String(); result != test.expectedResult {
208 t.Errorf("unexpected result: %s, expected: %s", result, test.expectedResult)
209 }
210 }
211 intercepted := obj.interceptedCalls()
212 if len(intercepted) != 1 {
213 t.Fatalf("unexpected number of intercepted calls: %v", intercepted)
214 }
215 if intercepted[0] != e.Identifier() {
216 t.Errorf("unexpected intercepted call: %v, expected: %v", intercepted, e.Identifier())
217 }
218 })
219 }
220 }
221
View as plain text