@@ -21,6 +21,7 @@ import (
21
21
"context"
22
22
"fmt"
23
23
"io"
24
+ "math"
24
25
"net"
25
26
"net/http"
26
27
"time"
@@ -651,6 +652,154 @@ spec:
651
652
})
652
653
})
653
654
655
+ Context ("Test ApisixRoute Traffic Split" , func () {
656
+ It ("2:1 traffic split test" , func () {
657
+ const apisixRouteSpec = `
658
+ apiVersion: apisix.apache.org/v2
659
+ kind: ApisixRoute
660
+ metadata:
661
+ name: default
662
+ spec:
663
+ ingressClassName: apisix
664
+ http:
665
+ - name: rule1
666
+ match:
667
+ hosts:
668
+ - httpbin.org
669
+ paths:
670
+ - /get
671
+ backends:
672
+ - serviceName: httpbin-service-e2e-test
673
+ servicePort: 80
674
+ weight: 10
675
+ - serviceName: %s
676
+ servicePort: 9180
677
+ weight: 5
678
+ `
679
+ By ("apply ApisixRoute with traffic split" )
680
+ applier .MustApplyAPIv2 (types.NamespacedName {Namespace : s .Namespace (), Name : "default" }, new (apiv2.ApisixRoute ),
681
+ fmt .Sprintf (apisixRouteSpec , s .Deployer .GetAdminServiceName ()))
682
+ verifyRequest := func () int {
683
+ return s .NewAPISIXClient ().GET ("/get" ).WithHost ("httpbin.org" ).Expect ().Raw ().StatusCode
684
+ }
685
+ By ("send requests to verify traffic split" )
686
+ var (
687
+ successCount int
688
+ failCount int
689
+ )
690
+
691
+ s .RequestAssert (& scaffold.RequestAssert {
692
+ Method : "GET" ,
693
+ Path : "/get" ,
694
+ Host : "httpbin.org" ,
695
+ Check : scaffold .WithExpectedStatus (http .StatusOK ),
696
+ Timeout : 10 * time .Second ,
697
+ })
698
+ for range 90 {
699
+ code := verifyRequest ()
700
+ if code == http .StatusOK {
701
+ successCount ++
702
+ } else {
703
+ failCount ++
704
+ }
705
+ }
706
+
707
+ By ("verify traffic distribution ratio" )
708
+ ratio := float64 (successCount ) / float64 (failCount )
709
+ expectedRatio := 10.0 / 5.0 // 2:1 ratio
710
+ deviation := math .Abs (ratio - expectedRatio )
711
+ Expect (deviation ).Should (BeNumerically ("<" , 0.5 ),
712
+ "traffic distribution deviation too large (got %.2f, expected %.2f)" , ratio , expectedRatio )
713
+ })
714
+
715
+ It ("zero-weight test" , func () {
716
+ const apisixRouteSpec = `
717
+ apiVersion: apisix.apache.org/v2
718
+ kind: ApisixRoute
719
+ metadata:
720
+ name: default
721
+ spec:
722
+ ingressClassName: apisix
723
+ http:
724
+ - name: rule1
725
+ match:
726
+ hosts:
727
+ - httpbin.org
728
+ paths:
729
+ - /get
730
+ backends:
731
+ - serviceName: httpbin-service-e2e-test
732
+ servicePort: 80
733
+ weight: 10
734
+ - serviceName: %s
735
+ servicePort: 9180
736
+ weight: 0
737
+ `
738
+ By ("apply ApisixRoute with zero-weight backend" )
739
+ applier .MustApplyAPIv2 (types.NamespacedName {Namespace : s .Namespace (), Name : "default" }, new (apiv2.ApisixRoute ),
740
+ fmt .Sprintf (apisixRouteSpec , s .Deployer .GetAdminServiceName ()))
741
+ verifyRequest := func () int {
742
+ return s .NewAPISIXClient ().GET ("/get" ).WithHost ("httpbin.org" ).Expect ().Raw ().StatusCode
743
+ }
744
+
745
+ By ("wait for route to be ready" )
746
+ s .RequestAssert (& scaffold.RequestAssert {
747
+ Method : "GET" ,
748
+ Path : "/get" ,
749
+ Host : "httpbin.org" ,
750
+ Check : scaffold .WithExpectedStatus (http .StatusOK ),
751
+ Timeout : 10 * time .Second ,
752
+ })
753
+ By ("send requests to verify zero-weight behavior" )
754
+ for range 30 {
755
+ code := verifyRequest ()
756
+ Expect (code ).Should (Equal (200 ))
757
+ }
758
+ })
759
+ It ("valid backend is set even if other backend is invalid" , func () {
760
+ const apisixRouteSpec = `
761
+ apiVersion: apisix.apache.org/v2
762
+ kind: ApisixRoute
763
+ metadata:
764
+ name: default
765
+ spec:
766
+ ingressClassName: apisix
767
+ http:
768
+ - name: rule1
769
+ match:
770
+ hosts:
771
+ - httpbin.org
772
+ paths:
773
+ - /get
774
+ backends:
775
+ - serviceName: httpbin-service-e2e-test
776
+ servicePort: 80
777
+ weight: 10
778
+ - serviceName: invalid-service
779
+ servicePort: 9180
780
+ weight: 5
781
+ `
782
+ By ("apply ApisixRoute with traffic split" )
783
+ applier .MustApplyAPIv2 (types.NamespacedName {Namespace : s .Namespace (), Name : "default" }, new (apiv2.ApisixRoute ), apisixRouteSpec )
784
+ verifyRequest := func () int {
785
+ return s .NewAPISIXClient ().GET ("/get" ).WithHost ("httpbin.org" ).Expect ().Raw ().StatusCode
786
+ }
787
+
788
+ By ("wait for route to be ready" )
789
+ s .RequestAssert (& scaffold.RequestAssert {
790
+ Method : "GET" ,
791
+ Path : "/get" ,
792
+ Host : "httpbin.org" ,
793
+ Check : scaffold .WithExpectedStatus (http .StatusOK ),
794
+ Timeout : 10 * time .Second ,
795
+ })
796
+ By ("send requests to verify all requests routed to valid upstream" )
797
+ for range 30 {
798
+ code := verifyRequest ()
799
+ Expect (code ).Should (Equal (200 ))
800
+ }
801
+ })
802
+ })
654
803
Context ("Test ApisixRoute sync during startup" , func () {
655
804
const route = `
656
805
apiVersion: apisix.apache.org/v2
0 commit comments