Rewrite HTTP handler for routes HTTP POST/PUT/PATCH methods

- adding tests for HTTP PUT
 - more tests for HTTP PATCH
This commit is contained in:
Denis Makogon
2017-08-16 13:55:30 +03:00
parent d11bafb868
commit 62d650f0a5
9 changed files with 226 additions and 93 deletions

View File

@@ -11,6 +11,8 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var bad routeResponse
/* handleRouteCreateOrUpdate is used to handle POST PUT and PATCH for routes. /* handleRouteCreateOrUpdate is used to handle POST PUT and PATCH for routes.
Post will only create route if its not there and create app if its not. Post will only create route if its not there and create app if its not.
create only create only
@@ -22,41 +24,102 @@ import (
update only update only
Patch accepts partial updates / skips validation of zero values. Patch accepts partial updates / skips validation of zero values.
*/ */
func (s *Server) handleRouteCreateOrUpdate(c *gin.Context) { func (s *Server) handleRoutesPostPutPatch(c *gin.Context) {
ctx := c.Request.Context() ctx := c.Request.Context()
method := strings.ToUpper(c.Request.Method) method := strings.ToUpper(c.Request.Method)
var wroute models.RouteWrapper var wroute models.RouteWrapper
err := bindRoute(c, method, &wroute)
err := s.bindAndValidate(c, method, &wroute)
if err != nil { if err != nil {
handleErrorResponse(c, err) handleErrorResponse(c, err)
return return
} }
if method != http.MethodPatch {
// Create the app if it does not exist.
err = s.ensureApp(ctx, &wroute, method) err = s.ensureApp(ctx, &wroute, method)
if err != nil { if err != nil {
handleErrorResponse(c, err) handleErrorResponse(c, err)
return return
} }
}
resp, err := s.updateOrInsertRoute(ctx, method, wroute) resp, err := s.ensureRoute(ctx, method, &wroute)
if err != nil { if err != nil {
handleErrorResponse(c, err) handleErrorResponse(c, err)
return return
} }
s.cachedelete(resp.Route.AppName, resp.Route.Path) s.cachedelete(resp.Route.AppName, resp.Route.Path)
c.JSON(http.StatusOK, resp) c.JSON(http.StatusOK, resp)
} }
func (s *Server) submitRoute(ctx context.Context, wroute *models.RouteWrapper) error {
err := s.setDefaultsAndValidate(wroute)
if err != nil {
return err
}
r, err := s.Datastore.InsertRoute(ctx, wroute.Route)
if err != nil {
return err
}
wroute.Route = r
return nil
}
func (s *Server) changeRoute(ctx context.Context, wroute *models.RouteWrapper) error {
err := wroute.Validate(true)
if err != nil {
return err
}
r, err := s.Datastore.UpdateRoute(ctx, wroute.Route)
if err != nil {
return err
}
wroute.Route = r
return nil
}
// ensureApp will only execute if it is on put
func (s *Server) ensureRoute(ctx context.Context, method string, wroute *models.RouteWrapper) (routeResponse, error) {
resp := routeResponse{"Route successfully created", nil}
up := routeResponse{"Route successfully updated", nil}
switch method {
case http.MethodPost:
err := s.submitRoute(ctx, wroute)
if err != nil {
return bad, err
}
resp.Route = wroute.Route
return resp, nil
case http.MethodPut:
_, err := s.Datastore.GetRoute(ctx, wroute.Route.AppName, wroute.Route.Path)
if err != nil && err == models.ErrRoutesNotFound {
err := s.submitRoute(ctx, wroute)
if err != nil {
return bad, err
}
resp.Route = wroute.Route
return resp, nil
} else {
err := s.changeRoute(ctx, wroute)
if err != nil {
return bad, err
}
up.Route = wroute.Route
return up, nil
}
case http.MethodPatch:
err := s.changeRoute(ctx, wroute)
if err != nil {
return bad, err
}
up.Route = wroute.Route
return up, nil
}
return bad, nil
}
// ensureApp will only execute if it is on post or put. Patch is not allowed to create apps. // ensureApp will only execute if it is on post or put. Patch is not allowed to create apps.
func (s *Server) ensureApp(ctx context.Context, wroute *models.RouteWrapper, method string) error { func (s *Server) ensureApp(ctx context.Context, wroute *models.RouteWrapper, method string) error {
if !(method == http.MethodPost || method == http.MethodPut) {
return nil
}
app, err := s.Datastore.GetApp(ctx, wroute.Route.AppName) app, err := s.Datastore.GetApp(ctx, wroute.Route.AppName)
if err != nil && err != models.ErrAppsNotFound { if err != nil && err != models.ErrAppsNotFound {
return err return err
@@ -86,11 +149,8 @@ func (s *Server) ensureApp(ctx context.Context, wroute *models.RouteWrapper, met
return nil return nil
} }
/* bindAndValidate binds the RouteWrapper to the json from the request and validates that it is correct. // bindRoute binds the RouteWrapper to the json from the request.
If it is a put or patch it makes sure that the path in the url matches the provideed one in the body. func bindRoute(c *gin.Context, method string, wroute *models.RouteWrapper) error {
Defaults are set and if patch skipZero is true for validating the RouteWrapper
*/
func (s *Server) bindAndValidate(c *gin.Context, method string, wroute *models.RouteWrapper) error {
err := c.BindJSON(wroute) err := c.BindJSON(wroute)
if err != nil { if err != nil {
return models.ErrInvalidJSON return models.ErrInvalidJSON
@@ -109,35 +169,15 @@ func (s *Server) bindAndValidate(c *gin.Context, method string, wroute *models.R
} }
wroute.Route.Path = p wroute.Route.Path = p
} }
if method == http.MethodPost {
if wroute.Route.Path == "" {
return models.ErrRoutesValidationMissingPath
}
}
return nil
}
if method != http.MethodPatch { func (s *Server) setDefaultsAndValidate(wroute *models.RouteWrapper) error {
wroute.Route.SetDefaults() wroute.Route.SetDefaults()
} return wroute.Validate(false)
return wroute.Validate(method == http.MethodPatch)
}
// updateOrInsertRoute will either update or insert the route respective the method.
func (s *Server) updateOrInsertRoute(ctx context.Context, method string, wroute models.RouteWrapper) (routeResponse, error) {
var route *models.Route
var err error
resp := routeResponse{"Route successfully created", nil}
up := routeResponse{"Route successfully updated", nil}
switch method {
case http.MethodPost:
route, err = s.Datastore.InsertRoute(ctx, wroute.Route)
case http.MethodPut:
route, err = s.Datastore.UpdateRoute(ctx, wroute.Route)
if err == models.ErrRoutesNotFound {
// try insert then
route, err = s.Datastore.InsertRoute(ctx, wroute.Route)
}
case http.MethodPatch:
// When patching if there is an error around the app we will return one and the update fails.
route, err = s.Datastore.UpdateRoute(ctx, wroute.Route)
resp = up
}
resp.Route = route
return resp, err
} }

View File

@@ -100,15 +100,6 @@ func TestRoutePut(t *testing.T) {
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "funcy/hello", "type": "sync" } }`, http.StatusOK, nil}, {datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "funcy/hello", "type": "sync" } }`, http.StatusOK, nil},
} { } {
test.run(t, i, buf) test.run(t, i, buf)
test.ds = datastore.NewMockInit(nil,
[]*models.Route{
{
AppName: "a",
Path: "/myroute",
},
}, nil, nil,
)
test.run(t, i, buf)
} }
} }

