Skip to content

Commit

Permalink
Add Istio routes A/B testing unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanprodan committed Mar 8, 2019
1 parent 49c942b commit 3c7a561
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 4 deletions.
60 changes: 60 additions & 0 deletions pkg/router/istio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,63 @@ func TestIstioRouter_CORS(t *testing.T) {
t.Fatalf("Got CORS allow methods %v wanted %v", len(methods), 2)
}
}

func TestIstioRouter_ABTest(t *testing.T) {
mocks := setupfakeClients()
router := &IstioRouter{
logger: mocks.logger,
flaggerClient: mocks.flaggerClient,
istioClient: mocks.istioClient,
kubeClient: mocks.kubeClient,
}

err := router.Sync(mocks.abtest)
if err != nil {
t.Fatal(err.Error())
}

// test insert
vs, err := mocks.istioClient.NetworkingV1alpha3().VirtualServices("default").Get("abtest", metav1.GetOptions{})
if err != nil {
t.Fatal(err.Error())
}

if len(vs.Spec.Http) != 2 {
t.Errorf("Got Istio VS Http %v wanted %v", len(vs.Spec.Http), 2)
}

p := 0
c := 100

err = router.SetRoutes(mocks.abtest, p, c)
if err != nil {
t.Fatal(err.Error())
}

vs, err = mocks.istioClient.NetworkingV1alpha3().VirtualServices("default").Get("abtest", metav1.GetOptions{})
if err != nil {
t.Fatal(err.Error())
}

pRoute := istiov1alpha3.DestinationWeight{}
cRoute := istiov1alpha3.DestinationWeight{}

for _, http := range vs.Spec.Http {
for _, route := range http.Route {
if route.Destination.Host == fmt.Sprintf("%s-primary", mocks.abtest.Spec.TargetRef.Name) {
pRoute = route
}
if route.Destination.Host == fmt.Sprintf("%s-canary", mocks.abtest.Spec.TargetRef.Name) {
cRoute = route
}
}
}

if pRoute.Weight != p {
t.Errorf("Got primary weight %v wanted %v", pRoute.Weight, p)
}

if cRoute.Weight != c {
t.Errorf("Got canary weight %v wanted %v", cRoute.Weight, c)
}
}
100 changes: 96 additions & 4 deletions pkg/router/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package router

import (
"github.com/stefanprodan/flagger/pkg/apis/flagger/v1alpha3"
istiov1alpha1 "github.com/stefanprodan/flagger/pkg/apis/istio/common/v1alpha1"
istiov1alpha3 "github.com/stefanprodan/flagger/pkg/apis/istio/v1alpha3"
clientset "github.com/stefanprodan/flagger/pkg/client/clientset/versioned"
fakeFlagger "github.com/stefanprodan/flagger/pkg/client/clientset/versioned/fake"
Expand All @@ -17,6 +18,7 @@ import (

type fakeClients struct {
canary *v1alpha3.Canary
abtest *v1alpha3.Canary
kubeClient kubernetes.Interface
istioClient clientset.Interface
flaggerClient clientset.Interface
Expand All @@ -25,17 +27,17 @@ type fakeClients struct {

func setupfakeClients() fakeClients {
canary := newMockCanary()
flaggerClient := fakeFlagger.NewSimpleClientset(canary)
abtest := newMockABTest()
flaggerClient := fakeFlagger.NewSimpleClientset(canary, abtest)

kubeClient := fake.NewSimpleClientset(
newMockDeployment(),
)
kubeClient := fake.NewSimpleClientset(newMockDeployment(), newMockABTestDeployment())

istioClient := fakeFlagger.NewSimpleClientset()
logger, _ := logging.NewLogger("debug")

return fakeClients{
canary: canary,
abtest: abtest,
kubeClient: kubeClient,
istioClient: istioClient,
flaggerClient: flaggerClient,
Expand Down Expand Up @@ -93,6 +95,51 @@ func newMockCanary() *v1alpha3.Canary {
return cd
}

func newMockABTest() *v1alpha3.Canary {
cd := &v1alpha3.Canary{
TypeMeta: metav1.TypeMeta{APIVersion: v1alpha3.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "abtest",
},
Spec: v1alpha3.CanarySpec{
TargetRef: hpav1.CrossVersionObjectReference{
Name: "abtest",
APIVersion: "apps/v1",
Kind: "Deployment",
},
Service: v1alpha3.CanaryService{
Port: 9898,
}, CanaryAnalysis: v1alpha3.CanaryAnalysis{
Threshold: 10,
Iterations: 2,
Match: []istiov1alpha3.HTTPMatchRequest{
{
Headers: map[string]istiov1alpha1.StringMatch{
"x-user-type": {
Exact: "test",
},
},
},
},
Metrics: []v1alpha3.CanaryMetric{
{
Name: "istio_requests_total",
Threshold: 99,
Interval: "1m",
},
{
Name: "istio_request_duration_seconds_bucket",
Threshold: 500,
Interval: "1m",
},
},
},
},
}
return cd
}

func newMockDeployment() *appsv1.Deployment {
d := &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{APIVersion: appsv1.SchemeGroupVersion.String()},
Expand Down Expand Up @@ -137,3 +184,48 @@ func newMockDeployment() *appsv1.Deployment {

return d
}

func newMockABTestDeployment() *appsv1.Deployment {
d := &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{APIVersion: appsv1.SchemeGroupVersion.String()},
ObjectMeta: metav1.ObjectMeta{
Namespace: "default",
Name: "abtest",
},
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "abtest",
},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": "abtest",
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "podinfo",
Image: "quay.io/stefanprodan/podinfo:1.4.0",
Command: []string{
"./podinfo",
"--port=9898",
},
Ports: []corev1.ContainerPort{
{
Name: "http",
ContainerPort: 9898,
Protocol: corev1.ProtocolTCP,
},
},
},
},
},
},
},
}

return d
}

0 comments on commit 3c7a561

Please sign in to comment.