@@ -17,20 +17,27 @@ limitations under the License.
17
17
package v1_test
18
18
19
19
import (
20
+ "encoding/json"
21
+ "math/rand"
20
22
"net/url"
21
23
"reflect"
22
24
"testing"
23
25
"time"
24
26
25
27
"k8s.io/api/core/v1"
28
+ extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
26
29
apiequality "k8s.io/apimachinery/pkg/api/equality"
27
30
"k8s.io/apimachinery/pkg/api/resource"
31
+ "k8s.io/apimachinery/pkg/api/testing/fuzzer"
28
32
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29
33
"k8s.io/apimachinery/pkg/runtime"
30
34
"k8s.io/apimachinery/pkg/util/diff"
31
35
"k8s.io/kubernetes/pkg/api"
32
36
"k8s.io/kubernetes/pkg/api/legacyscheme"
37
+ kapitesting "k8s.io/kubernetes/pkg/api/testing"
33
38
k8s_api_v1 "k8s.io/kubernetes/pkg/api/v1"
39
+ "k8s.io/kubernetes/pkg/apis/extensions"
40
+ utilpointer "k8s.io/kubernetes/pkg/util/pointer"
34
41
35
42
// enforce that all types are installed
36
43
_ "k8s.io/kubernetes/pkg/api/testapi"
@@ -226,3 +233,115 @@ func TestResourceListConversion(t *testing.T) {
226
233
}
227
234
}
228
235
}
236
+
237
+ func TestReplicationControllerConversion (t * testing.T ) {
238
+ // If we start with a RC, we should always have round-trip fidelity.
239
+ inputs := []* v1.ReplicationController {
240
+ {
241
+ ObjectMeta : metav1.ObjectMeta {
242
+ Name : "name" ,
243
+ Namespace : "namespace" ,
244
+ },
245
+ Spec : v1.ReplicationControllerSpec {
246
+ Replicas : utilpointer .Int32Ptr (1 ),
247
+ MinReadySeconds : 32 ,
248
+ Selector : map [string ]string {"foo" : "bar" , "bar" : "foo" },
249
+ Template : & v1.PodTemplateSpec {
250
+ ObjectMeta : metav1.ObjectMeta {
251
+ Labels : map [string ]string {"foo" : "bar" , "bar" : "foo" },
252
+ },
253
+ Spec : v1.PodSpec {
254
+ Containers : []v1.Container {
255
+ {
256
+ Name : "container" ,
257
+ Image : "image" ,
258
+ },
259
+ },
260
+ },
261
+ },
262
+ },
263
+ Status : v1.ReplicationControllerStatus {
264
+ Replicas : 1 ,
265
+ FullyLabeledReplicas : 2 ,
266
+ ReadyReplicas : 3 ,
267
+ AvailableReplicas : 4 ,
268
+ ObservedGeneration : 5 ,
269
+ Conditions : []v1.ReplicationControllerCondition {
270
+ {
271
+ Type : v1 .ReplicationControllerReplicaFailure ,
272
+ Status : v1 .ConditionTrue ,
273
+ LastTransitionTime : metav1 .NewTime (time .Unix (123456789 , 0 )),
274
+ Reason : "Reason" ,
275
+ Message : "Message" ,
276
+ },
277
+ },
278
+ },
279
+ },
280
+ }
281
+
282
+ // Add some fuzzed RCs.
283
+ apiObjectFuzzer := fuzzer .FuzzerFor (kapitesting .FuzzerFuncs , rand .NewSource (152 ), legacyscheme .Codecs )
284
+ for i := 0 ; i < 100 ; i ++ {
285
+ rc := & v1.ReplicationController {}
286
+ apiObjectFuzzer .Fuzz (rc )
287
+ // Sometimes the fuzzer decides to leave Spec.Template nil.
288
+ // We can't support that because Spec.Template is not a pointer in RS,
289
+ // so it will round-trip as non-nil but empty.
290
+ if rc .Spec .Template == nil {
291
+ rc .Spec .Template = & v1.PodTemplateSpec {}
292
+ }
293
+ // Sometimes the fuzzer decides to insert an empty label key.
294
+ // This doesn't round-trip properly because it's invalid.
295
+ if rc .Spec .Selector != nil {
296
+ delete (rc .Spec .Selector , "" )
297
+ }
298
+ inputs = append (inputs , rc )
299
+ }
300
+
301
+ // Round-trip the input RCs before converting to RS.
302
+ for i := range inputs {
303
+ inputs [i ] = roundTrip (t , inputs [i ]).(* v1.ReplicationController )
304
+ }
305
+
306
+ for _ , in := range inputs {
307
+ rs := & extensions.ReplicaSet {}
308
+ // Use in.DeepCopy() to avoid sharing pointers with `in`.
309
+ if err := k8s_api_v1 .Convert_v1_ReplicationController_to_extensions_ReplicaSet (in .DeepCopy (), rs , nil ); err != nil {
310
+ t .Errorf ("can't convert RC to RS: %v" , err )
311
+ continue
312
+ }
313
+ // Round-trip RS before converting back to RC.
314
+ rs = roundTripRS (t , rs )
315
+ out := & v1.ReplicationController {}
316
+ if err := k8s_api_v1 .Convert_extensions_ReplicaSet_to_v1_ReplicationController (rs , out , nil ); err != nil {
317
+ t .Errorf ("can't convert RS to RC: %v" , err )
318
+ continue
319
+ }
320
+ if ! apiequality .Semantic .DeepEqual (in , out ) {
321
+ instr , _ := json .MarshalIndent (in , "" , " " )
322
+ outstr , _ := json .MarshalIndent (out , "" , " " )
323
+ t .Errorf ("RC-RS conversion round-trip failed:\n in:\n %s\n out:\n %s" , instr , outstr )
324
+ }
325
+ }
326
+ }
327
+
328
+ func roundTripRS (t * testing.T , rs * extensions.ReplicaSet ) * extensions.ReplicaSet {
329
+ codec := legacyscheme .Codecs .LegacyCodec (extensionsv1beta1 .SchemeGroupVersion )
330
+ data , err := runtime .Encode (codec , rs )
331
+ if err != nil {
332
+ t .Errorf ("%v\n %#v" , err , rs )
333
+ return nil
334
+ }
335
+ obj2 , err := runtime .Decode (codec , data )
336
+ if err != nil {
337
+ t .Errorf ("%v\n Data: %s\n Source: %#v" , err , string (data ), rs )
338
+ return nil
339
+ }
340
+ obj3 := & extensions.ReplicaSet {}
341
+ err = legacyscheme .Scheme .Convert (obj2 , obj3 , nil )
342
+ if err != nil {
343
+ t .Errorf ("%v\n Source: %#v" , err , obj2 )
344
+ return nil
345
+ }
346
+ return obj3
347
+ }
0 commit comments