Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add some waypoint related E2E test cases #580

Merged
merged 3 commits into from
Jul 17, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 218 additions & 0 deletions test/e2e/baseline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ package kmesh

import (
"fmt"
"strings"
"testing"
"time"

"istio.io/istio/pkg/test/echo/common/scheme"
"istio.io/istio/pkg/test/framework"
"istio.io/istio/pkg/test/framework/components/echo"
"istio.io/istio/pkg/test/framework/components/echo/check"
"istio.io/istio/pkg/util/sets"
)

var (
Expand Down Expand Up @@ -138,12 +140,228 @@ spec:
})
}

func TestServerSideLB(t *testing.T) {
framework.NewTest(t).Run(func(t framework.TestContext) {
runTestToServiceWaypoint(t, func(t framework.TestContext, src echo.Instance, dst echo.Instance, opt echo.CallOptions) {
// Need HTTP
if opt.Scheme != scheme.HTTP {
return
}
var singleHost echo.Checker = func(result echo.CallResult, _ error) error {
hostnames := make([]string, len(result.Responses))
for i, r := range result.Responses {
hostnames[i] = r.Hostname
}
unique := sets.SortedList(sets.New(hostnames...))
if len(unique) != 1 {
return fmt.Errorf("excepted only one destination, got: %v", unique)
}
return nil
}
var multipleHost echo.Checker = func(result echo.CallResult, _ error) error {
hostnames := make([]string, len(result.Responses))
for i, r := range result.Responses {
hostnames[i] = r.Hostname
}
unique := sets.SortedList(sets.New(hostnames...))
want := dst.WorkloadsOrFail(t)
wn := []string{}
for _, w := range want {
wn = append(wn, w.PodName())
}
if len(unique) != len(wn) {
return fmt.Errorf("excepted all destinations (%v), got: %v", wn, unique)
}
return nil
}

shouldBalance := dst.Config().HasServiceAddressedWaypointProxy()
// Istio client will not reuse connections for HTTP/1.1
opt.HTTP.HTTP2 = true
// Make sure we make multiple calls
opt.Count = 10
c := singleHost
if shouldBalance {
c = multipleHost
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have workload level waypoint?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet, relevant test cases will be added later

}
opt.Check = check.And(check.OK(), c)
opt.NewConnectionPerRequest = false
src.CallOrFail(t, opt)
})
})
}

func TestServerRouting(t *testing.T) {
framework.NewTest(t).Run(func(t framework.TestContext) {
runTestToServiceWaypoint(t, func(t framework.TestContext, src echo.Instance, dst echo.Instance, opt echo.CallOptions) {
// Need waypoint proxy and HTTP
if opt.Scheme != scheme.HTTP {
return
}
t.NewSubTest("set header").Run(func(t framework.TestContext) {
t.ConfigIstio().Eval(apps.Namespace.Name(), map[string]string{
"Destination": dst.Config().Service,
}, `apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: route
spec:
hosts:
- "{{.Destination}}"
http:
- headers:
request:
add:
istio-custom-header: user-defined-value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should update to kmesh

route:
- destination:
host: "{{.Destination}}"
`).ApplyOrFail(t)
opt.Check = check.And(
check.OK(),
check.RequestHeader("Istio-Custom-Header", "user-defined-value"))
src.CallOrFail(t, opt)
})
t.NewSubTest("subset").Run(func(t framework.TestContext) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace subset with a more meaningful name

t.ConfigIstio().Eval(apps.Namespace.Name(), map[string]string{
"Destination": dst.Config().Service,
}, `apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: route
spec:
hosts:
- "{{.Destination}}"
http:
- route:
- destination:
host: "{{.Destination}}"
subset: v1
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: route
namespace:
spec:
host: "{{.Destination}}"
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
`).ApplyOrFail(t)
var exp string
for _, w := range dst.WorkloadsOrFail(t) {
if strings.Contains(w.PodName(), "-v1") {
exp = w.PodName()
}
}
opt.Count = 10
opt.Check = check.And(
check.OK(),
check.Hostname(exp))
src.CallOrFail(t, opt)
})
})
})
}

func TestWaypointEnvoyFilter(t *testing.T) {
framework.NewTest(t).Run(func(t framework.TestContext) {
runTestToServiceWaypoint(t, func(t framework.TestContext, src echo.Instance, dst echo.Instance, opt echo.CallOptions) {
// Need at least one waypoint proxy and HTTP
if opt.Scheme != scheme.HTTP {
return
}
t.ConfigIstio().Eval(apps.Namespace.Name(), map[string]string{
"Destination": "waypoint",
}, `apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: inbound
spec:
workloadSelector:
labels:
gateway.networking.k8s.io/gateway-name: "{{.Destination}}"
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
inlineCode: |
function envoy_on_request(request_handle)
request_handle:headers():add("x-lua-inbound", "hello world")
end
- applyTo: VIRTUAL_HOST
match:
context: SIDECAR_INBOUND
patch:
operation: MERGE
value:
request_headers_to_add:
- header:
key: x-vhost-inbound
value: "hello world"
- applyTo: CLUSTER
match:
context: SIDECAR_INBOUND
cluster: {}
patch:
operation: MERGE
value:
http2_protocol_options: {}
`).ApplyOrFail(t)
opt.Count = 5
opt.Timeout = time.Second * 10
opt.Check = check.And(
check.OK(),
check.RequestHeaders(map[string]string{
"X-Lua-Inbound": "hello world",
"X-Vhost-Inbound": "hello world",
}))
src.CallOrFail(t, opt)
})
})
}

func runTest(t *testing.T, f func(t framework.TestContext, src echo.Instance, dst echo.Instance, opt echo.CallOptions)) {
framework.NewTest(t).Run(func(t framework.TestContext) {
runTestContext(t, f)
})
}

// runTestToServiceWaypoint runs a given function against every src/dst pair where a call will traverse a service waypoint
func runTestToServiceWaypoint(t framework.TestContext, f func(t framework.TestContext, src echo.Instance, dst echo.Instance, opt echo.CallOptions)) {
runTestContext(t, func(t framework.TestContext, src echo.Instance, dst echo.Instance, opt echo.CallOptions) {
if !dst.Config().HasServiceAddressedWaypointProxy() {
return
}
if !src.Config().HasProxyCapabilities() {
// Only respected if the client knows about waypoints
return
}
if src.Config().HasSidecar() {
// TODO: sidecars do not currently respect waypoints
t.Skip("https://github.com/istio/istio/issues/51445")
}
f(t, src, dst, opt)
})
}

func runTestContext(t framework.TestContext, f func(t framework.TestContext, src echo.Instance, dst echo.Instance, opt echo.CallOptions)) {
svcs := apps.All
for _, src := range svcs {
Expand Down
Loading