Files
higress/test/e2e/conformance/utils/http/http_test.go
2024-01-16 11:43:30 +08:00

1104 lines
33 KiB
Go

// Copyright (c) 2022 Alibaba Group Holding Ltd.
//
// 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 http
import (
"testing"
"github.com/alibaba/higress/test/e2e/conformance/utils/roundtripper"
"github.com/stretchr/testify/require"
)
func TestCompareRequest(t *testing.T) {
cases := []struct {
caseName string
errMsg string
req *roundtripper.Request
cReq *roundtripper.CapturedRequest
cRes *roundtripper.CapturedResponse
expected Assertion
}{
{
caseName: "compare request header ok",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{
Path: "/",
Host: "foo.com",
Method: "GET",
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
Body: []byte(``),
Namespace: "",
Pod: "",
},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
Body: []byte(``),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetRequest},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{
Host: "foo.com",
Method: "GET",
Path: "/",
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(``),
ContentType: "",
},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{},
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare request header&body ok",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{
Path: "/",
Host: "foo.com",
Method: "GET",
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"application/json"},
},
Body: map[string]interface{}{
"X-body-test1": []interface{}{"b1"},
"X-body-test2": []interface{}{"b2", "b22"},
},
Namespace: "",
Pod: "",
},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetRequest},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{
Host: "foo.com",
Method: "GET",
Path: "/",
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`
{
"X-body-test1":["b1"],
"X-body-test2":["b2","b22"]
}`),
ContentType: ContentTypeApplicationJson,
},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{},
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare request header&body fail, because headers not consistent",
errMsg: "expected X-header-test1 header to be set to h1, got h1,hn",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{
Path: "/",
Host: "foo.com",
Method: "GET",
Headers: map[string][]string{
"X-header-test1": {"h1", "hn"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"application/json"},
},
Body: map[string]interface{}{
"X-body-test1": []interface{}{"b1"},
"X-body-test2": []interface{}{"b2", "b22"},
},
Namespace: "",
Pod: "",
},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetRequest},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{
Host: "foo.com",
Method: "GET",
Path: "/",
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`
{
"X-body-test1":["b1"],
"X-body-test2":["b2","b22"]
}`),
ContentType: ContentTypeApplicationJson,
},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{},
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare request header&body fail, because body not consistent",
errMsg: "expected application/json body to be",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{
Path: "/",
Host: "foo.com",
Method: "GET",
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"application/json"},
},
Body: map[string]interface{}{
"X-body-test1": []interface{}{"b1", "bn"},
"X-body-test2": []interface{}{"b2", "b22"},
},
Namespace: "",
Pod: "",
},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetRequest},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{
Host: "foo.com",
Method: "GET",
Path: "/",
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`
{
"X-body-test1":["b1"],
"X-body-test2":["b2","b22"]
}`),
ContentType: ContentTypeApplicationJson,
},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{},
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare request header&body ok, body type is text/plain",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{
Path: "/",
Host: "foo.com",
Method: "GET",
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"text/plain"},
},
Body: "hello higress",
Namespace: "",
Pod: "",
},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetRequest},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{
Host: "foo.com",
Method: "GET",
Path: "/",
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`hello higress`),
ContentType: ContentTypeTextPlain,
},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{},
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare request header&body fail, because body not consistent. body type is text/plain",
errMsg: "expected text/plain body to be",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{
Path: "/",
Host: "foo.com",
Method: "GET",
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"text/plain"},
},
Body: "Hello Higress",
Namespace: "",
Pod: "",
},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetRequest},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{
Host: "foo.com",
Method: "GET",
Path: "/",
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`hello higress`),
ContentType: ContentTypeTextPlain,
},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{},
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare request header&body ok, body type is FormUrlencoded",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{
Path: "/",
Host: "foo.com",
Method: "GET",
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"application/x-www-form-urlencoded"},
},
Body: map[string][]string{
"X-body-test1": {"b1"},
"X-body-test2": {"b2", "b22"},
},
Namespace: "",
Pod: "",
},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetRequest},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{
Host: "foo.com",
Method: "GET",
Path: "/",
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`X-body-test1=b1&X-body-test2=b2&X-body-test2=b22`),
ContentType: ContentTypeFormUrlencoded,
},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{},
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare request header&body fail, because body not consistent, body type is FormUrlencoded",
errMsg: "expected application/x-www-form-urlencoded body to be",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{
Path: "/",
Host: "foo.com",
Method: "GET",
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"application/x-www-form-urlencoded"},
},
Body: map[string][]string{
"X-body-test1": {"b1", "bn"},
"X-body-test2": {"b2", "b22"},
},
Namespace: "",
Pod: "",
},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetRequest},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{
Host: "foo.com",
Method: "GET",
Path: "/",
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`X-body-test1=b1&X-body-test2=b2&X-body-test2=b22`),
ContentType: ContentTypeFormUrlencoded,
},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{},
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare request header&body ok, body type is MultipartForm",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{
Path: "/",
Host: "foo.com",
Method: "GET",
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"multipart/form-data; boundary=----WebKitFormBoundaryAnydWsQ1ajKuGoCd"},
},
Body: map[string][]string{
"name": {"denzel"},
"flag": {"test"},
},
Namespace: "",
Pod: "",
},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetRequest},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{
Host: "foo.com",
Method: "GET",
Path: "/",
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"Screenshot.png\"\r\n" +
"Content-Type: image/png\r\n\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"name\"\r\n\r\n" +
"denzel\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"flag\"\r\n\r\n" +
"test\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd--\r\n"),
ContentType: ContentTypeMultipartForm + "; boundary=----WebKitFormBoundaryAnydWsQ1ajKuGoCd",
},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{},
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare request header&body fail, because body not consistent. body type is MultipartForm",
errMsg: "expected multipart/form-data body to be",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{
Path: "/",
Host: "foo.com",
Method: "GET",
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"multipart/form-data; boundary=----WebKitFormBoundaryAnydWsQ1ajKuGoCd"},
},
Body: map[string][]string{
"name": {"higress"},
"flag": {"test"},
},
Namespace: "",
Pod: "",
},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetRequest},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{
Host: "foo.com",
Method: "GET",
Path: "/",
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"Screenshot.png\"\r\n" +
"Content-Type: image/png\r\n\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"name\"\r\n\r\n" +
"denzel\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"flag\"\r\n\r\n" +
"test\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd--\r\n"),
ContentType: ContentTypeMultipartForm + "; boundary=----WebKitFormBoundaryAnydWsQ1ajKuGoCd",
},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{},
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
}
for _, c := range cases {
t.Run(c.caseName, func(t *testing.T) {
err := CompareRequest(c.req, c.cReq, c.cRes, c.expected)
if c.errMsg != "" {
require.ErrorContains(t, err, c.errMsg)
return
}
require.NoError(t, err)
})
}
}
func TestCompareResponse(t *testing.T) {
cases := []struct {
caseName string
errMsg string
req *roundtripper.Request
cReq *roundtripper.CapturedRequest
cRes *roundtripper.CapturedResponse
expected Assertion
}{
{
caseName: "compare response header ok",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
},
Body: []byte(``),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetResponse},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(``),
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare response header&body ok",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"application/json"},
},
Body: []byte(`
{
"X-body-test1":["b1"],
"X-body-test2":["b2", "b22"]
}`),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetResponse},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`
{
"X-body-test1":["b1"],
"X-body-test2":["b2","b22"]
}`),
ContentType: ContentTypeApplicationJson,
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare response header&body fail, because headers not consistent",
errMsg: "expected X-header-test1 header to be set to h1, got h1,hn",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1", "hn"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"application/json"},
},
Body: []byte(`
{
"X-body-test1":["b1"],
"X-body-test2":["b2", "b22"]
}`),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetResponse},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`
{
"X-body-test1":["b1"],
"X-body-test2":["b2","b22"]
}`),
ContentType: ContentTypeApplicationJson,
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare response header&body fail, because body not consistent",
errMsg: "expected application/json body to be",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"application/json"},
},
Body: []byte(`
{
"X-body-test1":["b1", "bn"],
"X-body-test2":["b2", "b22"]
}`),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetResponse},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`
{
"X-body-test1":["b1"],
"X-body-test2":["b2","b22"]
}`),
ContentType: ContentTypeApplicationJson,
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare response header&body ok, body type is text/plain",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"text/plain"},
},
Body: []byte(`hello higress`),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetResponse},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`hello higress`),
ContentType: ContentTypeTextPlain,
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare response header&body fail, because body not consistent. body type is text/plain",
errMsg: "expected text/plain body to be",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"text/plain"},
},
Body: []byte(`Hello Higress`),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetResponse},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`hello higress`),
ContentType: ContentTypeTextPlain,
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare response header&body ok, body type is FormUrlencoded",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"application/x-www-form-urlencoded"},
},
Body: []byte(`X-body-test1=b1&X-body-test2=b2&X-body-test2=b22`),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetResponse},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`X-body-test1=b1&X-body-test2=b2&X-body-test2=b22`),
ContentType: ContentTypeFormUrlencoded,
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare response header&body fail, because body not consistent, body type is FormUrlencoded",
errMsg: "expected application/x-www-form-urlencoded body to be",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"Content-Type": {"application/x-www-form-urlencoded"},
},
Body: []byte(`X-body-test1=b1&X-body-test1=bn&X-body-test2=b2&X-body-test2=b22`),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetResponse},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(`X-body-test1=b1&X-body-test2=b2&X-body-test2=b22`),
ContentType: ContentTypeFormUrlencoded,
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare response header&body ok, body type is MultipartForm",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"ContentType": {"multipart/form-data; boundary=----WebKitFormBoundaryAnydWsQ1ajKuGoCd"},
},
Body: []byte(
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"Screenshot.png\"\r\n" +
"Content-Type: image/png\r\n\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"name\"\r\n\r\n" +
"denzel\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"flag\"\r\n\r\n" +
"test\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd--\r\n"),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetResponse},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"Screenshot.png\"\r\n" +
"Content-Type: image/png\r\n\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"name\"\r\n\r\n" +
"denzel\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"flag\"\r\n\r\n" +
"test\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd--\r\n"),
ContentType: ContentTypeMultipartForm + "; boundary=----WebKitFormBoundaryAnydWsQ1ajKuGoCd",
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
{
caseName: "compare response header&body fail, because body not consistent. body type is MultipartForm",
errMsg: "expected multipart/form-data body to be",
req: &roundtripper.Request{},
cReq: &roundtripper.CapturedRequest{},
cRes: &roundtripper.CapturedResponse{
StatusCode: 200,
Headers: map[string][]string{
"X-header-test1": {"h1"},
"X-header-test2": {"h2", "h22"},
"ContentType": {"multipart/form-data; boundary=----WebKitFormBoundaryAnydWsQ1ajKuGoCd"},
},
Body: []byte(
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"Screenshot.png\"\r\n" +
"Content-Type: image/png\r\n\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"name\"\r\n\r\n" +
"higress\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"flag\"\r\n\r\n" +
"test\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd--\r\n"),
},
expected: Assertion{
Meta: AssertionMeta{TestCaseName: "", TargetBackend: "", TargetNamespace: "", CompareTarget: CompareTargetResponse},
Request: AssertionRequest{
ActualRequest: Request{},
ExpectedRequest: &ExpectedRequest{
Request: Request{},
AbsentHeaders: []string{},
},
},
Response: AssertionResponse{
ExpectedResponse: Response{
StatusCode: 200,
Headers: map[string]string{
"X-header-test1": "h1",
"X-header-test2": "h2,h22",
},
Body: []byte(
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"Screenshot.png\"\r\n" +
"Content-Type: image/png\r\n\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"name\"\r\n\r\n" +
"denzel\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd\r\n" +
"Content-Disposition: form-data; name=\"flag\"\r\n\r\n" +
"test\r\n" +
"------WebKitFormBoundaryAnydWsQ1ajKuGoCd--\r\n"),
ContentType: ContentTypeMultipartForm + "; boundary=----WebKitFormBoundaryAnydWsQ1ajKuGoCd",
AbsentHeaders: []string{},
},
AdditionalResponseHeaders: map[string]string{},
ExpectedResponseNoRequest: false,
},
},
},
}
for _, c := range cases {
t.Run(c.caseName, func(t *testing.T) {
err := CompareResponse(c.cRes, c.expected)
if c.errMsg != "" {
require.ErrorContains(t, err, c.errMsg)
return
}
require.NoError(t, err)
})
}
}