From badf7b9a4f24b053415741badb3b6ef63c0a2d83 Mon Sep 17 00:00:00 2001 From: Gallardot Date: Wed, 9 Nov 2022 14:35:14 +0800 Subject: [PATCH] chore: add UT, add DIFF Signed-off-by: Gallardot --- pkg/router/apisix.go | 41 +++++++++++++++++++++--- pkg/router/apisix_test.go | 65 +++++++++++++++++++++++++++++++++++---- pkg/router/router_test.go | 43 +++++++++++++++++++++++++- 3 files changed, 137 insertions(+), 12 deletions(-) diff --git a/pkg/router/apisix.go b/pkg/router/apisix.go index ddc0b69e..ac38a501 100644 --- a/pkg/router/apisix.go +++ b/pkg/router/apisix.go @@ -20,7 +20,10 @@ import ( "context" "fmt" - apisixv2 "github.com/fluxcd/flagger/pkg/apis/apisix/v2" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + + a6v2 "github.com/fluxcd/flagger/pkg/apis/apisix/v2" flaggerv1 "github.com/fluxcd/flagger/pkg/apis/flagger/v1beta1" clientset "github.com/fluxcd/flagger/pkg/client/clientset/versioned" "go.uber.org/zap" @@ -66,7 +69,7 @@ func (ar *ApisixRouter) Reconcile(canary *flaggerv1.Canary) error { httpBackend.Backends[0] = primaryBackend canaryWeight := 0 - canaryBackend := apisixv2.ApisixRouteHTTPBackend{ + canaryBackend := a6v2.ApisixRouteHTTPBackend{ ServiceName: canaryName, ServicePort: primaryBackend.ServicePort, ResolveGranularity: primaryBackend.ResolveGranularity, @@ -77,10 +80,10 @@ func (ar *ApisixRouter) Reconcile(canary *flaggerv1.Canary) error { apisixRouteClone.Spec.HTTP[0] = httpBackend canaryApisixRouteName := fmt.Sprintf("%s-canary", canary.Spec.RouteRef.Name) - _, err = ar.apisixClient.ApisixV2().ApisixRoutes(canary.Namespace).Get(context.TODO(), canaryApisixRouteName, metav1.GetOptions{}) + canaryApisixRoute, err := ar.apisixClient.ApisixV2().ApisixRoutes(canary.Namespace).Get(context.TODO(), canaryApisixRouteName, metav1.GetOptions{}) if errors.IsNotFound(err) { - route := &apisixv2.ApisixRoute{ + route := &a6v2.ApisixRoute{ ObjectMeta: metav1.ObjectMeta{ Name: canaryApisixRouteName, Namespace: canary.Namespace, @@ -112,7 +115,35 @@ func (ar *ApisixRouter) Reconcile(canary *flaggerv1.Canary) error { return fmt.Errorf("apisix route %s.%s query error: %w", canaryApisixRouteName, canary.Namespace, err) } - //TODO diff + diffHttpSpec := "placeholder" + diffBackend := "placeholder" + diffCanaryBackend := "placeholder" + if len(canaryApisixRoute.Spec.HTTP) == 1 && + len(canaryApisixRoute.Spec.HTTP[0].Backends) == 2 { + diffHttpSpec = cmp.Diff(apisixRouteClone.Spec.HTTP[0], + canaryApisixRoute.Spec.HTTP[0], + cmpopts.IgnoreFields(a6v2.ApisixRouteHTTP{}, "Backends")) + + diffBackend = cmp.Diff(apisixRouteClone.Spec.HTTP[0].Backends[0], + canaryApisixRoute.Spec.HTTP[0].Backends[0], + cmpopts.IgnoreFields(a6v2.ApisixRouteHTTPBackend{}, "Weight")) + + diffCanaryBackend = cmp.Diff(apisixRouteClone.Spec.HTTP[0].Backends[1], + canaryApisixRoute.Spec.HTTP[0].Backends[1], + cmpopts.IgnoreFields(a6v2.ApisixRouteHTTPBackend{}, "Weight")) + } + + if diffHttpSpec != "" || diffBackend != "" || diffCanaryBackend != "" { + iClone := canaryApisixRoute.DeepCopy() + iClone.Spec = apisixRouteClone.Spec + + _, err := ar.apisixClient.ApisixV2().ApisixRoutes(canary.Namespace).Update(context.TODO(), iClone, metav1.UpdateOptions{}) + if err != nil { + return fmt.Errorf("apisix route %s.%s update error: %w", canaryApisixRouteName, iClone.Namespace, err) + } + ar.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)). + Infof("Apisix route %s updated", canaryApisixRouteName) + } return nil } diff --git a/pkg/router/apisix_test.go b/pkg/router/apisix_test.go index a405062b..9e6ba290 100644 --- a/pkg/router/apisix_test.go +++ b/pkg/router/apisix_test.go @@ -17,17 +17,70 @@ limitations under the License. package router import ( + "context" + "fmt" "testing" + + "github.com/fluxcd/flagger/pkg/apis/flagger/v1beta1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestApisixRouter_Reconcile(t *testing.T) { - // TODO + mocks := newFixture(nil) + mocks.canary.Spec.RouteRef = &v1beta1.LocalObjectReference{ + Name: "podinfo", + Kind: "ApisixRoute", + APIVersion: "apisix.apache.org/v2", + } + router := &ApisixRouter{ + apisixClient: mocks.flaggerClient, + logger: mocks.logger, + } + err := router.Reconcile(mocks.canary) + require.NoError(t, err) + canaryName := fmt.Sprintf("%s-canary", mocks.canary.Spec.RouteRef.Name) + arCanary, err := router.apisixClient.ApisixV2().ApisixRoutes("default").Get(context.TODO(), canaryName, metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, 2, len(arCanary.Spec.HTTP[0].Backends)) } -func TestApisixRouter_SetRoutes(t *testing.T) { - // TODO -} +func TestApisixRouter_GetSetRoutes(t *testing.T) { + mocks := newFixture(nil) + mocks.canary.Spec.RouteRef = &v1beta1.LocalObjectReference{ + Name: "podinfo", + Kind: "ApisixRoute", + APIVersion: "apisix.apache.org/v2", + } + router := &ApisixRouter{ + apisixClient: mocks.flaggerClient, + logger: mocks.logger, + } + err := router.Reconcile(mocks.canary) + require.NoError(t, err) + p, c, m, err := router.GetRoutes(mocks.canary) + require.NoError(t, err) + assert.Equal(t, 100, p) + assert.Equal(t, 0, c) + assert.False(t, m) -func TestApisixRouter_GetRoutes(t *testing.T) { - // TODO + p = 50 + c = 50 + m = false + err = router.SetRoutes(mocks.canary, p, c, m) + require.NoError(t, err) + + p, c, m, err = router.GetRoutes(mocks.canary) + require.NoError(t, err) + assert.Equal(t, 50, p) + assert.Equal(t, 50, c) + assert.False(t, m) + + canaryName := fmt.Sprintf("%s-canary", mocks.canary.Spec.RouteRef.Name) + arRouter, err := router.apisixClient.ApisixV2().ApisixRoutes("default").Get(context.TODO(), canaryName, metav1.GetOptions{}) + require.NoError(t, err) + assert.Equal(t, 2, len(arRouter.Spec.HTTP[0].Backends)) + assert.Equal(t, 50, *arRouter.Spec.HTTP[0].Backends[0].Weight) + assert.Equal(t, 50, *arRouter.Spec.HTTP[0].Backends[1].Weight) } diff --git a/pkg/router/router_test.go b/pkg/router/router_test.go index e81eaba9..a2509248 100644 --- a/pkg/router/router_test.go +++ b/pkg/router/router_test.go @@ -17,6 +17,7 @@ limitations under the License. package router import ( + a6v2 "github.com/fluxcd/flagger/pkg/apis/apisix/v2" "go.uber.org/zap" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -41,7 +42,6 @@ type fixture struct { abtest *flaggerv1.Canary appmeshCanary *flaggerv1.Canary ingressCanary *flaggerv1.Canary - apisixCanary *flaggerv1.Canary kubeClient kubernetes.Interface meshClient clientset.Interface flaggerClient clientset.Interface @@ -56,12 +56,14 @@ func newFixture(c *flaggerv1.Canary) fixture { abtest := newTestABTest() appmeshCanary := newTestCanaryAppMesh() ingressCanary := newTestCanaryIngress() + apisixRoute := newTestApisixRoute() flaggerClient := fakeFlagger.NewSimpleClientset( canary, abtest, appmeshCanary, ingressCanary, + apisixRoute, ) kubeClient := fake.NewSimpleClientset( @@ -85,6 +87,45 @@ func newFixture(c *flaggerv1.Canary) fixture { } } +func newTestApisixRoute() *a6v2.ApisixRoute { + ar := &a6v2.ApisixRoute{ + TypeMeta: metav1.TypeMeta{APIVersion: a6v2.SchemeGroupVersion.String()}, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "podinfo", + }, + Spec: a6v2.ApisixRouteSpec{HTTP: []a6v2.ApisixRouteHTTP{ + { + Name: "method", + Match: a6v2.ApisixRouteHTTPMatch{ + Hosts: []string{"foobar.com"}, + Methods: []string{"GET"}, + Paths: []string{"/*"}, + }, + Plugins: []a6v2.ApisixRoutePlugin{ + { + Name: "prometheus", + Enable: true, + Config: a6v2.ApisixRoutePluginConfig{ + "disable": "false", + "prefer_name": "true", + }, + }, + }, + Backends: []a6v2.ApisixRouteHTTPBackend{ + {ServiceName: "podinfo", + ServicePort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }}, + }, + }, + }, + }, + } + return ar +} + func newTestCanary() *flaggerv1.Canary { cd := &flaggerv1.Canary{ TypeMeta: metav1.TypeMeta{APIVersion: flaggerv1.SchemeGroupVersion.String()},