Remove V1 endpoints and Routes (#1210)

Largely a removal job, however many tests, particularly system level
ones relied on Routes. These have been migrated to use Fns.

* Add 410 response to swagger
* No app names in log tags
* Adding constraint in GetCall for FnID
* Adding test to check FnID is required on call
* Add fn_id to call selector
* Fix text in docker mem warning
* Correct buildConfig func name
* Test fix up
* Removing CPU setting from Agent test

CPU setting has been deprecated, but the code base is still riddled
with it. This just removes it from this layer. Really we need to
remove it from Call.

* Remove fn id check on calls
* Reintroduce fn id required on call
* Adding fnID to calls for execute test
* Correct setting of app id in middleware
* Removes root middlewares ability to redirect fun invocations
* Add over sized test check
* Removing call fn id check
This commit is contained in:
Tom Coupland
2018-09-17 16:44:51 +01:00
committed by Owen Cliffe
parent 6a01dae923
commit d56a49b321
82 changed files with 572 additions and 5558 deletions

View File

@@ -3,9 +3,7 @@ package tests
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"path"
@@ -13,6 +11,7 @@ import (
"testing"
"time"
"github.com/fnproject/fn/api/id"
"github.com/fnproject/fn/api/models"
)
@@ -21,7 +20,20 @@ import (
func TestCanExecuteFunction(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
rt := ensureRoute(t)
app := &models.App{Name: id.New().String()}
app = ensureApp(t, app)
fn := &models.Fn{
AppID: app.ID,
Name: id.New().String(),
Image: image,
Format: format,
ResourceConfig: models.ResourceConfig{
Memory: memory,
},
}
fn = ensureFn(t, fn)
lb, err := LB()
if err != nil {
@@ -31,13 +43,13 @@ func TestCanExecuteFunction(t *testing.T) {
Scheme: "http",
Host: lb,
}
u.Path = path.Join(u.Path, "r", appName, rt.Path)
u.Path = path.Join(u.Path, "invoke", fn.ID)
body := `{"echoContent": "HelloWorld", "sleepTime": 0, "isDebug": true}`
content := bytes.NewBuffer([]byte(body))
output := &bytes.Buffer{}
resp, err := callFN(ctx, u.String(), content, output, "POST")
resp, err := callFN(ctx, u.String(), content, output)
if err != nil {
t.Fatalf("Got unexpected error: %v", err)
}
@@ -68,7 +80,20 @@ func TestCanExecuteFunction(t *testing.T) {
func TestCanExecuteBigOutput(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
rt := ensureRoute(t)
app := &models.App{Name: id.New().String()}
app = ensureApp(t, app)
fn := &models.Fn{
AppID: app.ID,
Name: id.New().String(),
Image: image,
Format: format,
ResourceConfig: models.ResourceConfig{
Memory: memory,
},
}
fn = ensureFn(t, fn)
lb, err := LB()
if err != nil {
@@ -78,14 +103,14 @@ func TestCanExecuteBigOutput(t *testing.T) {
Scheme: "http",
Host: lb,
}
u.Path = path.Join(u.Path, "r", appName, rt.Path)
u.Path = path.Join(u.Path, "invoke", fn.ID)
// Approx 5.3MB output
body := `{"echoContent": "HelloWorld", "sleepTime": 0, "isDebug": true, "trailerRepeat": 410000}`
content := bytes.NewBuffer([]byte(body))
output := &bytes.Buffer{}
resp, err := callFN(ctx, u.String(), content, output, "POST")
resp, err := callFN(ctx, u.String(), content, output)
if err != nil {
t.Fatalf("Got unexpected error: %v", err)
}
@@ -105,7 +130,20 @@ func TestCanExecuteBigOutput(t *testing.T) {
func TestCanExecuteTooBigOutput(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
rt := ensureRoute(t)
app := &models.App{Name: id.New().String()}
app = ensureApp(t, app)
fn := &models.Fn{
AppID: app.ID,
Name: id.New().String(),
Image: image,
Format: format,
ResourceConfig: models.ResourceConfig{
Memory: memory,
},
}
fn = ensureFn(t, fn)
lb, err := LB()
if err != nil {
@@ -115,19 +153,19 @@ func TestCanExecuteTooBigOutput(t *testing.T) {
Scheme: "http",
Host: lb,
}
u.Path = path.Join(u.Path, "r", appName, rt.Path)
u.Path = path.Join(u.Path, "invoke", fn.ID)
// > 6MB output
body := `{"echoContent": "HelloWorld", "sleepTime": 0, "isDebug": true, "trailerRepeat": 600000}`
content := bytes.NewBuffer([]byte(body))
output := &bytes.Buffer{}
resp, err := callFN(ctx, u.String(), content, output, "POST")
resp, err := callFN(ctx, u.String(), content, output)
if err != nil {
t.Fatalf("Got unexpected error: %v", err)
}
exp := "{\"error\":{\"message\":\"function response too large\"}}\n"
exp := "{\"message\":\"function response too large\"}\n"
actual := output.String()
if !strings.Contains(exp, actual) || len(exp) != len(actual) {
@@ -142,7 +180,20 @@ func TestCanExecuteTooBigOutput(t *testing.T) {
func TestCanExecuteEmptyOutput(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
rt := ensureRoute(t)
app := &models.App{Name: id.New().String()}
app = ensureApp(t, app)
fn := &models.Fn{
AppID: app.ID,
Name: id.New().String(),
Image: image,
Format: format,
ResourceConfig: models.ResourceConfig{
Memory: memory,
},
}
fn = ensureFn(t, fn)
lb, err := LB()
if err != nil {
@@ -152,14 +203,14 @@ func TestCanExecuteEmptyOutput(t *testing.T) {
Scheme: "http",
Host: lb,
}
u.Path = path.Join(u.Path, "r", appName, rt.Path)
u.Path = path.Join(u.Path, "invoke", fn.ID)
// empty body output
body := `{"sleepTime": 0, "isDebug": true, "isEmptyBody": true}`
content := bytes.NewBuffer([]byte(body))
output := &bytes.Buffer{}
resp, err := callFN(ctx, u.String(), content, output, "POST")
resp, err := callFN(ctx, u.String(), content, output)
if err != nil {
t.Fatalf("Got unexpected error: %v", err)
}
@@ -178,7 +229,20 @@ func TestCanExecuteEmptyOutput(t *testing.T) {
func TestBasicConcurrentExecution(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
rt := ensureRoute(t)
app := &models.App{Name: id.New().String()}
app = ensureApp(t, app)
fn := &models.Fn{
AppID: app.ID,
Name: id.New().String(),
Image: image,
Format: format,
ResourceConfig: models.ResourceConfig{
Memory: memory,
},
}
fn = ensureFn(t, fn)
lb, err := LB()
if err != nil {
@@ -188,7 +252,7 @@ func TestBasicConcurrentExecution(t *testing.T) {
Scheme: "http",
Host: lb,
}
u.Path = path.Join(u.Path, "r", appName, rt.Path)
u.Path = path.Join(u.Path, "invoke", fn.ID)
results := make(chan error)
concurrentFuncs := 10
@@ -197,7 +261,7 @@ func TestBasicConcurrentExecution(t *testing.T) {
body := `{"echoContent": "HelloWorld", "sleepTime": 0, "isDebug": true}`
content := bytes.NewBuffer([]byte(body))
output := &bytes.Buffer{}
resp, err := callFN(ctx, u.String(), content, output, "POST")
resp, err := callFN(ctx, u.String(), content, output)
if err != nil {
results <- fmt.Errorf("Got unexpected error: %v", err)
return
@@ -222,87 +286,4 @@ func TestBasicConcurrentExecution(t *testing.T) {
t.Fatalf("Error in basic concurrency execution test: %v", err)
}
}
}
func callFN(ctx context.Context, u string, content io.Reader, output io.Writer, method string) (*http.Response, error) {
if method == "" {
if content == nil {
method = "GET"
} else {
method = "POST"
}
}
req, err := http.NewRequest(method, u, content)
if err != nil {
return nil, fmt.Errorf("error running route: %s", err)
}
req.Header.Set("Content-Type", "application/json")
req = req.WithContext(ctx)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error running route: %s", err)
}
io.Copy(output, resp.Body)
return resp, nil
}
func ensureRoute(t *testing.T, rts ...*models.Route) *models.Route {
var rt *models.Route
if len(rts) > 0 {
rt = rts[0]
} else {
rt = &models.Route{
Path: routeName + "yabbadabbadoo",
Image: image,
Format: format,
Memory: memory,
Type: typ,
}
}
var wrapped struct {
Route *models.Route `json:"route"`
}
wrapped.Route = rt
var buf bytes.Buffer
err := json.NewEncoder(&buf).Encode(wrapped)
if err != nil {
t.Fatal("error encoding body", err)
}
urlStr := host() + "/v1/apps/" + appName + "/routes" + rt.Path
u, err := url.Parse(urlStr)
if err != nil {
t.Fatal("error creating url", urlStr, err)
}
req, err := http.NewRequest("PUT", u.String(), &buf)
if err != nil {
t.Fatal("error creating request", err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatal("error creating route", err)
}
buf.Reset()
io.Copy(&buf, resp.Body)
if resp.StatusCode != 200 {
t.Fatal("error creating/updating app or otherwise ensuring it exists:", resp.StatusCode, buf.String())
}
wrapped.Route = nil
err = json.NewDecoder(&buf).Decode(&wrapped)
if err != nil {
t.Fatal("error decoding response")
}
return wrapped.Route
}

View File

@@ -3,6 +3,7 @@ package tests
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"net/url"
@@ -10,10 +11,31 @@ import (
"testing"
"time"
"github.com/fnproject/fn/api/id"
"github.com/fnproject/fn/api/models"
"github.com/fnproject/fn/api/runnerpool"
)
func callFN(ctx context.Context, u string, content io.Reader, output io.Writer) (*http.Response, error) {
method := "POST"
req, err := http.NewRequest(method, u, content)
if err != nil {
return nil, fmt.Errorf("error running fn: %s", err)
}
req.Header.Set("Content-Type", "application/json")
req = req.WithContext(ctx)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error running fn: %s", err)
}
io.Copy(output, resp.Body)
return resp, nil
}
// We should not be able to invoke a StatusImage
func TestCannotExecuteStatusImage(t *testing.T) {
if StatusImage == "" {
@@ -23,15 +45,19 @@ func TestCannotExecuteStatusImage(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
rt := &models.Route{
Path: routeName + "yogurt",
app := &models.App{Name: id.New().String()}
app = ensureApp(t, app)
fn := &models.Fn{
AppID: app.ID,
Name: id.New().String(),
Image: StatusImage,
Format: format,
Memory: memory,
Type: typ,
ResourceConfig: models.ResourceConfig{
Memory: memory,
},
}
rt = ensureRoute(t, rt)
fn = ensureFn(t, fn)
lb, err := LB()
if err != nil {
@@ -41,12 +67,12 @@ func TestCannotExecuteStatusImage(t *testing.T) {
Scheme: "http",
Host: lb,
}
u.Path = path.Join(u.Path, "r", appName, rt.Path)
u.Path = path.Join(u.Path, "invoke", fn.ID)
content := bytes.NewBuffer([]byte(`status`))
output := &bytes.Buffer{}
resp, err := callFN(ctx, u.String(), content, output, "POST")
resp, err := callFN(ctx, u.String(), content, output)
if err != nil {
t.Fatalf("Got unexpected error: %v", err)
}