Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions conformance/conformance.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ func RunConformanceWithOptions(t *testing.T, opts confsuite.ConformanceOptions)
installedCRDs := &apiextensionsv1.CustomResourceDefinitionList{}
err = opts.Client.List(ctx, installedCRDs)
require.NoError(t, err, "error getting installedCRDs")
apiVersion, err := getGatewayInferenceExtentionVersion(installedCRDs.Items)
apiVersion, err := getGatewayInferenceExtensionVersion(installedCRDs.Items)
if err != nil {
if opts.AllowCRDsMismatch {
apiVersion = "UNDEFINED"
Expand Down Expand Up @@ -266,7 +266,7 @@ func SetupConformanceTestSuite(ctx context.Context, t *testing.T, suite *confsui
ensureGatewayAvailableAndReady(ctx, t, suite.Client, opts, resources.SecondaryGatewayNN)
}

func getGatewayInferenceExtentionVersion(crds []apiextensionsv1.CustomResourceDefinition) (string, error) {
func getGatewayInferenceExtensionVersion(crds []apiextensionsv1.CustomResourceDefinition) (string, error) {
var inferenceVersion string
for _, crd := range crds {
v, okv := crd.Annotations[version.BundleVersionAnnotation]
Expand Down
44 changes: 27 additions & 17 deletions conformance/tests/epp_unavailable_fail_open.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ import (

"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/types"
gwhttp "sigs.k8s.io/gateway-api/conformance/utils/http"
"sigs.k8s.io/gateway-api/conformance/utils/suite"
"sigs.k8s.io/gateway-api/pkg/features"

"sigs.k8s.io/gateway-api-inference-extension/conformance/resources"
"sigs.k8s.io/gateway-api-inference-extension/conformance/utils/config"
k8sutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
trafficutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/traffic"
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/test"
)

Expand Down Expand Up @@ -69,19 +69,24 @@ var EppUnAvailableFailOpen = suite.ConformanceTest{
targetPodIP := pods[0].Status.PodIP
t.Run("Phase 1: Verify baseline connectivity with EPP available", func(t *testing.T) {
t.Log("Sending request to ensure the Gateway and EPP are working correctly...")
trafficutils.MakeRequestAndExpectSuccess(
gwhttp.MakeRequestAndExpectEventuallyConsistentResponse(
t,
s.RoundTripper,
s.TimeoutConfig,
gwAddr,
trafficutils.Request{
Host: hostname,
Path: path,
Headers: map[string]string{
test.HeaderTestEppEndPointSelectionKey: targetPodIP,
gwhttp.ExpectedResponse{
Request: gwhttp.Request{
Host: hostname,
Path: path,
Headers: map[string]string{
test.HeaderTestEppEndPointSelectionKey: targetPodIP,
},
Method: http.MethodPost,
Body: requestBody,
},
Response: gwhttp.Response{
StatusCodes: []int{http.StatusOK},
},
Method: http.MethodPost,
Body: requestBody,
Backend: pods[0].Name, // Make sure the request is from the targetPod when the EPP is alive.
Namespace: resources.AppBackendNamespace,
},
Expand All @@ -96,19 +101,24 @@ var EppUnAvailableFailOpen = suite.ConformanceTest{
require.NoError(t, err, "Failed to make the EPP service %v unavailable", resources.PrimaryEppServiceNN)

t.Log("Sending request again, expecting success to verify fail-open...")
trafficutils.MakeRequestAndExpectSuccess(
gwhttp.MakeRequestAndExpectEventuallyConsistentResponse(
t,
s.RoundTripper,
s.TimeoutConfig,
gwAddr,
trafficutils.Request{
Host: hostname,
Path: path,
Headers: map[string]string{
test.HeaderTestEppEndPointSelectionKey: targetPodIP,
gwhttp.ExpectedResponse{
Request: gwhttp.Request{
Host: hostname,
Path: path,
Headers: map[string]string{
test.HeaderTestEppEndPointSelectionKey: targetPodIP,
},
Method: http.MethodPost,
Body: requestBody,
},
Response: gwhttp.Response{
StatusCodes: []int{http.StatusOK},
},
Method: http.MethodPost,
Body: requestBody,
Backend: appPodBackendPrefix, // Only checks the prefix since the EPP is not alive and the response can return from any Pod.
Namespace: resources.AppBackendNamespace,
},
Expand Down
30 changes: 17 additions & 13 deletions conformance/tests/gateway_following_epp_routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (

"sigs.k8s.io/gateway-api-inference-extension/conformance/resources"
k8sutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
"sigs.k8s.io/gateway-api-inference-extension/conformance/utils/traffic"
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/test"
)

Expand Down Expand Up @@ -86,19 +85,24 @@ var GatewayFollowingEPPRouting = suite.ConformanceTest{
for i := 0; i < len(pods); i++ {
// Send an initial request targeting a single pod and wait for it to be successful to ensure the Gateway and EPP
// are functioning correctly before running the main test cases.
traffic.MakeRequestAndExpectSuccess(
gwhttp.MakeRequestAndExpectEventuallyConsistentResponse(
t,
s.RoundTripper,
s.TimeoutConfig,
gwAddr,
traffic.Request{
Host: hostname,
Path: path,
Headers: map[string]string{
test.HeaderTestEppEndPointSelectionKey: podIPs[i],
gwhttp.ExpectedResponse{
Request: gwhttp.Request{
Host: hostname,
Path: path,
Method: http.MethodPost,
Body: requestBody,
Headers: map[string]string{
test.HeaderTestEppEndPointSelectionKey: podIPs[i],
},
},
Response: gwhttp.Response{
StatusCodes: []int{http.StatusOK},
},
Method: http.MethodPost,
Body: requestBody,
Backend: podNames[i],
Namespace: resources.AppBackendNamespace,
},
Expand Down Expand Up @@ -142,21 +146,21 @@ var GatewayFollowingEPPRouting = suite.ConformanceTest{
Host: hostname,
Path: path,
Method: http.MethodPost,
Body: requestBody,
Headers: headers,
},
Response: gwhttp.Response{
StatusCode: http.StatusOK,
},
// DO NOT SUBMIT
Backend: appPodBackendPrefix,
Namespace: resources.AppBackendNamespace,
}, requestBody, tc.expectAllRequestsRoutedWithinPodNames)
}, tc.expectAllRequestsRoutedWithinPodNames)
})
}
},
}

func assertTrafficOnlyReachesToExpectedPods(t *testing.T, suite *suite.ConformanceTestSuite, gwAddr string, expected gwhttp.ExpectedResponse, requestBody string, expectedPodNames []string) {
func assertTrafficOnlyReachesToExpectedPods(t *testing.T, suite *suite.ConformanceTestSuite, gwAddr string, expected gwhttp.ExpectedResponse, expectedPodNames []string) {
t.Helper()
const (
concurrentRequests = 10
Expand All @@ -170,7 +174,7 @@ func assertTrafficOnlyReachesToExpectedPods(t *testing.T, suite *suite.Conforman
g.SetLimit(concurrentRequests)
for i := 0; i < totalRequests; i++ {
g.Go(func() error {
cReq, cRes, err := traffic.MakeCallRoundTripper(t, roundTripper, &traffic.RequestWithBody{Request: req, Body: strings.NewReader(requestBody)})
cReq, cRes, err := roundTripper.CaptureRoundTrip(req)
if err != nil {
return fmt.Errorf("failed to roundtrip request: %w", err)
}
Expand Down
28 changes: 15 additions & 13 deletions conformance/tests/gateway_weighted_two_pools.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import (

"sigs.k8s.io/gateway-api-inference-extension/conformance/resources"
k8sutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
"sigs.k8s.io/gateway-api-inference-extension/conformance/utils/traffic"
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/framework/plugins/test"
)

Expand Down Expand Up @@ -113,19 +112,24 @@ var GatewayWeightedAcrossTwoInferencePools = suite.ConformanceTest{
allIPs := append(append([]string{}, primaryPodIPs...), secondaryPodIPs...)
allNames := append(append([]string{}, primaryPodNames...), secondaryPodNames...)
for i := 0; i < len(allIPs); i++ {
traffic.MakeRequestAndExpectSuccess(
gwhttp.MakeRequestAndExpectEventuallyConsistentResponse(
t,
s.RoundTripper,
s.TimeoutConfig,
gwAddr,
traffic.Request{
Host: hostname,
Path: path,
Headers: map[string]string{
test.HeaderTestEppEndPointSelectionKey: allIPs[i],
gwhttp.ExpectedResponse{
Request: gwhttp.Request{
Host: hostname,
Path: path,
Method: http.MethodPost,
Body: `{"model":"conformance-fake-model","prompt":"Warmup"}`,
Headers: map[string]string{
test.HeaderTestEppEndPointSelectionKey: allIPs[i],
},
},
Response: gwhttp.Response{
StatusCodes: []int{http.StatusOK},
},
Method: http.MethodPost,
Body: `{"model":"conformance-fake-model","prompt":"Warmup"}`,
Backend: allNames[i],
Namespace: resources.AppBackendNamespace,
},
Expand Down Expand Up @@ -160,6 +164,7 @@ var GatewayWeightedAcrossTwoInferencePools = suite.ConformanceTest{
Path: path,
Method: http.MethodPost,
Headers: headers,
Body: requestBody,
},
Response: gwhttp.Response{
StatusCode: http.StatusOK,
Expand All @@ -174,10 +179,7 @@ var GatewayWeightedAcrossTwoInferencePools = suite.ConformanceTest{

for i := 0; i < totalRequests; i++ {
g.Go(func() error {
cReq, cRes, err := traffic.MakeCallRoundTripper(t, s.RoundTripper, &traffic.RequestWithBody{
Request: req,
Body: strings.NewReader(requestBody),
})
cReq, cRes, err := s.RoundTripper.CaptureRoundTrip(req)
if err != nil {
return fmt.Errorf("failed to roundtrip request: %w", err)
}
Expand Down
38 changes: 23 additions & 15 deletions conformance/tests/httproute_multiple_gateways_different_pools.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import (
"testing"

"k8s.io/apimachinery/pkg/types"
gwhttp "sigs.k8s.io/gateway-api/conformance/utils/http"
"sigs.k8s.io/gateway-api/conformance/utils/suite"

"sigs.k8s.io/gateway-api-inference-extension/conformance/resources"
k8sutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
"sigs.k8s.io/gateway-api-inference-extension/conformance/utils/traffic"
)

func init() {
Expand Down Expand Up @@ -65,17 +65,21 @@ var HTTPRouteMultipleGatewaysDifferentPools = suite.ConformanceTest{

primaryGwAddr := k8sutils.GetGatewayEndpoint(t, s.Client, s.TimeoutConfig, primaryGatewayNN)

traffic.MakeRequestAndExpectEventuallyConsistentResponse(
gwhttp.MakeRequestAndExpectEventuallyConsistentResponse(
t,
s.RoundTripper,
s.TimeoutConfig,
primaryGwAddr,
traffic.Request{
Host: primaryRouteHostname,
Path: primaryRoutePath,
ExpectedStatusCode: http.StatusOK,
Backend: primaryBackendPodName,
Namespace: resources.AppBackendNamespace,
gwhttp.ExpectedResponse{
Request: gwhttp.Request{
Host: primaryRouteHostname,
Path: primaryRoutePath,
},
Response: gwhttp.Response{
StatusCodes: []int{http.StatusOK},
},
Backend: primaryBackendPodName,
Namespace: resources.AppBackendNamespace,
},
)
})
Expand All @@ -91,17 +95,21 @@ var HTTPRouteMultipleGatewaysDifferentPools = suite.ConformanceTest{

secondaryGwAddr := k8sutils.GetGatewayEndpoint(t, s.Client, s.TimeoutConfig, secondaryGatewayNN)

traffic.MakeRequestAndExpectEventuallyConsistentResponse(
gwhttp.MakeRequestAndExpectEventuallyConsistentResponse(
t,
s.RoundTripper,
s.TimeoutConfig,
secondaryGwAddr,
traffic.Request{
Host: secondaryRouteHostname,
Path: secondaryRoutePath,
ExpectedStatusCode: http.StatusOK,
Backend: secondaryBackendPodName,
Namespace: resources.AppBackendNamespace,
gwhttp.ExpectedResponse{
Request: gwhttp.Request{
Host: secondaryRouteHostname,
Path: secondaryRoutePath,
},
Response: gwhttp.Response{
StatusCodes: []int{http.StatusOK},
},
Backend: secondaryBackendPodName,
Namespace: resources.AppBackendNamespace,
},
)
})
Expand Down
42 changes: 29 additions & 13 deletions conformance/tests/inferencepool_httproute_port_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ limitations under the License.
package tests

import (
"net/http"
"testing"

"k8s.io/apimachinery/pkg/types"
gwhttp "sigs.k8s.io/gateway-api/conformance/utils/http"
"sigs.k8s.io/gateway-api/conformance/utils/suite"
"sigs.k8s.io/gateway-api/pkg/features"

"sigs.k8s.io/gateway-api-inference-extension/conformance/resources"
k8sutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
trafficutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/traffic"
)

func init() {
Expand Down Expand Up @@ -54,14 +55,19 @@ var InferencePoolHTTPRoutePortValidation = suite.ConformanceTest{
k8sutils.HTTPRouteMustBeAcceptedAndResolved(t, s.Client, s.TimeoutConfig, routeNN, gatewayNN)
k8sutils.InferencePoolMustBeAcceptedByParent(t, s.Client, poolNN, gatewayNN)

trafficutils.MakeRequestAndExpectSuccess(
gwhttp.MakeRequestAndExpectEventuallyConsistentResponse(
t,
s.RoundTripper,
s.TimeoutConfig,
gatewayAddr,
trafficutils.Request{
Host: hostname,
Path: path,
gwhttp.ExpectedResponse{
Request: gwhttp.Request{
Host: hostname,
Path: path,
},
Response: gwhttp.Response{
StatusCodes: []int{http.StatusOK},
},
Backend: resources.PrimaryModelServerDeploymentName,
Namespace: resources.AppBackendNamespace,
},
Expand All @@ -76,14 +82,19 @@ var InferencePoolHTTPRoutePortValidation = suite.ConformanceTest{
k8sutils.HTTPRouteMustBeAcceptedAndResolved(t, s.Client, s.TimeoutConfig, routeNN, gatewayNN)
k8sutils.InferencePoolMustBeAcceptedByParent(t, s.Client, poolNN, gatewayNN)

trafficutils.MakeRequestAndExpectSuccess(
gwhttp.MakeRequestAndExpectEventuallyConsistentResponse(
t,
s.RoundTripper,
s.TimeoutConfig,
gatewayAddr,
trafficutils.Request{
Host: hostname,
Path: path,
gwhttp.ExpectedResponse{
Request: gwhttp.Request{
Host: hostname,
Path: path,
},
Response: gwhttp.Response{
StatusCodes: []int{http.StatusOK},
},
Backend: resources.PrimaryModelServerDeploymentName,
Namespace: resources.AppBackendNamespace,
},
Expand All @@ -99,14 +110,19 @@ var InferencePoolHTTPRoutePortValidation = suite.ConformanceTest{
k8sutils.HTTPRouteMustBeAcceptedAndResolved(t, s.Client, s.TimeoutConfig, routeNN, gatewayNN)
k8sutils.InferencePoolMustBeAcceptedByParent(t, s.Client, poolNN, gatewayNN)

trafficutils.MakeRequestAndExpectSuccess(
gwhttp.MakeRequestAndExpectEventuallyConsistentResponse(
t,
s.RoundTripper,
s.TimeoutConfig,
gatewayAddr,
trafficutils.Request{
Host: hostname,
Path: path,
gwhttp.ExpectedResponse{
Request: gwhttp.Request{
Host: hostname,
Path: path,
},
Response: gwhttp.Response{
StatusCodes: []int{http.StatusOK},
},
Backend: resources.PrimaryModelServerDeploymentName,
Namespace: resources.AppBackendNamespace,
},
Expand Down
Loading