feat: add features to conformance and do some refactors (#532)

Signed-off-by: bitliu <bitliu@tencent.com>
This commit is contained in:
Xunzhuo
2023-09-19 11:53:06 +08:00
committed by GitHub
parent 54a8a906ae
commit 8062625d75
49 changed files with 260 additions and 162 deletions

View File

@@ -147,6 +147,10 @@ jobs:
higress-wasmplugin-test:
runs-on: ubuntu-latest
needs: [build]
strategy:
matrix:
# TODO(Xunzhuo): Enable C WASM Filters in CI
wasmPluginType: [ GO ]
steps:
- uses: actions/checkout@v3
@@ -179,7 +183,7 @@ jobs:
- run: git stash # restore patch
- name: "Run Ingress WasmPlugins Tests"
run: GOPROXY="https://proxy.golang.org,direct" make higress-wasmplugin-test
run: GOPROXY="https://proxy.golang.org,direct" PLUGIN_TYPE=${{ matrix.wasmPluginType }} make higress-wasmplugin-test
publish:
runs-on: ubuntu-latest

View File

@@ -13,6 +13,7 @@ $ PLUGIN_NAME=request_block make build
<details>
<summary>Output</summary>
<pre><code>
DOCKER_BUILDKIT=1 docker build --build-arg PLUGIN_NAME=request_block \
-t request_block:20230721-141120-aa17e95 \
--output extensions/request_block \
@@ -106,16 +107,17 @@ spec:
The rules will be matched in the order of configuration. If one match is found, it will stop, and the matching configuration will take effect.
## E2E test
When you complete a GO plug-in function, you can create associated e2e test cases at the same time, and complete the test verification of the plug-in function locally.
### step1. write test cases
In the directory of `./ test/e2e/conformance/tests/`, add the xxx.yaml file and xxx.go file. Such as test for `request-block` wasm-plugin,
./test/e2e/conformance/tests/request-block.yaml
```
``` yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
...
@@ -126,16 +128,18 @@ spec:
- "swagger.html"
url: file:///opt/plugins/wasm-go/extensions/request-block/plugin.wasm
```
`Above of the url, the name of after extensions indicates the name of the folder where the plug-in resides.`
./test/e2e/conformance/tests/request-block.go
### step2. add test cases
Add the test cases written above to the e2e test list,
./test/e2e/e2e_test.go
```
```go
...
cSuite.Setup(t)
var higressTests []suite.ConformanceTest
@@ -160,8 +164,9 @@ cSuite.Setup(t)
```
### step3. compile and run test cases
Considering that building wasm locally is time-consuming, we support building only the plug-ins that need to be tested (at the same time, you can also temporarily modify the list of test cases in the second small step above, and only execute your newly written cases).
```bash
PLUGIN_TYPE=CPP PLUGIN_NAME=request_block make higress-wasmplugin-test
```
```

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, CPPWasmPluginsBasicAuth)
Register(CPPWasmPluginsBasicAuth)
}
var CPPWasmPluginsBasicAuth = suite.ConformanceTest{
ShortName: "CPPWasmPluginsBasicAuth",
Description: "The Ingress in the higress-conformance-infra namespace test the CPP basic-auth WASM plugin.",
Manifests: []string{"tests/cpp-basic-auth.yaml"},
Manifests: []string{"tests/cpp-wasm-basic-auth.yaml"},
Features: []suite.SupportedFeature{suite.WASMCPPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, CPPWasmPluginsKeyAuth)
Register(CPPWasmPluginsKeyAuth)
}
var CPPWasmPluginsKeyAuth = suite.ConformanceTest{
ShortName: "CPPWasmPluginsKeyAuth",
Description: "The Ingress in the higress-conformance-infra namespace test the CPP key_auth wasmplugins.",
Manifests: []string{"tests/cpp-key_auth.yaml"},
Manifests: []string{"tests/cpp-wasm-key-auth.yaml"},
Features: []suite.SupportedFeature{suite.WASMCPPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, CPPWasmPluginsRequestBlock)
Register(CPPWasmPluginsRequestBlock)
}
var CPPWasmPluginsRequestBlock = suite.ConformanceTest{
ShortName: "CPPWasmPluginsRequestBlock",
Description: "The Ingress in the higress-conformance-infra namespace test the cpp request-block wasmplugins.",
Manifests: []string{"tests/cpp-request_block.yaml"},
Manifests: []string{"tests/cpp-wasm-request-block.yaml"},
Features: []suite.SupportedFeature{suite.WASMCPPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, WasmPluginsBasicAuth)
Register(WasmPluginsBasicAuth)
}
var WasmPluginsBasicAuth = suite.ConformanceTest{
ShortName: "WasmPluginsBasicAuth",
Description: "The Ingress in the higress-conformance-infra namespace test the basic-auth WASM plugin.",
Manifests: []string{"tests/basic-auth.yaml"},
Manifests: []string{"tests/go-wasm-basic-auth.yaml"},
Features: []suite.SupportedFeature{suite.WASMGoConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, WasmPluginsJwtAuth)
Register(WasmPluginsJwtAuth)
}
var WasmPluginsJwtAuth = suite.ConformanceTest{
ShortName: "WasmPluginsJwtAuth",
Description: "The Ingress in the higress-conformance-infra namespace test the jwt-auth wasmplugins.",
Manifests: []string{"tests/jwt-auth.yaml"},
Manifests: []string{"tests/go-wasm-jwt-auth.yaml"},
Features: []suite.SupportedFeature{suite.WASMGoConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, WasmPluginsRequestBlock)
Register(WasmPluginsRequestBlock)
}
var WasmPluginsRequestBlock = suite.ConformanceTest{
ShortName: "WasmPluginsRequestBlock",
Description: "The Ingress in the higress-conformance-infra namespace test the request-block wasmplugins.",
Manifests: []string{"tests/request-block.yaml"},
Manifests: []string{"tests/go-wasm-request-block.yaml"},
Features: []suite.SupportedFeature{suite.WASMGoConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -23,13 +23,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteAppRoot)
Register(HTTPRouteAppRoot)
}
var HTTPRouteAppRoot = suite.ConformanceTest{
ShortName: "HTTPRouteAppRoot",
Description: "The Ingress in the higress-conformance-infra namespace uses the app root.",
Manifests: []string{"tests/httproute-app-root.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteCanaryHeaderWithCustomizedHeader)
Register(HTTPRouteCanaryHeaderWithCustomizedHeader)
}
var HTTPRouteCanaryHeaderWithCustomizedHeader = suite.ConformanceTest{
ShortName: "HTTPRouteCanaryHeaderWithCustomizedHeader",
Description: "The Ingress in the higress-conformance-infra namespace uses the canary header traffic split when same host and path but different header",
Manifests: []string{"tests/httproute-canary-header-with-customized-header.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteCanaryHeader)
Register(HTTPRouteCanaryHeader)
}
var HTTPRouteCanaryHeader = suite.ConformanceTest{
ShortName: "HTTPRouteCanaryHeader",
Description: "The Ingress in the higress-conformance-infra namespace uses the canary header traffic split.",
Manifests: []string{"tests/httproute-canary-header.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteCanaryWeight)
Register(HTTPRouteCanaryWeight)
}
var HTTPRouteCanaryWeight = suite.ConformanceTest{
ShortName: "HTTPRouteCanaryWeight",
Description: "The Ingress in the higress-conformance-infra namespace uses the canary weight traffic split.",
Manifests: []string{"tests/httproute-canary-weight.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
// test if the weight is 0

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteConsulHttpBin)
Register(HTTPRouteConsulHttpBin)
}
var HTTPRouteConsulHttpBin = suite.ConformanceTest{
ShortName: "HTTPRouteConsulHttpBin",
Description: "The Ingress in the higress-conformance-infra namespace uses the consul service registry.",
Manifests: []string{"tests/httproute-consul-httpbin.yaml"},
Features: []suite.SupportedFeature{suite.ConsulConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -27,13 +27,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteDownstreamEncryption)
Register(HTTPRouteDownstreamEncryption)
}
var HTTPRouteDownstreamEncryption = suite.ConformanceTest{
ShortName: "HTTPRouteDownstreamEncryption",
Description: "A single Ingress in the higress-conformance-infra namespace for downstream encryption.",
Manifests: []string{"tests/httproute-downstream-encryption.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
// Prepare certificates and secrets for testcases
caCertOut, _, caCert, caKey := cert.MustGenerateCaCert(t)

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteEnableCors)
Register(HTTPRouteEnableCors)
}
var HTTPRouteEnableCors = suite.ConformanceTest{
ShortName: "HTTPRouteEnableCors",
Description: "A single Ingress in the higress-conformance-infra namespace demonstrates enable cors ability.",
Manifests: []string{"tests/httproute-enable-cors.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteEnableIgnoreCase)
Register(HTTPRouteEnableIgnoreCase)
}
var HTTPRouteEnableIgnoreCase = suite.ConformanceTest{
ShortName: "HTTPRouteEnableIgnoreCase",
Description: "A Ingress in the higress-conformance-infra namespace that ignores URI case in HTTP match.",
Manifests: []string{"tests/httproute-enable-ignore-case.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -23,13 +23,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteEurekaRegistry)
Register(HTTPRouteEurekaRegistry)
}
var HTTPRouteEurekaRegistry = suite.ConformanceTest{
ShortName: "HTTPRouteEurekaRegistry",
Description: "The Ingress in the higress-conformance-infra namespace uses the eureka service registry.",
Manifests: []string{"tests/httproute-eureka-registry.yaml"},
Features: []suite.SupportedFeature{suite.EurekaConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -23,13 +23,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HttpForceRedirectHttps)
Register(HttpForceRedirectHttps)
}
var HttpForceRedirectHttps = suite.ConformanceTest{
ShortName: "HttpForceRedirectHttps",
Description: " The ingress in the higress-conformance-infra namespace enforces server-side HTTPS with forced redirection.",
Manifests: []string{"tests/httproute-force-redirect-https.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteFullPathRegex)
Register(HTTPRouteFullPathRegex)
}
var HTTPRouteFullPathRegex = suite.ConformanceTest{
ShortName: "HTTPRouteFullPathRegex",
Description: "test for 'higress.io/full-path-regex' annotation",
Manifests: []string{"tests/httproute-full-path-regex.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testCases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteHostNameSameNamespace)
Register(HTTPRouteHostNameSameNamespace)
}
var HTTPRouteHostNameSameNamespace = suite.ConformanceTest{
ShortName: "HTTPRouteHostNameSameNamespace",
Description: "A Ingress in the higress-conformance-infra namespace demonstrates host match ability.",
Manifests: []string{"tests/httproute-hostname-same-namespace.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteHttp2Rpc)
Register(HTTPRouteHttp2Rpc)
}
var HTTPRouteHttp2Rpc = suite.ConformanceTest{
ShortName: "HTTPRouteHttp2Rpc",
Description: "The Ingress in the higress-conformance-infra namespace uses the http2rpc.",
Manifests: []string{"tests/httproute-http2rpc.yaml"},
Features: []suite.SupportedFeature{suite.DubboConformanceFeature, suite.NacosConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{
@@ -47,7 +48,7 @@ var HTTPRouteHttp2Rpc = suite.ConformanceTest{
},
},
}
t.Run("HTTPRoute app root", func(t *testing.T) {
t.Run("HTTPRoute uses HTTP to RPC", func(t *testing.T) {
for _, testcase := range testcases {
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, suite.GatewayAddress, testcase)
}

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteMatchHeaders)
Register(HTTPRouteMatchHeaders)
}
var HTTPRouteMatchHeaders = suite.ConformanceTest{
ShortName: "HTTPRouteMatchHeaders",
Description: "A single Ingress in the higress-conformance-infra namespace uses the match headers.",
Manifests: []string{"tests/httproute-match-headers.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteMatchMethods)
Register(HTTPRouteMatchMethods)
}
var HTTPRouteMatchMethods = suite.ConformanceTest{
ShortName: "HTTPRouteMatchMethods",
Description: "A single Ingress in the higress-conformance-infra namespace uses the match methods.",
Manifests: []string{"tests/httproute-match-methods.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteMatchPath)
Register(HTTPRouteMatchPath)
}
var HTTPRouteMatchPath = suite.ConformanceTest{
ShortName: "HTTPRouteMatchPath",
Description: "A Ingress in the higress-conformance-infra namespace that match different path.",
Manifests: []string{"tests/httproute-match-path.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteMatchQueryParams)
Register(HTTPRouteMatchQueryParams)
}
var HTTPRouteMatchQueryParams = suite.ConformanceTest{
ShortName: "HTTPRouteMatchQueryParams",
Description: "A single Ingress in the higress-conformance-infra namespace uses the match queryParams.",
Manifests: []string{"tests/httproute-match-query-params.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -23,13 +23,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRoutePermanentRedirectCode)
Register(HTTPRoutePermanentRedirectCode)
}
var HTTPRoutePermanentRedirectCode = suite.ConformanceTest{
ShortName: "HTTPRoutePermanentRedirectCode",
Description: "The Ingress in the higress-conformance-infra namespace uses the permanent redirect code header.",
Manifests: []string{"tests/httproute-permanent-redirect-code.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -23,13 +23,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRoutePermanentRedirect)
Register(HTTPRoutePermanentRedirect)
}
var HTTPRoutePermanentRedirect = suite.ConformanceTest{
ShortName: "HTTPRoutePermanentRedirect",
Description: "The Ingress in the higress-conformance-infra namespace uses the permanent redirect header.",
Manifests: []string{"tests/httproute-permanent-redirect.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -23,13 +23,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HttpRedirectAsHttps)
Register(HttpRedirectAsHttps)
}
var HttpRedirectAsHttps = suite.ConformanceTest{
ShortName: "HttpRedirectAsHttps",
Description: "The Ingress in the higress-conformance-infra namespace Server-side HTTPS enforcement through redirect.",
Manifests: []string{"tests/httproute-redirct-as-https.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteRequestHeaderControl)
Register(HTTPRouteRequestHeaderControl)
}
var HTTPRouteRequestHeaderControl = suite.ConformanceTest{
ShortName: "HTTPRouteRequestHeaderControl",
Description: "A single Ingress in the higress-conformance-infra namespace controls the request header.",
Manifests: []string{"tests/httproute-request-header-control.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteRewriteHost)
Register(HTTPRouteRewriteHost)
}
var HTTPRouteRewriteHost = suite.ConformanceTest{
ShortName: "HTTPRouteRewriteHost",
Description: "A single Ingress in the higress-conformance-infra namespace uses the rewrite host.",
Manifests: []string{"tests/httproute-rewrite-host.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteRewritePath)
Register(HTTPRouteRewritePath)
}
var HTTPRouteRewritePath = suite.ConformanceTest{
ShortName: "HTTPRouteRewritePath",
Description: "A single Ingress in the higress-conformance-infra namespace uses the rewrite path.",
Manifests: []string{"tests/httproute-rewrite-path.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testCases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteSameHostAndPath)
Register(HTTPRouteSameHostAndPath)
}
var HTTPRouteSameHostAndPath = suite.ConformanceTest{
ShortName: "HTTPRouteSameHostAndPath",
Description: "A single Ingress in the higress-conformance-infra namespace demonstrates the situation with same path and host",
Manifests: []string{"tests/httproute-same-host-and-path.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteSimpleSameNamespace)
Register(HTTPRouteSimpleSameNamespace)
}
var HTTPRouteSimpleSameNamespace = suite.ConformanceTest{
ShortName: "HTTPRouteSimpleSameNamespace",
Description: "A single Ingress in the higress-conformance-infra namespace demonstrates basic routing ability.",
Manifests: []string{"tests/httproute-simple-same-namespace.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
t.Run("Simple HTTP request should reach infra-backend", func(t *testing.T) {
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, suite.GatewayAddress, http.Assertion{

View File

@@ -23,13 +23,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteTemporalRedirect)
Register(HTTPRouteTemporalRedirect)
}
var HTTPRouteTemporalRedirect = suite.ConformanceTest{
ShortName: "HTTPRouteTemporalRedirect",
Description: "The Ingress in the higress-conformance-infra namespace uses the temporal redirect header.",
Manifests: []string{"tests/httproute-temporal-redirect.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -22,13 +22,14 @@ import (
)
func init() {
HigressConformanceTests = append(HigressConformanceTests, HTTPRouteWhitelistSourceRange)
Register(HTTPRouteWhitelistSourceRange)
}
var HTTPRouteWhitelistSourceRange = suite.ConformanceTest{
ShortName: "HTTPRouteWhitelistSourceRange",
Description: "A single Ingress in the higress-conformance-infra namespace demonstrates ip access control",
Manifests: []string{"tests/httproute-whitelist-source-range.yaml"},
Features: []suite.SupportedFeature{suite.HTTPConformanceFeature},
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
testcases := []http.Assertion{
{

View File

@@ -16,4 +16,11 @@ package tests
import "github.com/alibaba/higress/test/e2e/conformance/utils/suite"
var HigressConformanceTests []suite.ConformanceTest
func Register(testcase suite.ConformanceTest) {
if len(testcase.Features) == 0 {
panic("must set at least one feature of the test case")
}
ConformanceTests = append(ConformanceTests, testcase)
}
var ConformanceTests []suite.ConformanceTest

View File

@@ -23,4 +23,7 @@ var (
CleanupBaseResources = flag.Bool("cleanup-base-resources", true, "Whether to cleanup base test resources after the run")
SupportedFeatures = flag.String("supported-features", "", "Supported features included in conformance tests suites")
ExemptFeatures = flag.String("exempt-features", "", "Exempt Features excluded from conformance tests suites")
IsWasmPluginTest = flag.Bool("isWasmPluginTest", false, "Determine if run wasm plugin conformance test")
WasmPluginType = flag.String("wasmPluginType", "GO", "Define wasm plugin type, currently supports GO, CPP")
WasmPluginName = flag.String("wasmPluginName", "", "Define wasm plugin name")
)

View File

@@ -97,7 +97,7 @@ func (a Applier) MustApplyObjectsWithCleanup(t *testing.T, c client.Client, time
ctx, cancel := context.WithTimeout(context.Background(), timeoutConfig.CreateTimeout)
defer cancel()
t.Logf("Creating %s %s", resource.GetName(), resource.GetObjectKind().GroupVersionKind().Kind)
t.Logf("🏗 Creating %s %s", resource.GetName(), resource.GetObjectKind().GroupVersionKind().Kind)
err := c.Create(ctx, resource)
if err != nil {
@@ -110,7 +110,7 @@ func (a Applier) MustApplyObjectsWithCleanup(t *testing.T, c client.Client, time
t.Cleanup(func() {
ctx, cancel = context.WithTimeout(context.Background(), timeoutConfig.DeleteTimeout)
defer cancel()
t.Logf("Deleting %s %s", resource.GetName(), resource.GetObjectKind().GroupVersionKind().Kind)
t.Logf("🚮 Deleting %s %s", resource.GetName(), resource.GetObjectKind().GroupVersionKind().Kind)
err = c.Delete(ctx, resource)
require.NoErrorf(t, err, "error deleting resource")
})
@@ -129,7 +129,7 @@ func (a Applier) MustApplyWithCleanup(t *testing.T, c client.Client, timeoutConf
resources, err := a.prepareResources(t, decoder)
if err != nil {
t.Logf("manifest: %s", data.String())
t.Logf("🧳 Manifest: %s", data.String())
require.NoErrorf(t, err, "error parsing manifest")
}
@@ -146,7 +146,7 @@ func (a Applier) MustApplyWithCleanup(t *testing.T, c client.Client, timeoutConf
if !apierrors.IsNotFound(err) {
require.NoErrorf(t, err, "error getting resource")
}
t.Logf("Creating %s %s", uObj.GetName(), uObj.GetKind())
t.Logf("🏗 Creating %s %s", uObj.GetName(), uObj.GetKind())
err = c.Create(ctx, uObj)
require.NoErrorf(t, err, "error creating resource")
@@ -154,7 +154,7 @@ func (a Applier) MustApplyWithCleanup(t *testing.T, c client.Client, timeoutConf
t.Cleanup(func() {
ctx, cancel = context.WithTimeout(context.Background(), timeoutConfig.DeleteTimeout)
defer cancel()
t.Logf("Deleting %s %s", uObj.GetName(), uObj.GetKind())
t.Logf("🚮 Deleting %s %s", uObj.GetName(), uObj.GetKind())
err = c.Delete(ctx, uObj)
require.NoErrorf(t, err, "error deleting resource")
})
@@ -163,14 +163,14 @@ func (a Applier) MustApplyWithCleanup(t *testing.T, c client.Client, timeoutConf
}
uObj.SetResourceVersion(fetchedObj.GetResourceVersion())
t.Logf("Updating %s %s", uObj.GetName(), uObj.GetKind())
t.Logf("🏗 Updating %s %s", uObj.GetName(), uObj.GetKind())
err = c.Update(ctx, uObj)
if cleanup {
t.Cleanup(func() {
ctx, cancel = context.WithTimeout(context.Background(), timeoutConfig.DeleteTimeout)
defer cancel()
t.Logf("Deleting %s %s", uObj.GetName(), uObj.GetKind())
t.Logf("🚮 Deleting %s %s", uObj.GetName(), uObj.GetKind())
err = c.Delete(ctx, uObj)
require.NoErrorf(t, err, "error deleting resource")
})

View File

@@ -54,7 +54,7 @@ func NamespacesMustBeAccepted(t *testing.T, c client.Client, timeoutConfig confi
podList := &v1.PodList{}
err := c.List(ctx, podList, client.InNamespace(ns))
if err != nil {
t.Errorf("Error listing Pods: %v", err)
t.Errorf("Error listing Pods: %v", err)
}
for _, pod := range podList.Items {
if !FindPodConditionInList(t, pod.Status.Conditions, "Ready", "True") &&
@@ -64,7 +64,7 @@ func NamespacesMustBeAccepted(t *testing.T, c client.Client, timeoutConfig confi
}
}
}
t.Logf("Gateways and Pods in %s namespaces ready", strings.Join(namespaces, ", "))
t.Logf("Gateways and Pods in %s namespaces ready", strings.Join(namespaces, ", "))
return true, nil
})
require.NoErrorf(t, waitErr, "error waiting for %s namespaces to be ready", strings.Join(namespaces, ", "))
@@ -72,7 +72,7 @@ func NamespacesMustBeAccepted(t *testing.T, c client.Client, timeoutConfig confi
func ConditionsMatch(t *testing.T, expected, actual []metav1.Condition) bool {
if len(actual) < len(expected) {
t.Logf("Expected more conditions to be present")
t.Logf("⌛️ Expected more conditions to be present")
return false
}
for _, condition := range expected {
@@ -81,7 +81,7 @@ func ConditionsMatch(t *testing.T, expected, actual []metav1.Condition) bool {
}
}
t.Logf("Conditions matched expectations")
t.Logf("Conditions matched expectations")
return true
}
@@ -95,14 +95,14 @@ func FindConditionInList(t *testing.T, conditions []metav1.Condition, condName,
if expectedReason == "" || cond.Reason == expectedReason {
return true
}
t.Logf("%s condition Reason set to %s, expected %s", condName, cond.Reason, expectedReason)
t.Logf("⌛️ %s condition Reason set to %s, expected %s", condName, cond.Reason, expectedReason)
}
t.Logf("%s condition set to Status %s with Reason %v, expected Status %s", condName, cond.Status, cond.Reason, expectedStatus)
t.Logf("⌛️ %s condition set to Status %s with Reason %v, expected Status %s", condName, cond.Status, cond.Reason, expectedStatus)
}
}
t.Logf("%s was not in conditions list", condName)
t.Logf("⌛️ %s was not in conditions list", condName)
return false
}
@@ -112,10 +112,10 @@ func FindPodConditionInList(t *testing.T, conditions []v1.PodCondition, condName
if cond.Status == v1.ConditionStatus(condValue) {
return true
}
t.Logf("%s condition set to %s, expected %s", condName, cond.Status, condValue)
t.Logf("⌛️ %s condition set to %s, expected %s", condName, cond.Status, condValue)
}
}
t.Logf("%s was not in conditions list", condName)
t.Logf("⌛️ %s was not in conditions list", condName)
return false
}

View File

@@ -0,0 +1,45 @@
// 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 suite
import "istio.io/istio/pilot/pkg/util/sets"
type SupportedFeature string
const (
// core: http
HTTPConformanceFeature SupportedFeature = "http"
// extended: extensibility
WASMGoConformanceFeature SupportedFeature = "wasm-go"
WASMCPPConformanceFeature SupportedFeature = "wasm-cpp"
// extended: service discovery
DubboConformanceFeature SupportedFeature = "dubbo"
EurekaConformanceFeature SupportedFeature = "eureka"
ConsulConformanceFeature SupportedFeature = "consul"
NacosConformanceFeature SupportedFeature = "nacos"
)
var AllFeatures = sets.Set{}.
Insert(string(HTTPConformanceFeature)).
Insert(string(DubboConformanceFeature)).
Insert(string(EurekaConformanceFeature)).
Insert(string(ConsulConformanceFeature)).
Insert(string(NacosConformanceFeature))
var ExperimentFeatures = sets.Set{}.
Insert(string(WASMGoConformanceFeature)).
Insert(string(WASMCPPConformanceFeature))

View File

@@ -20,32 +20,41 @@ import (
"github.com/alibaba/higress/test/e2e/conformance/utils/config"
"github.com/alibaba/higress/test/e2e/conformance/utils/kubernetes"
"github.com/alibaba/higress/test/e2e/conformance/utils/roundtripper"
"istio.io/istio/pilot/pkg/util/sets"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// ConformanceTestSuite defines the test suite used to run Gateway API
// conformance tests.
type ConformanceTestSuite struct {
Client client.Client
RoundTripper roundtripper.RoundTripper
GatewayAddress string
IngressClassName string
Debug bool
Cleanup bool
BaseManifests string
Applier kubernetes.Applier
TimeoutConfig config.TimeoutConfig
Client client.Client
RoundTripper roundtripper.RoundTripper
GatewayAddress string
IngressClassName string
Debug bool
Cleanup bool
BaseManifests string
Applier kubernetes.Applier
SkipTests sets.Set
TimeoutConfig config.TimeoutConfig
SupportedFeatures sets.Set
}
// Options can be used to initialize a ConformanceTestSuite.
type Options struct {
Client client.Client
GatewayAddress string
IngressClassName string
Debug bool
RoundTripper roundtripper.RoundTripper
BaseManifests string
NamespaceLabels map[string]string
SupportedFeatures sets.Set
ExemptFeatures sets.Set
EnableAllSupportedFeatures bool
Client client.Client
GatewayAddress string
IngressClassName string
Debug bool
RoundTripper roundtripper.RoundTripper
BaseManifests string
NamespaceLabels map[string]string
// Options for wasm extended features
WASMOptions
// CleanupBaseResources indicates whether or not the base test
// resources such as Gateways should be cleaned up after the run.
@@ -53,6 +62,12 @@ type Options struct {
TimeoutConfig config.TimeoutConfig
}
type WASMOptions struct {
IsWasmPluginTest bool
WasmPluginType string
WasmPluginName string
}
// New returns a new ConformanceTestSuite.
func New(s Options) *ConformanceTestSuite {
config.SetupTimeoutConfig(&s.TimeoutConfig)
@@ -62,14 +77,33 @@ func New(s Options) *ConformanceTestSuite {
roundTripper = &roundtripper.DefaultRoundTripper{Debug: s.Debug, TimeoutConfig: s.TimeoutConfig}
}
if s.SupportedFeatures == nil {
s.SupportedFeatures = sets.Set{}
}
if s.IsWasmPluginTest {
if s.WasmPluginType == "CPP" {
s.SupportedFeatures.Insert(string(WASMCPPConformanceFeature))
} else {
s.SupportedFeatures.Insert(string(WASMGoConformanceFeature))
}
} else if s.EnableAllSupportedFeatures {
s.SupportedFeatures = AllFeatures
}
for feature := range s.ExemptFeatures {
s.SupportedFeatures.Delete(feature)
}
suite := &ConformanceTestSuite{
Client: s.Client,
RoundTripper: roundTripper,
IngressClassName: s.IngressClassName,
Debug: s.Debug,
Cleanup: s.CleanupBaseResources,
BaseManifests: s.BaseManifests,
GatewayAddress: s.GatewayAddress,
Client: s.Client,
RoundTripper: roundTripper,
IngressClassName: s.IngressClassName,
Debug: s.Debug,
Cleanup: s.CleanupBaseResources,
BaseManifests: s.BaseManifests,
SupportedFeatures: s.SupportedFeatures,
GatewayAddress: s.GatewayAddress,
Applier: kubernetes.Applier{
NamespaceLabels: s.NamespaceLabels,
},
@@ -87,20 +121,20 @@ func New(s Options) *ConformanceTestSuite {
// Setup ensures the base resources required for conformance tests are installed
// in the cluster. It also ensures that all relevant resources are ready.
func (suite *ConformanceTestSuite) Setup(t *testing.T) {
t.Logf("Test Setup: Ensuring IngressClass has been accepted")
t.Logf("📦 Test Setup: Ensuring IngressClass has been accepted")
suite.Applier.IngressClass = suite.IngressClassName
t.Logf("Test Setup: Applying base manifests")
t.Logf("📦 Test Setup: Applying base manifests")
suite.Applier.MustApplyWithCleanup(t, suite.Client, suite.TimeoutConfig, suite.BaseManifests, suite.Cleanup)
t.Logf("Test Setup: Applying programmatic resources")
t.Logf("📦 Test Setup: Applying programmatic resources")
secret := kubernetes.MustCreateSelfSignedCertSecret(t, "higress-conformance-web-backend", "certificate", []string{"*"})
suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{secret}, suite.Cleanup)
secret = kubernetes.MustCreateSelfSignedCertSecret(t, "higress-conformance-infra", "tls-validity-checks-certificate", []string{"*"})
suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{secret}, suite.Cleanup)
t.Logf("Test Setup: Ensuring Pods from base manifests are ready")
t.Logf("📦 Test Setup: Ensuring Pods from base manifests are ready")
namespaces := []string{
"higress-conformance-infra",
"higress-conformance-app-backend",
@@ -109,12 +143,13 @@ func (suite *ConformanceTestSuite) Setup(t *testing.T) {
"dubbo-demo-provider",
}
kubernetes.NamespacesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, namespaces)
t.Logf("🌱 Supported Features: %+v", suite.SupportedFeatures.UnsortedList())
}
// Run runs the provided set of conformance tests.
// RunWithTests runs the provided set of conformance tests.
func (suite *ConformanceTestSuite) Run(t *testing.T, tests []ConformanceTest) {
t.Logf("Start Running %d Test Cases: \n\n%s", len(tests), globalConformanceTestsListInfo(tests))
t.Logf("🚀 Start Running %d Test Cases: \n\n%s", len(tests), globalConformanceTestsListInfo(tests))
for _, test := range tests {
t.Run(test.ShortName, func(t *testing.T) {
test.Run(t, suite)
@@ -125,17 +160,20 @@ func (suite *ConformanceTestSuite) Run(t *testing.T, tests []ConformanceTest) {
func globalConformanceTestsListInfo(tests []ConformanceTest) string {
var cases string
for index, test := range tests {
cases += fmt.Sprintf("CaseNum: %d\nCaseName: %s\nScenario: %s\n\n", index+1, test.ShortName, test.Description)
cases += fmt.Sprintf("🎯 CaseNum: %d\nCaseName: %s\nScenario: %s\nFeatures: %+v\n\n", index+1, test.ShortName, test.Description, test.Features)
}
return cases
}
type ConformanceTests []ConformanceTest
// ConformanceTest is used to define each individual conformance test.
type ConformanceTest struct {
ShortName string
Description string
Manifests []string
Features []SupportedFeature
Slow bool
Parallel bool
Test func(*testing.T, *ConformanceTestSuite)
@@ -148,8 +186,23 @@ func (test *ConformanceTest) Run(t *testing.T, suite *ConformanceTestSuite) {
t.Parallel()
}
// Check that all features exercised by the test have been opted into by
// the suite.
for _, feature := range test.Features {
if !suite.SupportedFeatures.Contains(string(feature)) {
t.Skipf("🏊🏼 Skipping %s: suite does not support %s", test.ShortName, feature)
}
}
// check that the test should not be skipped
if suite.SkipTests.Contains(test.ShortName) {
t.Skipf("🏊🏼 Skipping %s: test explicitly skipped", test.ShortName)
}
t.Logf("🔥 Running Conformance Test: %s", test.ShortName)
for _, manifestLocation := range test.Manifests {
t.Logf("Applying %s", manifestLocation)
t.Logf("🧳 Applying Manifests: %s", manifestLocation)
suite.Applier.MustApplyWithCleanup(t, suite.Client, suite.TimeoutConfig, manifestLocation, true)
}

View File

@@ -16,7 +16,6 @@ package test
import (
"flag"
"strings"
"testing"
"github.com/stretchr/testify/require"
@@ -29,10 +28,6 @@ import (
"github.com/alibaba/higress/test/e2e/conformance/utils/suite"
)
var isWasmPluginTest = flag.Bool("isWasmPluginTest", false, "")
var wasmPluginType = flag.String("wasmPluginType", "GO", "")
var wasmPluginName = flag.String("wasmPluginName", "", "")
func TestHigressConformanceTests(t *testing.T) {
flag.Parse()
@@ -49,60 +44,15 @@ func TestHigressConformanceTests(t *testing.T) {
IngressClassName: *flags.IngressClassName,
Debug: *flags.ShowDebug,
CleanupBaseResources: *flags.CleanupBaseResources,
GatewayAddress: "localhost",
WASMOptions: suite.WASMOptions{
IsWasmPluginTest: *flags.IsWasmPluginTest,
WasmPluginName: *flags.WasmPluginName,
WasmPluginType: *flags.WasmPluginType,
},
GatewayAddress: "localhost",
EnableAllSupportedFeatures: true,
})
cSuite.Setup(t)
var higressTests []suite.ConformanceTest
if *isWasmPluginTest {
if strings.Compare(*wasmPluginType, "CPP") == 0 {
m := make(map[string]suite.ConformanceTest)
m["request_block"] = tests.CPPWasmPluginsRequestBlock
m["key_auth"] = tests.CPPWasmPluginsKeyAuth
m["basic_auth"] = tests.CPPWasmPluginsBasicAuth
higressTests = []suite.ConformanceTest{
m[*wasmPluginName],
}
} else {
higressTests = []suite.ConformanceTest{
tests.WasmPluginsRequestBlock,
tests.WasmPluginsJwtAuth,
tests.WasmPluginsBasicAuth,
}
}
} else {
higressTests = []suite.ConformanceTest{
tests.HTTPRouteSimpleSameNamespace,
tests.HTTPRouteHostNameSameNamespace,
tests.HTTPRouteRewritePath,
tests.HTTPRouteRewriteHost,
tests.HTTPRouteCanaryHeader,
tests.HTTPRouteEnableCors,
tests.HTTPRouteEnableIgnoreCase,
tests.HTTPRouteMatchMethods,
tests.HTTPRouteMatchQueryParams,
tests.HTTPRouteMatchHeaders,
tests.HTTPRouteAppRoot,
tests.HTTPRoutePermanentRedirect,
tests.HTTPRoutePermanentRedirectCode,
tests.HTTPRouteTemporalRedirect,
tests.HTTPRouteSameHostAndPath,
tests.HTTPRouteCanaryHeaderWithCustomizedHeader,
tests.HTTPRouteWhitelistSourceRange,
tests.HTTPRouteCanaryWeight,
tests.HTTPRouteMatchPath,
tests.HttpForceRedirectHttps,
tests.HttpRedirectAsHttps,
tests.HTTPRouteRequestHeaderControl,
tests.HTTPRouteDownstreamEncryption,
tests.HTTPRouteFullPathRegex,
tests.HTTPRouteHttp2Rpc,
tests.HTTPRouteConsulHttpBin,
tests.HTTPRouteEurekaRegistry,
}
}
cSuite.Run(t, higressTests)
cSuite.Run(t, tests.ConformanceTests)
}

View File

@@ -20,37 +20,35 @@ set -euo pipefail
TYPE=${PLUGIN_TYPE-""}
INNER_PLUGIN_NAME=${PLUGIN_NAME-""}
if [ $TYPE == "CPP" ]
if [ "$TYPE" == "CPP" ]
then
cd ./plugins/wasm-cpp/
if [ ! -n "$INNER_PLUGIN_NAME" ]; then
echo "you must specify which cpp plugin you want to compile"
echo "You must specify which cpp plugin you want to compile"
else
echo "build wasmplugin-cpp name of $INNER_PLUGIN_NAME"
echo "🚀 Build CPP WasmPlugin: $INNER_PLUGIN_NAME"
PLUGIN_NAME=${INNER_PLUGIN_NAME} make build
fi
else
echo "not specify plugin language, so just compile wasm-go as default"
echo "Not specify plugin language, so just compile wasm-go as default"
cd ./plugins/wasm-go/
if [ ! -n "$INNER_PLUGIN_NAME" ]; then
EXTENSIONS_DIR=$(pwd)"/extensions/"
echo "build all wasmplugins-go under folder of $EXTENSIONS_DIR"
echo "🚀 Build all Go WasmPlugins under folder of $EXTENSIONS_DIR"
for file in `ls $EXTENSIONS_DIR`
do
# TODO: adjust waf build
if [ $file == "waf" ]; then
if [ "$file" == "waf" ]; then
continue
fi
if [ -d $EXTENSIONS_DIR$file ]; then
name=${file##*/}
echo "build wasmplugin name of $name"
echo "🚀 Build Go WasmPlugin: $name"
PLUGIN_NAME=${name} make build
fi
done
else
echo "build wasmplugin-go name of $INNER_PLUGIN_NAME"
echo "🚀 Build Go WasmPlugin: $INNER_PLUGIN_NAME"
PLUGIN_NAME=${INNER_PLUGIN_NAME} make build
fi
fi