fn: favor fn-test-utils over hello (to be decommissioned) (#761)

This commit is contained in:
Tolga Ceylan
2018-02-28 17:44:13 -08:00
committed by GitHub
parent a2ed1dfb2d
commit a83f2cfbe8
8 changed files with 72 additions and 65 deletions

View File

@@ -16,18 +16,19 @@ type taskDockerTest struct {
id string
input io.Reader
output io.Writer
errors io.Writer
}
func (f *taskDockerTest) Command() string { return "" }
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) Id() string { return f.id }
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) 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) Volumes() [][2]string { return [][2]string{} }
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) {
dkr := NewDocker(drivers.Config{})
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)
if err != nil {
@@ -59,7 +62,8 @@ func TestRunnerDocker(t *testing.T) {
}
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{})
ctx := context.Background()
input := `{"name": "test"}`
var output bytes.Buffer
input := `{"echoContent": "italian parsley", "isDebug": true}`
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)
if err != nil {
@@ -109,10 +115,11 @@ func TestRunnerDockerStdin(t *testing.T) {
}
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()
if !strings.Contains(got, expect) {
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) {
image := "fnproject/hello"
image := "fnproject/fn-test-utils"
sizer, err := CheckRegistry(context.Background(), image, docker.AuthConfiguration{})
if err != nil {

View File

@@ -95,14 +95,14 @@ func TestDecimate(t *testing.T) {
func TestParseImage(t *testing.T) {
cases := map[string][]string{
"fnproject/hello": {"", "fnproject/hello", "latest"},
"fnproject/hello:v1": {"", "fnproject/hello", "v1"},
"my.registry/hello": {"my.registry", "hello", "latest"},
"my.registry/hello:v1": {"my.registry", "hello", "v1"},
"fnproject/fn-test-utils": {"", "fnproject/fn-test-utils", "latest"},
"fnproject/fn-test-utils:v1": {"", "fnproject/fn-test-utils", "v1"},
"my.registry/fn-test-utils": {"my.registry", "fn-test-utils", "latest"},
"my.registry/fn-test-utils:v1": {"my.registry", "fn-test-utils", "v1"},
"mongo": {"", "library/mongo", "latest"},
"mongo:v1": {"", "library/mongo", "v1"},
"quay.com/fnproject/hello": {"quay.com", "fnproject/hello", "latest"},
"quay.com:8080/fnproject/hello:v2": {"quay.com:8080", "fnproject/hello", "v2"},
"quay.com/fnproject/fn-test-utils": {"quay.com", "fnproject/fn-test-utils", "latest"},
"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/isthisallowedeven:latest": {"localhost.localdomain:5000", "samalba/hipache/isthisallowedeven", "latest"},
}

View File

@@ -526,7 +526,7 @@ func Test(t *testing.T, dsf func(t *testing.T) models.Datastore) {
// unchanged
AppName: testRoute.AppName,
Path: testRoute.Path,
Image: "fnproject/hello",
Image: "fnproject/fn-test-utils",
Type: "sync",
Format: "http",
IdleTimeout: testRoute.IdleTimeout,
@@ -570,7 +570,7 @@ func Test(t *testing.T, dsf func(t *testing.T) models.Datastore) {
// unchanged
AppName: testRoute.AppName,
Path: testRoute.Path,
Image: "fnproject/hello",
Image: "fnproject/fn-test-utils",
Type: "sync",
Format: "http",
Timeout: 2,
@@ -724,7 +724,7 @@ var testApp = &models.App{
var testRoute = &models.Route{
AppName: testApp.Name,
Path: "/test",
Image: "fnproject/hello",
Image: "fnproject/fn-test-utils",
Type: "sync",
Format: "http",
Timeout: models.DefaultTimeout,

View File

@@ -20,7 +20,7 @@ var testApp = &models.App{
var testRoute = &models.Route{
AppName: testApp.Name,
Path: "/test",
Image: "fnproject/hello",
Image: "fnproject/fn-test-utils",
Type: "sync",
Format: "http",
}

View File

@@ -73,9 +73,9 @@ func TestRootMiddleware(t *testing.T) {
{Name: "myapp2", Config: models.Config{}},
},
[]*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: "/myroute", AppName: "myapp", Image: "fnproject/hello", 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: "/", 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/fn-test-utils", 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"},
},
}, nil,
@@ -119,9 +119,9 @@ func TestRootMiddleware(t *testing.T) {
expectedCode int
expectedInBody string
}{
{"/r/myapp", ``, "GET", map[string][]string{}, http.StatusOK, "middle"},
{"/r/myapp/myroute", ``, "GET", map[string][]string{}, http.StatusOK, "middle"},
{"/v1/apps", ``, "GET", map[string][]string{"funcit": {"Test"}}, http.StatusOK, "johnny"},
{"/r/myapp", `{"isDebug": true}`, "GET", map[string][]string{}, http.StatusOK, "middle"},
{"/r/myapp/myroute", `{"isDebug": true}`, "GET", map[string][]string{}, http.StatusOK, "middle"},
{"/v1/apps", `{"isDebug": true}`, "GET", map[string][]string{"funcit": {"Test"}}, http.StatusOK, "johnny"},
} {
body := strings.NewReader(test.body)
req, err := http.NewRequest(test.method, "http://127.0.0.1:8080"+test.path, body)

View File

@@ -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", `{ "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": { "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.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/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", "type": "sync" } }`, http.StatusBadRequest, models.ErrRoutesMissingPath},
{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/fn-test-utils", "path": "/myroute", "type": "sync" } }`, http.StatusBadRequest, models.ErrAppsInvalidName},
{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,
[]*models.Route{
{
@@ -115,12 +115,12 @@ func TestRouteCreate(t *testing.T) {
Path: "/myroute",
},
}, 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
{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/hello", "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" } }`, 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/fn-test-utils", "path": "/myroute", "type": "sync", "cpus": "0.2" } }`, http.StatusOK, nil},
} {
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", `{ "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": { "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/$/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.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", "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/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/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/fn-test-utils", "path": "/myroute", "format": "invalid-format", "type": "sync" } }`, http.StatusBadRequest, models.ErrRoutesInvalidFormat},
// 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", "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/fn-test-utils", "type": "sync" } }`, http.StatusOK, nil},
} {
test.run(t, i, buf)
}
@@ -211,7 +211,7 @@ func TestRouteList(t *testing.T) {
{
AppName: "myapp",
Path: "/myroute2",
Image: "fnproject/hello",
Image: "fnproject/fn-test-utils",
},
},
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=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?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)
@@ -323,7 +323,7 @@ func TestRouteUpdate(t *testing.T) {
for i, test := range []routeTestCase{
// success
{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)
{ds, logs.NewMock(), http.MethodPatch, "/v1/apps/a/routes/myroute/do", ``, http.StatusBadRequest, models.ErrInvalidJSON},

View File

@@ -42,9 +42,9 @@ func TestRouteRunnerAsyncExecution(t *testing.T) {
[]*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-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: "/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,
)
mq := &mqs.Mock{}
@@ -56,16 +56,16 @@ func TestRouteRunnerAsyncExecution(t *testing.T) {
expectedCode int
expectedEnv map[string]string
}{
{"/r/myapp/myroute", ``, 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-json", `{"sleepTime": 0, "isDebug": true}`, 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", `{"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
//{"/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/myroute", `{ "name": "test" }`, 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", `{"echoContent": "test","isDebug": true}`, map[string][]string{}, http.StatusAccepted, map[string]string{"TEST": "true", "APP": "true"}},
{
"/r/myapp/myroute",
``,
`{"isDebug": true}`,
map[string][]string{"X-Function": []string{"test"}},
http.StatusAccepted,
map[string]string{

View File

@@ -134,12 +134,12 @@ func TestFullStack(t *testing.T) {
{"list apps", "GET", "/v1/apps", ``, 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
{"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},
{"get myroute", "GET", "/v1/apps/myapp/routes/myroute", ``, 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},
{"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},
{"get myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 2},
{"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
{
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 {
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 {
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
}{
// Support sync and async API calls
{"execute sync route succeeds", "POST", "/r/myapp/myroute", `{ "name": "Teste" }`, http.StatusOK, 1},
{"execute async route succeeds", "POST", "/r/myapp/myasyncroute", `{ "name": "Teste" }`, http.StatusAccepted, 1},
{"execute sync route succeeds", "POST", "/r/myapp/myroute", `{ "echoContent": "Teste" }`, http.StatusOK, 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
{"create app not found", "POST", "/v1/apps", `{ "app": { "name": "myapp" } }`, http.StatusBadRequest, 0},
{"list apps not found", "GET", "/v1/apps", ``, 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 all routes not found", "GET", "/v1/apps/myapp/routes", ``, 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},
{"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 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 myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 0},
{"get all routes", "GET", "/v1/apps/myapp/routes", ``, http.StatusOK, 0},
// Don't support calling sync or async
{"execute myroute", "POST", "/r/myapp/myroute", `{ "name": "Teste" }`, http.StatusBadRequest, 1},
{"execute myroute2", "POST", "/r/myapp/myroute2", `{ "name": "Teste" }`, http.StatusBadRequest, 2},
{"execute myasyncroute", "POST", "/r/myapp/myasyncroute", `{ "name": "Teste" }`, http.StatusBadRequest, 1},
{"execute myroute", "POST", "/r/myapp/myroute", `{ "echoContent": "Teste" }`, http.StatusBadRequest, 1},
{"execute myroute2", "POST", "/r/myapp/myroute2", `{ "echoContent": "Teste" }`, http.StatusBadRequest, 2},
{"execute myasyncroute", "POST", "/r/myapp/myasyncroute", `{ "echoContent": "Teste" }`, http.StatusBadRequest, 1},
{"get myroute2", "GET", "/v1/apps/myapp/routes/myroute2", ``, http.StatusOK, 2},
{"delete myroute", "DELETE", "/v1/apps/myapp/routes/myroute", ``, http.StatusOK, 1},