Uses BYO revision names for traffic splitting e2e tests (#506)

* Uses BYO revision names for traffic splitting e2e tests

 - Avoid getting the revision name after service create/update using LCR or LRR from service status

* Pauses 3 seconds before verifying actual vs expected traffic targets

 - for traffic splitting e2e tests
 - Check the comment on https://github.com/knative/client/issues/500#issuecomment-554355688
This commit is contained in:
Navid Shaikh 2019-11-15 21:06:02 +05:30 committed by Knative Prow Robot
parent 619b64cbb3
commit 1bcec16b24
1 changed files with 64 additions and 56 deletions

View File

@ -21,6 +21,7 @@ import (
"strconv"
"strings"
"testing"
"time"
"gotest.tools/assert"
"knative.dev/client/pkg/util"
@ -33,8 +34,8 @@ var targetFieldsLength = 4
// returns deployed service targets separated by '|' and each target fields seprated by comma
var targetsJsonPath = "jsonpath={range .status.traffic[*]}{.tag}{','}{.revisionName}{','}{.percent}{','}{.latestRevision}{'|'}{end}"
// returns deployed service latest revision name
var latestRevisionJsonPath = "jsonpath={.status.latestCreatedRevisionName}"
// returns latest ready revision name jsonpath
//var LRRJsonPath = "jsonpath={.status.latestReadyRevisionName}"
// TargetFields are used in e2e to store expected fields per traffic target
// and actual traffic targets fields of deployed service are converted into struct before comparing
@ -87,10 +88,12 @@ func TestTrafficSplit(t *testing.T) {
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v1"})
rev1 := test.latestRevisionOfService(t, serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2"})
rev2 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v1", "--revision-name", rev1})
rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2", "--revision-name", rev2})
tflags := []string{"--tag", fmt.Sprintf("%s=v1,%s=v2", rev1, rev2),
"--traffic", "v1=50,v2=50"}
@ -106,10 +109,12 @@ func TestTrafficSplit(t *testing.T) {
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v1"})
rev1 := test.latestRevisionOfService(t, serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2"})
rev2 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v1", "--revision-name", rev1})
rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2", "--revision-name", rev2})
tflags := []string{"--traffic", fmt.Sprintf("%s=20,%s=80", rev1, rev2)} // traffic by revision name
test.serviceUpdateWithOptions(t, serviceName, tflags)
@ -122,10 +127,11 @@ func TestTrafficSplit(t *testing.T) {
t.Run("tag a revision as candidate, without otherwise changing any traffic split",
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v1"})
rev2 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v1", "--revision-name", rev2})
tflags := []string{"--tag", fmt.Sprintf("%s=%s", rev1, "candidate")} // no traffic, append new target with tag in traffic block
test.serviceUpdateWithOptions(t, serviceName, tflags)
@ -138,10 +144,11 @@ func TestTrafficSplit(t *testing.T) {
t.Run("tag a revision as candidate, set 2% traffic adjusting other traffic to accommodate",
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v1"})
rev2 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v1", "--revision-name", rev2})
tflags := []string{"--tag", fmt.Sprintf("%s=%s", rev1, "candidate"),
"--traffic", "candidate=2%,@latest=98%"} // traffic by tag name and use % at the end
@ -156,14 +163,14 @@ func TestTrafficSplit(t *testing.T) {
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
// make available 3 revisions for service first
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2"})
rev2 := test.latestRevisionOfService(t, serviceName)
rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2", "--revision-name", rev2})
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v3"}) //note that this gives 100% traffic to latest revision (rev3)
rev3 := test.latestRevisionOfService(t, serviceName)
rev3 := fmt.Sprintf("%s-rev-3", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v3", "--revision-name", rev3}) //note that this gives 100% traffic to latest revision (rev3)
// make existing state: tag current and candidate exist in traffic block
tflags := []string{"--tag", fmt.Sprintf("%s=current,%s=candidate", rev1, rev2)}
@ -183,8 +190,8 @@ func TestTrafficSplit(t *testing.T) {
t.Run("update tag from testing to staging for @latest revision",
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
// make existing state: tag @latest as testing
tflags := []string{"--tag", "@latest=testing"}
@ -202,11 +209,11 @@ func TestTrafficSplit(t *testing.T) {
t.Run("update tag from testing to staging for a revision (non @latest)",
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2"})
rev2 := test.latestRevisionOfService(t, serviceName)
rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2", "--revision-name", rev2})
// make existing state: tag a revision as testing
tflags := []string{"--tag", fmt.Sprintf("%s=testing", rev1)}
@ -226,11 +233,11 @@ func TestTrafficSplit(t *testing.T) {
t.Run("remove a revision with tag old from traffic block entirely",
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2"})
rev2 := test.latestRevisionOfService(t, serviceName)
rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2", "--revision-name", rev2})
// existing state: traffic block having a revision with tag old and some traffic
tflags := []string{"--tag", fmt.Sprintf("%s=old", rev1),
@ -249,8 +256,8 @@ func TestTrafficSplit(t *testing.T) {
t.Run("tag a revision as stable and current with 50-50% traffic",
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
// existing state: traffic block having two targets
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2"})
@ -268,17 +275,17 @@ func TestTrafficSplit(t *testing.T) {
t.Run("revert all traffic to latest ready revision of service",
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2"})
rev2 := test.latestRevisionOfService(t, serviceName)
rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2", "--revision-name", rev2})
// existing state: latest revision not getting any traffic
// existing state: latest ready revision not getting any traffic
tflags := []string{"--traffic", fmt.Sprintf("%s=100", rev1)}
test.serviceUpdateWithOptions(t, serviceName, tflags)
// desired state: revert traffic to latest revision
// desired state: revert traffic to latest ready revision
tflags = []string{"--traffic", "@latest=100"}
test.serviceUpdateWithOptions(t, serviceName, tflags)
@ -291,10 +298,10 @@ func TestTrafficSplit(t *testing.T) {
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
// existing state: latest revision has no tag
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
// desired state: tag current to latest ready revision
// desired state: tag latest ready revision as 'current'
tflags := []string{"--tag", "@latest=current"}
test.serviceUpdateWithOptions(t, serviceName, tflags)
@ -306,11 +313,11 @@ func TestTrafficSplit(t *testing.T) {
t.Run("update tag for a revision as testing and assign all the traffic to it:",
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2"})
rev2 := test.latestRevisionOfService(t, serviceName)
rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2", "--revision-name", rev2})
// existing state: two revision exists with traffic share and
// each revision has tag and traffic portions
@ -332,11 +339,11 @@ func TestTrafficSplit(t *testing.T) {
t.Run("replace latest tag of a revision with old and give latest to another revision",
func(t *testing.T) {
serviceName := getServiceNameAndIncrement(serviceBase)
test.serviceCreate(t, serviceName)
rev1 := test.latestRevisionOfService(t, serviceName)
rev1 := fmt.Sprintf("%s-rev-1", serviceName)
test.serviceCreateWithOptions(t, serviceName, []string{"--revision-name", rev1})
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2"})
rev2 := test.latestRevisionOfService(t, serviceName)
rev2 := fmt.Sprintf("%s-rev-2", serviceName)
test.serviceUpdateWithOptions(t, serviceName, []string{"--env", "TARGET=v2", "--revision-name", rev2})
// existing state: a revision exist with latest tag
tflags := []string{"--tag", fmt.Sprintf("%s=latest", rev1)}
@ -360,6 +367,7 @@ func TestTrafficSplit(t *testing.T) {
}
func (test *e2eTest) verifyTargets(t *testing.T, serviceName string, expectedTargets []TargetFields) {
time.Sleep(3 * time.Second)
out := test.serviceDescribeWithJsonPath(t, serviceName, targetsJsonPath)
assert.Check(t, out != "")
actualTargets, err := splitTargets(out, targetsSeparator, len(expectedTargets))
@ -368,9 +376,9 @@ func (test *e2eTest) verifyTargets(t *testing.T, serviceName string, expectedTar
assert.DeepEqual(t, expectedTargets, formattedActualTargets)
}
func (test *e2eTest) latestRevisionOfService(t *testing.T, serviceName string) string {
return test.serviceDescribeWithJsonPath(t, serviceName, latestRevisionJsonPath)
}
//func (test *e2eTest) latestReadyRevisionOfService(t *testing.T, serviceName string) string {
// return test.serviceDescribeWithJsonPath(t, serviceName, LRRJsonPath)
//}
func (test *e2eTest) serviceDescribeWithJsonPath(t *testing.T, serviceName, jsonpath string) string {
command := []string{"service", "describe", serviceName, "-o", jsonpath}