@@ -551,6 +551,209 @@ func Test_TransitionsForTrafficDistribution(t *testing.T) {
551
551
assertEndpointSliceHints (t , ctx , client , ns .GetName (), svc .GetName (), false , false )
552
552
}
553
553
554
+ // Test transitions involving the `trafficDistribution` field with
555
+ // PreferSameTrafficDistribution enabled.
556
+ func Test_TransitionsForPreferSameTrafficDistribution (t * testing.T ) {
557
+
558
+ ////////////////////////////////////////////////////////////////////////////
559
+ // Setup components, like kube-apiserver and EndpointSlice controller.
560
+ ////////////////////////////////////////////////////////////////////////////
561
+
562
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .ServiceTrafficDistribution , true )
563
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .PreferSameTrafficDistribution , true )
564
+
565
+ // Disable ServiceAccount admission plugin as we don't have serviceaccount controller running.
566
+ server := kubeapiservertesting .StartTestServerOrDie (t , nil , framework .DefaultTestServerFlags (), framework .SharedEtcd ())
567
+ defer server .TearDownFn ()
568
+
569
+ client , err := clientset .NewForConfig (server .ClientConfig )
570
+ if err != nil {
571
+ t .Fatalf ("Error creating clientset: %v" , err )
572
+ }
573
+
574
+ resyncPeriod := 12 * time .Hour
575
+ informers := informers .NewSharedInformerFactory (client , resyncPeriod )
576
+
577
+ ctx := ktesting .Init (t )
578
+ defer ctx .Cancel ("test has completed" )
579
+ epsController := endpointslice .NewController (
580
+ ctx ,
581
+ informers .Core ().V1 ().Pods (),
582
+ informers .Core ().V1 ().Services (),
583
+ informers .Core ().V1 ().Nodes (),
584
+ informers .Discovery ().V1 ().EndpointSlices (),
585
+ int32 (100 ),
586
+ client ,
587
+ 1 * time .Second ,
588
+ )
589
+
590
+ informers .Start (ctx .Done ())
591
+ go epsController .Run (ctx , 1 )
592
+
593
+ ////////////////////////////////////////////////////////////////////////////
594
+ // Create a namespace, node, pod in the node, and a service exposing the pod.
595
+ ////////////////////////////////////////////////////////////////////////////
596
+
597
+ ns := framework .CreateNamespaceOrDie (client , "test-service-traffic-distribution" , t )
598
+ defer framework .DeleteNamespaceOrDie (client , ns , t )
599
+
600
+ node := & corev1.Node {
601
+ ObjectMeta : metav1.ObjectMeta {
602
+ Name : "fake-node" ,
603
+ Labels : map [string ]string {
604
+ corev1 .LabelTopologyZone : "fake-zone-1" ,
605
+ },
606
+ },
607
+ }
608
+
609
+ pod := & corev1.Pod {
610
+ ObjectMeta : metav1.ObjectMeta {
611
+ Name : "test-pod" ,
612
+ Namespace : ns .GetName (),
613
+ Labels : map [string ]string {
614
+ "foo" : "bar" ,
615
+ },
616
+ },
617
+ Spec : corev1.PodSpec {
618
+ NodeName : node .GetName (),
619
+ Containers : []corev1.Container {
620
+ {
621
+ Name : "fake-name" ,
622
+ Image : "fake-image" ,
623
+ Ports : []corev1.ContainerPort {
624
+ {
625
+ Name : "port-443" ,
626
+ ContainerPort : 443 ,
627
+ },
628
+ },
629
+ },
630
+ },
631
+ },
632
+ Status : corev1.PodStatus {
633
+ Phase : corev1 .PodRunning ,
634
+ Conditions : []corev1.PodCondition {
635
+ {
636
+ Type : corev1 .PodReady ,
637
+ Status : corev1 .ConditionTrue ,
638
+ },
639
+ },
640
+ PodIP : "10.0.0.1" ,
641
+ PodIPs : []corev1.PodIP {
642
+ {
643
+ IP : "10.0.0.1" ,
644
+ },
645
+ },
646
+ },
647
+ }
648
+
649
+ svc := & corev1.Service {
650
+ ObjectMeta : metav1.ObjectMeta {
651
+ Name : "test-service" ,
652
+ Namespace : ns .GetName (),
653
+ },
654
+ Spec : corev1.ServiceSpec {
655
+ Selector : map [string ]string {
656
+ "foo" : "bar" ,
657
+ },
658
+ Ports : []corev1.ServicePort {
659
+ {Name : "port-443" , Port : 443 , Protocol : "TCP" , TargetPort : intstr .FromInt32 (443 )},
660
+ },
661
+ },
662
+ }
663
+
664
+ _ , err = client .CoreV1 ().Nodes ().Create (ctx , node , metav1.CreateOptions {})
665
+ if err != nil {
666
+ t .Fatalf ("Failed to create test node: %v" , err )
667
+ }
668
+ _ , err = client .CoreV1 ().Pods (ns .Name ).Create (ctx , pod , metav1.CreateOptions {})
669
+ if err != nil {
670
+ t .Fatalf ("Failed to create test ready pod: %v" , err )
671
+ }
672
+ _ , err = client .CoreV1 ().Pods (ns .Name ).UpdateStatus (ctx , pod , metav1.UpdateOptions {})
673
+ if err != nil {
674
+ t .Fatalf ("Failed to update status for test pod to Ready: %v" , err )
675
+ }
676
+ _ , err = client .CoreV1 ().Services (ns .Name ).Create (ctx , svc , metav1.CreateOptions {})
677
+ if err != nil {
678
+ t .Fatalf ("Failed to create test service: %v" , err )
679
+ }
680
+
681
+ ////////////////////////////////////////////////////////////////////////////
682
+ // Assert that without the presence of `trafficDistribution` field there are
683
+ // no zone hints in EndpointSlice.
684
+ ////////////////////////////////////////////////////////////////////////////
685
+
686
+ assertEndpointSliceHints (t , ctx , client , ns .GetName (), svc .GetName (), false , false )
687
+
688
+ ////////////////////////////////////////////////////////////////////////////
689
+ // Update the service by setting `trafficDistribution: PreferSameZone`
690
+ //
691
+ // Assert that the respective EndpointSlices get the same-zone hints.
692
+ ////////////////////////////////////////////////////////////////////////////
693
+
694
+ trafficDist := corev1 .ServiceTrafficDistributionPreferSameZone
695
+ svc .Spec .TrafficDistribution = & trafficDist
696
+ _ , err = client .CoreV1 ().Services (ns .Name ).Update (ctx , svc , metav1.UpdateOptions {})
697
+ if err != nil {
698
+ t .Fatalf ("Failed to update test service with 'trafficDistribution: PreferSameZone': %v" , err )
699
+ }
700
+
701
+ assertEndpointSliceHints (t , ctx , client , ns .GetName (), svc .GetName (), true , false )
702
+
703
+ ////////////////////////////////////////////////////////////////////////////
704
+ // Change `trafficDistribution` to `PreferSameNode`.
705
+ //
706
+ // Assert that the respective EndpointSlices have both same-zone and
707
+ // same-node hints.
708
+ ////////////////////////////////////////////////////////////////////////////
709
+
710
+ trafficDist = corev1 .ServiceTrafficDistributionPreferSameNode
711
+ svc .Spec .TrafficDistribution = & trafficDist
712
+ _ , err = client .CoreV1 ().Services (ns .Name ).Update (ctx , svc , metav1.UpdateOptions {})
713
+ if err != nil {
714
+ t .Fatalf ("Failed to update test service with 'trafficDistribution: PreferSameNode': %v" , err )
715
+ }
716
+
717
+ assertEndpointSliceHints (t , ctx , client , ns .GetName (), svc .GetName (), true , true )
718
+
719
+ ////////////////////////////////////////////////////////////////////////////
720
+ // Remove the field `trafficDistribution` from the service.
721
+ //
722
+ // Assert that EndpointSlice for service again has no zone hints.
723
+ ////////////////////////////////////////////////////////////////////////////
724
+
725
+ svc .Spec .TrafficDistribution = nil
726
+ _ , err = client .CoreV1 ().Services (ns .Name ).Update (ctx , svc , metav1.UpdateOptions {})
727
+ if err != nil {
728
+ t .Fatalf ("Failed to remove annotation 'service.kubernetes.io/topology-mode=Auto' from service: %v" , err )
729
+ }
730
+
731
+ assertEndpointSliceHints (t , ctx , client , ns .GetName (), svc .GetName (), false , false )
732
+
733
+ ////////////////////////////////////////////////////////////////////////////
734
+ // Update the Node to no longer have a zone label, and re-enable
735
+ // `PreferSameNode`.
736
+ //
737
+ // Assert that the respective EndpointSlices have same-node hints but not
738
+ // same-zone.
739
+ ////////////////////////////////////////////////////////////////////////////
740
+
741
+ delete (node .Labels , corev1 .LabelTopologyZone )
742
+ _ , err = client .CoreV1 ().Nodes ().Update (ctx , node , metav1.UpdateOptions {})
743
+ if err != nil {
744
+ t .Fatalf ("Failed to update test node with no zone label: %v" , err )
745
+ }
746
+
747
+ trafficDist = corev1 .ServiceTrafficDistributionPreferSameNode
748
+ svc .Spec .TrafficDistribution = & trafficDist
749
+ _ , err = client .CoreV1 ().Services (ns .Name ).Update (ctx , svc , metav1.UpdateOptions {})
750
+ if err != nil {
751
+ t .Fatalf ("Failed to update test service with 'trafficDistribution: PreferSameNode': %v" , err )
752
+ }
753
+
754
+ assertEndpointSliceHints (t , ctx , client , ns .GetName (), svc .GetName (), false , true )
755
+ }
756
+
554
757
func Test_TrafficDistribution_FeatureGateEnableDisable (t * testing.T ) {
555
758
556
759
////////////////////////////////////////////////////////////////////////////
0 commit comments