diff --git a/api/test/e2e/base.go b/api/test/e2e/base.go index 72ec325707..d6cb57782c 100644 --- a/api/test/e2e/base.go +++ b/api/test/e2e/base.go @@ -94,7 +94,7 @@ func APISIXHTTPSExpect(t *testing.T) *httpexpect.Expect { return e } -var sleepTime = time.Duration(20) * time.Millisecond +var sleepTime = time.Duration(50) * time.Millisecond type HttpTestCase struct { caseDesc string @@ -107,6 +107,7 @@ type HttpTestCase struct { ExpectCode int ExpectMessage string ExpectBody string + ExpectHeaders map[string]string Sleep time.Duration //ms } @@ -154,8 +155,16 @@ func testCaseCheck(tc HttpTestCase) { resp.Status(tc.ExpectStatus) } + //match headers + if tc.ExpectHeaders != nil { + for key, val := range tc.ExpectHeaders { + resp.Header(key).Equal(val) + } + } + //match body if tc.ExpectBody != "" { - resp.Body().Equal(tc.ExpectBody) + resp.Body().Contains(tc.ExpectBody) } + } diff --git a/api/test/e2e/ssl_test.go b/api/test/e2e/ssl_test.go index 3a1fb5557f..711671fbf6 100644 --- a/api/test/e2e/ssl_test.go +++ b/api/test/e2e/ssl_test.go @@ -127,7 +127,7 @@ func TestSSL_Basic(t *testing.T) { // try again after deleting SSL, make a HTTPS request // If use the test framework, errors will cause failure, so we need to make a separate https request for testing. - time.Sleep(time.Duration(20) * time.Millisecond) + time.Sleep(sleepTime) _, err = http.Get("https://www.test2.com:9443") assert.NotNil(t, err) assert.EqualError(t, err, "Get https://www.test2.com:9443: remote error: tls: internal error") diff --git a/api/test/e2e/upstream_test.go b/api/test/e2e/upstream_test.go new file mode 100644 index 0000000000..0974384872 --- /dev/null +++ b/api/test/e2e/upstream_test.go @@ -0,0 +1,242 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 e2e + +import ( + "net/http" + "testing" +) + +func TestUpstream_Create(t *testing.T) { + tests := []HttpTestCase{ + { + caseDesc: "use upstream that not exist", + Object: MangerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/r1", + Body: `{ + "uri": "/hello_", + "upstream_id": "not-exists" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusBadRequest, + }, + { + caseDesc: "create upstream", + Object: MangerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/upstreams/1", + Body: `{ + "nodes": [{ + "host": "172.16.238.20", + "port": 1980, + "weight": 1 + }], + "type": "roundrobin" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "create route using the upstream just created", + Object: MangerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/1", + Body: `{ + "uri": "/server_port", + "upstream_id": "1" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "hit the route just created", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/server_port", + ExpectStatus: http.StatusOK, + ExpectBody: "1980", + Sleep: sleepTime, + }, + } + + for _, tc := range tests { + testCaseCheck(tc) + } +} + +func TestUpstream_Update(t *testing.T) { + tests := []HttpTestCase{ + { + caseDesc: "update upstream with domain", + Object: MangerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/upstreams/1", + Body: `{ + "nodes": [{ + "host": "172.16.238.20", + "port": 1981, + "weight": 1 + }], + "type": "roundrobin" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "hit the route using upstream 1", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/server_port", + ExpectStatus: http.StatusOK, + ExpectBody: "1981", + Sleep: sleepTime, + }, + } + + for _, tc := range tests { + testCaseCheck(tc) + } +} + +func TestRoute_Node_Host(t *testing.T) { + tests := []HttpTestCase{ + { + caseDesc: "update upstream - pass host: node", + Object: MangerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/upstreams/1", + Body: `{ + "nodes": [{ + "host": "httpbin.org", + "port": 80, + "weight": 1 + }], + "type": "roundrobin", + "pass_host": "node" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "update path for route", + Object: MangerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/routes/1", + Body: `{ + "uri": "/*", + "upstream_id": "1" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "hit the route ", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/get", + ExpectStatus: http.StatusOK, + ExpectBody: "\"Host\": \"httpbin.org\"", + Sleep: sleepTime, + }, + { + caseDesc: "update upstream - pass host: rewrite", + Object: MangerApiExpect(t), + Method: http.MethodPut, + Path: "/apisix/admin/upstreams/1", + Body: `{ + "nodes": [{ + "host": "172.16.238.20", + "port": 1980, + "weight": 1 + }], + "type": "roundrobin", + "pass_host": "rewrite", + "upstream_host": "httpbin.org" + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "hit the route ", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/uri", + ExpectStatus: http.StatusOK, + ExpectBody: "x-forwarded-host: 127.0.0.1", + Sleep: sleepTime, + }, + } + + for _, tc := range tests { + testCaseCheck(tc) + } +} + +//TODO cHash +//TODO websocket + +func TestRoute_Delete(t *testing.T) { + tests := []HttpTestCase{ + { + caseDesc: "delete not exist upstream", + Object: MangerApiExpect(t), + Method: http.MethodDelete, + Path: "/apisix/admin/upstreams/not-exist", + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusNotFound, + }, + // TODO it's a bug here, see: https://github.com/apache/apisix-dashboard/issues/728 + //{ + // caseDesc: "delete upstream - being used by route 1", + // Object: MangerApiExpect(t), + // Method: http.MethodDelete, + // Path: "/apisix/admin/upstreams/1", + // Headers: map[string]string{"Authorization": token}, + // ExpectStatus: http.StatusBadRequest, + //}, + { + caseDesc: "delete route", + Object: MangerApiExpect(t), + Method: http.MethodDelete, + Path: "/apisix/admin/routes/1", + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "delete upstream", + Object: MangerApiExpect(t), + Method: http.MethodDelete, + Path: "/apisix/admin/upstreams/1", + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "hit the route just deleted", + Object: APISIXExpect(t), + Method: http.MethodGet, + Path: "/hello1", + ExpectStatus: http.StatusNotFound, + ExpectBody: "{\"error_msg\":\"404 Route Not Found\"}\n", + Sleep: sleepTime, + }, + } + + for _, tc := range tests { + testCaseCheck(tc) + } +}