Files
flagger/pkg/router/appmesh_test.go
Sanskar Jaiswal 20f2d3f2f9 add annotation to enable appmesh logs
Signed-off-by: Sanskar Jaiswal <sanskar.jaiswal@weave.works>
Co-authored-by: wucg <wucg@trip.com>
2022-03-22 15:45:02 +05:30

193 lines
7.0 KiB
Go

/*
Copyright 2020 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package router
import (
"context"
"fmt"
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestAppmeshRouter_Reconcile(t *testing.T) {
mocks := newFixture(nil)
router := &AppMeshRouter{
logger: mocks.logger,
flaggerClient: mocks.flaggerClient,
appmeshClient: mocks.meshClient,
kubeClient: mocks.kubeClient,
}
err := router.Reconcile(mocks.appmeshCanary)
require.NoError(t, err)
// check virtual service
vsName := fmt.Sprintf("%s.%s", mocks.appmeshCanary.Spec.TargetRef.Name, mocks.appmeshCanary.Namespace)
vs, err := router.appmeshClient.AppmeshV1beta1().VirtualServices("default").Get(context.TODO(), vsName, metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, mocks.appmeshCanary.Spec.Service.MeshName, vs.Spec.MeshName)
assert.Len(t, vs.Spec.Routes[0].Http.Action.WeightedTargets, 2)
// check canary virtual service
vsCanaryName := fmt.Sprintf("%s-canary.%s", mocks.appmeshCanary.Spec.TargetRef.Name, mocks.appmeshCanary.Namespace)
vsCanary, err := router.appmeshClient.AppmeshV1beta1().VirtualServices("default").Get(context.TODO(), vsCanaryName, metav1.GetOptions{})
require.NoError(t, err)
// check if the canary virtual service routes all traffic to the canary virtual node
target := vsCanary.Spec.Routes[0].Http.Action.WeightedTargets[0]
canaryVirtualNodeName := fmt.Sprintf("%s-canary", mocks.appmeshCanary.Spec.TargetRef.Name)
assert.Equal(t, canaryVirtualNodeName, target.VirtualNodeName)
assert.Equal(t, int64(100), target.Weight)
// check virtual node
vnName := mocks.appmeshCanary.Spec.TargetRef.Name
vn, err := router.appmeshClient.AppmeshV1beta1().VirtualNodes("default").Get(context.TODO(), vnName, metav1.GetOptions{})
require.NoError(t, err)
require.NotNil(t, vn.Spec.Logging)
primaryDNS := fmt.Sprintf("%s-primary.%s", mocks.appmeshCanary.Spec.TargetRef.Name, mocks.appmeshCanary.Namespace)
assert.Equal(t, primaryDNS, vn.Spec.ServiceDiscovery.Dns.HostName)
// test backends update
cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get(context.TODO(), "appmesh", metav1.GetOptions{})
require.NoError(t, err)
cdClone := cd.DeepCopy()
hosts := cdClone.Spec.Service.Backends
hosts = append(hosts, "test.example.com")
cdClone.Spec.Service.Backends = hosts
canary, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(context.TODO(), cdClone, metav1.UpdateOptions{})
require.NoError(t, err)
// apply change
err = router.Reconcile(canary)
require.NoError(t, err)
// verify
vnCanaryName := fmt.Sprintf("%s-canary", mocks.appmeshCanary.Spec.TargetRef.Name)
vnCanary, err := router.appmeshClient.AppmeshV1beta1().VirtualNodes("default").Get(context.TODO(), vnCanaryName, metav1.GetOptions{})
require.NoError(t, err)
require.Len(t, vnCanary.Spec.Backends, 2)
// test weight update
vsClone := vs.DeepCopy()
vsClone.Spec.Routes[0].Http.Action.WeightedTargets[0].Weight = 50
vsClone.Spec.Routes[0].Http.Action.WeightedTargets[1].Weight = 50
vs, err = mocks.meshClient.AppmeshV1beta1().VirtualServices("default").Update(context.TODO(), vsClone, metav1.UpdateOptions{})
require.NoError(t, err)
// apply change
err = router.Reconcile(canary)
require.NoError(t, err)
vs, err = router.appmeshClient.AppmeshV1beta1().VirtualServices("default").Get(context.TODO(), vsName, metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, int64(50), vs.Spec.Routes[0].Http.Action.WeightedTargets[0].Weight)
// test URI update
vsClone = vs.DeepCopy()
vsClone.Spec.Routes[0].Http.Match.Prefix = "api"
vs, err = mocks.meshClient.AppmeshV1beta1().VirtualServices("default").Update(context.TODO(), vsClone, metav1.UpdateOptions{})
require.NoError(t, err)
// apply change
err = router.Reconcile(canary)
require.NoError(t, err)
vs, err = router.appmeshClient.AppmeshV1beta1().VirtualServices("default").Get(context.TODO(), vsName, metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, "/", vs.Spec.Routes[0].Http.Match.Prefix)
}
func TestAppmeshRouter_GetSetRoutes(t *testing.T) {
mocks := newFixture(nil)
router := &AppMeshRouter{
logger: mocks.logger,
flaggerClient: mocks.flaggerClient,
appmeshClient: mocks.meshClient,
kubeClient: mocks.kubeClient,
}
err := router.Reconcile(mocks.appmeshCanary)
require.NoError(t, err)
err = router.SetRoutes(mocks.appmeshCanary, 60, 40, false)
require.NoError(t, err)
p, c, m, err := router.GetRoutes(mocks.appmeshCanary)
require.NoError(t, err)
assert.Equal(t, 60, p)
assert.Equal(t, 40, c)
assert.False(t, m)
}
func TestAppmeshRouter_ABTest(t *testing.T) {
mocks := newFixture(nil)
router := &AppMeshRouter{
logger: mocks.logger,
flaggerClient: mocks.flaggerClient,
appmeshClient: mocks.meshClient,
kubeClient: mocks.kubeClient,
}
err := router.Reconcile(mocks.abtest)
require.NoError(t, err)
// check virtual service
vsName := fmt.Sprintf("%s.%s", mocks.abtest.Spec.TargetRef.Name, mocks.abtest.Namespace)
vs, err := router.appmeshClient.AppmeshV1beta1().VirtualServices("default").Get(context.TODO(), vsName, metav1.GetOptions{})
require.NoError(t, err)
// check virtual service
assert.Len(t, vs.Spec.Routes, 2)
// check headers
assert.GreaterOrEqual(t, len(vs.Spec.Routes[0].Http.Match.Headers), 1, "Got no http match headers")
assert.Equal(t, "x-user-type", vs.Spec.Routes[0].Http.Match.Headers[0].Name)
assert.Equal(t, "test", *vs.Spec.Routes[0].Http.Match.Headers[0].Match.Exact)
}
func TestAppmeshRouter_Gateway(t *testing.T) {
mocks := newFixture(nil)
router := &AppMeshRouter{
logger: mocks.logger,
flaggerClient: mocks.flaggerClient,
appmeshClient: mocks.meshClient,
kubeClient: mocks.kubeClient,
}
err := router.Reconcile(mocks.appmeshCanary)
require.NoError(t, err)
// check virtual service
vsName := fmt.Sprintf("%s.%s", mocks.appmeshCanary.Spec.TargetRef.Name, mocks.appmeshCanary.Namespace)
vs, err := router.appmeshClient.AppmeshV1beta1().VirtualServices("default").Get(context.TODO(), vsName, metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, "true", vs.Annotations["gateway.appmesh.k8s.aws/expose"])
assert.True(t, strings.Contains(vs.Annotations["gateway.appmesh.k8s.aws/domain"], mocks.appmeshCanary.Spec.Service.Hosts[0]))
assert.Equal(t, mocks.appmeshCanary.Spec.Service.Timeout, vs.Annotations["gateway.appmesh.k8s.aws/timeout"])
retries := vs.Annotations["gateway.appmesh.k8s.aws/retries"]
assert.Equal(t, strconv.Itoa(mocks.appmeshCanary.Spec.Service.Retries.Attempts), retries)
}