blob: 4f28cfee4968b883c011861409c80e65395c9b76 [file] [log] [blame]
/*
* 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 data_loader_test
import (
"encoding/json"
"net/http"
"path/filepath"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/savsgio/gotils/bytes"
"github.com/tidwall/gjson"
"github.com/apisix/manager-api/test/e2e/base"
)
var _ = Describe("OpenAPI 3", func() {
DescribeTable("Import cases",
func(f func()) {
f()
},
Entry("default.yaml", func() {
path, err := filepath.Abs("../../testdata/import/default.yaml")
Expect(err).To(BeNil())
req := base.ManagerApiExpect().POST("/apisix/admin/import/routes")
req.WithMultipart().WithForm(map[string]string{
"type": "openapi3",
"task_name": "test_default_yaml",
"_file": "default.yaml",
})
req.WithMultipart().WithFile("file", path)
req.WithHeader("Authorization", base.GetToken())
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("code").Uint()).To(Equal(uint64(0)))
r = r.Get("data")
for s, result := range r.Map() {
if s == "route" {
Expect(result.Get("total").Uint()).To(Equal(uint64(1)))
Expect(result.Get("failed").Uint()).To(Equal(uint64(0)))
}
}
}),
Entry("default.json", func() {
path, err := filepath.Abs("../../testdata/import/default.json")
Expect(err).To(BeNil())
req := base.ManagerApiExpect().POST("/apisix/admin/import/routes")
req.WithMultipart().WithForm(map[string]string{
"type": "openapi3",
"task_name": "test_default_json",
"_file": "default.json",
})
req.WithMultipart().WithFile("file", path)
req.WithHeader("Authorization", base.GetToken())
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("code").Uint()).To(Equal(uint64(0)))
r = r.Get("data")
for s, result := range r.Map() {
if s == "route" {
Expect(result.Get("total").Uint()).To(Equal(uint64(1)))
Expect(result.Get("failed").Uint()).To(Equal(uint64(0)))
}
}
}),
Entry("Postman-API101.yaml merge method", func() {
path, err := filepath.Abs("../../testdata/import/Postman-API101.yaml")
Expect(err).To(BeNil())
req := base.ManagerApiExpect().POST("/apisix/admin/import/routes")
req.WithMultipart().WithForm(map[string]string{
"type": "openapi3",
"task_name": "test_postman_api101_yaml_mm",
"_file": "Postman-API101.yaml",
"merge_method": "true",
})
req.WithMultipart().WithFile("file", path)
req.WithHeader("Authorization", base.GetToken())
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("code").Uint()).To(Equal(uint64(0)))
r = r.Get("data")
for s, result := range r.Map() {
if s == "route" {
Expect(result.Get("total").Uint()).To(Equal(uint64(3)))
Expect(result.Get("failed").Uint()).To(Equal(uint64(0)))
}
if s == "upstream" {
Expect(result.Get("total").Uint()).To(Equal(uint64(1)))
Expect(result.Get("failed").Uint()).To(Equal(uint64(0)))
}
}
}),
Entry("Postman-API101.yaml non-merge method", func() {
// clean routes
base.CleanResource("routes")
path, err := filepath.Abs("../../testdata/import/Postman-API101.yaml")
Expect(err).To(BeNil())
req := base.ManagerApiExpect().POST("/apisix/admin/import/routes")
req.WithMultipart().WithForm(map[string]string{
"type": "openapi3",
"task_name": "test_postman_api101_yaml_nmm",
"_file": "Postman-API101.yaml",
"merge_method": "false",
})
req.WithMultipart().WithFile("file", path)
req.WithHeader("Authorization", base.GetToken())
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("code").Uint()).To(Equal(uint64(0)))
r = r.Get("data")
for s, result := range r.Map() {
if s == "route" {
Expect(result.Get("total").Uint()).To(Equal(uint64(5)))
Expect(result.Get("failed").Uint()).To(Equal(uint64(0)))
}
if s == "upstream" {
Expect(result.Get("total").Uint()).To(Equal(uint64(1)))
Expect(result.Get("failed").Uint()).To(Equal(uint64(0)))
}
}
}),
Entry("Clean resources", func() {
base.CleanResource("routes")
base.CleanResource("upstreams")
base.CleanResource("services")
}),
)
DescribeTable("Exception cases",
func(f func()) {
f()
},
Entry("Empty upload file", func() {
req := base.ManagerApiExpect().POST("/apisix/admin/import/routes")
req.WithMultipart().WithForm(map[string]string{
"type": "openapi3",
"task_name": "empty_upload",
"_file": "default.yaml",
})
req.WithHeader("Authorization", base.GetToken())
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("code").Uint()).To(Equal(uint64(10000)))
Expect(r.Get("message").String()).To(Equal("uploaded file is empty"))
}),
Entry("Exceed limit upload file", func() {
req := base.ManagerApiExpect().POST("/apisix/admin/import/routes")
req.WithMultipart().WithForm(map[string]string{
"type": "openapi3",
"task_name": "exceed_limit_upload",
"_file": "default.yaml",
})
req.WithMultipart().WithFileBytes("file", "default.yaml", bytes.Rand(make([]byte, 10*1024*1024+1)))
req.WithHeader("Authorization", base.GetToken())
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("code").Uint()).To(Equal(uint64(10000)))
Expect(r.Get("message").String()).To(Equal("uploaded file size exceeds the limit, limit is 10485760"))
}),
Entry("Routes duplicate #1", func() {
path, err := filepath.Abs("../../testdata/import/Postman-API101.yaml")
Expect(err).To(BeNil())
req := base.ManagerApiExpect().POST("/apisix/admin/import/routes")
req.WithMultipart().WithForm(map[string]string{
"type": "openapi3",
"task_name": "duplicate",
"_file": "Postman-API101.yaml",
"merge_method": "true",
})
req.WithMultipart().WithFile("file", path)
req.WithHeader("Authorization", base.GetToken())
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("code").Uint()).To(Equal(uint64(0)))
}),
Entry("Route duplicate #2", func() {
path, err := filepath.Abs("../../testdata/import/Postman-API101.yaml")
Expect(err).To(BeNil())
req := base.ManagerApiExpect().POST("/apisix/admin/import/routes")
req.WithMultipart().WithForm(map[string]string{
"type": "openapi3",
"task_name": "duplicate",
"_file": "Postman-API101.yaml",
"merge_method": "true",
})
req.WithMultipart().WithFile("file", path)
req.WithHeader("Authorization", base.GetToken())
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("code").Uint()).To(Equal(uint64(0)))
Expect(r.Get("data").Map()["route"].Get("failed").Uint()).To(Equal(uint64(1)))
Expect(r.Get("data").Map()["route"].Get("errors").Array()[0].String()).
To(ContainSubstring("is duplicated with route duplicate_"))
}),
Entry("Clean resources", func() {
base.CleanResource("routes")
base.CleanResource("upstreams")
base.CleanResource("services")
}),
)
DescribeTable("Real API cases",
func(f func()) {
f()
},
Entry("Import httpbin.org YAML", func() {
path, err := filepath.Abs("../../testdata/import/httpbin.yaml")
Expect(err).To(BeNil())
req := base.ManagerApiExpect().POST("/apisix/admin/import/routes")
req.WithMultipart().WithForm(map[string]string{
"type": "openapi3",
"task_name": "httpbin",
"_file": "httpbin.yaml",
})
req.WithMultipart().WithFile("file", path)
req.WithHeader("Authorization", base.GetToken())
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("code").Uint()).To(Equal(uint64(0)))
r = r.Get("data")
for s, result := range r.Map() {
if s == "route" {
Expect(result.Get("total").Uint()).To(Equal(uint64(1)))
Expect(result.Get("failed").Uint()).To(Equal(uint64(0)))
}
}
}),
Entry("Modify upstream", func() {
body := make(map[string]interface{})
body["nodes"] = []map[string]interface{}{
{
"host": "httpbin.org",
"port": 80,
"weight": 1,
},
}
body["type"] = "roundrobin"
_body, err := json.Marshal(body)
Expect(err).To(BeNil())
base.RunTestCase(base.HttpTestCase{
Object: base.ManagerApiExpect(),
Method: http.MethodPatch,
Path: "/apisix/admin/upstreams/httpbin",
Body: string(_body),
Headers: map[string]string{"Authorization": base.GetToken()},
ExpectStatus: http.StatusOK,
})
}),
Entry("Enable route", func() {
// get route id
req := base.ManagerApiExpect().GET("/apisix/admin/routes")
req.WithHeader("Authorization", base.GetToken())
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("code").Uint()).To(Equal(uint64(0)))
id := r.Get("data").Get("rows").Array()[0].Get("id").String()
body := make(map[string]interface{})
body["status"] = 1
_body, err := json.Marshal(body)
Expect(err).To(BeNil())
base.RunTestCase(base.HttpTestCase{
Object: base.ManagerApiExpect(),
Method: http.MethodPatch,
Path: "/apisix/admin/routes/" + id,
Body: string(_body),
Headers: map[string]string{"Authorization": base.GetToken()},
ExpectStatus: http.StatusOK,
Sleep: base.SleepTime,
})
}),
Entry("Request API", func() {
req := base.APISIXExpect().GET("/get")
resp := req.Expect()
resp.Status(http.StatusOK)
r := gjson.ParseBytes([]byte(resp.Body().Raw()))
Expect(r.Get("headers").Get("User-Agent").String()).To(Equal("Go-http-client/1.1"))
}),
)
})