mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Merge pull request #366 from fnproject/saner-route-cfg
more strict configuration of routes
This commit is contained in:
@@ -32,7 +32,10 @@ jobs:
|
|||||||
- run: docker version
|
- run: docker version
|
||||||
# login here for tests
|
# login here for tests
|
||||||
- run: docker login -u $DOCKER_USER -p $DOCKER_PASS
|
- run: docker login -u $DOCKER_USER -p $DOCKER_PASS
|
||||||
- run: ./test.sh
|
- run: make docker-build
|
||||||
|
- run: make install
|
||||||
|
- run: make test
|
||||||
|
# TODO these should be inside test.sh file ?
|
||||||
- run: ./api_test.sh mysql 4
|
- run: ./api_test.sh mysql 4
|
||||||
- run: ./api_test.sh postgres 4
|
- run: ./api_test.sh postgres 4
|
||||||
- run: ./api_test.sh sqlite 4
|
- run: ./api_test.sh sqlite 4
|
||||||
|
|||||||
3
Makefile
3
Makefile
@@ -10,6 +10,9 @@ dep-up:
|
|||||||
build:
|
build:
|
||||||
go build -o functions
|
go build -o functions
|
||||||
|
|
||||||
|
install:
|
||||||
|
go install
|
||||||
|
|
||||||
test:
|
test:
|
||||||
./test.sh
|
./test.sh
|
||||||
|
|
||||||
|
|||||||
@@ -146,6 +146,13 @@ func FromRequest(appName, path string, req *http.Request) CallOpt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this ensures that there is an image, path, timeouts, memory, etc are valid.
|
||||||
|
// NOTE: this means assign any changes above into route's fields
|
||||||
|
err = route.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
c.Call = &models.Call{
|
c.Call = &models.Call{
|
||||||
ID: id,
|
ID: id,
|
||||||
AppName: appName,
|
AppName: appName,
|
||||||
@@ -166,14 +173,6 @@ func FromRequest(appName, path string, req *http.Request) CallOpt {
|
|||||||
Method: req.Method,
|
Method: req.Method,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO if these made it to here we have a problemo. error instead?
|
|
||||||
if c.Timeout <= 0 {
|
|
||||||
c.Timeout = models.DefaultRouteTimeout
|
|
||||||
}
|
|
||||||
if c.IdleTimeout <= 0 {
|
|
||||||
c.IdleTimeout = models.DefaultIdleTimeout
|
|
||||||
}
|
|
||||||
|
|
||||||
c.req = req
|
c.req = req
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -449,7 +449,7 @@ func Test(t *testing.T, dsf func() models.Datastore) {
|
|||||||
updated, err := ds.UpdateRoute(ctx, &models.Route{
|
updated, err := ds.UpdateRoute(ctx, &models.Route{
|
||||||
AppName: testRoute.AppName,
|
AppName: testRoute.AppName,
|
||||||
Path: testRoute.Path,
|
Path: testRoute.Path,
|
||||||
Timeout: 100,
|
Timeout: 2,
|
||||||
Config: map[string]string{
|
Config: map[string]string{
|
||||||
"FIRST": "1",
|
"FIRST": "1",
|
||||||
"SECOND": "2",
|
"SECOND": "2",
|
||||||
@@ -467,13 +467,15 @@ func Test(t *testing.T, dsf func() models.Datastore) {
|
|||||||
}
|
}
|
||||||
expected := &models.Route{
|
expected := &models.Route{
|
||||||
// unchanged
|
// unchanged
|
||||||
AppName: testRoute.AppName,
|
AppName: testRoute.AppName,
|
||||||
Path: testRoute.Path,
|
Path: testRoute.Path,
|
||||||
Image: "fnproject/hello",
|
Image: "fnproject/hello",
|
||||||
Type: "sync",
|
Type: "sync",
|
||||||
Format: "http",
|
Format: "http",
|
||||||
|
IdleTimeout: testRoute.IdleTimeout,
|
||||||
|
Memory: testRoute.Memory,
|
||||||
// updated
|
// updated
|
||||||
Timeout: 100,
|
Timeout: 2,
|
||||||
Config: map[string]string{
|
Config: map[string]string{
|
||||||
"FIRST": "1",
|
"FIRST": "1",
|
||||||
"SECOND": "2",
|
"SECOND": "2",
|
||||||
@@ -510,12 +512,14 @@ func Test(t *testing.T, dsf func() models.Datastore) {
|
|||||||
}
|
}
|
||||||
expected = &models.Route{
|
expected = &models.Route{
|
||||||
// unchanged
|
// unchanged
|
||||||
AppName: testRoute.AppName,
|
AppName: testRoute.AppName,
|
||||||
Path: testRoute.Path,
|
Path: testRoute.Path,
|
||||||
Image: "fnproject/hello",
|
Image: "fnproject/hello",
|
||||||
Type: "sync",
|
Type: "sync",
|
||||||
Format: "http",
|
Format: "http",
|
||||||
Timeout: 100,
|
Timeout: 2,
|
||||||
|
Memory: testRoute.Memory,
|
||||||
|
IdleTimeout: testRoute.IdleTimeout,
|
||||||
// updated
|
// updated
|
||||||
Config: map[string]string{
|
Config: map[string]string{
|
||||||
"FIRST": "first",
|
"FIRST": "first",
|
||||||
@@ -682,9 +686,12 @@ var testApp = &models.App{
|
|||||||
}
|
}
|
||||||
|
|
||||||
var testRoute = &models.Route{
|
var testRoute = &models.Route{
|
||||||
AppName: testApp.Name,
|
AppName: testApp.Name,
|
||||||
Path: "/test",
|
Path: "/test",
|
||||||
Image: "fnproject/hello",
|
Image: "fnproject/hello",
|
||||||
Type: "sync",
|
Type: "sync",
|
||||||
Format: "http",
|
Format: "http",
|
||||||
|
Timeout: models.DefaultTimeout,
|
||||||
|
IdleTimeout: models.DefaultIdleTimeout,
|
||||||
|
Memory: models.DefaultMemory,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,8 +144,14 @@ func (m *mock) UpdateRoute(ctx context.Context, route *models.Route) (*models.Ro
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
r.Update(route)
|
clone := r.Clone()
|
||||||
return r.Clone(), nil
|
clone.Update(route)
|
||||||
|
err = clone.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r.Update(route) // only if validate works (pointer)
|
||||||
|
return clone, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mock) RemoveRoute(ctx context.Context, appName, routePath string) error {
|
func (m *mock) RemoveRoute(ctx context.Context, appName, routePath string) error {
|
||||||
|
|||||||
@@ -335,6 +335,10 @@ func (ds *sqlStore) UpdateRoute(ctx context.Context, newroute *models.Route) (*m
|
|||||||
}
|
}
|
||||||
|
|
||||||
route.Update(newroute)
|
route.Update(newroute)
|
||||||
|
err = route.Validate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
query = tx.Rebind(`UPDATE routes SET
|
query = tx.Rebind(`UPDATE routes SET
|
||||||
image = :image,
|
image = :image,
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ type App struct {
|
|||||||
|
|
||||||
func (a *App) Validate() error {
|
func (a *App) Validate() error {
|
||||||
if a.Name == "" {
|
if a.Name == "" {
|
||||||
return ErrAppsValidationMissingName
|
return ErrAppsMissingName
|
||||||
}
|
}
|
||||||
if len(a.Name) > maxAppName {
|
if len(a.Name) > maxAppName {
|
||||||
return ErrAppsValidationTooLongName
|
return ErrAppsTooLongName
|
||||||
}
|
}
|
||||||
for _, c := range a.Name {
|
for _, c := range a.Name {
|
||||||
if (c < '0' || '9' < c) && (c < 'A' || 'Z' > c) && (c < 'a' || 'z' < c) && c != '_' && c != '-' {
|
if (c < '0' || '9' < c) && (c < 'A' || 'Z' > c) && (c < 'a' || 'z' < c) && c != '_' && c != '-' {
|
||||||
return ErrAppsValidationInvalidName
|
return ErrAppsInvalidName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -20,15 +20,15 @@ var (
|
|||||||
code: http.StatusGatewayTimeout,
|
code: http.StatusGatewayTimeout,
|
||||||
error: errors.New("Timed out"),
|
error: errors.New("Timed out"),
|
||||||
}
|
}
|
||||||
ErrAppsValidationMissingName = err{
|
ErrAppsMissingName = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Missing app name"),
|
error: errors.New("Missing app name"),
|
||||||
}
|
}
|
||||||
ErrAppsValidationTooLongName = err{
|
ErrAppsTooLongName = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: fmt.Errorf("App name must be %v characters or less", maxAppName),
|
error: fmt.Errorf("App name must be %v characters or less", maxAppName),
|
||||||
}
|
}
|
||||||
ErrAppsValidationInvalidName = err{
|
ErrAppsInvalidName = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Invalid app name"),
|
error: errors.New("Invalid app name"),
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ var (
|
|||||||
}
|
}
|
||||||
ErrAppsNameImmutable = err{
|
ErrAppsNameImmutable = err{
|
||||||
code: http.StatusConflict,
|
code: http.StatusConflict,
|
||||||
error: errors.New("Could not update app - name is immutable"),
|
error: errors.New("Could not update - name is immutable"),
|
||||||
}
|
}
|
||||||
ErrAppsNotFound = err{
|
ErrAppsNotFound = err{
|
||||||
code: http.StatusNotFound,
|
code: http.StatusNotFound,
|
||||||
@@ -94,41 +94,41 @@ var (
|
|||||||
}
|
}
|
||||||
ErrRoutesPathImmutable = err{
|
ErrRoutesPathImmutable = err{
|
||||||
code: http.StatusConflict,
|
code: http.StatusConflict,
|
||||||
error: errors.New("Could not update route - path is immutable"),
|
error: errors.New("Could not update - path is immutable"),
|
||||||
}
|
}
|
||||||
ErrFoundDynamicURL = err{
|
ErrFoundDynamicURL = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Dynamic URL is not allowed"),
|
error: errors.New("Dynamic URL is not allowed"),
|
||||||
}
|
}
|
||||||
ErrInvalidPath = err{
|
ErrRoutesInvalidPath = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Invalid Path format"),
|
error: errors.New("Invalid route path format"),
|
||||||
}
|
}
|
||||||
ErrInvalidType = err{
|
ErrRoutesInvalidType = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Invalid route Type"),
|
error: errors.New("Invalid route Type"),
|
||||||
}
|
}
|
||||||
ErrInvalidFormat = err{
|
ErrRoutesInvalidFormat = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Invalid route Format"),
|
error: errors.New("Invalid route Format"),
|
||||||
}
|
}
|
||||||
ErrMissingAppName = err{
|
ErrRoutesMissingAppName = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Missing route AppName"),
|
error: errors.New("Missing route AppName"),
|
||||||
}
|
}
|
||||||
ErrMissingImage = err{
|
ErrRoutesMissingImage = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Missing route Image"),
|
error: errors.New("Missing route Image"),
|
||||||
}
|
}
|
||||||
ErrMissingName = err{
|
ErrRoutesMissingName = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Missing route Name"),
|
error: errors.New("Missing route Name"),
|
||||||
}
|
}
|
||||||
ErrMissingPath = err{
|
ErrRoutesMissingPath = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Missing route Path"),
|
error: errors.New("Missing route Path"),
|
||||||
}
|
}
|
||||||
ErrMissingType = err{
|
ErrRoutesMissingType = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Missing route Type"),
|
error: errors.New("Missing route Type"),
|
||||||
}
|
}
|
||||||
@@ -144,13 +144,17 @@ var (
|
|||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("from_time is not an epoch time"),
|
error: errors.New("from_time is not an epoch time"),
|
||||||
}
|
}
|
||||||
ErrNegativeTimeout = err{
|
ErrRoutesInvalidTimeout = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Negative timeout"),
|
error: fmt.Errorf("timeout value is too large or small. 0 < timeout < max. async max: %d sync max: %d", MaxAsyncTimeout, MaxSyncTimeout),
|
||||||
}
|
}
|
||||||
ErrNegativeIdleTimeout = err{
|
ErrRoutesInvalidIdleTimeout = err{
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
error: errors.New("Negative idle timeout"),
|
error: fmt.Errorf("idle_timeout value is too large or small. 0 < timeout < %d", MaxIdleTimeout),
|
||||||
|
}
|
||||||
|
ErrRoutesInvalidMemory = err{
|
||||||
|
code: http.StatusBadRequest,
|
||||||
|
error: fmt.Errorf("memory value is invalid. 0 < memory < %d", MaxMemory),
|
||||||
}
|
}
|
||||||
ErrCallNotFound = err{
|
ErrCallNotFound = err{
|
||||||
code: http.StatusNotFound,
|
code: http.StatusNotFound,
|
||||||
|
|||||||
@@ -8,8 +8,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultRouteTimeout = 30 // seconds
|
DefaultTimeout = 30 // seconds
|
||||||
DefaultIdleTimeout = 30 // seconds
|
DefaultIdleTimeout = 30 // seconds
|
||||||
|
DefaultMemory = 128 // MB
|
||||||
|
|
||||||
|
MaxSyncTimeout = 120 // 2 minutes
|
||||||
|
MaxAsyncTimeout = 3600 // 1 hour
|
||||||
|
MaxIdleTimeout = MaxAsyncTimeout
|
||||||
|
MaxMemory = 1024 * 8 // 8GB TODO should probably be a var of machine max?
|
||||||
)
|
)
|
||||||
|
|
||||||
type Routes []*Route
|
type Routes []*Route
|
||||||
@@ -30,7 +36,7 @@ type Route struct {
|
|||||||
// SetDefaults sets zeroed field to defaults.
|
// SetDefaults sets zeroed field to defaults.
|
||||||
func (r *Route) SetDefaults() {
|
func (r *Route) SetDefaults() {
|
||||||
if r.Memory == 0 {
|
if r.Memory == 0 {
|
||||||
r.Memory = 128
|
r.Memory = DefaultMemory
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Type == TypeNone {
|
if r.Type == TypeNone {
|
||||||
@@ -50,7 +56,7 @@ func (r *Route) SetDefaults() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if r.Timeout == 0 {
|
if r.Timeout == 0 {
|
||||||
r.Timeout = DefaultRouteTimeout
|
r.Timeout = DefaultTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.IdleTimeout == 0 {
|
if r.IdleTimeout == 0 {
|
||||||
@@ -58,24 +64,15 @@ func (r *Route) SetDefaults() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates field values, skipping zeroed fields if skipZero is true.
|
// Validate validates all field values, returning the first error, if any.
|
||||||
// it returns the first error, if any.
|
func (r *Route) Validate() error {
|
||||||
func (r *Route) Validate(skipZero bool) error {
|
if r.AppName == "" {
|
||||||
if !skipZero {
|
return ErrRoutesMissingAppName
|
||||||
if r.AppName == "" {
|
|
||||||
return ErrMissingAppName
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Path == "" {
|
|
||||||
return ErrMissingPath
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Image == "" {
|
|
||||||
return ErrMissingImage
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !skipZero || r.Path != "" {
|
if r.Path == "" {
|
||||||
|
return ErrRoutesMissingPath
|
||||||
|
} else {
|
||||||
u, err := url.Parse(r.Path)
|
u, err := url.Parse(r.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrPathMalformed
|
return ErrPathMalformed
|
||||||
@@ -86,28 +83,34 @@ func (r *Route) Validate(skipZero bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !path.IsAbs(u.Path) {
|
if !path.IsAbs(u.Path) {
|
||||||
return ErrInvalidPath
|
return ErrRoutesInvalidPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !skipZero || r.Type != "" {
|
if r.Image == "" {
|
||||||
if r.Type != TypeAsync && r.Type != TypeSync {
|
return ErrRoutesMissingImage
|
||||||
return ErrInvalidType
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !skipZero || r.Format != "" {
|
if r.Type != TypeAsync && r.Type != TypeSync {
|
||||||
if r.Format != FormatDefault && r.Format != FormatHTTP {
|
return ErrRoutesInvalidType
|
||||||
return ErrInvalidFormat
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Timeout < 0 {
|
if r.Format != FormatDefault && r.Format != FormatHTTP {
|
||||||
return ErrNegativeTimeout
|
return ErrRoutesInvalidFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.IdleTimeout < 0 {
|
if r.Timeout <= 0 ||
|
||||||
return ErrNegativeIdleTimeout
|
(r.Type == TypeSync && r.Timeout > MaxSyncTimeout) ||
|
||||||
|
(r.Type == TypeAsync && r.Timeout > MaxAsyncTimeout) {
|
||||||
|
return ErrRoutesInvalidTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.IdleTimeout <= 0 || r.IdleTimeout > MaxIdleTimeout {
|
||||||
|
return ErrRoutesInvalidIdleTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Memory < 1 || r.Memory > MaxMemory {
|
||||||
|
return ErrRoutesInvalidMemory
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -4,15 +4,9 @@ type RouteWrapper struct {
|
|||||||
Route *Route `json:"route"`
|
Route *Route `json:"route"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *RouteWrapper) Validate(skipZero bool) error { return m.validateRoute(skipZero) }
|
func (m *RouteWrapper) Validate() error {
|
||||||
|
|
||||||
func (m *RouteWrapper) validateRoute(skipZero bool) error {
|
|
||||||
|
|
||||||
if m.Route != nil {
|
if m.Route != nil {
|
||||||
if err := m.Route.Validate(skipZero); err != nil {
|
return m.Route.Validate()
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ func TestAppCreate(t *testing.T) {
|
|||||||
{datastore.NewMock(), logs.NewMock(), "/v1/apps", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
{datastore.NewMock(), logs.NewMock(), "/v1/apps", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
||||||
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{}`, http.StatusBadRequest, models.ErrAppsMissingNew},
|
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{}`, http.StatusBadRequest, models.ErrAppsMissingNew},
|
||||||
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "name": "Test" }`, http.StatusBadRequest, models.ErrAppsMissingNew},
|
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "name": "Test" }`, http.StatusBadRequest, models.ErrAppsMissingNew},
|
||||||
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "app": { "name": "" } }`, http.StatusBadRequest, models.ErrAppsValidationMissingName},
|
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "app": { "name": "" } }`, http.StatusBadRequest, models.ErrAppsMissingName},
|
||||||
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "app": { "name": "1234567890123456789012345678901" } }`, http.StatusBadRequest, models.ErrAppsValidationTooLongName},
|
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "app": { "name": "1234567890123456789012345678901" } }`, http.StatusBadRequest, models.ErrAppsTooLongName},
|
||||||
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusBadRequest, models.ErrAppsValidationInvalidName},
|
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusBadRequest, models.ErrAppsInvalidName},
|
||||||
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusBadRequest, models.ErrAppsValidationInvalidName},
|
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusBadRequest, models.ErrAppsInvalidName},
|
||||||
|
|
||||||
// success
|
// success
|
||||||
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "app": { "name": "teste" } }`, http.StatusOK, nil},
|
{datastore.NewMock(), logs.NewMock(), "/v1/apps", `{ "app": { "name": "teste" } }`, http.StatusOK, nil},
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func TestCallGet(t *testing.T) {
|
|||||||
expectedCode int
|
expectedCode int
|
||||||
expectedError error
|
expectedError error
|
||||||
}{
|
}{
|
||||||
{"/v1/apps//calls/" + call.ID, "", http.StatusBadRequest, models.ErrMissingAppName},
|
{"/v1/apps//calls/" + call.ID, "", http.StatusBadRequest, models.ErrAppsMissingName},
|
||||||
{"/v1/apps/nodawg/calls/" + call.ID, "", http.StatusNotFound, models.ErrCallNotFound}, // TODO a little weird
|
{"/v1/apps/nodawg/calls/" + call.ID, "", http.StatusNotFound, models.ErrCallNotFound}, // TODO a little weird
|
||||||
{"/v1/apps/myapp/calls/" + call.ID[:3], "", http.StatusNotFound, models.ErrCallNotFound},
|
{"/v1/apps/myapp/calls/" + call.ID[:3], "", http.StatusNotFound, models.ErrCallNotFound},
|
||||||
{"/v1/apps/myapp/calls/" + call.ID, "", http.StatusOK, nil},
|
{"/v1/apps/myapp/calls/" + call.ID, "", http.StatusOK, nil},
|
||||||
@@ -140,7 +140,7 @@ func TestCallList(t *testing.T) {
|
|||||||
expectedLen int
|
expectedLen int
|
||||||
nextCursor string
|
nextCursor string
|
||||||
}{
|
}{
|
||||||
{"/v1/apps//calls", "", http.StatusBadRequest, models.ErrMissingAppName, 0, ""},
|
{"/v1/apps//calls", "", http.StatusBadRequest, models.ErrAppsMissingName, 0, ""},
|
||||||
{"/v1/apps/nodawg/calls", "", http.StatusNotFound, models.ErrAppsNotFound, 0, ""},
|
{"/v1/apps/nodawg/calls", "", http.StatusNotFound, models.ErrAppsNotFound, 0, ""},
|
||||||
{"/v1/apps/myapp/calls", "", http.StatusOK, nil, 3, ""},
|
{"/v1/apps/myapp/calls", "", http.StatusOK, nil, 3, ""},
|
||||||
{"/v1/apps/myapp/calls?per_page=1", "", http.StatusOK, nil, 1, c3.ID},
|
{"/v1/apps/myapp/calls?per_page=1", "", http.StatusOK, nil, 1, c3.ID},
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ func (s *Server) handleRoutesPostPutPatch(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) submitRoute(ctx context.Context, wroute *models.RouteWrapper) error {
|
func (s *Server) submitRoute(ctx context.Context, wroute *models.RouteWrapper) error {
|
||||||
err := s.setDefaultsAndValidate(wroute)
|
wroute.Route.SetDefaults()
|
||||||
|
err := wroute.Route.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -62,10 +63,6 @@ func (s *Server) submitRoute(ctx context.Context, wroute *models.RouteWrapper) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) changeRoute(ctx context.Context, wroute *models.RouteWrapper) error {
|
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)
|
r, err := s.Datastore.UpdateRoute(ctx, wroute.Route)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -163,13 +160,8 @@ func bindRoute(c *gin.Context, method string, wroute *models.RouteWrapper) error
|
|||||||
}
|
}
|
||||||
if method == http.MethodPost {
|
if method == http.MethodPost {
|
||||||
if wroute.Route.Path == "" {
|
if wroute.Route.Path == "" {
|
||||||
return models.ErrMissingPath
|
return models.ErrRoutesMissingPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) setDefaultsAndValidate(wroute *models.RouteWrapper) error {
|
|
||||||
wroute.Route.SetDefaults()
|
|
||||||
return wroute.Validate(false)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -61,11 +61,11 @@ func TestRouteCreate(t *testing.T) {
|
|||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "type": "sync" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "type": "sync" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "path": "/myroute", "type": "sync" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "path": "/myroute", "type": "sync" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { } }`, http.StatusBadRequest, models.ErrMissingPath},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { } }`, http.StatusBadRequest, models.ErrRoutesMissingPath},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "path": "/myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrMissingImage},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "path": "/myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrRoutesMissingImage},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/hello", "type": "sync" } }`, http.StatusBadRequest, models.ErrMissingPath},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/hello", "type": "sync" } }`, http.StatusBadRequest, models.ErrRoutesMissingPath},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/hello", "path": "myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrInvalidPath},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/hello", "path": "myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrRoutesInvalidPath},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/$/routes", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrAppsValidationInvalidName},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/$/routes", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrAppsInvalidName},
|
||||||
{datastore.NewMockInit(nil,
|
{datastore.NewMockInit(nil,
|
||||||
[]*models.Route{
|
[]*models.Route{
|
||||||
{
|
{
|
||||||
@@ -89,13 +89,13 @@ func TestRoutePut(t *testing.T) {
|
|||||||
// errors (NOTE: this route doesn't exist yet)
|
// errors (NOTE: this route doesn't exist yet)
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "path": "/myroute", "type": "sync" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "path": "/myroute", "type": "sync" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "type": "sync" } }`, http.StatusBadRequest, models.ErrMissingImage},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "type": "sync" } }`, http.StatusBadRequest, models.ErrRoutesMissingImage},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "path": "/myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrMissingImage},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "path": "/myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrRoutesMissingImage},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "myroute", "type": "sync" } }`, http.StatusConflict, models.ErrRoutesPathImmutable},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "myroute", "type": "sync" } }`, http.StatusConflict, models.ErrRoutesPathImmutable},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "diffRoute", "type": "sync" } }`, http.StatusConflict, models.ErrRoutesPathImmutable},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "diffRoute", "type": "sync" } }`, http.StatusConflict, models.ErrRoutesPathImmutable},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/$/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrAppsValidationInvalidName},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/$/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrAppsInvalidName},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "invalid-type" } }`, http.StatusBadRequest, models.ErrInvalidType},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "invalid-type" } }`, http.StatusBadRequest, models.ErrRoutesInvalidType},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "format": "invalid-format", "type": "sync" } }`, http.StatusBadRequest, models.ErrInvalidFormat},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "format": "invalid-format", "type": "sync" } }`, http.StatusBadRequest, models.ErrRoutesInvalidFormat},
|
||||||
|
|
||||||
// success
|
// success
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync" } }`, http.StatusOK, nil},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync" } }`, http.StatusOK, nil},
|
||||||
@@ -189,7 +189,7 @@ func TestRouteList(t *testing.T) {
|
|||||||
expectedLen int
|
expectedLen int
|
||||||
nextCursor string
|
nextCursor string
|
||||||
}{
|
}{
|
||||||
{"/v1/apps//routes", "", http.StatusBadRequest, models.ErrMissingAppName, 0, ""},
|
{"/v1/apps//routes", "", http.StatusBadRequest, models.ErrAppsMissingName, 0, ""},
|
||||||
{"/v1/apps/a/routes", "", http.StatusNotFound, models.ErrAppsNotFound, 0, ""},
|
{"/v1/apps/a/routes", "", http.StatusNotFound, models.ErrAppsNotFound, 0, ""},
|
||||||
{"/v1/apps/myapp/routes", "", http.StatusOK, nil, 3, ""},
|
{"/v1/apps/myapp/routes", "", http.StatusOK, nil, 3, ""},
|
||||||
{"/v1/apps/myapp/routes?per_page=1", "", http.StatusOK, nil, 1, r1b},
|
{"/v1/apps/myapp/routes?per_page=1", "", http.StatusOK, nil, 1, r1b},
|
||||||
@@ -274,33 +274,29 @@ func TestRouteGet(t *testing.T) {
|
|||||||
|
|
||||||
func TestRouteUpdate(t *testing.T) {
|
func TestRouteUpdate(t *testing.T) {
|
||||||
buf := setLogBuffer()
|
buf := setLogBuffer()
|
||||||
|
ds := datastore.NewMockInit(nil, nil, nil)
|
||||||
|
|
||||||
for i, test := range []routeTestCase{
|
for i, test := range []routeTestCase{
|
||||||
// errors
|
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{}`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "type": "invalid-type" } }`, http.StatusBadRequest, models.ErrInvalidType},
|
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "format": "invalid-format" } }`, http.StatusBadRequest, models.ErrInvalidFormat},
|
|
||||||
|
|
||||||
// success
|
// success
|
||||||
{datastore.NewMockInit(nil,
|
{ds, logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute/do", `{ "route": { "image": "fnproject/yodawg" } }`, http.StatusOK, nil},
|
||||||
[]*models.Route{
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "image": "fnproject/hello" } }`, http.StatusOK, nil},
|
||||||
{
|
|
||||||
AppName: "a",
|
// errors (after success, so route exists)
|
||||||
Path: "/myroute/do",
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
||||||
},
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{}`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
||||||
}, nil,
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "type": "invalid-type" } }`, http.StatusBadRequest, models.ErrRoutesInvalidType},
|
||||||
), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "image": "fnproject/hello" } }`, http.StatusOK, nil},
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "format": "invalid-format" } }`, http.StatusBadRequest, models.ErrRoutesInvalidFormat},
|
||||||
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "timeout": 121 } }`, http.StatusBadRequest, models.ErrRoutesInvalidTimeout},
|
||||||
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "type": "async", "timeout": 3601 } }`, http.StatusBadRequest, models.ErrRoutesInvalidTimeout},
|
||||||
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "type": "async", "timeout": 121, "idle_timeout": 240 } }`, http.StatusOK, nil}, // should work if async
|
||||||
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "idle_timeout": 3601 } }`, http.StatusBadRequest, models.ErrRoutesInvalidIdleTimeout},
|
||||||
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "memory": 100000000000000 } }`, http.StatusBadRequest, models.ErrRoutesInvalidMemory},
|
||||||
|
// TODO this should be correct, waiting for patch to come in
|
||||||
|
//{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/b/routes/myroute/dont", `{ "route": {} }`, http.StatusNotFound, models.ErrAppsNotFound},
|
||||||
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/dont", `{ "route": {} }`, http.StatusNotFound, models.ErrRoutesNotFound},
|
||||||
|
|
||||||
// Addresses #381
|
// Addresses #381
|
||||||
{datastore.NewMockInit(nil,
|
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "path": "/otherpath" } }`, http.StatusConflict, models.ErrRoutesPathImmutable},
|
||||||
[]*models.Route{
|
|
||||||
{
|
|
||||||
AppName: "a",
|
|
||||||
Path: "/myroute/do",
|
|
||||||
},
|
|
||||||
}, nil,
|
|
||||||
), logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", `{ "route": { "path": "/otherpath" } }`, http.StatusConflict, models.ErrRoutesPathImmutable},
|
|
||||||
} {
|
} {
|
||||||
test.run(t, i, buf)
|
test.run(t, i, buf)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ func TestRouteRunnerAsyncExecution(t *testing.T) {
|
|||||||
{Name: "myapp", Config: map[string]string{"app": "true"}},
|
{Name: "myapp", Config: map[string]string{"app": "true"}},
|
||||||
},
|
},
|
||||||
[]*models.Route{
|
[]*models.Route{
|
||||||
{Type: "async", Path: "/myroute", AppName: "myapp", Image: "fnproject/hello", Config: map[string]string{"test": "true"}},
|
{Type: "async", Path: "/myroute", AppName: "myapp", Image: "fnproject/hello", Config: map[string]string{"test": "true"}, Memory: 128, Timeout: 30, IdleTimeout: 30},
|
||||||
{Type: "async", Path: "/myerror", AppName: "myapp", Image: "fnproject/error", Config: map[string]string{"test": "true"}},
|
{Type: "async", Path: "/myerror", AppName: "myapp", Image: "fnproject/error", Config: map[string]string{"test": "true"}, Memory: 128, Timeout: 30, IdleTimeout: 30},
|
||||||
{Type: "async", Path: "/myroute/:param", AppName: "myapp", Image: "fnproject/hello", Config: map[string]string{"test": "true"}},
|
{Type: "async", Path: "/myroute/:param", AppName: "myapp", Image: "fnproject/hello", Config: map[string]string{"test": "true"}, Memory: 128, Timeout: 30, IdleTimeout: 30},
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
mq := &mqs.Mock{}
|
mq := &mqs.Mock{}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -128,11 +129,11 @@ func TestRouteRunnerExecution(t *testing.T) {
|
|||||||
{Name: "myapp", Config: models.Config{}},
|
{Name: "myapp", Config: models.Config{}},
|
||||||
},
|
},
|
||||||
[]*models.Route{
|
[]*models.Route{
|
||||||
{Path: "/", AppName: "myapp", Image: "fnproject/hello", Headers: map[string][]string{"X-Function": {"Test"}}},
|
{Path: "/", AppName: "myapp", Image: "fnproject/hello", Type: "sync", Memory: 128, Timeout: 30, IdleTimeout: 30, Headers: map[string][]string{"X-Function": {"Test"}}},
|
||||||
{Path: "/myroute", AppName: "myapp", Image: "fnproject/hello", Headers: map[string][]string{"X-Function": {"Test"}}},
|
{Path: "/myroute", AppName: "myapp", Image: "fnproject/hello", Type: "sync", Memory: 128, Timeout: 30, IdleTimeout: 30, Headers: map[string][]string{"X-Function": {"Test"}}},
|
||||||
{Path: "/myerror", AppName: "myapp", Image: "fnproject/error", Headers: map[string][]string{"X-Function": {"Test"}}},
|
{Path: "/myerror", AppName: "myapp", Image: "fnproject/error", Type: "sync", Memory: 128, Timeout: 30, IdleTimeout: 30, Headers: map[string][]string{"X-Function": {"Test"}}},
|
||||||
{Path: "/mydne", AppName: "myapp", Image: "fnproject/imagethatdoesnotexist"},
|
{Path: "/mydne", AppName: "myapp", Image: "fnproject/imagethatdoesnotexist", Type: "sync", Memory: 128, Timeout: 30, IdleTimeout: 30},
|
||||||
{Path: "/mydnehot", AppName: "myapp", Image: "fnproject/imagethatdoesnotexist", Format: "http"},
|
{Path: "/mydnehot", AppName: "myapp", Image: "fnproject/imagethatdoesnotexist", Type: "sync", Format: "http", Memory: 128, Timeout: 30, IdleTimeout: 30},
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -165,8 +166,9 @@ func TestRouteRunnerExecution(t *testing.T) {
|
|||||||
|
|
||||||
if rec.Code != test.expectedCode {
|
if rec.Code != test.expectedCode {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Errorf("Test %d: Expected status code to be %d but was %d",
|
bod, _ := ioutil.ReadAll(rec.Body)
|
||||||
i, test.expectedCode, rec.Code)
|
t.Errorf("Test %d: Expected status code to be %d but was %d. body: %s",
|
||||||
|
i, test.expectedCode, rec.Code, string(bod))
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.expectedHeaders == nil {
|
if test.expectedHeaders == nil {
|
||||||
@@ -200,7 +202,7 @@ func TestFailedEnqueue(t *testing.T) {
|
|||||||
{Name: "myapp", Config: models.Config{}},
|
{Name: "myapp", Config: models.Config{}},
|
||||||
},
|
},
|
||||||
[]*models.Route{
|
[]*models.Route{
|
||||||
{Path: "/dummy", AppName: "myapp", Image: "dummy/dummy", Type: "async"},
|
{Path: "/dummy", AppName: "myapp", Image: "dummy/dummy", Type: "async", Memory: 128, Timeout: 30, IdleTimeout: 30},
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
err := errors.New("Unable to push task to queue")
|
err := errors.New("Unable to push task to queue")
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ func loggerWrap(c *gin.Context) {
|
|||||||
func appWrap(c *gin.Context) {
|
func appWrap(c *gin.Context) {
|
||||||
appName := c.GetString(api.AppName)
|
appName := c.GetString(api.AppName)
|
||||||
if appName == "" {
|
if appName == "" {
|
||||||
handleErrorResponse(c, models.ErrMissingAppName)
|
handleErrorResponse(c, models.ErrAppsMissingName)
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
3
test.sh
3
test.sh
@@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
make build
|
|
||||||
make docker-build
|
|
||||||
|
|
||||||
docker rm -fv func-postgres-test || echo No prev test db container
|
docker rm -fv func-postgres-test || echo No prev test db container
|
||||||
docker run --name func-postgres-test -p 15432:5432 -d postgres
|
docker run --name func-postgres-test -p 15432:5432 -d postgres
|
||||||
docker rm -fv func-mysql-test || echo No prev mysql test db container
|
docker rm -fv func-mysql-test || echo No prev mysql test db container
|
||||||
|
|||||||
Reference in New Issue
Block a user