@@ -25,6 +25,7 @@ import (
25
25
26
26
v1 "k8s.io/api/core/v1"
27
27
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
28
29
"k8s.io/apimachinery/pkg/runtime"
29
30
"k8s.io/apimachinery/pkg/types"
30
31
"k8s.io/utils/ptr"
@@ -34,22 +35,24 @@ func TestDataConsistencyChecker(t *testing.T) {
34
35
scenarios := []struct {
35
36
name string
36
37
37
- listResponse * v1.PodList
38
- retrievedItems []* v1.Pod
39
- requestOptions metav1.ListOptions
38
+ lastSyncedResourceVersion string
39
+ listResponse runtime.Object
40
+ retrievedItems []runtime.Object
41
+ requestOptions metav1.ListOptions
40
42
41
43
expectedRequestOptions []metav1.ListOptions
42
44
expectedListRequests int
43
45
expectPanic bool
44
46
}{
45
47
{
46
- name : "data consistency check won't panic when data is consistent" ,
48
+ name : "data consistency check won't panic when data is consistent" ,
49
+ lastSyncedResourceVersion : "2" ,
47
50
listResponse : & v1.PodList {
48
51
ListMeta : metav1.ListMeta {ResourceVersion : "2" },
49
52
Items : []v1.Pod {* makePod ("p1" , "1" ), * makePod ("p2" , "2" )},
50
53
},
51
54
requestOptions : metav1.ListOptions {TimeoutSeconds : ptr .To (int64 (39 ))},
52
- retrievedItems : []* v1. Pod {makePod ("p1" , "1" ), makePod ("p2" , "2" )},
55
+ retrievedItems : []runtime. Object {makePod ("p1" , "1" ), makePod ("p2" , "2" )},
53
56
expectedListRequests : 1 ,
54
57
expectedRequestOptions : []metav1.ListOptions {
55
58
{
@@ -61,13 +64,42 @@ func TestDataConsistencyChecker(t *testing.T) {
61
64
},
62
65
63
66
{
64
- name : "legacy, the limit is removed from the list options when it wasn't honored by the watch cache" ,
67
+ name : "data consistency check works with unstructured data (dynamic client)" ,
68
+ lastSyncedResourceVersion : "2" ,
69
+ listResponse : & unstructured.UnstructuredList {
70
+ Object : map [string ]interface {}{
71
+ "apiVersion" : "vTest" ,
72
+ "kind" : "rTestList" ,
73
+ },
74
+ Items : []unstructured.Unstructured {
75
+ * makeUnstructuredObject ("vTest" , "rTest" , "item1" ),
76
+ * makeUnstructuredObject ("vTest" , "rTest" , "item2" ),
77
+ },
78
+ },
79
+ requestOptions : metav1.ListOptions {TimeoutSeconds : ptr .To (int64 (39 ))},
80
+ retrievedItems : []runtime.Object {
81
+ makeUnstructuredObject ("vTest" , "rTest" , "item1" ),
82
+ makeUnstructuredObject ("vTest" , "rTest" , "item2" ),
83
+ },
84
+ expectedListRequests : 1 ,
85
+ expectedRequestOptions : []metav1.ListOptions {
86
+ {
87
+ ResourceVersion : "2" ,
88
+ ResourceVersionMatch : metav1 .ResourceVersionMatchExact ,
89
+ TimeoutSeconds : ptr .To (int64 (39 )),
90
+ },
91
+ },
92
+ },
93
+
94
+ {
95
+ name : "legacy, the limit is removed from the list options when it wasn't honored by the watch cache" ,
96
+ lastSyncedResourceVersion : "2" ,
65
97
listResponse : & v1.PodList {
66
98
ListMeta : metav1.ListMeta {ResourceVersion : "2" },
67
99
Items : []v1.Pod {* makePod ("p1" , "1" ), * makePod ("p2" , "2" ), * makePod ("p3" , "3" )},
68
100
},
69
101
requestOptions : metav1.ListOptions {ResourceVersion : "0" , Limit : 2 },
70
- retrievedItems : []* v1. Pod {makePod ("p1" , "1" ), makePod ("p2" , "2" ), makePod ("p3" , "3" )},
102
+ retrievedItems : []runtime. Object {makePod ("p1" , "1" ), makePod ("p2" , "2" ), makePod ("p3" , "3" )},
71
103
expectedListRequests : 1 ,
72
104
expectedRequestOptions : []metav1.ListOptions {
73
105
{
@@ -78,13 +110,14 @@ func TestDataConsistencyChecker(t *testing.T) {
78
110
},
79
111
80
112
{
81
- name : "the limit is NOT removed from the list options for non-legacy request" ,
113
+ name : "the limit is NOT removed from the list options for non-legacy request" ,
114
+ lastSyncedResourceVersion : "2" ,
82
115
listResponse : & v1.PodList {
83
116
ListMeta : metav1.ListMeta {ResourceVersion : "2" },
84
117
Items : []v1.Pod {* makePod ("p1" , "1" ), * makePod ("p2" , "2" ), * makePod ("p3" , "3" )},
85
118
},
86
119
requestOptions : metav1.ListOptions {ResourceVersion : "2" , Limit : 2 },
87
- retrievedItems : []* v1. Pod {makePod ("p1" , "1" ), makePod ("p2" , "2" ), makePod ("p3" , "3" )},
120
+ retrievedItems : []runtime. Object {makePod ("p1" , "1" ), makePod ("p2" , "2" ), makePod ("p3" , "3" )},
88
121
expectedListRequests : 1 ,
89
122
expectedRequestOptions : []metav1.ListOptions {
90
123
{
@@ -96,13 +129,14 @@ func TestDataConsistencyChecker(t *testing.T) {
96
129
},
97
130
98
131
{
99
- name : "legacy, the limit is NOT removed from the list options when the watch cache is disabled" ,
132
+ name : "legacy, the limit is NOT removed from the list options when the watch cache is disabled" ,
133
+ lastSyncedResourceVersion : "2" ,
100
134
listResponse : & v1.PodList {
101
135
ListMeta : metav1.ListMeta {ResourceVersion : "2" },
102
136
Items : []v1.Pod {* makePod ("p1" , "1" ), * makePod ("p2" , "2" ), * makePod ("p3" , "3" )},
103
137
},
104
138
requestOptions : metav1.ListOptions {ResourceVersion : "0" , Limit : 5 },
105
- retrievedItems : []* v1. Pod {makePod ("p1" , "1" ), makePod ("p2" , "2" ), makePod ("p3" , "3" )},
139
+ retrievedItems : []runtime. Object {makePod ("p1" , "1" ), makePod ("p2" , "2" ), makePod ("p3" , "3" )},
106
140
expectedListRequests : 1 ,
107
141
expectedRequestOptions : []metav1.ListOptions {
108
142
{
@@ -114,7 +148,8 @@ func TestDataConsistencyChecker(t *testing.T) {
114
148
},
115
149
116
150
{
117
- name : "data consistency check won't panic when there is no data" ,
151
+ name : "data consistency check won't panic when there is no data" ,
152
+ lastSyncedResourceVersion : "2" ,
118
153
listResponse : & v1.PodList {
119
154
ListMeta : metav1.ListMeta {ResourceVersion : "2" },
120
155
},
@@ -136,7 +171,8 @@ func TestDataConsistencyChecker(t *testing.T) {
136
171
},
137
172
138
173
{
139
- name : "data consistency check won't be performed when ResourceVersion was set to 0" ,
174
+ name : "data consistency check won't be performed when ResourceVersion was set to 0" ,
175
+ lastSyncedResourceVersion : "0" ,
140
176
listResponse : & v1.PodList {
141
177
ListMeta : metav1.ListMeta {ResourceVersion : "0" },
142
178
Items : []v1.Pod {* makePod ("p1" , "1" ), * makePod ("p2" , "2" )},
@@ -146,13 +182,14 @@ func TestDataConsistencyChecker(t *testing.T) {
146
182
},
147
183
148
184
{
149
- name : "data consistency panics when data is inconsistent" ,
185
+ name : "data consistency panics when data is inconsistent" ,
186
+ lastSyncedResourceVersion : "2" ,
150
187
listResponse : & v1.PodList {
151
188
ListMeta : metav1.ListMeta {ResourceVersion : "2" },
152
189
Items : []v1.Pod {* makePod ("p1" , "1" ), * makePod ("p2" , "2" ), * makePod ("p3" , "3" )},
153
190
},
154
191
requestOptions : metav1.ListOptions {TimeoutSeconds : ptr .To (int64 (39 ))},
155
- retrievedItems : []* v1. Pod {makePod ("p1" , "1" ), makePod ("p2" , "2" )},
192
+ retrievedItems : []runtime. Object {makePod ("p1" , "1" ), makePod ("p2" , "2" )},
156
193
expectedListRequests : 1 ,
157
194
expectedRequestOptions : []metav1.ListOptions {
158
195
{
@@ -172,16 +209,16 @@ func TestDataConsistencyChecker(t *testing.T) {
172
209
scenario .listResponse = & v1.PodList {}
173
210
}
174
211
fakeLister := & listWrapper {response : scenario .listResponse }
175
- retrievedItemsFunc := func () []* v1. Pod {
212
+ retrievedItemsFunc := func () []runtime. Object {
176
213
return scenario .retrievedItems
177
214
}
178
215
179
216
if scenario .expectPanic {
180
217
require .Panics (t , func () {
181
- CheckDataConsistency (ctx , "" , scenario .listResponse . ResourceVersion , fakeLister .List , scenario .requestOptions , retrievedItemsFunc )
218
+ CheckDataConsistency (ctx , "" , scenario .lastSyncedResourceVersion , fakeLister .List , scenario .requestOptions , retrievedItemsFunc )
182
219
})
183
220
} else {
184
- CheckDataConsistency (ctx , "" , scenario .listResponse . ResourceVersion , fakeLister .List , scenario .requestOptions , retrievedItemsFunc )
221
+ CheckDataConsistency (ctx , "" , scenario .lastSyncedResourceVersion , fakeLister .List , scenario .requestOptions , retrievedItemsFunc )
185
222
}
186
223
187
224
require .Equal (t , fakeLister .counter , scenario .expectedListRequests )
@@ -218,10 +255,10 @@ func (lw *errorLister) List(_ context.Context, _ metav1.ListOptions) (runtime.Ob
218
255
type listWrapper struct {
219
256
counter int
220
257
requestOptions []metav1.ListOptions
221
- response * v1. PodList
258
+ response runtime. Object
222
259
}
223
260
224
- func (lw * listWrapper ) List (_ context.Context , opts metav1.ListOptions ) (* v1. PodList , error ) {
261
+ func (lw * listWrapper ) List (_ context.Context , opts metav1.ListOptions ) (runtime. Object , error ) {
225
262
lw .counter ++
226
263
lw .requestOptions = append (lw .requestOptions , opts )
227
264
return lw .response , nil
@@ -230,3 +267,15 @@ func (lw *listWrapper) List(_ context.Context, opts metav1.ListOptions) (*v1.Pod
230
267
func makePod (name , rv string ) * v1.Pod {
231
268
return & v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : name , ResourceVersion : rv , UID : types .UID (name )}}
232
269
}
270
+
271
+ func makeUnstructuredObject (version , kind , name string ) * unstructured.Unstructured {
272
+ return & unstructured.Unstructured {
273
+ Object : map [string ]interface {}{
274
+ "apiVersion" : version ,
275
+ "kind" : kind ,
276
+ "metadata" : map [string ]interface {}{
277
+ "name" : name ,
278
+ },
279
+ },
280
+ }
281
+ }
0 commit comments