diff --git a/Makefile.core.mk b/Makefile.core.mk index fc3d0aacc..09f024cae 100644 --- a/Makefile.core.mk +++ b/Makefile.core.mk @@ -257,13 +257,13 @@ delete-cluster: $(tools/kind) ## Delete kind cluster. .PHONY: kube-load-image kube-load-image: $(tools/kind) ## Install the Higress image to a kind cluster using the provided $IMAGE and $TAG. tools/hack/kind-load-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/higress $(TAG) - tools/hack/docker-pull-image.sh docker.io/alihigress/dubbo-provider-demo 0.0.1 + tools/hack/docker-pull-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/dubbo-provider-demo 0.0.3-x86 tools/hack/docker-pull-image.sh docker.io/alihigress/nacos-standlone-rc3 1.0.0-RC3 tools/hack/docker-pull-image.sh docker.io/hashicorp/consul 1.16.0 tools/hack/docker-pull-image.sh docker.io/charlie1380/eureka-registry-provider v0.3.0 tools/hack/docker-pull-image.sh docker.io/bitinit/eureka latest tools/hack/docker-pull-image.sh docker.io/alihigress/httpbin 1.0.2 - tools/hack/kind-load-image.sh docker.io/alihigress/dubbo-provider-demo 0.0.1 + tools/hack/kind-load-image.sh higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/dubbo-provider-demo 0.0.3-x86 tools/hack/kind-load-image.sh docker.io/alihigress/nacos-standlone-rc3 1.0.0-RC3 tools/hack/kind-load-image.sh docker.io/hashicorp/consul 1.16.0 tools/hack/kind-load-image.sh docker.io/alihigress/httpbin 1.0.2 diff --git a/test/e2e/conformance/base/dubbo.yaml b/test/e2e/conformance/base/dubbo.yaml index 396647b61..c4e9898c0 100644 --- a/test/e2e/conformance/base/dubbo.yaml +++ b/test/e2e/conformance/base/dubbo.yaml @@ -29,7 +29,7 @@ metadata: spec: containers: - name: dubbo-demo-provider - image: registry.cn-hangzhou.aliyuncs.com/hinsteny/dubbo-provider-demo:0.0.2 + image: higress-registry.cn-hangzhou.cr.aliyuncs.com/higress/dubbo-provider-demo:0.0.3-x86 env: - name: NACOS_K8S_NAMESPACE value: higress-conformance-app-backend @@ -37,3 +37,7 @@ spec: value: dev ports: - containerPort: 20880 + resources: + requests: + cpu: 10m + memory: 300Mi diff --git a/test/e2e/conformance/tests/httproute-http2rpc.yaml b/test/e2e/conformance/tests/httproute-http2rpc-0-create.yaml similarity index 100% rename from test/e2e/conformance/tests/httproute-http2rpc.yaml rename to test/e2e/conformance/tests/httproute-http2rpc-0-create.yaml diff --git a/test/e2e/conformance/tests/httproute-http2rpc-1-update.yaml b/test/e2e/conformance/tests/httproute-http2rpc-1-update.yaml new file mode 100644 index 000000000..538b15965 --- /dev/null +++ b/test/e2e/conformance/tests/httproute-http2rpc-1-update.yaml @@ -0,0 +1,86 @@ +# 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. + +apiVersion: networking.higress.io/v1 +kind: Http2Rpc +metadata: + name: httproute-http2rpc-demo + namespace: higress-system +spec: + dubbo: + service: com.dubbo.demo.api.DemoService + version: 1.0.0 + group: dev + methods: + - serviceMethod: sayHello + headersAttach: "*" + httpMethods: + - GET + httpPath: "/dubbo/hello_update" + params: + - paramKey: name + paramSource: QUERY + paramType: "java.lang.String" +--- +apiVersion: networking.higress.io/v1 +kind: Http2Rpc +metadata: + name: httproute-http2rpc-healthservice + namespace: higress-system +spec: + dubbo: + service: com.dubbo.demo.api.HealthService + version: 1.0.0 + group: dev + methods: + - serviceMethod: readiness + headersAttach: "*" + httpMethods: + - GET + httpPath: "/dubbo/health/readiness" + params: + - paramKey: type + paramSource: QUERY + paramType: "java.lang.String" + - serviceMethod: liveness + headersAttach: "*" + httpMethods: + - GET + httpPath: "/dubbo/health/liveness" + params: + - paramKey: type + paramSource: QUERY + paramType: "java.lang.String" +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + higress.io/destination: providers:com.dubbo.demo.api.HealthService:1.0.0:dev.DEFAULT-GROUP.public.nacos + higress.io/rpc-destination-name: httproute-http2rpc-healthservice + name: httproute-http2rpc-healthservice-ingress + namespace: higress-system +spec: + ingressClassName: higress + rules: + - host: "foo.com" + http: + paths: + - pathType: Prefix + path: /dubbo/health + backend: + resource: + apiGroup: networking.higress.io + kind: McpBridge + name: default diff --git a/test/e2e/conformance/tests/httproute-http2rpc-2-delete.yaml b/test/e2e/conformance/tests/httproute-http2rpc-2-delete.yaml new file mode 100644 index 000000000..350933971 --- /dev/null +++ b/test/e2e/conformance/tests/httproute-http2rpc-2-delete.yaml @@ -0,0 +1,34 @@ +# 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. + +apiVersion: networking.higress.io/v1 +kind: Http2Rpc +metadata: + name: httproute-http2rpc-demo + namespace: higress-system +spec: + dubbo: + service: com.dubbo.demo.api.DemoService + version: 1.0.0 + group: dev + methods: + - serviceMethod: sayHello + headersAttach: "*" + httpMethods: + - GET + httpPath: "/dubbo/hello_update" + params: + - paramKey: name + paramSource: QUERY + paramType: "java.lang.String" \ No newline at end of file diff --git a/test/e2e/conformance/tests/httproute-http2rpc.go b/test/e2e/conformance/tests/httproute-http2rpc.go index f34a0d8cc..b5115d0da 100644 --- a/test/e2e/conformance/tests/httproute-http2rpc.go +++ b/test/e2e/conformance/tests/httproute-http2rpc.go @@ -22,13 +22,15 @@ import ( ) func init() { - Register(HTTPRouteHttp2Rpc) + Register(HTTPRouteHttp2RpcCreate) + Register(HTTPRouteHttp2RpcUpdate) + Register(HTTPRouteHttp2RpcDelete) } -var HTTPRouteHttp2Rpc = suite.ConformanceTest{ - ShortName: "HTTPRouteHttp2Rpc", - Description: "The Ingress in the higress-conformance-infra namespace uses the http2rpc.", - Manifests: []string{"tests/httproute-http2rpc.yaml"}, +var HTTPRouteHttp2RpcCreate = suite.ConformanceTest{ + ShortName: "HTTPRouteHttp2RpcCreate", + Description: "The Ingress in the higress-conformance-infra namespace test create the http2rpc.", + Manifests: []string{"tests/httproute-http2rpc-0-create.yaml"}, Features: []suite.SupportedFeature{suite.DubboConformanceFeature, suite.NacosConformanceFeature}, Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { testcases := []http.Assertion{ @@ -55,3 +57,141 @@ var HTTPRouteHttp2Rpc = suite.ConformanceTest{ }) }, } + +var HTTPRouteHttp2RpcUpdate = suite.ConformanceTest{ + ShortName: "HTTPRouteHttp2RpcUpdate", + Description: "The Ingress in the higress-conformance-infra namespace test delete the http2rpc.", + Manifests: []string{"tests/httproute-http2rpc-1-update.yaml"}, + Features: []suite.SupportedFeature{suite.DubboConformanceFeature, suite.NacosConformanceFeature}, + NotCleanup: true, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + testcases := []http.Assertion{ + { + Request: http.AssertionRequest{ + ActualRequest: http.Request{ + Host: "foo.com", + Path: "/dubbo/hello?name=higress", + Method: "GET", + }, + }, + Response: http.AssertionResponse{ + ExpectedResponseNoRequest: true, + ExpectedResponse: http.Response{ + StatusCode: 200, + }, + }, + }, + { + Request: http.AssertionRequest{ + ActualRequest: http.Request{ + Host: "foo.com", + Path: "/dubbo/hello_update?name=higress", + Method: "GET", + }, + }, + Response: http.AssertionResponse{ + ExpectedResponseNoRequest: true, + ExpectedResponse: http.Response{ + StatusCode: 404, + }, + }, + }, + { + Request: http.AssertionRequest{ + ActualRequest: http.Request{ + Host: "foo.com", + Path: "/dubbo/health/readiness?type=readiness", + Method: "GET", + }, + }, + Response: http.AssertionResponse{ + ExpectedResponseNoRequest: true, + ExpectedResponse: http.Response{ + StatusCode: 200, + }, + }, + }, + { + Request: http.AssertionRequest{ + ActualRequest: http.Request{ + Host: "foo.com", + Path: "/dubbo/health/liveness?type=liveness", + Method: "GET", + }, + }, + Response: http.AssertionResponse{ + ExpectedResponseNoRequest: true, + ExpectedResponse: http.Response{ + StatusCode: 200, + }, + }, + }, + } + 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) + } + }) + }, +} + +var HTTPRouteHttp2RpcDelete = suite.ConformanceTest{ + ShortName: "HTTPRouteHttp2RpcDelete", + Description: "The Ingress in the higress-conformance-infra namespace test delete the http2rpc.", + PreDeleteRs: []string{"tests/httproute-http2rpc-2-delete.yaml"}, + Features: []suite.SupportedFeature{suite.DubboConformanceFeature, suite.NacosConformanceFeature}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + testcases := []http.Assertion{ + { + Request: http.AssertionRequest{ + ActualRequest: http.Request{ + Host: "foo.com", + Path: "/dubbo/hello_update?name=higress", + Method: "GET", + }, + }, + Response: http.AssertionResponse{ + ExpectedResponseNoRequest: true, + ExpectedResponse: http.Response{ + StatusCode: 404, + }, + }, + }, + { + Request: http.AssertionRequest{ + ActualRequest: http.Request{ + Host: "foo.com", + Path: "/dubbo/health/readiness?type=readiness", + Method: "GET", + }, + }, + Response: http.AssertionResponse{ + ExpectedResponseNoRequest: true, + ExpectedResponse: http.Response{ + StatusCode: 200, + }, + }, + }, + { + Request: http.AssertionRequest{ + ActualRequest: http.Request{ + Host: "foo.com", + Path: "/dubbo/health/liveness?type=liveness", + Method: "GET", + }, + }, + Response: http.AssertionResponse{ + ExpectedResponseNoRequest: true, + ExpectedResponse: http.Response{ + StatusCode: 200, + }, + }, + }, + } + 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) + } + }) + }, +} diff --git a/test/e2e/conformance/utils/kubernetes/apply.go b/test/e2e/conformance/utils/kubernetes/apply.go index a42065ff1..28a44ff0e 100644 --- a/test/e2e/conformance/utils/kubernetes/apply.go +++ b/test/e2e/conformance/utils/kubernetes/apply.go @@ -179,6 +179,39 @@ func (a Applier) MustApplyWithCleanup(t *testing.T, c client.Client, timeoutConf } } +// MustDelete delete Kubernetes resources defined with the provided YAML file . +func (a Applier) MustDelete(t *testing.T, c client.Client, timeoutConfig config.TimeoutConfig, location string) { + data, err := getContentsFromPathOrURL(location, timeoutConfig) + require.NoError(t, err) + + decoder := yaml.NewYAMLOrJSONDecoder(data, 4096) + + resources, err := a.prepareResources(t, decoder) + if err != nil { + t.Logf("🧳 Manifest: %s", data.String()) + require.NoErrorf(t, err, "error parsing manifest") + } + + for i := range resources { + uObj := &resources[i] + + ctx, cancel := context.WithTimeout(context.Background(), timeoutConfig.CreateTimeout) + defer cancel() + + // namespacedName := types.NamespacedName{Namespace: uObj.GetNamespace(), Name: uObj.GetName()} + // err := c.Get(ctx, namespacedName, uObj) + // if err != nil { + // if !apierrors.IsNotFound(err) { + // require.NoErrorf(t, err, "error getting resource") + // } + // } + + t.Logf("🏗 Deleting %s %s %s", uObj.GetName(), uObj.GetKind(), uObj.GetNamespace()) + err = c.Delete(ctx, uObj) + require.NoErrorf(t, err, "error delete resource") + } +} + // getContentsFromPathOrURL takes a string that can either be a local file // path or an https:// URL to YAML manifests and provides the contents. func getContentsFromPathOrURL(location string, timeoutConfig config.TimeoutConfig) (*bytes.Buffer, error) { diff --git a/test/e2e/conformance/utils/suite/suite.go b/test/e2e/conformance/utils/suite/suite.go index ba5fe21f3..f15a55fc5 100644 --- a/test/e2e/conformance/utils/suite/suite.go +++ b/test/e2e/conformance/utils/suite/suite.go @@ -115,9 +115,9 @@ func New(s Options) *ConformanceTestSuite { suite.BaseManifests = []string{ "base/manifests.yaml", "base/consul.yaml", - "base/dubbo.yaml", "base/eureka.yaml", "base/nacos.yaml", + "base/dubbo.yaml", } } @@ -179,11 +179,13 @@ type ConformanceTests []ConformanceTest type ConformanceTest struct { ShortName string Description string + PreDeleteRs []string Manifests []string Features []SupportedFeature Slow bool Parallel bool Test func(*testing.T, *ConformanceTestSuite) + NotCleanup bool } // Run runs an individual tests, applying and cleaning up the required manifests @@ -208,9 +210,14 @@ func (test *ConformanceTest) Run(t *testing.T, suite *ConformanceTestSuite) { t.Logf("🔥 Running Conformance Test: %s", test.ShortName) + for _, manifestLocation := range test.PreDeleteRs { + t.Logf("🧳 Applying PreDeleteRs Manifests: %s", manifestLocation) + suite.Applier.MustDelete(t, suite.Client, suite.TimeoutConfig, manifestLocation) + } + for _, manifestLocation := range test.Manifests { t.Logf("🧳 Applying Manifests: %s", manifestLocation) - suite.Applier.MustApplyWithCleanup(t, suite.Client, suite.TimeoutConfig, manifestLocation, true) + suite.Applier.MustApplyWithCleanup(t, suite.Client, suite.TimeoutConfig, manifestLocation, !test.NotCleanup) } test.Test(t, suite)