mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-10 23:20:20 +00:00
445 lines
10 KiB
Go
445 lines
10 KiB
Go
|
// Copyright 2015 go-swagger maintainers
|
||
|
//
|
||
|
// 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 swag
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"net/http"
|
||
|
"net/http/httptest"
|
||
|
"testing"
|
||
|
|
||
|
yaml "gopkg.in/yaml.v2"
|
||
|
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
)
|
||
|
|
||
|
type failJSONMarhal struct {
|
||
|
}
|
||
|
|
||
|
func (f failJSONMarhal) MarshalJSON() ([]byte, error) {
|
||
|
return nil, errors.New("expected")
|
||
|
}
|
||
|
|
||
|
func TestLoadHTTPBytes(t *testing.T) {
|
||
|
_, err := LoadFromFileOrHTTP("httx://12394:abd")
|
||
|
assert.Error(t, err)
|
||
|
|
||
|
serv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||
|
rw.WriteHeader(http.StatusNotFound)
|
||
|
}))
|
||
|
defer serv.Close()
|
||
|
|
||
|
_, err = LoadFromFileOrHTTP(serv.URL)
|
||
|
assert.Error(t, err)
|
||
|
|
||
|
ts2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||
|
rw.WriteHeader(http.StatusOK)
|
||
|
rw.Write([]byte("the content"))
|
||
|
}))
|
||
|
defer ts2.Close()
|
||
|
|
||
|
d, err := LoadFromFileOrHTTP(ts2.URL)
|
||
|
assert.NoError(t, err)
|
||
|
assert.Equal(t, []byte("the content"), d)
|
||
|
}
|
||
|
|
||
|
func TestYAMLToJSON(t *testing.T) {
|
||
|
|
||
|
sd := `---
|
||
|
1: the int key value
|
||
|
name: a string value
|
||
|
'y': some value
|
||
|
`
|
||
|
var data yaml.MapSlice
|
||
|
yaml.Unmarshal([]byte(sd), &data)
|
||
|
|
||
|
d, err := YAMLToJSON(data)
|
||
|
if assert.NoError(t, err) {
|
||
|
assert.Equal(t, `{"1":"the int key value","name":"a string value","y":"some value"}`, string(d))
|
||
|
}
|
||
|
|
||
|
data = append(data, yaml.MapItem{Key: true, Value: "the bool value"})
|
||
|
d, err = YAMLToJSON(data)
|
||
|
assert.Error(t, err)
|
||
|
assert.Nil(t, d)
|
||
|
|
||
|
data = data[:len(data)-1]
|
||
|
|
||
|
tag := yaml.MapSlice{{Key: "name", Value: "tag name"}}
|
||
|
data = append(data, yaml.MapItem{Key: "tag", Value: tag})
|
||
|
|
||
|
d, err = YAMLToJSON(data)
|
||
|
assert.NoError(t, err)
|
||
|
assert.Equal(t, `{"1":"the int key value","name":"a string value","y":"some value","tag":{"name":"tag name"}}`, string(d))
|
||
|
|
||
|
tag = yaml.MapSlice{{Key: true, Value: "bool tag name"}}
|
||
|
data = append(data[:len(data)-1], yaml.MapItem{Key: "tag", Value: tag})
|
||
|
|
||
|
d, err = YAMLToJSON(data)
|
||
|
assert.Error(t, err)
|
||
|
assert.Nil(t, d)
|
||
|
|
||
|
var lst []interface{}
|
||
|
lst = append(lst, "hello")
|
||
|
|
||
|
d, err = YAMLToJSON(lst)
|
||
|
assert.NoError(t, err)
|
||
|
assert.Equal(t, []byte(`["hello"]`), []byte(d))
|
||
|
|
||
|
lst = append(lst, data)
|
||
|
|
||
|
d, err = YAMLToJSON(lst)
|
||
|
assert.Error(t, err)
|
||
|
assert.Nil(t, d)
|
||
|
|
||
|
// _, err := yamlToJSON(failJSONMarhal{})
|
||
|
// assert.Error(t, err)
|
||
|
|
||
|
_, err = BytesToYAMLDoc([]byte("- name: hello\n"))
|
||
|
assert.Error(t, err)
|
||
|
|
||
|
dd, err := BytesToYAMLDoc([]byte("description: 'object created'\n"))
|
||
|
assert.NoError(t, err)
|
||
|
|
||
|
d, err = YAMLToJSON(dd)
|
||
|
assert.NoError(t, err)
|
||
|
assert.Equal(t, json.RawMessage(`{"description":"object created"}`), d)
|
||
|
}
|
||
|
|
||
|
func TestLoadStrategy(t *testing.T) {
|
||
|
|
||
|
loader := func(p string) ([]byte, error) {
|
||
|
return []byte(yamlPetStore), nil
|
||
|
}
|
||
|
remLoader := func(p string) ([]byte, error) {
|
||
|
return []byte("not it"), nil
|
||
|
}
|
||
|
|
||
|
ld := LoadStrategy("blah", loader, remLoader)
|
||
|
b, _ := ld("")
|
||
|
assert.Equal(t, []byte(yamlPetStore), b)
|
||
|
|
||
|
serv := httptest.NewServer(http.HandlerFunc(yamlPestoreServer))
|
||
|
defer serv.Close()
|
||
|
|
||
|
s, err := YAMLDoc(serv.URL)
|
||
|
assert.NoError(t, err)
|
||
|
assert.NotNil(t, s)
|
||
|
|
||
|
ts2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||
|
rw.WriteHeader(http.StatusNotFound)
|
||
|
rw.Write([]byte("\n"))
|
||
|
}))
|
||
|
defer ts2.Close()
|
||
|
_, err = YAMLDoc(ts2.URL)
|
||
|
assert.Error(t, err)
|
||
|
}
|
||
|
|
||
|
var yamlPestoreServer = func(rw http.ResponseWriter, r *http.Request) {
|
||
|
rw.WriteHeader(http.StatusOK)
|
||
|
rw.Write([]byte(yamlPetStore))
|
||
|
}
|
||
|
|
||
|
func TestWithYKey(t *testing.T) {
|
||
|
doc, err := BytesToYAMLDoc([]byte(withYKey))
|
||
|
if assert.NoError(t, err) {
|
||
|
_, err := YAMLToJSON(doc)
|
||
|
if assert.Error(t, err) {
|
||
|
doc, err := BytesToYAMLDoc([]byte(withQuotedYKey))
|
||
|
if assert.NoError(t, err) {
|
||
|
jsond, err := YAMLToJSON(doc)
|
||
|
if assert.NoError(t, err) {
|
||
|
var yt struct {
|
||
|
Definitions struct {
|
||
|
Viewbox struct {
|
||
|
Properties struct {
|
||
|
Y struct {
|
||
|
Type string `json:"type"`
|
||
|
} `json:"y"`
|
||
|
} `json:"properties"`
|
||
|
} `json:"viewbox"`
|
||
|
} `json:"definitions"`
|
||
|
}
|
||
|
if assert.NoError(t, json.Unmarshal(jsond, &yt)) {
|
||
|
assert.Equal(t, "integer", yt.Definitions.Viewbox.Properties.Y.Type)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const withQuotedYKey = `consumes:
|
||
|
- application/json
|
||
|
definitions:
|
||
|
viewBox:
|
||
|
type: object
|
||
|
properties:
|
||
|
x:
|
||
|
type: integer
|
||
|
format: int16
|
||
|
# y -> types don't match: expect map key string or int get: bool
|
||
|
"y":
|
||
|
type: integer
|
||
|
format: int16
|
||
|
width:
|
||
|
type: integer
|
||
|
format: int16
|
||
|
height:
|
||
|
type: integer
|
||
|
format: int16
|
||
|
info:
|
||
|
description: Test RESTful APIs
|
||
|
title: Test Server
|
||
|
version: 1.0.0
|
||
|
basePath: /api
|
||
|
paths:
|
||
|
/test:
|
||
|
get:
|
||
|
operationId: findAll
|
||
|
parameters:
|
||
|
- name: since
|
||
|
in: query
|
||
|
type: integer
|
||
|
format: int64
|
||
|
- name: limit
|
||
|
in: query
|
||
|
type: integer
|
||
|
format: int32
|
||
|
default: 20
|
||
|
responses:
|
||
|
200:
|
||
|
description: Array[Trigger]
|
||
|
schema:
|
||
|
type: array
|
||
|
items:
|
||
|
$ref: "#/definitions/viewBox"
|
||
|
produces:
|
||
|
- application/json
|
||
|
schemes:
|
||
|
- https
|
||
|
swagger: "2.0"
|
||
|
`
|
||
|
|
||
|
const withYKey = `consumes:
|
||
|
- application/json
|
||
|
definitions:
|
||
|
viewBox:
|
||
|
type: object
|
||
|
properties:
|
||
|
x:
|
||
|
type: integer
|
||
|
format: int16
|
||
|
# y -> types don't match: expect map key string or int get: bool
|
||
|
y:
|
||
|
type: integer
|
||
|
format: int16
|
||
|
width:
|
||
|
type: integer
|
||
|
format: int16
|
||
|
height:
|
||
|
type: integer
|
||
|
format: int16
|
||
|
info:
|
||
|
description: Test RESTful APIs
|
||
|
title: Test Server
|
||
|
version: 1.0.0
|
||
|
basePath: /api
|
||
|
paths:
|
||
|
/test:
|
||
|
get:
|
||
|
operationId: findAll
|
||
|
parameters:
|
||
|
- name: since
|
||
|
in: query
|
||
|
type: integer
|
||
|
format: int64
|
||
|
- name: limit
|
||
|
in: query
|
||
|
type: integer
|
||
|
format: int32
|
||
|
default: 20
|
||
|
responses:
|
||
|
200:
|
||
|
description: Array[Trigger]
|
||
|
schema:
|
||
|
type: array
|
||
|
items:
|
||
|
$ref: "#/definitions/viewBox"
|
||
|
produces:
|
||
|
- application/json
|
||
|
schemes:
|
||
|
- https
|
||
|
swagger: "2.0"
|
||
|
`
|
||
|
|
||
|
const yamlPetStore = `swagger: '2.0'
|
||
|
info:
|
||
|
version: '1.0.0'
|
||
|
title: Swagger Petstore
|
||
|
description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification
|
||
|
termsOfService: http://helloreverb.com/terms/
|
||
|
contact:
|
||
|
name: Swagger API team
|
||
|
email: foo@example.com
|
||
|
url: http://swagger.io
|
||
|
license:
|
||
|
name: MIT
|
||
|
url: http://opensource.org/licenses/MIT
|
||
|
host: petstore.swagger.wordnik.com
|
||
|
basePath: /api
|
||
|
schemes:
|
||
|
- http
|
||
|
consumes:
|
||
|
- application/json
|
||
|
produces:
|
||
|
- application/json
|
||
|
paths:
|
||
|
/pets:
|
||
|
get:
|
||
|
description: Returns all pets from the system that the user has access to
|
||
|
operationId: findPets
|
||
|
produces:
|
||
|
- application/json
|
||
|
- application/xml
|
||
|
- text/xml
|
||
|
- text/html
|
||
|
parameters:
|
||
|
- name: tags
|
||
|
in: query
|
||
|
description: tags to filter by
|
||
|
required: false
|
||
|
type: array
|
||
|
items:
|
||
|
type: string
|
||
|
collectionFormat: csv
|
||
|
- name: limit
|
||
|
in: query
|
||
|
description: maximum number of results to return
|
||
|
required: false
|
||
|
type: integer
|
||
|
format: int32
|
||
|
responses:
|
||
|
'200':
|
||
|
description: pet response
|
||
|
schema:
|
||
|
type: array
|
||
|
items:
|
||
|
$ref: '#/definitions/pet'
|
||
|
default:
|
||
|
description: unexpected error
|
||
|
schema:
|
||
|
$ref: '#/definitions/errorModel'
|
||
|
post:
|
||
|
description: Creates a new pet in the store. Duplicates are allowed
|
||
|
operationId: addPet
|
||
|
produces:
|
||
|
- application/json
|
||
|
parameters:
|
||
|
- name: pet
|
||
|
in: body
|
||
|
description: Pet to add to the store
|
||
|
required: true
|
||
|
schema:
|
||
|
$ref: '#/definitions/newPet'
|
||
|
responses:
|
||
|
'200':
|
||
|
description: pet response
|
||
|
schema:
|
||
|
$ref: '#/definitions/pet'
|
||
|
default:
|
||
|
description: unexpected error
|
||
|
schema:
|
||
|
$ref: '#/definitions/errorModel'
|
||
|
/pets/{id}:
|
||
|
get:
|
||
|
description: Returns a user based on a single ID, if the user does not have access to the pet
|
||
|
operationId: findPetById
|
||
|
produces:
|
||
|
- application/json
|
||
|
- application/xml
|
||
|
- text/xml
|
||
|
- text/html
|
||
|
parameters:
|
||
|
- name: id
|
||
|
in: path
|
||
|
description: ID of pet to fetch
|
||
|
required: true
|
||
|
type: integer
|
||
|
format: int64
|
||
|
responses:
|
||
|
'200':
|
||
|
description: pet response
|
||
|
schema:
|
||
|
$ref: '#/definitions/pet'
|
||
|
default:
|
||
|
description: unexpected error
|
||
|
schema:
|
||
|
$ref: '#/definitions/errorModel'
|
||
|
delete:
|
||
|
description: deletes a single pet based on the ID supplied
|
||
|
operationId: deletePet
|
||
|
parameters:
|
||
|
- name: id
|
||
|
in: path
|
||
|
description: ID of pet to delete
|
||
|
required: true
|
||
|
type: integer
|
||
|
format: int64
|
||
|
responses:
|
||
|
'204':
|
||
|
description: pet deleted
|
||
|
default:
|
||
|
description: unexpected error
|
||
|
schema:
|
||
|
$ref: '#/definitions/errorModel'
|
||
|
definitions:
|
||
|
pet:
|
||
|
required:
|
||
|
- id
|
||
|
- name
|
||
|
properties:
|
||
|
id:
|
||
|
type: integer
|
||
|
format: int64
|
||
|
name:
|
||
|
type: string
|
||
|
tag:
|
||
|
type: string
|
||
|
newPet:
|
||
|
allOf:
|
||
|
- $ref: '#/definitions/pet'
|
||
|
- required:
|
||
|
- name
|
||
|
properties:
|
||
|
id:
|
||
|
type: integer
|
||
|
format: int64
|
||
|
name:
|
||
|
type: string
|
||
|
errorModel:
|
||
|
required:
|
||
|
- code
|
||
|
- message
|
||
|
properties:
|
||
|
code:
|
||
|
type: integer
|
||
|
format: int32
|
||
|
message:
|
||
|
type: string
|
||
|
`
|