View File

@@ -365,10 +365,10 @@ func (s *Server) bindHandlers(ctx context.Context) {
apps := v1.Group("/apps/:app") apps := v1.Group("/apps/:app")
{ {
apps.GET("/routes", s.handleRouteList) apps.GET("/routes", s.handleRouteList)
apps.POST("/routes", s.handleRouteCreateOrUpdate) apps.POST("/routes", s.handleRoutesPostPutPatch)
apps.GET("/routes/*route", s.handleRouteGet) apps.GET("/routes/*route", s.handleRouteGet)
apps.PATCH("/routes/*route", s.handleRouteCreateOrUpdate) apps.PATCH("/routes/*route", s.handleRoutesPostPutPatch)
apps.PUT("/routes/*route", s.handleRouteCreateOrUpdate) apps.PUT("/routes/*route", s.handleRoutesPostPutPatch)
apps.DELETE("/routes/*route", s.handleRouteDelete) apps.DELETE("/routes/*route", s.handleRouteDelete)
apps.GET("/calls", s.handleCallList) apps.GET("/calls", s.handleCallList)

View File

@@ -84,6 +84,7 @@ func CreateUpdateApp(t *testing.T, ctx context.Context, fnclient *client.Functio
}, },
Context: ctx, Context: ctx,
} }
cfg.WithTimeout(time.Second * 60)
appPayload, err := fnclient.Apps.PatchAppsApp(cfg) appPayload, err := fnclient.Apps.PatchAppsApp(cfg)
CheckAppResponseError(t, err) CheckAppResponseError(t, err)
return appPayload return appPayload
@@ -98,3 +99,14 @@ func DeleteApp(t *testing.T, ctx context.Context, fnclient *client.Functions, ap
_, err := fnclient.Apps.DeleteAppsApp(cfg) _, err := fnclient.Apps.DeleteAppsApp(cfg)
CheckAppResponseError(t, err) CheckAppResponseError(t, err)
} }
func GetApp(t *testing.T, ctx context.Context, fnclient *client.Functions, appName string) *models.App {
cfg := &apps.GetAppsAppParams{
App: appName,
Context: ctx,
}
cfg.WithTimeout(time.Second * 60)
app, err := fnclient.Apps.GetAppsApp(cfg)
CheckAppResponseError(t, err)
return app.Payload.App
}

