mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
fn: favor fn-test-utils over hello (to be decommissioned) (#761)
This commit is contained in:
@@ -16,18 +16,19 @@ type taskDockerTest struct {
|
|||||||
id string
|
id string
|
||||||
input io.Reader
|
input io.Reader
|
||||||
output io.Writer
|
output io.Writer
|
||||||
|
errors io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *taskDockerTest) Command() string { return "" }
|
func (f *taskDockerTest) Command() string { return "" }
|
||||||
func (f *taskDockerTest) EnvVars() map[string]string {
|
func (f *taskDockerTest) EnvVars() map[string]string {
|
||||||
return map[string]string{}
|
return map[string]string{"FN_FORMAT": "default"}
|
||||||
}
|
}
|
||||||
func (f *taskDockerTest) Labels() map[string]string { return nil }
|
func (f *taskDockerTest) Labels() map[string]string { return nil }
|
||||||
func (f *taskDockerTest) Id() string { return f.id }
|
func (f *taskDockerTest) Id() string { return f.id }
|
||||||
func (f *taskDockerTest) Group() string { return "" }
|
func (f *taskDockerTest) Group() string { return "" }
|
||||||
func (f *taskDockerTest) Image() string { return "fnproject/hello" }
|
func (f *taskDockerTest) Image() string { return "fnproject/fn-test-utils" }
|
||||||
func (f *taskDockerTest) Timeout() time.Duration { return 30 * time.Second }
|
func (f *taskDockerTest) Timeout() time.Duration { return 30 * time.Second }
|
||||||
func (f *taskDockerTest) Logger() (stdout, stderr io.Writer) { return f.output, nil }
|
func (f *taskDockerTest) Logger() (stdout, stderr io.Writer) { return f.output, f.errors }
|
||||||
func (f *taskDockerTest) WriteStat(context.Context, drivers.Stat) { /* TODO */ }
|
func (f *taskDockerTest) WriteStat(context.Context, drivers.Stat) { /* TODO */ }
|
||||||
func (f *taskDockerTest) Volumes() [][2]string { return [][2]string{} }
|
func (f *taskDockerTest) Volumes() [][2]string { return [][2]string{} }
|
||||||
func (f *taskDockerTest) Memory() uint64 { return 256 * 1024 * 1024 }
|
func (f *taskDockerTest) Memory() uint64 { return 256 * 1024 * 1024 }
|
||||||
@@ -39,8 +40,10 @@ func (f *taskDockerTest) Input() io.Reader { return f.inp
|
|||||||
func TestRunnerDocker(t *testing.T) {
|
func TestRunnerDocker(t *testing.T) {
|
||||||
dkr := NewDocker(drivers.Config{})
|
dkr := NewDocker(drivers.Config{})
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
var output bytes.Buffer
|
||||||
|
var errors bytes.Buffer
|
||||||
|
|
||||||
task := &taskDockerTest{"test-docker", nil, nil}
|
task := &taskDockerTest{"test-docker", bytes.NewBufferString(`{"isDebug": true}`), &output, &errors}
|
||||||
|
|
||||||
cookie, err := dkr.Prepare(ctx, task)
|
cookie, err := dkr.Prepare(ctx, task)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -59,7 +62,8 @@ func TestRunnerDocker(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if result.Status() != "success" {
|
if result.Status() != "success" {
|
||||||
t.Fatal("Test should successfully run the image")
|
t.Fatalf("Test should successfully run the image: %s output: %s errors: %s",
|
||||||
|
result.Error(), output.String(), errors.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,10 +91,12 @@ func TestRunnerDockerStdin(t *testing.T) {
|
|||||||
dkr := NewDocker(drivers.Config{})
|
dkr := NewDocker(drivers.Config{})
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
input := `{"name": "test"}`
|
input := `{"echoContent": "italian parsley", "isDebug": true}`
|
||||||
var output bytes.Buffer
|
|
||||||
|
|
||||||
task := &taskDockerTest{"test-docker-stdin", bytes.NewBufferString(input), &output}
|
var output bytes.Buffer
|
||||||
|
var errors bytes.Buffer
|
||||||
|
|
||||||
|
task := &taskDockerTest{"test-docker-stdin", bytes.NewBufferString(input), &output, &errors}
|
||||||
|
|
||||||
cookie, err := dkr.Prepare(ctx, task)
|
cookie, err := dkr.Prepare(ctx, task)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -109,10 +115,11 @@ func TestRunnerDockerStdin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if result.Status() != "success" {
|
if result.Status() != "success" {
|
||||||
t.Error("Test should successfully run the image")
|
t.Fatalf("Test should successfully run the image: %s output: %s errors: %s",
|
||||||
|
result.Error(), output.String(), errors.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
expect := "Hello test!"
|
expect := "italian parsley"
|
||||||
got := output.String()
|
got := output.String()
|
||||||
if !strings.Contains(got, expect) {
|
if !strings.Contains(got, expect) {
|
||||||
t.Errorf("Test expected output to contain '%s', got '%s'", expect, got)
|
t.Errorf("Test expected output to contain '%s', got '%s'", expect, got)
|
||||||
@@ -120,7 +127,7 @@ func TestRunnerDockerStdin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRegistry(t *testing.T) {
|
func TestRegistry(t *testing.T) {
|
||||||
image := "fnproject/hello"
|
image := "fnproject/fn-test-utils"
|
||||||
|
|
||||||
sizer, err := CheckRegistry(context.Background(), image, docker.AuthConfiguration{})
|
sizer, err := CheckRegistry(context.Background(), image, docker.AuthConfiguration{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -95,14 +95,14 @@ func TestDecimate(t *testing.T) {
|
|||||||
|
|
||||||
func TestParseImage(t *testing.T) {
|
func TestParseImage(t *testing.T) {
|
||||||
cases := map[string][]string{
|
cases := map[string][]string{
|
||||||
"fnproject/hello": {"", "fnproject/hello", "latest"},
|
"fnproject/fn-test-utils": {"", "fnproject/fn-test-utils", "latest"},
|
||||||
"fnproject/hello:v1": {"", "fnproject/hello", "v1"},
|
"fnproject/fn-test-utils:v1": {"", "fnproject/fn-test-utils", "v1"},
|
||||||
"my.registry/hello": {"my.registry", "hello", "latest"},
|
"my.registry/fn-test-utils": {"my.registry", "fn-test-utils", "latest"},
|
||||||
"my.registry/hello:v1": {"my.registry", "hello", "v1"},
|
"my.registry/fn-test-utils:v1": {"my.registry", "fn-test-utils", "v1"},
|
||||||
"mongo": {"", "library/mongo", "latest"},
|
"mongo": {"", "library/mongo", "latest"},
|
||||||
"mongo:v1": {"", "library/mongo", "v1"},
|
"mongo:v1": {"", "library/mongo", "v1"},
|
||||||
"quay.com/fnproject/hello": {"quay.com", "fnproject/hello", "latest"},
|
"quay.com/fnproject/fn-test-utils": {"quay.com", "fnproject/fn-test-utils", "latest"},
|
||||||
"quay.com:8080/fnproject/hello:v2": {"quay.com:8080", "fnproject/hello", "v2"},
|
"quay.com:8080/fnproject/fn-test-utils:v2": {"quay.com:8080", "fnproject/fn-test-utils", "v2"},
|
||||||
"localhost.localdomain:5000/samalba/hipache:latest": {"localhost.localdomain:5000", "samalba/hipache", "latest"},
|
"localhost.localdomain:5000/samalba/hipache:latest": {"localhost.localdomain:5000", "samalba/hipache", "latest"},
|
||||||
"localhost.localdomain:5000/samalba/hipache/isthisallowedeven:latest": {"localhost.localdomain:5000", "samalba/hipache/isthisallowedeven", "latest"},
|
"localhost.localdomain:5000/samalba/hipache/isthisallowedeven:latest": {"localhost.localdomain:5000", "samalba/hipache/isthisallowedeven", "latest"},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -526,7 +526,7 @@ func Test(t *testing.T, dsf func(t *testing.T) models.Datastore) {
|
|||||||
// unchanged
|
// unchanged
|
||||||
AppName: testRoute.AppName,
|
AppName: testRoute.AppName,
|
||||||
Path: testRoute.Path,
|
Path: testRoute.Path,
|
||||||
Image: "fnproject/hello",
|
Image: "fnproject/fn-test-utils",
|
||||||
Type: "sync",
|
Type: "sync",
|
||||||
Format: "http",
|
Format: "http",
|
||||||
IdleTimeout: testRoute.IdleTimeout,
|
IdleTimeout: testRoute.IdleTimeout,
|
||||||
@@ -570,7 +570,7 @@ func Test(t *testing.T, dsf func(t *testing.T) models.Datastore) {
|
|||||||
// unchanged
|
// unchanged
|
||||||
AppName: testRoute.AppName,
|
AppName: testRoute.AppName,
|
||||||
Path: testRoute.Path,
|
Path: testRoute.Path,
|
||||||
Image: "fnproject/hello",
|
Image: "fnproject/fn-test-utils",
|
||||||
Type: "sync",
|
Type: "sync",
|
||||||
Format: "http",
|
Format: "http",
|
||||||
Timeout: 2,
|
Timeout: 2,
|
||||||
@@ -724,7 +724,7 @@ 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/fn-test-utils",
|
||||||
Type: "sync",
|
Type: "sync",
|
||||||
Format: "http",
|
Format: "http",
|
||||||
Timeout: models.DefaultTimeout,
|
Timeout: models.DefaultTimeout,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ 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/fn-test-utils",
|
||||||
Type: "sync",
|
Type: "sync",
|
||||||
Format: "http",
|
Format: "http",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ func TestRootMiddleware(t *testing.T) {
|
|||||||
{Name: "myapp2", Config: models.Config{}},
|
{Name: "myapp2", Config: models.Config{}},
|
||||||
},
|
},
|
||||||
[]*models.Route{
|
[]*models.Route{
|
||||||
{Path: "/", AppName: "myapp", Image: "fnproject/hello", Type: "sync", Memory: 128, CPUs: 100, Timeout: 30, IdleTimeout: 30, Headers: map[string][]string{"X-Function": {"Test"}}},
|
{Path: "/", AppName: "myapp", Image: "fnproject/fn-test-utils", Type: "sync", Memory: 128, CPUs: 100, Timeout: 30, IdleTimeout: 30, 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: "/myroute", AppName: "myapp", Image: "fnproject/fn-test-utils", Type: "sync", Memory: 128, Timeout: 30, IdleTimeout: 30, Headers: map[string][]string{"X-Function": {"Test"}}},
|
||||||
{Path: "/app2func", AppName: "myapp2", Image: "fnproject/hello", Type: "sync", Memory: 128, Timeout: 30, IdleTimeout: 30, Headers: map[string][]string{"X-Function": {"Test"}},
|
{Path: "/app2func", AppName: "myapp2", Image: "fnproject/fn-test-utils", Type: "sync", Memory: 128, Timeout: 30, IdleTimeout: 30, Headers: map[string][]string{"X-Function": {"Test"}},
|
||||||
Config: map[string]string{"NAME": "johnny"},
|
Config: map[string]string{"NAME": "johnny"},
|
||||||
},
|
},
|
||||||
}, nil,
|
}, nil,
|
||||||
@@ -119,9 +119,9 @@ func TestRootMiddleware(t *testing.T) {
|
|||||||
expectedCode int
|
expectedCode int
|
||||||
expectedInBody string
|
expectedInBody string
|
||||||
}{
|
}{
|
||||||
{"/r/myapp", ``, "GET", map[string][]string{}, http.StatusOK, "middle"},
|
{"/r/myapp", `{"isDebug": true}`, "GET", map[string][]string{}, http.StatusOK, "middle"},
|
||||||
{"/r/myapp/myroute", ``, "GET", map[string][]string{}, http.StatusOK, "middle"},
|
{"/r/myapp/myroute", `{"isDebug": true}`, "GET", map[string][]string{}, http.StatusOK, "middle"},
|
||||||
{"/v1/apps", ``, "GET", map[string][]string{"funcit": {"Test"}}, http.StatusOK, "johnny"},
|
{"/v1/apps", `{"isDebug": true}`, "GET", map[string][]string{"funcit": {"Test"}}, http.StatusOK, "johnny"},
|
||||||
} {
|
} {
|
||||||
body := strings.NewReader(test.body)
|
body := strings.NewReader(test.body)
|
||||||
req, err := http.NewRequest(test.method, "http://127.0.0.1:8080"+test.path, body)
|
req, err := http.NewRequest(test.method, "http://127.0.0.1:8080"+test.path, body)
|
||||||
|
|||||||
@@ -104,10 +104,10 @@ func TestRouteCreate(t *testing.T) {
|
|||||||
{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.ErrRoutesMissingPath},
|
{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.ErrRoutesMissingImage},
|
{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.ErrRoutesMissingPath},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/fn-test-utils", "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.ErrRoutesInvalidPath},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/fn-test-utils", "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.ErrAppsInvalidName},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/$/routes", `{ "route": { "image": "fnproject/fn-test-utils", "path": "/myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrAppsInvalidName},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync", "cpus": "-100" } }`, http.StatusBadRequest, models.ErrInvalidCPUs},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/fn-test-utils", "path": "/myroute", "type": "sync", "cpus": "-100" } }`, http.StatusBadRequest, models.ErrInvalidCPUs},
|
||||||
{datastore.NewMockInit(nil,
|
{datastore.NewMockInit(nil,
|
||||||
[]*models.Route{
|
[]*models.Route{
|
||||||
{
|
{
|
||||||
@@ -115,12 +115,12 @@ func TestRouteCreate(t *testing.T) {
|
|||||||
Path: "/myroute",
|
Path: "/myroute",
|
||||||
},
|
},
|
||||||
}, nil,
|
}, nil,
|
||||||
), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync" } }`, http.StatusConflict, models.ErrRoutesAlreadyExists},
|
), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/fn-test-utils", "path": "/myroute", "type": "sync" } }`, http.StatusConflict, models.ErrRoutesAlreadyExists},
|
||||||
|
|
||||||
// success
|
// success
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync" } }`, http.StatusOK, nil},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/fn-test-utils", "path": "/myroute", "type": "sync" } }`, http.StatusOK, nil},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync", "cpus": "100m" } }`, http.StatusOK, nil},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/fn-test-utils", "path": "/myroute", "type": "sync", "cpus": "100m" } }`, http.StatusOK, nil},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/hello", "path": "/myroute", "type": "sync", "cpus": "0.2" } }`, http.StatusOK, nil},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPost, "/v1/apps/a/routes", `{ "route": { "image": "fnproject/fn-test-utils", "path": "/myroute", "type": "sync", "cpus": "0.2" } }`, http.StatusOK, nil},
|
||||||
} {
|
} {
|
||||||
test.run(t, i, buf)
|
test.run(t, i, buf)
|
||||||
}
|
}
|
||||||
@@ -135,15 +135,15 @@ func TestRoutePut(t *testing.T) {
|
|||||||
{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.ErrRoutesMissingImage},
|
{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.ErrRoutesMissingImage},
|
{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/fn-test-utils", "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/fn-test-utils", "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.ErrAppsInvalidName},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/$/routes/myroute", `{ "route": { "image": "fnproject/fn-test-utils", "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.ErrRoutesInvalidType},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/fn-test-utils", "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.ErrRoutesInvalidFormat},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/fn-test-utils", "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/fn-test-utils", "path": "/myroute", "type": "sync" } }`, http.StatusOK, nil},
|
||||||
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/hello", "type": "sync" } }`, http.StatusOK, nil},
|
{datastore.NewMock(), logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute", `{ "route": { "image": "fnproject/fn-test-utils", "type": "sync" } }`, http.StatusOK, nil},
|
||||||
} {
|
} {
|
||||||
test.run(t, i, buf)
|
test.run(t, i, buf)
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,7 @@ func TestRouteList(t *testing.T) {
|
|||||||
{
|
{
|
||||||
AppName: "myapp",
|
AppName: "myapp",
|
||||||
Path: "/myroute2",
|
Path: "/myroute2",
|
||||||
Image: "fnproject/hello",
|
Image: "fnproject/fn-test-utils",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nil, // no calls
|
nil, // no calls
|
||||||
@@ -241,7 +241,7 @@ func TestRouteList(t *testing.T) {
|
|||||||
{"/v1/apps/myapp/routes?per_page=1&cursor=" + r2b, "", http.StatusOK, nil, 1, r3b},
|
{"/v1/apps/myapp/routes?per_page=1&cursor=" + r2b, "", http.StatusOK, nil, 1, r3b},
|
||||||
{"/v1/apps/myapp/routes?per_page=100&cursor=" + r2b, "", http.StatusOK, nil, 1, ""}, // cursor is empty if per_page > len(results)
|
{"/v1/apps/myapp/routes?per_page=100&cursor=" + r2b, "", http.StatusOK, nil, 1, ""}, // cursor is empty if per_page > len(results)
|
||||||
{"/v1/apps/myapp/routes?per_page=1&cursor=" + r3b, "", http.StatusOK, nil, 0, ""}, // cursor could point to empty page
|
{"/v1/apps/myapp/routes?per_page=1&cursor=" + r3b, "", http.StatusOK, nil, 0, ""}, // cursor could point to empty page
|
||||||
{"/v1/apps/myapp/routes?image=fnproject/hello", "", http.StatusOK, nil, 1, ""},
|
{"/v1/apps/myapp/routes?image=fnproject/fn-test-utils", "", http.StatusOK, nil, 1, ""},
|
||||||
} {
|
} {
|
||||||
_, rec := routerRequest(t, srv.Router, "GET", test.path, nil)
|
_, rec := routerRequest(t, srv.Router, "GET", test.path, nil)
|
||||||
|
|
||||||
@@ -323,7 +323,7 @@ func TestRouteUpdate(t *testing.T) {
|
|||||||
for i, test := range []routeTestCase{
|
for i, test := range []routeTestCase{
|
||||||
// success
|
// success
|
||||||
{ds, logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute/do", `{ "route": { "image": "fnproject/yodawg" } }`, http.StatusOK, nil},
|
{ds, logs.NewMock(), http.MethodPut, "/v1/apps/a/routes/myroute/do", `{ "route": { "image": "fnproject/yodawg" } }`, http.StatusOK, nil},
|
||||||
{ds, 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": { "image": "fnproject/fn-test-utils" } }`, http.StatusOK, nil},
|
||||||
|
|
||||||
// errors (after success, so route exists)
|
// errors (after success, so route exists)
|
||||||
{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.ErrInvalidJSON},
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ func TestRouteRunnerAsyncExecution(t *testing.T) {
|
|||||||
[]*models.Route{
|
[]*models.Route{
|
||||||
{Type: "async", Path: "/hot-http", AppName: "myapp", Image: "fnproject/fn-test-utils", Format: "http", Config: map[string]string{"test": "true"}, Memory: 128, Timeout: 4, IdleTimeout: 30},
|
{Type: "async", Path: "/hot-http", AppName: "myapp", Image: "fnproject/fn-test-utils", Format: "http", Config: map[string]string{"test": "true"}, Memory: 128, Timeout: 4, IdleTimeout: 30},
|
||||||
{Type: "async", Path: "/hot-json", AppName: "myapp", Image: "fnproject/fn-test-utils", Format: "json", Config: map[string]string{"test": "true"}, Memory: 128, Timeout: 4, IdleTimeout: 30},
|
{Type: "async", Path: "/hot-json", AppName: "myapp", Image: "fnproject/fn-test-utils", Format: "json", Config: map[string]string{"test": "true"}, Memory: 128, Timeout: 4, IdleTimeout: 30},
|
||||||
{Type: "async", Path: "/myroute", AppName: "myapp", Image: "fnproject/hello", Config: map[string]string{"test": "true"}, Memory: 128, CPUs: 200, Timeout: 30, IdleTimeout: 30},
|
{Type: "async", Path: "/myroute", AppName: "myapp", Image: "fnproject/fn-test-utils", Config: map[string]string{"test": "true"}, Memory: 128, CPUs: 200, Timeout: 30, IdleTimeout: 30},
|
||||||
{Type: "async", Path: "/myerror", AppName: "myapp", Image: "fnproject/fn-test-utils", Config: map[string]string{"test": "true"}, Memory: 128, Timeout: 30, IdleTimeout: 30},
|
{Type: "async", Path: "/myerror", AppName: "myapp", Image: "fnproject/fn-test-utils", 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"}, Memory: 128, Timeout: 30, IdleTimeout: 30},
|
{Type: "async", Path: "/myroute/:param", AppName: "myapp", Image: "fnproject/fn-test-utils", Config: map[string]string{"test": "true"}, Memory: 128, Timeout: 30, IdleTimeout: 30},
|
||||||
}, nil,
|
}, nil,
|
||||||
)
|
)
|
||||||
mq := &mqs.Mock{}
|
mq := &mqs.Mock{}
|
||||||
@@ -56,16 +56,16 @@ func TestRouteRunnerAsyncExecution(t *testing.T) {
|
|||||||
expectedCode int
|
expectedCode int
|
||||||
expectedEnv map[string]string
|
expectedEnv map[string]string
|
||||||
}{
|
}{
|
||||||
{"/r/myapp/myroute", ``, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
{"/r/myapp/myroute", `{"isDebug": true}`, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
||||||
{"/r/myapp/hot-http", `{"sleepTime": 0, "isDebug": true}`, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
{"/r/myapp/hot-http", `{"isDebug": true}`, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
||||||
{"/r/myapp/hot-json", `{"sleepTime": 0, "isDebug": true}`, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
{"/r/myapp/hot-json", `{"isDebug": true}`, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
||||||
// FIXME: this just hangs
|
// FIXME: this just hangs
|
||||||
//{"/r/myapp/myroute/1", ``, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
//{"/r/myapp/myroute/1", ``, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
||||||
{"/r/myapp/myerror", `{"sleepTime": 0, "isDebug": true, "isCrash": true}`, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
{"/r/myapp/myerror", `{"isDebug": true, "isCrash": true}`, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
||||||
{"/r/myapp/myroute", `{ "name": "test" }`, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
{"/r/myapp/myroute", `{"echoContent": "test","isDebug": true}`, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
|
||||||
{
|
{
|
||||||
"/r/myapp/myroute",
|
"/r/myapp/myroute",
|
||||||
``,
|
`{"isDebug": true}`,
|
||||||
map[string][]string{"X-Function": []string{"test"}},
|
map[string][]string{"X-Function": []string{"test"}},
|
||||||
http.StatusAccepted,
|
http.StatusAccepted,
|
||||||
map[string]string{
|
map[string]string{
|
||||||
|
|||||||
@@ -134,12 +134,12 @@ func TestFullStack(t *testing.T) {
|
|||||||
{"list apps", "GET", "/v1/apps", ``, http.StatusOK, 0},
|
{"list apps", "GET", "/v1/apps", ``, http.StatusOK, 0},
|
||||||
{"get app", "GET", "/v1/apps/myapp", ``, http.StatusOK, 0},
|
{"get app", "GET", "/v1/apps/myapp", ``, http.StatusOK, 0},
|
||||||
// NOTE: cache is lazy, loads when a request comes in for the route, not when added
|
// NOTE: cache is lazy, loads when a request comes in for the route, not when added
|
||||||
{"add myroute", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myroute", "path": "/myroute", "image": "fnproject/hello", "type": "sync" } }`, http.StatusOK, 0},
|
{"add myroute", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myroute", "path": "/myroute", "image": "fnproject/fn-test-utils", "type": "sync" } }`, http.StatusOK, 0},
|
||||||
{"add myroute2", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myroute2", "path": "/myroute2", "image": "fnproject/fn-test-utils", "type": "sync" } }`, http.StatusOK, 0},
|
{"add myroute2", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myroute2", "path": "/myroute2", "image": "fnproject/fn-test-utils", "type": "sync" } }`, http.StatusOK, 0},
|
||||||
{"get myroute", "GET", "/v1/apps/myapp/routes/myroute", ``, http.StatusOK, 0},
|
{"get myroute", "GET", "/v1/apps/myapp/routes/myroute", ``, http.StatusOK, 0},
|
||||||
{"get myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 0},
|
{"get myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 0},
|
||||||
{"get all routes", "GET", "/v1/apps/myapp/routes", ``, http.StatusOK, 0},
|
{"get all routes", "GET", "/v1/apps/myapp/routes", ``, http.StatusOK, 0},
|
||||||
{"execute myroute", "POST", "/r/myapp/myroute", `{ "name": "Teste" }`, http.StatusOK, 1},
|
{"execute myroute", "POST", "/r/myapp/myroute", `{ "echoContent": "Teste" }`, http.StatusOK, 1},
|
||||||
{"execute myroute2", "POST", "/r/myapp/myroute2", `{"sleepTime": 0, "isDebug": true, "isCrash": true}`, http.StatusBadGateway, 2},
|
{"execute myroute2", "POST", "/r/myapp/myroute2", `{"sleepTime": 0, "isDebug": true, "isCrash": true}`, http.StatusBadGateway, 2},
|
||||||
{"get myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 2},
|
{"get myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 2},
|
||||||
{"delete myroute", "DELETE", "/v1/apps/myapp/routes/myroute", ``, http.StatusOK, 1},
|
{"delete myroute", "DELETE", "/v1/apps/myapp/routes/myroute", ``, http.StatusOK, 1},
|
||||||
@@ -170,11 +170,11 @@ func TestRunnerNode(t *testing.T) {
|
|||||||
// Add route with an API server using the same DB
|
// Add route with an API server using the same DB
|
||||||
{
|
{
|
||||||
apiServer := testServer(ds, &mqs.Mock{}, logDB, nil, ServerTypeAPI)
|
apiServer := testServer(ds, &mqs.Mock{}, logDB, nil, ServerTypeAPI)
|
||||||
_, rec := routerRequest(t, apiServer.Router, "POST", "/v1/apps/myapp/routes", bytes.NewBuffer([]byte(`{ "route": { "name": "myroute", "path": "/myroute", "image": "fnproject/hello", "type": "sync" } }`)))
|
_, rec := routerRequest(t, apiServer.Router, "POST", "/v1/apps/myapp/routes", bytes.NewBuffer([]byte(`{ "route": { "name": "myroute", "path": "/myroute", "image": "fnproject/fn-test-utils", "type": "sync" } }`)))
|
||||||
if rec.Code != http.StatusOK {
|
if rec.Code != http.StatusOK {
|
||||||
t.Errorf("Expected status code 200 when creating sync route, but got %d", rec.Code)
|
t.Errorf("Expected status code 200 when creating sync route, but got %d", rec.Code)
|
||||||
}
|
}
|
||||||
_, rec = routerRequest(t, apiServer.Router, "POST", "/v1/apps/myapp/routes", bytes.NewBuffer([]byte(`{ "route": { "name": "myasyncroute", "path": "/myasyncroute", "image": "fnproject/hello", "type": "async" } }`)))
|
_, rec = routerRequest(t, apiServer.Router, "POST", "/v1/apps/myapp/routes", bytes.NewBuffer([]byte(`{ "route": { "name": "myasyncroute", "path": "/myasyncroute", "image": "fnproject/fn-test-utils", "type": "async" } }`)))
|
||||||
if rec.Code != http.StatusOK {
|
if rec.Code != http.StatusOK {
|
||||||
t.Errorf("Expected status code 200 when creating async route, but got %d", rec.Code)
|
t.Errorf("Expected status code 200 when creating async route, but got %d", rec.Code)
|
||||||
}
|
}
|
||||||
@@ -191,15 +191,15 @@ func TestRunnerNode(t *testing.T) {
|
|||||||
expectedCacheSize int // TODO kill me
|
expectedCacheSize int // TODO kill me
|
||||||
}{
|
}{
|
||||||
// Support sync and async API calls
|
// Support sync and async API calls
|
||||||
{"execute sync route succeeds", "POST", "/r/myapp/myroute", `{ "name": "Teste" }`, http.StatusOK, 1},
|
{"execute sync route succeeds", "POST", "/r/myapp/myroute", `{ "echoContent": "Teste" }`, http.StatusOK, 1},
|
||||||
{"execute async route succeeds", "POST", "/r/myapp/myasyncroute", `{ "name": "Teste" }`, http.StatusAccepted, 1},
|
{"execute async route succeeds", "POST", "/r/myapp/myasyncroute", `{ "echoContent": "Teste" }`, http.StatusAccepted, 1},
|
||||||
|
|
||||||
// All other API functions should not be available on runner nodes
|
// All other API functions should not be available on runner nodes
|
||||||
{"create app not found", "POST", "/v1/apps", `{ "app": { "name": "myapp" } }`, http.StatusBadRequest, 0},
|
{"create app not found", "POST", "/v1/apps", `{ "app": { "name": "myapp" } }`, http.StatusBadRequest, 0},
|
||||||
{"list apps not found", "GET", "/v1/apps", ``, http.StatusBadRequest, 0},
|
{"list apps not found", "GET", "/v1/apps", ``, http.StatusBadRequest, 0},
|
||||||
{"get app not found", "GET", "/v1/apps/myapp", ``, http.StatusBadRequest, 0},
|
{"get app not found", "GET", "/v1/apps/myapp", ``, http.StatusBadRequest, 0},
|
||||||
|
|
||||||
{"add route not found", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myroute", "path": "/myroute", "image": "fnproject/hello", "type": "sync" } }`, http.StatusBadRequest, 0},
|
{"add route not found", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myroute", "path": "/myroute", "image": "fnproject/fn-test-utils", "type": "sync" } }`, http.StatusBadRequest, 0},
|
||||||
{"get route not found", "GET", "/v1/apps/myapp/routes/myroute", ``, http.StatusBadRequest, 0},
|
{"get route not found", "GET", "/v1/apps/myapp/routes/myroute", ``, http.StatusBadRequest, 0},
|
||||||
{"get all routes not found", "GET", "/v1/apps/myapp/routes", ``, http.StatusBadRequest, 0},
|
{"get all routes not found", "GET", "/v1/apps/myapp/routes", ``, http.StatusBadRequest, 0},
|
||||||
{"delete app not found", "DELETE", "/v1/apps/myapp", ``, http.StatusBadRequest, 0},
|
{"delete app not found", "DELETE", "/v1/apps/myapp", ``, http.StatusBadRequest, 0},
|
||||||
@@ -238,17 +238,17 @@ func TestApiNode(t *testing.T) {
|
|||||||
{"list apps", "GET", "/v1/apps", ``, http.StatusOK, 0},
|
{"list apps", "GET", "/v1/apps", ``, http.StatusOK, 0},
|
||||||
{"get app", "GET", "/v1/apps/myapp", ``, http.StatusOK, 0},
|
{"get app", "GET", "/v1/apps/myapp", ``, http.StatusOK, 0},
|
||||||
|
|
||||||
{"add myroute", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myroute", "path": "/myroute", "image": "fnproject/hello", "type": "sync" } }`, http.StatusOK, 0},
|
{"add myroute", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myroute", "path": "/myroute", "image": "fnproject/fn-test-utils", "type": "sync" } }`, http.StatusOK, 0},
|
||||||
{"add myroute2", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myroute2", "path": "/myroute2", "image": "fnproject/fn-test-utils", "type": "sync" } }`, http.StatusOK, 0},
|
{"add myroute2", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myroute2", "path": "/myroute2", "image": "fnproject/fn-test-utils", "type": "sync" } }`, http.StatusOK, 0},
|
||||||
{"add myasyncroute", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myasyncroute", "path": "/myasyncroute", "image": "fnproject/hello", "type": "async" } }`, http.StatusOK, 0},
|
{"add myasyncroute", "POST", "/v1/apps/myapp/routes", `{ "route": { "name": "myasyncroute", "path": "/myasyncroute", "image": "fnproject/fn-test-utils", "type": "async" } }`, http.StatusOK, 0},
|
||||||
{"get myroute", "GET", "/v1/apps/myapp/routes/myroute", ``, http.StatusOK, 0},
|
{"get myroute", "GET", "/v1/apps/myapp/routes/myroute", ``, http.StatusOK, 0},
|
||||||
{"get myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 0},
|
{"get myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 0},
|
||||||
{"get all routes", "GET", "/v1/apps/myapp/routes", ``, http.StatusOK, 0},
|
{"get all routes", "GET", "/v1/apps/myapp/routes", ``, http.StatusOK, 0},
|
||||||
|
|
||||||
// Don't support calling sync or async
|
// Don't support calling sync or async
|
||||||
{"execute myroute", "POST", "/r/myapp/myroute", `{ "name": "Teste" }`, http.StatusBadRequest, 1},
|
{"execute myroute", "POST", "/r/myapp/myroute", `{ "echoContent": "Teste" }`, http.StatusBadRequest, 1},
|
||||||
{"execute myroute2", "POST", "/r/myapp/myroute2", `{ "name": "Teste" }`, http.StatusBadRequest, 2},
|
{"execute myroute2", "POST", "/r/myapp/myroute2", `{ "echoContent": "Teste" }`, http.StatusBadRequest, 2},
|
||||||
{"execute myasyncroute", "POST", "/r/myapp/myasyncroute", `{ "name": "Teste" }`, http.StatusBadRequest, 1},
|
{"execute myasyncroute", "POST", "/r/myapp/myasyncroute", `{ "echoContent": "Teste" }`, http.StatusBadRequest, 1},
|
||||||
|
|
||||||
{"get myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 2},
|
{"get myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 2},
|
||||||
{"delete myroute", "DELETE", "/v1/apps/myapp/routes/myroute", ``, http.StatusOK, 1},
|
{"delete myroute", "DELETE", "/v1/apps/myapp/routes/myroute", ``, http.StatusOK, 1},
|
||||||
|
|||||||
Reference in New Issue
Block a user