mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Adding JSON format validation API tests
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
@@ -34,7 +35,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
person := Person{}
|
person := Person{}
|
||||||
stderr.Encode(in.Body)
|
stderr.Encode(in.Body)
|
||||||
stderr.Encode(fmt.Sprintf(in.Body))
|
|
||||||
if len(in.Body) != 0 {
|
if len(in.Body) != 0 {
|
||||||
if err := json.NewDecoder(bytes.NewReader([]byte(in.Body))).Decode(&person); err != nil {
|
if err := json.NewDecoder(bytes.NewReader([]byte(in.Body))).Decode(&person); err != nil {
|
||||||
log.Fatalf("Unable to decode Person object data: %s", err.Error())
|
log.Fatalf("Unable to decode Person object data: %s", err.Error())
|
||||||
@@ -51,9 +51,13 @@ func main() {
|
|||||||
log.Fatalf("Unable to marshal JSON response body: %s", err.Error())
|
log.Fatalf("Unable to marshal JSON response body: %s", err.Error())
|
||||||
fmt.Fprintf(os.Stderr, err.Error())
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
}
|
}
|
||||||
|
h := http.Header{}
|
||||||
|
h.Set("Content-Type", "application/json")
|
||||||
|
h.Set("Content-Length", strconv.Itoa(len(b)))
|
||||||
out := &JSON{
|
out := &JSON{
|
||||||
StatusCode: http.StatusOK,
|
StatusCode: http.StatusOK,
|
||||||
Body: string(b),
|
Body: string(b),
|
||||||
|
Headers: h,
|
||||||
}
|
}
|
||||||
stderr.Encode(out)
|
stderr.Encode(out)
|
||||||
if err := stdout.Encode(out); err != nil {
|
if err := stdout.Encode(out); err != nil {
|
||||||
|
|||||||
8
test/fn-api-tests/fn/formats/json/go/Dockerfile
Normal file
8
test/fn-api-tests/fn/formats/json/go/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
FROM fnproject/go:dev as build-stage
|
||||||
|
WORKDIR /function
|
||||||
|
ADD . /src
|
||||||
|
RUN cd /src && go build -o func
|
||||||
|
FROM fnproject/go
|
||||||
|
WORKDIR /function
|
||||||
|
COPY --from=build-stage /src/func /function/
|
||||||
|
ENTRYPOINT ["./func"]
|
||||||
68
test/fn-api-tests/fn/formats/json/go/func.go
Normal file
68
test/fn-api-tests/fn/formats/json/go/func.go
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type JSON struct {
|
||||||
|
Headers http.Header `json:"headers"`
|
||||||
|
Body string `json:"body,omitempty"`
|
||||||
|
StatusCode int `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
stdin := json.NewDecoder(os.Stdin)
|
||||||
|
stdout := json.NewEncoder(os.Stdout)
|
||||||
|
stderr := json.NewEncoder(os.Stderr)
|
||||||
|
for {
|
||||||
|
in := &JSON{}
|
||||||
|
|
||||||
|
err := stdin.Decode(in)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to decode incoming data: %s", err.Error())
|
||||||
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
|
}
|
||||||
|
person := Person{}
|
||||||
|
stderr.Encode(in.Body)
|
||||||
|
if len(in.Body) != 0 {
|
||||||
|
if err := json.NewDecoder(bytes.NewReader([]byte(in.Body))).Decode(&person); err != nil {
|
||||||
|
log.Fatalf("Unable to decode Person object data: %s", err.Error())
|
||||||
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if person.Name == "" {
|
||||||
|
person.Name = "World"
|
||||||
|
}
|
||||||
|
|
||||||
|
mapResult := map[string]string{"message": fmt.Sprintf("Hello %s", person.Name)}
|
||||||
|
b, err := json.Marshal(mapResult)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Unable to marshal JSON response body: %s", err.Error())
|
||||||
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
|
}
|
||||||
|
h := http.Header{}
|
||||||
|
h.Set("Content-Type", "application/json")
|
||||||
|
h.Set("Content-Length", strconv.Itoa(len(b)))
|
||||||
|
out := &JSON{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Body: string(b),
|
||||||
|
Headers: h,
|
||||||
|
}
|
||||||
|
stderr.Encode(out)
|
||||||
|
if err := stdout.Encode(out); err != nil {
|
||||||
|
log.Fatalf("Unable to encode JSON response: %s", err.Error())
|
||||||
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
72
test/fn-api-tests/formats_test.go
Normal file
72
test/fn-api-tests/formats_test.go
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"net/url"
|
||||||
|
"path"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type JSONResponse struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFnFormats(t *testing.T) {
|
||||||
|
|
||||||
|
t.Run("test-json-format", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
s := SetupDefaultSuite()
|
||||||
|
|
||||||
|
// TODO(treeder): put image in fnproject @ dockerhub
|
||||||
|
image := "denismakogon/test-hot-json-go:0.0.1"
|
||||||
|
format := "json"
|
||||||
|
route := "/test-hot-json-go"
|
||||||
|
|
||||||
|
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
|
||||||
|
CreateRoute(t, s.Context, s.Client, s.AppName, route, image, "sync",
|
||||||
|
format, s.RouteConfig, s.RouteHeaders)
|
||||||
|
|
||||||
|
u := url.URL{
|
||||||
|
Scheme: "http",
|
||||||
|
Host: Host(),
|
||||||
|
}
|
||||||
|
u.Path = path.Join(u.Path, "r", s.AppName, s.RoutePath)
|
||||||
|
|
||||||
|
b, _ := json.Marshal(&struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}{
|
||||||
|
Name: "Jimmy",
|
||||||
|
})
|
||||||
|
content := bytes.NewBuffer(b)
|
||||||
|
output := &bytes.Buffer{}
|
||||||
|
headers, err := CallFN(u.String(), content, output, "POST", []string{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Got unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := &JSONResponse{}
|
||||||
|
json.Unmarshal(output.Bytes(), msg)
|
||||||
|
expectedOutput := "Hello Jimmy"
|
||||||
|
if !strings.Contains(expectedOutput, msg.Message) {
|
||||||
|
t.Errorf("Assertion error.\n\tExpected: %v\n\tActual: %v", expectedOutput, output.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedHeaderNames := []string{"Content-Type", "Content-Length"}
|
||||||
|
expectedHeaderValues := []string{"application/json; charset=utf-8", strconv.Itoa(output.Len())}
|
||||||
|
for i, name := range expectedHeaderNames {
|
||||||
|
actual := headers.Get(name)
|
||||||
|
expected := expectedHeaderValues[i]
|
||||||
|
if !strings.Contains(expected, actual) {
|
||||||
|
t.Errorf("HTTP header assertion error for %v."+
|
||||||
|
"\n\tExpected: %v\n\tActual: %v", name, expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteApp(t, s.Context, s.Client, s.AppName)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
@@ -89,7 +89,7 @@ func assertRouteFields(t *testing.T, routeObject *models.Route, path, image, rou
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createRoute(ctx context.Context, fnclient *client.Fn, appName, image, routePath, routeType string, routeConfig map[string]string, headers map[string][]string) (*routes.PostAppsAppRoutesOK, error) {
|
func createRoute(ctx context.Context, fnclient *client.Fn, appName, image, routePath, routeType, routeFormat string, routeConfig map[string]string, headers map[string][]string) (*routes.PostAppsAppRoutesOK, error) {
|
||||||
cfg := &routes.PostAppsAppRoutesParams{
|
cfg := &routes.PostAppsAppRoutesParams{
|
||||||
App: appName,
|
App: appName,
|
||||||
Body: &models.RouteWrapper{
|
Body: &models.RouteWrapper{
|
||||||
@@ -99,6 +99,7 @@ func createRoute(ctx context.Context, fnclient *client.Fn, appName, image, route
|
|||||||
Image: image,
|
Image: image,
|
||||||
Path: routePath,
|
Path: routePath,
|
||||||
Type: routeType,
|
Type: routeType,
|
||||||
|
Format: routeFormat,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
@@ -119,7 +120,7 @@ func createRoute(ctx context.Context, fnclient *client.Fn, appName, image, route
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateRoute(t *testing.T, ctx context.Context, fnclient *client.Fn, appName, routePath, image, routeType, routeFormat string, routeConfig map[string]string, headers map[string][]string) {
|
func CreateRoute(t *testing.T, ctx context.Context, fnclient *client.Fn, appName, routePath, image, routeType, routeFormat string, routeConfig map[string]string, headers map[string][]string) {
|
||||||
routeResponse, err := createRoute(ctx, fnclient, appName, image, routePath, routeType, routeConfig, headers)
|
routeResponse, err := createRoute(ctx, fnclient, appName, image, routePath, routeType, routeFormat, routeConfig, headers)
|
||||||
CheckRouteResponseError(t, err)
|
CheckRouteResponseError(t, err)
|
||||||
|
|
||||||
assertRouteFields(t, routeResponse.Payload.Route, routePath, image, routeType, routeFormat)
|
assertRouteFields(t, routeResponse.Payload.Route, routePath, image, routeType, routeFormat)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func TestRoutes(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
s := SetupDefaultSuite()
|
s := SetupDefaultSuite()
|
||||||
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
|
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
|
||||||
_, err := createRoute(s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "",
|
_, err := createRoute(s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "", s.Format,
|
||||||
s.RouteConfig, s.RouteHeaders)
|
s.RouteConfig, s.RouteHeaders)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Should fail with Invalid route Type.")
|
t.Errorf("Should fail with Invalid route Type.")
|
||||||
@@ -128,7 +128,8 @@ func TestRoutes(t *testing.T) {
|
|||||||
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, s.RouteType,
|
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, s.RouteType,
|
||||||
s.Format, s.RouteConfig, s.RouteHeaders)
|
s.Format, s.RouteConfig, s.RouteHeaders)
|
||||||
|
|
||||||
_, err := createRoute(s.Context, s.Client, s.AppName, s.Image, s.RoutePath, newRouteType, s.RouteConfig, s.RouteHeaders)
|
_, err := createRoute(s.Context, s.Client, s.AppName, s.Image, s.RoutePath,
|
||||||
|
newRouteType, s.Format, s.RouteConfig, s.RouteHeaders)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Route duplicate error should appear, but it didn't")
|
t.Errorf("Route duplicate error should appear, but it didn't")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user