View File

@@ -41,14 +41,8 @@ func TestApps(t *testing.T) {
t.Parallel() t.Parallel()
s := SetupDefaultSuite() s := SetupDefaultSuite()
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{"A": "a"}) CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{"A": "a"})
cfg := &apps.GetAppsAppParams{ app := GetApp(t, s.Context, s.Client, s.AppName)
Context: s.Context, val, ok := app.Config["A"]
App: s.AppName,
}
appPayload, err := s.Client.Apps.GetAppsApp(cfg)
CheckAppResponseError(t, err)
appBody := appPayload.Payload.App
val, ok := appBody.Config["A"]
if !ok { if !ok {
t.Error("Error during app config inspect: config map misses required entity `A` with value `a`.") t.Error("Error during app config inspect: config map misses required entity `A` with value `a`.")
} }

View File

@@ -49,7 +49,7 @@ func TestCalls(t *testing.T) {
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{})
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.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
cfg := &call.GetAppsAppCallsCallParams{ cfg := &call.GetAppsAppCallsCallParams{
Call: "dummy", Call: "dummy",
@@ -71,7 +71,7 @@ func TestCalls(t *testing.T) {
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{})
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.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
u := url.URL{ u := url.URL{
Scheme: "http", Scheme: "http",
@@ -106,7 +106,7 @@ func TestCalls(t *testing.T) {
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{})
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.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
u := url.URL{ u := url.URL{
Scheme: "http", Scheme: "http",

View File

@@ -57,7 +57,7 @@ func TestRouteExecutions(t *testing.T) {
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{})
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "sync", CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "sync",
s.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
u := url.URL{ u := url.URL{
Scheme: "http", Scheme: "http",
@@ -84,7 +84,7 @@ func TestRouteExecutions(t *testing.T) {
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{})
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "sync", CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "sync",
s.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
u := url.URL{ u := url.URL{
Scheme: "http", Scheme: "http",
@@ -115,7 +115,7 @@ func TestRouteExecutions(t *testing.T) {
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{})
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "sync", CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "sync",
s.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
u := url.URL{ u := url.URL{
Scheme: "http", Scheme: "http",
@@ -141,7 +141,7 @@ func TestRouteExecutions(t *testing.T) {
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{})
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "sync", CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, "sync",
s.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
u := url.URL{ u := url.URL{
Scheme: "http", Scheme: "http",
@@ -202,7 +202,7 @@ func TestRouteExecutions(t *testing.T) {
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{}) CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
CreateRoute(t, s.Context, s.Client, s.AppName, routePath, image, routeType, CreateRoute(t, s.Context, s.Client, s.AppName, routePath, image, routeType,
s.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
u := url.URL{ u := url.URL{
Scheme: "http", Scheme: "http",
@@ -253,7 +253,7 @@ func TestRouteExecutions(t *testing.T) {
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{}) CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
CreateRoute(t, s.Context, s.Client, s.AppName, routePath, image, routeType, CreateRoute(t, s.Context, s.Client, s.AppName, routePath, image, routeType,
s.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
u := url.URL{ u := url.URL{
Scheme: "http", Scheme: "http",
@@ -298,7 +298,7 @@ func TestRouteExecutions(t *testing.T) {
image := "denismakogon/os.environ" image := "denismakogon/os.environ"
routeType := "sync" routeType := "sync"
CreateRoute(t, s.Context, s.Client, s.AppName, routePath, image, routeType, CreateRoute(t, s.Context, s.Client, s.AppName, routePath, image, routeType,
s.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
u := url.URL{ u := url.URL{
Scheme: "http", Scheme: "http",
@@ -330,7 +330,7 @@ func TestRouteExecutions(t *testing.T) {
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{}) CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
CreateRoute(t, s.Context, s.Client, s.AppName, routePath, image, routeType, CreateRoute(t, s.Context, s.Client, s.AppName, routePath, image, routeType,
s.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
u := url.URL{ u := url.URL{
Scheme: "http", Scheme: "http",
@@ -372,7 +372,7 @@ func TestRouteExecutions(t *testing.T) {
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{}) CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
CreateRoute(t, s.Context, s.Client, s.AppName, routePath, image, routeType, CreateRoute(t, s.Context, s.Client, s.AppName, routePath, image, routeType,
s.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
size := 1 * 1024 * 1024 * 1024 size := 1 * 1024 * 1024 * 1024
u := url.URL{ u := url.URL{

View File

@@ -55,19 +55,28 @@ func CheckRouteResponseError(t *testing.T, err error) {
msg := err.(*routes.PatchAppsAppRoutesRouteDefault).Payload.Error.Message msg := err.(*routes.PatchAppsAppRoutesRouteDefault).Payload.Error.Message
code := err.(*routes.PatchAppsAppRoutesRouteDefault).Code() code := err.(*routes.PatchAppsAppRoutesRouteDefault).Code()
t.Errorf("Unexpected error occurred: %v. Status code: %v", msg, code) t.Errorf("Unexpected error occurred: %v. Status code: %v", msg, code)
case *routes.PutAppsAppRoutesRouteBadRequest:
msg := err.(*routes.PutAppsAppRoutesRouteBadRequest).Payload.Error.Message
t.Errorf("Unexpected error occurred: %v.", msg)
case *routes.PutAppsAppRoutesRouteDefault:
msg := err.(*routes.PutAppsAppRoutesRouteDefault).Payload.Error.Message
code := err.(*routes.PutAppsAppRoutesRouteDefault).Code()
t.Errorf("Unexpected error occurred: %v. Status code: %v", msg, code)
default: default:
t.Errorf("Unable to determine type of error: %s", err) t.Errorf("Unable to determine type of error: %s", err)
} }
} }
} }
func assertRouteFields(t *testing.T, routeObject *models.Route, path, image, routeType string) { func assertRouteFields(t *testing.T, routeObject *models.Route, path, image, routeType, routeFormat string) {
rPath := routeObject.Path rPath := routeObject.Path
rImage := routeObject.Image rImage := routeObject.Image
rType := routeObject.Type rType := routeObject.Type
rTimeout := *routeObject.Timeout rTimeout := *routeObject.Timeout
rIdleTimeout := *routeObject.IDLETimeout rIdleTimeout := *routeObject.IDLETimeout
rFormat := routeObject.Format
if rPath != path { if rPath != path {
t.Errorf("Route path mismatch. Expected: %v. Actual: %v", path, rPath) t.Errorf("Route path mismatch. Expected: %v. Actual: %v", path, rPath)
} }
@@ -83,6 +92,9 @@ func assertRouteFields(t *testing.T, routeObject *models.Route, path, image, rou
if rIdleTimeout == 0 { if rIdleTimeout == 0 {
t.Error("Route idle timeout should have default value of 30 seconds, but got 0 seconds") t.Error("Route idle timeout should have default value of 30 seconds, but got 0 seconds")
} }
if rFormat != routeFormat {
t.Errorf("Route format mismatch. Expected: %v. Actual: %v", routeFormat, rFormat)
}
} }
@@ -105,11 +117,11 @@ func createRoute(ctx context.Context, fnclient *client.Functions, appName, image
} }
func CreateRoute(t *testing.T, ctx context.Context, fnclient *client.Functions, appName, routePath, image, routeType string, routeConfig map[string]string, headers map[string][]string) { func CreateRoute(t *testing.T, ctx context.Context, fnclient *client.Functions, 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, routeConfig, headers)
CheckRouteResponseError(t, err) CheckRouteResponseError(t, err)
assertRouteFields(t, routeResponse.Payload.Route, routePath, image, routeType) assertRouteFields(t, routeResponse.Payload.Route, routePath, image, routeType, routeFormat)
} }
func deleteRoute(ctx context.Context, fnclient *client.Functions, appName, routePath string) (*routes.DeleteAppsAppRoutesRouteOK, error) { func deleteRoute(ctx context.Context, fnclient *client.Functions, appName, routePath string) (*routes.DeleteAppsAppRoutesRouteOK, error) {
@@ -218,3 +230,25 @@ func assertContainsRoute(routeModels []*models.Route, expectedRoute string) bool
} }
return false return false
} }
func DeployRoute(t *testing.T, ctx context.Context, fnclient *client.Functions, appName, routePath, image, routeType, routeFormat string, routeConfig map[string]string, headers map[string][]string) *models.Route {
cfg := &routes.PutAppsAppRoutesRouteParams{
App: appName,
Context: ctx,
Route: routePath,
Body: &models.RouteWrapper{
Route: &models.Route{
Config: routeConfig,
Headers: headers,
Image: image,
Path: routePath,
Type: routeType,
Format: routeFormat,
},
},
}
cfg.WithTimeout(time.Second * 60)
route, err := fnclient.Routes.PutAppsAppRoutesRoute(cfg)
CheckRouteResponseError(t, err)
return route.Payload.Route
}

View File

@@ -11,7 +11,6 @@ import (
func TestRoutes(t *testing.T) { func TestRoutes(t *testing.T) {
newRouteType := "sync" newRouteType := "sync"
newRoutePath := id.New().String() newRoutePath := id.New().String()
t.Run("create-route-with-empty-type", func(t *testing.T) { t.Run("create-route-with-empty-type", func(t *testing.T) {
t.Parallel() t.Parallel()
s := SetupDefaultSuite() s := SetupDefaultSuite()
@@ -29,7 +28,7 @@ func TestRoutes(t *testing.T) {
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{})
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.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
DeleteRoute(t, s.Context, s.Client, s.AppName, s.RoutePath) DeleteRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)
DeleteApp(t, s.Context, s.Client, s.AppName) DeleteApp(t, s.Context, s.Client, s.AppName)
}) })
@@ -39,7 +38,7 @@ func TestRoutes(t *testing.T) {
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{})
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.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
if !assertContainsRoute(ListRoutes(t, s.Context, s.Client, s.AppName), s.RoutePath) { if !assertContainsRoute(ListRoutes(t, s.Context, s.Client, s.AppName), s.RoutePath) {
t.Errorf("Unable to find corresponding route `%v` in list", s.RoutePath) t.Errorf("Unable to find corresponding route `%v` in list", s.RoutePath)
} }
@@ -52,7 +51,7 @@ func TestRoutes(t *testing.T) {
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{})
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.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
rObjects := []*models.Route{GetRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)} rObjects := []*models.Route{GetRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)}
if !assertContainsRoute(rObjects, s.RoutePath) { if !assertContainsRoute(rObjects, s.RoutePath) {
@@ -68,7 +67,7 @@ func TestRoutes(t *testing.T) {
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{})
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.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
routeResp, err := UpdateRoute( routeResp, err := UpdateRoute(
t, s.Context, s.Client, t, s.Context, s.Client,
@@ -77,7 +76,31 @@ func TestRoutes(t *testing.T) {
s.Memory, s.RouteConfig, s.RouteHeaders, "") s.Memory, s.RouteConfig, s.RouteHeaders, "")
CheckRouteResponseError(t, err) CheckRouteResponseError(t, err)
assertRouteFields(t, routeResp.Payload.Route, s.RoutePath, s.Image, newRouteType) assertRouteFields(t, routeResp.Payload.Route, s.RoutePath, s.Image, newRouteType, s.Format)
DeleteRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)
DeleteApp(t, s.Context, s.Client, s.AppName)
})
t.Run("patch-route-with-config", func(t *testing.T) {
t.Parallel()
s := SetupDefaultSuite()
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, s.RouteType,
s.Format, s.RouteConfig, s.RouteHeaders)
newRouteConf := map[string]string{
"A": "a",
}
routeResp, err := UpdateRoute(
t, s.Context, s.Client,
s.AppName, s.RoutePath,
s.Image, s.RouteType, s.Format,
s.Memory, newRouteConf, s.RouteHeaders, "")
CheckRouteResponseError(t, err)
assertRouteFields(t, routeResp.Payload.Route, s.RoutePath, s.Image, s.RouteType, s.Format)
DeleteRoute(t, s.Context, s.Client, s.AppName, s.RoutePath) DeleteRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)
DeleteApp(t, s.Context, s.Client, s.AppName) DeleteApp(t, s.Context, s.Client, s.AppName)
@@ -88,7 +111,7 @@ func TestRoutes(t *testing.T) {
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{})
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.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
_, err := UpdateRoute( _, err := UpdateRoute(
t, s.Context, s.Client, t, s.Context, s.Client,
@@ -108,7 +131,7 @@ func TestRoutes(t *testing.T) {
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{})
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.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.RouteConfig, s.RouteHeaders)
if err == nil { if err == nil {
@@ -124,7 +147,7 @@ func TestRoutes(t *testing.T) {
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{})
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.RouteConfig, s.RouteHeaders) s.Format, s.RouteConfig, s.RouteHeaders)
DeleteRoute(t, s.Context, s.Client, s.AppName, s.RoutePath) DeleteRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)
DeleteApp(t, s.Context, s.Client, s.AppName) DeleteApp(t, s.Context, s.Client, s.AppName)
@@ -141,4 +164,43 @@ func TestRoutes(t *testing.T) {
} }
DeleteApp(t, s.Context, s.Client, s.AppName) DeleteApp(t, s.Context, s.Client, s.AppName)
}) })
t.Run("deploy-route-without-existing-app", func(T *testing.T) {
t.Parallel()
s := SetupDefaultSuite()
DeployRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, s.RouteType, s.Format, s.RouteConfig, s.RouteHeaders)
GetApp(t, s.Context, s.Client, s.AppName)
GetRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)
DeleteRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)
DeleteApp(t, s.Context, s.Client, s.AppName)
})
t.Run("deploy-route-with-existing-app", func(T *testing.T) {
s := SetupDefaultSuite()
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
DeployRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, s.RouteType, s.Format, s.RouteConfig, s.RouteHeaders)
GetApp(t, s.Context, s.Client, s.AppName)
GetRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)
DeleteRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)
DeleteApp(t, s.Context, s.Client, s.AppName)
})
t.Run("deploy-update-with-existing-route-and-app", func(T *testing.T) {
newRouteType := "sync"
s := SetupDefaultSuite()
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, s.RouteType,
s.Format, s.RouteConfig, s.RouteHeaders)
updatedRoute := DeployRoute(
t, s.Context, s.Client,
s.AppName, s.RoutePath,
s.Image, newRouteType,
s.Format, s.RouteConfig, s.RouteHeaders)
assertRouteFields(t, updatedRoute, s.RoutePath, s.Image, newRouteType, s.Format)
DeleteRoute(t, s.Context, s.Client, s.AppName, s.RoutePath)
DeleteApp(t, s.Context, s.Client, s.AppName)
})
} }