@@ -24,6 +24,7 @@ import (
24
24
"time"
25
25
26
26
"k8s.io/api/core/v1"
27
+ apiequality "k8s.io/apimachinery/pkg/api/equality"
27
28
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28
29
"k8s.io/apimachinery/pkg/runtime"
29
30
"k8s.io/apimachinery/pkg/util/sets"
@@ -451,3 +452,125 @@ func TestPanicPropagated(t *testing.T) {
451
452
t .Errorf ("timeout: the panic failed to propagate from the controller run method!" )
452
453
}
453
454
}
455
+
456
+ func TestTransformingInformer (t * testing.T ) {
457
+ // source simulates an apiserver object endpoint.
458
+ source := fcache .NewFakeControllerSource ()
459
+
460
+ makePod := func (name , generation string ) * v1.Pod {
461
+ return & v1.Pod {
462
+ ObjectMeta : metav1.ObjectMeta {
463
+ Name : name ,
464
+ Namespace : "namespace" ,
465
+ Labels : map [string ]string {"generation" : generation },
466
+ },
467
+ Spec : v1.PodSpec {
468
+ Hostname : "hostname" ,
469
+ Subdomain : "subdomain" ,
470
+ },
471
+ }
472
+ }
473
+ expectedPod := func (name , generation string ) * v1.Pod {
474
+ pod := makePod (name , generation )
475
+ pod .Spec .Hostname = "new-hostname"
476
+ pod .Spec .Subdomain = ""
477
+ pod .Spec .NodeName = "nodename"
478
+ return pod
479
+ }
480
+
481
+ source .Add (makePod ("pod1" , "1" ))
482
+ source .Modify (makePod ("pod1" , "2" ))
483
+
484
+ type event struct {
485
+ eventType watch.EventType
486
+ previous interface {}
487
+ current interface {}
488
+ }
489
+ events := make (chan event , 10 )
490
+ recordEvent := func (eventType watch.EventType , previous , current interface {}) {
491
+ events <- event {eventType : eventType , previous : previous , current : current }
492
+ }
493
+ verifyEvent := func (eventType watch.EventType , previous , current interface {}) {
494
+ select {
495
+ case event := <- events :
496
+ if event .eventType != eventType {
497
+ t .Errorf ("expected type %v, got %v" , eventType , event .eventType )
498
+ }
499
+ if ! apiequality .Semantic .DeepEqual (event .previous , previous ) {
500
+ t .Errorf ("expected previous object %#v, got %#v" , previous , event .previous )
501
+ }
502
+ if ! apiequality .Semantic .DeepEqual (event .current , current ) {
503
+ t .Errorf ("expected object %#v, got %#v" , current , event .current )
504
+ }
505
+ case <- time .After (wait .ForeverTestTimeout ):
506
+ t .Errorf ("failed to get event" )
507
+ }
508
+ }
509
+
510
+ podTransformer := func (obj interface {}) (interface {}, error ) {
511
+ pod , ok := obj .(* v1.Pod )
512
+ if ! ok {
513
+ return nil , fmt .Errorf ("unexpected object type: %T" , obj )
514
+ }
515
+ pod .Spec .Hostname = "new-hostname"
516
+ pod .Spec .Subdomain = ""
517
+ pod .Spec .NodeName = "nodename"
518
+
519
+ // Clear out ResourceVersion to simplify comparisons.
520
+ pod .ResourceVersion = ""
521
+
522
+ return pod , nil
523
+ }
524
+
525
+ store , controller := NewTransformingInformer (
526
+ source ,
527
+ & v1.Pod {},
528
+ 0 ,
529
+ ResourceEventHandlerFuncs {
530
+ AddFunc : func (obj interface {}) { recordEvent (watch .Added , nil , obj ) },
531
+ UpdateFunc : func (oldObj , newObj interface {}) { recordEvent (watch .Modified , oldObj , newObj ) },
532
+ DeleteFunc : func (obj interface {}) { recordEvent (watch .Deleted , obj , nil ) },
533
+ },
534
+ podTransformer ,
535
+ )
536
+
537
+ verifyStore := func (expectedItems []interface {}) {
538
+ items := store .List ()
539
+ if len (items ) != len (expectedItems ) {
540
+ t .Errorf ("unexpected items %v, expected %v" , items , expectedItems )
541
+ }
542
+ for _ , expectedItem := range expectedItems {
543
+ found := false
544
+ for _ , item := range items {
545
+ if apiequality .Semantic .DeepEqual (item , expectedItem ) {
546
+ found = true
547
+ }
548
+ }
549
+ if ! found {
550
+ t .Errorf ("expected item %v not found in %v" , expectedItem , items )
551
+ }
552
+ }
553
+ }
554
+
555
+ stopCh := make (chan struct {})
556
+ go controller .Run (stopCh )
557
+
558
+ verifyEvent (watch .Added , nil , expectedPod ("pod1" , "2" ))
559
+ verifyStore ([]interface {}{expectedPod ("pod1" , "2" )})
560
+
561
+ source .Add (makePod ("pod2" , "1" ))
562
+ verifyEvent (watch .Added , nil , expectedPod ("pod2" , "1" ))
563
+ verifyStore ([]interface {}{expectedPod ("pod1" , "2" ), expectedPod ("pod2" , "1" )})
564
+
565
+ source .Add (makePod ("pod3" , "1" ))
566
+ verifyEvent (watch .Added , nil , expectedPod ("pod3" , "1" ))
567
+
568
+ source .Modify (makePod ("pod2" , "2" ))
569
+ verifyEvent (watch .Modified , expectedPod ("pod2" , "1" ), expectedPod ("pod2" , "2" ))
570
+
571
+ source .Delete (makePod ("pod1" , "2" ))
572
+ verifyEvent (watch .Deleted , expectedPod ("pod1" , "2" ), nil )
573
+ verifyStore ([]interface {}{expectedPod ("pod2" , "2" ), expectedPod ("pod3" , "1" )})
574
+
575
+ close (stopCh )
576
+ }
0 commit comments