mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Improving API tests
This commit is contained in:
committed by
James Jeffrey
parent
e0569192ee
commit
5b41fe2dc7
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitlab-odx.oracle.com/odx/functions/api/server"
|
||||
@@ -12,19 +11,19 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"github.com/funcy/functions_go/client"
|
||||
"github.com/funcy/functions_go/client/apps"
|
||||
"github.com/funcy/functions_go/client/routes"
|
||||
"github.com/funcy/functions_go/models"
|
||||
httptransport "github.com/go-openapi/runtime/client"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const lBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
func Host() string {
|
||||
apiURL := os.Getenv("API_URL")
|
||||
if apiURL == "" {
|
||||
@@ -45,18 +44,16 @@ func APIClient() *client.Functions {
|
||||
}
|
||||
|
||||
// create the API client, with the transport
|
||||
client := client.New(transport, strfmt.Default)
|
||||
|
||||
return client
|
||||
return client.New(transport, strfmt.Default)
|
||||
}
|
||||
|
||||
var (
|
||||
getServer sync.Once
|
||||
cancel2 context.CancelFunc
|
||||
s *server.Server
|
||||
)
|
||||
|
||||
func getServerWithCancel() (*server.Server, context.CancelFunc) {
|
||||
var cancel2 context.CancelFunc
|
||||
var s *server.Server
|
||||
getServer.Do(func() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
@@ -64,11 +61,15 @@ func getServerWithCancel() (*server.Server, context.CancelFunc) {
|
||||
viper.Set(server.EnvAPIURL, "http://localhost:8080")
|
||||
viper.Set(server.EnvLogLevel, "fatal")
|
||||
timeString := time.Now().Format("2006_01_02_15_04_05")
|
||||
db_url := os.Getenv("DB_URL")
|
||||
tmpDir := os.TempDir()
|
||||
tmpMq := fmt.Sprintf("%s/fn_integration_test_%s_worker_mq.db", tmpDir, timeString)
|
||||
tmpDB := fmt.Sprintf("%s/fn_integration_test_%s_fn.db", tmpDir, timeString)
|
||||
tmpDb := fmt.Sprintf("%s/fn_integration_test_%s_fn.db", tmpDir, timeString)
|
||||
viper.Set(server.EnvMQURL, fmt.Sprintf("bolt://%s", tmpMq))
|
||||
viper.Set(server.EnvDBURL, fmt.Sprintf("sqlite3://%s", tmpDB))
|
||||
if db_url == "" {
|
||||
db_url = fmt.Sprintf("sqlite3://%s", tmpDb)
|
||||
}
|
||||
viper.Set(server.EnvDBURL, db_url)
|
||||
|
||||
s = server.NewFromEnv(ctx)
|
||||
|
||||
@@ -79,6 +80,7 @@ func getServerWithCancel() (*server.Server, context.CancelFunc) {
|
||||
panic("Failed to start server.")
|
||||
}
|
||||
})
|
||||
log.Println(server.EnvAPIURL)
|
||||
_, err := http.Get(viper.GetString(server.EnvAPIURL) + "/version")
|
||||
for err != nil {
|
||||
_, err = http.Get(viper.GetString(server.EnvAPIURL) + "/version")
|
||||
@@ -87,7 +89,7 @@ func getServerWithCancel() (*server.Server, context.CancelFunc) {
|
||||
cancel2 = context.CancelFunc(func() {
|
||||
cancel()
|
||||
os.Remove(tmpMq)
|
||||
os.Remove(tmpDB)
|
||||
os.Remove(tmpDb)
|
||||
})
|
||||
})
|
||||
return s, cancel2
|
||||
@@ -107,12 +109,20 @@ type SuiteSetup struct {
|
||||
Cancel context.CancelFunc
|
||||
}
|
||||
|
||||
func RandStringBytes(n int) string {
|
||||
b := make([]byte, n)
|
||||
for i := range b {
|
||||
b[i] = lBytes[rand.Intn(len(lBytes))]
|
||||
}
|
||||
return strings.ToLower(string(b))
|
||||
}
|
||||
|
||||
func SetupDefaultSuite() *SuiteSetup {
|
||||
ss := &SuiteSetup{
|
||||
Context: context.Background(),
|
||||
Client: APIClient(),
|
||||
AppName: "test-app",
|
||||
RoutePath: "/hello",
|
||||
AppName: RandStringBytes(10),
|
||||
RoutePath: "/" + RandStringBytes(10),
|
||||
Image: "funcy/hello",
|
||||
Format: "default",
|
||||
RouteType: "async",
|
||||
@@ -137,353 +147,10 @@ func SetupDefaultSuite() *SuiteSetup {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ss
|
||||
}
|
||||
|
||||
func CheckAppResponseError(t *testing.T, err error) {
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
|
||||
case *apps.DeleteAppsAppDefault:
|
||||
msg := err.(*apps.DeleteAppsAppDefault).Payload.Error.Message
|
||||
code := err.(*apps.DeleteAppsAppDefault).Code()
|
||||
t.Fatalf("Unexpected error occurred: %v. Status code: %v", msg, code)
|
||||
return
|
||||
|
||||
case *apps.PostAppsDefault:
|
||||
msg := err.(*apps.PostAppsDefault).Payload.Error.Message
|
||||
code := err.(*apps.PostAppsDefault).Code()
|
||||
t.Fatalf("Unexpected error occurred: %v. Status code: %v", msg, code)
|
||||
return
|
||||
|
||||
case *apps.GetAppsAppNotFound:
|
||||
msg := err.(*apps.GetAppsAppNotFound).Payload.Error.Message
|
||||
if !strings.Contains("App not found", msg) {
|
||||
t.Fatalf("Unexpected error occurred: %v", msg)
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
case *apps.GetAppsAppDefault:
|
||||
msg := err.(*apps.GetAppsAppDefault).Payload.Error.Message
|
||||
code := err.(*apps.GetAppsAppDefault).Code()
|
||||
t.Fatalf("Unexpected error occurred: %v. Status code: %v", msg, code)
|
||||
return
|
||||
|
||||
case *apps.PatchAppsAppDefault:
|
||||
msg := err.(*apps.PatchAppsAppDefault).Payload.Error.Message
|
||||
code := err.(*apps.PatchAppsAppDefault).Code()
|
||||
t.Fatalf("Unexpected error occurred: %v. Status code: %v", msg, code)
|
||||
return
|
||||
|
||||
case *apps.PatchAppsAppNotFound:
|
||||
msg := err.(*apps.PatchAppsAppNotFound).Payload.Error.Message
|
||||
t.Fatalf("Unexpected error occurred: %v.", msg)
|
||||
return
|
||||
|
||||
case *apps.PatchAppsAppBadRequest:
|
||||
msg := err.(*apps.PatchAppsAppBadRequest).Payload.Error.Message
|
||||
t.Fatalf("Unexpected error occurred: %v.", msg)
|
||||
return
|
||||
}
|
||||
t.Fatalf("Unable to determine type of error: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func CreateAppNoAssert(ctx context.Context, fnclient *client.Functions, appName string, config map[string]string) (*apps.PostAppsOK, error) {
|
||||
cfg := &apps.PostAppsParams{
|
||||
Body: &models.AppWrapper{
|
||||
App: &models.App{
|
||||
Config: config,
|
||||
Name: appName,
|
||||
},
|
||||
},
|
||||
Context: ctx,
|
||||
}
|
||||
cfg.WithTimeout(time.Second * 60)
|
||||
return fnclient.Apps.PostApps(cfg)
|
||||
}
|
||||
|
||||
func CreateApp(t *testing.T, ctx context.Context, fnclient *client.Functions, appName string, config map[string]string) {
|
||||
appPayload, err := CreateAppNoAssert(ctx, fnclient, appName, config)
|
||||
CheckAppResponseError(t, err)
|
||||
if !strings.Contains(appName, appPayload.Payload.App.Name) {
|
||||
t.Fatalf("App name mismatch.\nExpected: %v\nActual: %v",
|
||||
appName, appPayload.Payload.App.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func UpdateApp(t *testing.T, ctx context.Context, fnclient *client.Functions, appName string, config map[string]string) *apps.PatchAppsAppOK {
|
||||
CreateApp(t, ctx, fnclient, appName, map[string]string{"A": "a"})
|
||||
cfg := &apps.PatchAppsAppParams{
|
||||
App: appName,
|
||||
Body: &models.AppWrapper{
|
||||
App: &models.App{
|
||||
Config: config,
|
||||
Name: "",
|
||||
},
|
||||
},
|
||||
Context: ctx,
|
||||
}
|
||||
appPayload, err := fnclient.Apps.PatchAppsApp(cfg)
|
||||
CheckAppResponseError(t, err)
|
||||
return appPayload
|
||||
}
|
||||
|
||||
func DeleteApp(t *testing.T, ctx context.Context, fnclient *client.Functions, appName string) {
|
||||
cfg := &apps.DeleteAppsAppParams{
|
||||
App: appName,
|
||||
Context: ctx,
|
||||
}
|
||||
cfg.WithTimeout(time.Second * 60)
|
||||
_, err := fnclient.Apps.DeleteAppsApp(cfg)
|
||||
CheckAppResponseError(t, err)
|
||||
}
|
||||
|
||||
func CheckRouteResponseError(t *testing.T, err error) {
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
|
||||
case *routes.PostAppsAppRoutesDefault:
|
||||
msg := err.(*routes.PostAppsAppRoutesDefault).Payload.Error.Message
|
||||
code := err.(*routes.PostAppsAppRoutesDefault).Code()
|
||||
t.Fatalf("Unexpected error occurred: %v. Status code: %v", msg, code)
|
||||
return
|
||||
|
||||
case *routes.PostAppsAppRoutesBadRequest:
|
||||
msg := err.(*routes.PostAppsAppRoutesBadRequest).Payload.Error.Message
|
||||
t.Fatalf("Unexpected error occurred: %v.", msg)
|
||||
return
|
||||
|
||||
case *routes.PostAppsAppRoutesConflict:
|
||||
msg := err.(*routes.PostAppsAppRoutesConflict).Payload.Error.Message
|
||||
t.Fatalf("Unexpected error occurred: %v.", msg)
|
||||
return
|
||||
|
||||
case *routes.GetAppsAppRoutesRouteNotFound:
|
||||
msg := err.(*routes.GetAppsAppRoutesRouteNotFound).Payload.Error.Message
|
||||
t.Fatalf("Unexpected error occurred: %v.", msg)
|
||||
return
|
||||
|
||||
case *routes.GetAppsAppRoutesRouteDefault:
|
||||
msg := err.(*routes.GetAppsAppRoutesRouteDefault).Payload.Error.Message
|
||||
code := err.(*routes.GetAppsAppRoutesRouteDefault).Code()
|
||||
t.Fatalf("Unexpected error occurred: %v. Status code: %v", msg, code)
|
||||
return
|
||||
|
||||
case *routes.DeleteAppsAppRoutesRouteNotFound:
|
||||
msg := err.(*routes.DeleteAppsAppRoutesRouteNotFound).Payload.Error.Message
|
||||
t.Fatalf("Unexpected error occurred: %v.", msg)
|
||||
return
|
||||
|
||||
case *routes.DeleteAppsAppRoutesRouteDefault:
|
||||
msg := err.(*routes.DeleteAppsAppRoutesRouteDefault).Payload.Error.Message
|
||||
code := err.(*routes.DeleteAppsAppRoutesRouteDefault).Code()
|
||||
t.Fatalf("Unexpected error occurred: %v. Status code: %v", msg, code)
|
||||
return
|
||||
case *routes.GetAppsAppRoutesNotFound:
|
||||
msg := err.(*routes.GetAppsAppRoutesNotFound).Payload.Error.Message
|
||||
t.Fatalf("Unexpected error occurred: %v.", msg)
|
||||
return
|
||||
|
||||
case *routes.GetAppsAppRoutesDefault:
|
||||
msg := err.(*routes.GetAppsAppRoutesDefault).Payload.Error.Message
|
||||
code := err.(*routes.GetAppsAppRoutesDefault).Code()
|
||||
t.Fatalf("Unexpected error occurred: %v. Status code: %v", msg, code)
|
||||
return
|
||||
|
||||
case *routes.PatchAppsAppRoutesRouteBadRequest:
|
||||
msg := err.(*routes.PatchAppsAppRoutesRouteBadRequest).Payload.Error.Message
|
||||
t.Fatalf("Unexpected error occurred: %v.", msg)
|
||||
return
|
||||
|
||||
case *routes.PatchAppsAppRoutesRouteNotFound:
|
||||
msg := err.(*routes.PatchAppsAppRoutesRouteNotFound).Payload.Error.Message
|
||||
t.Fatalf("Unexpected error occurred: %v.", msg)
|
||||
return
|
||||
|
||||
case *routes.PatchAppsAppRoutesRouteDefault:
|
||||
msg := err.(*routes.PatchAppsAppRoutesRouteDefault).Payload.Error.Message
|
||||
code := err.(*routes.PatchAppsAppRoutesRouteDefault).Code()
|
||||
t.Fatalf("Unexpected error occurred: %v. Status code: %v", msg, code)
|
||||
return
|
||||
|
||||
}
|
||||
t.Fatalf("Unable to determine type of error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func logRoute(t *testing.T, routeObject *models.Route) {
|
||||
t.Logf("Route path: %v", routeObject.Path)
|
||||
t.Logf("Route image: %v", routeObject.Image)
|
||||
t.Logf("Route type: %v", routeObject.Type)
|
||||
t.Logf("Route timeout: %vs", *routeObject.Timeout)
|
||||
t.Logf("Route idle timeout: %vs", *routeObject.IDLETimeout)
|
||||
}
|
||||
|
||||
func assertRouteFields(t *testing.T, routeObject *models.Route, path, image, routeType string) {
|
||||
|
||||
logRoute(t, routeObject)
|
||||
rPath := routeObject.Path
|
||||
rImage := routeObject.Image
|
||||
rType := routeObject.Type
|
||||
rTimeout := *routeObject.Timeout
|
||||
rIdleTimeout := *routeObject.IDLETimeout
|
||||
if rPath != path {
|
||||
t.Fatalf("Route path mismatch. Expected: %v. Actual: %v", path, rPath)
|
||||
}
|
||||
if rImage != image {
|
||||
t.Fatalf("Route image mismatch. Expected: %v. Actual: %v", image, rImage)
|
||||
}
|
||||
if rType != routeType {
|
||||
t.Fatalf("Route type mismatch. Expected: %v. Actual: %v", routeType, rType)
|
||||
}
|
||||
if rTimeout == 0 {
|
||||
t.Fatal("Route timeout should have default value of 30 seconds, but got 0 seconds")
|
||||
}
|
||||
if rIdleTimeout == 0 {
|
||||
t.Fatal("Route idle timeout should have default value of 30 seconds, but got 0 seconds")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func createRoute(ctx context.Context, fnclient *client.Functions, appName, image, routePath, routeType string, routeConfig map[string]string, headers map[string][]string) (*routes.PostAppsAppRoutesOK, error) {
|
||||
cfg := &routes.PostAppsAppRoutesParams{
|
||||
App: appName,
|
||||
Body: &models.RouteWrapper{
|
||||
Route: &models.Route{
|
||||
Config: routeConfig,
|
||||
Headers: headers,
|
||||
Image: image,
|
||||
Path: routePath,
|
||||
Type: routeType,
|
||||
},
|
||||
},
|
||||
Context: ctx,
|
||||
}
|
||||
cfg.WithTimeout(time.Second * 60)
|
||||
return fnclient.Routes.PostAppsAppRoutes(cfg)
|
||||
|
||||
}
|
||||
|
||||
func CreateRoute(t *testing.T, ctx context.Context, fnclient *client.Functions, appName, routePath, image, routeType string, routeConfig map[string]string, headers map[string][]string) {
|
||||
routeResponse, err := createRoute(ctx, fnclient, appName, image, routePath, routeType, routeConfig, headers)
|
||||
CheckRouteResponseError(t, err)
|
||||
|
||||
assertRouteFields(t, routeResponse.Payload.Route, routePath, image, routeType)
|
||||
}
|
||||
|
||||
func deleteRoute(ctx context.Context, fnclient *client.Functions, appName, routePath string) (*routes.DeleteAppsAppRoutesRouteOK, error) {
|
||||
cfg := &routes.DeleteAppsAppRoutesRouteParams{
|
||||
App: appName,
|
||||
Route: routePath,
|
||||
Context: ctx,
|
||||
}
|
||||
cfg.WithTimeout(time.Second * 60)
|
||||
return fnclient.Routes.DeleteAppsAppRoutesRoute(cfg)
|
||||
}
|
||||
|
||||
func DeleteRoute(t *testing.T, ctx context.Context, fnclient *client.Functions, appName, routePath string) {
|
||||
_, err := deleteRoute(ctx, fnclient, appName, routePath)
|
||||
CheckRouteResponseError(t, err)
|
||||
}
|
||||
|
||||
func ListRoutes(t *testing.T, ctx context.Context, fnclient *client.Functions, appName string) []*models.Route {
|
||||
cfg := &routes.GetAppsAppRoutesParams{
|
||||
App: appName,
|
||||
Context: ctx,
|
||||
}
|
||||
cfg.WithTimeout(time.Second * 60)
|
||||
routesResponse, err := fnclient.Routes.GetAppsAppRoutes(cfg)
|
||||
CheckRouteResponseError(t, err)
|
||||
return routesResponse.Payload.Routes
|
||||
}
|
||||
|
||||
func GetRoute(t *testing.T, ctx context.Context, fnclient *client.Functions, appName, routePath string) *models.Route {
|
||||
cfg := &routes.GetAppsAppRoutesRouteParams{
|
||||
App: appName,
|
||||
Route: routePath,
|
||||
Context: ctx,
|
||||
}
|
||||
cfg.WithTimeout(time.Second * 60)
|
||||
routeResponse, err := fnclient.Routes.GetAppsAppRoutesRoute(cfg)
|
||||
CheckRouteResponseError(t, err)
|
||||
return routeResponse.Payload.Route
|
||||
}
|
||||
|
||||
func UpdateRoute(t *testing.T, ctx context.Context, fnclient *client.Functions, appName, routePath, image, routeType, format string, memory int64, routeConfig map[string]string, headers map[string][]string, newRoutePath string) (*routes.PatchAppsAppRoutesRouteOK, error) {
|
||||
|
||||
routeObject := GetRoute(t, ctx, fnclient, appName, routePath)
|
||||
if routeObject.Config == nil {
|
||||
routeObject.Config = map[string]string{}
|
||||
}
|
||||
|
||||
if routeObject.Headers == nil {
|
||||
routeObject.Headers = map[string][]string{}
|
||||
}
|
||||
logRoute(t, routeObject)
|
||||
|
||||
routeObject.Path = ""
|
||||
if newRoutePath != "" {
|
||||
routeObject.Path = newRoutePath
|
||||
}
|
||||
|
||||
if routeConfig != nil {
|
||||
for k, v := range routeConfig {
|
||||
if string(k[0]) == "-" {
|
||||
delete(routeObject.Config, string(k[1:]))
|
||||
continue
|
||||
}
|
||||
routeObject.Config[k] = v
|
||||
}
|
||||
}
|
||||
if headers != nil {
|
||||
for k, v := range headers {
|
||||
if string(k[0]) == "-" {
|
||||
delete(routeObject.Headers, k)
|
||||
continue
|
||||
}
|
||||
routeObject.Headers[k] = v
|
||||
}
|
||||
}
|
||||
if image != "" {
|
||||
routeObject.Image = image
|
||||
}
|
||||
if format != "" {
|
||||
routeObject.Format = format
|
||||
}
|
||||
if routeType != "" {
|
||||
routeObject.Type = routeType
|
||||
}
|
||||
if memory > 0 {
|
||||
routeObject.Memory = memory
|
||||
}
|
||||
|
||||
cfg := &routes.PatchAppsAppRoutesRouteParams{
|
||||
App: appName,
|
||||
Context: ctx,
|
||||
Body: &models.RouteWrapper{
|
||||
Route: routeObject,
|
||||
},
|
||||
Route: routePath,
|
||||
}
|
||||
cfg.WithTimeout(time.Second * 60)
|
||||
|
||||
t.Log("Calling update")
|
||||
|
||||
return fnclient.Routes.PatchAppsAppRoutesRoute(cfg)
|
||||
}
|
||||
|
||||
func assertContainsRoute(routeModels []*models.Route, expectedRoute string) bool {
|
||||
for _, r := range routeModels {
|
||||
if r.Path == expectedRoute {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func EnvAsHeader(req *http.Request, selectedEnv []string) {
|
||||
detectedEnv := os.Environ()
|
||||
if len(selectedEnv) > 0 {
|
||||
|
||||
Reference in New Issue
Block a user