mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
* fn: user friendly timeout handling changes Timeout setting in routes now means "maximum amount of time a function can run in a container". Total wait time for a given http request is now expected to be handled by the client. As long as the client waits, the LB, runner or agents will search for resources to schedule it.
213 lines
5.4 KiB
Go
213 lines
5.4 KiB
Go
package protocol
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/fnproject/fn/api/models"
|
|
)
|
|
|
|
type RequestData struct {
|
|
A string `json:"a"`
|
|
}
|
|
|
|
func setupRequest(data interface{}) (*callInfoImpl, context.CancelFunc) {
|
|
req := &http.Request{
|
|
Method: http.MethodPost,
|
|
URL: &url.URL{
|
|
Scheme: "http",
|
|
Host: "localhost:8080",
|
|
Path: "/v1/apps",
|
|
RawQuery: "something=something&etc=etc",
|
|
},
|
|
ProtoMajor: 1,
|
|
ProtoMinor: 1,
|
|
Header: http.Header{
|
|
"Host": []string{"localhost:8080"},
|
|
"User-Agent": []string{"curl/7.51.0"},
|
|
"Content-Type": []string{"application/json"},
|
|
},
|
|
Host: "localhost:8080",
|
|
}
|
|
var buf bytes.Buffer
|
|
|
|
if data != nil {
|
|
_ = json.NewEncoder(&buf).Encode(data)
|
|
}
|
|
req.Body = ioutil.NopCloser(&buf)
|
|
|
|
call := &models.Call{Type: "sync"}
|
|
|
|
// fixup URL in models.Call
|
|
call.URL = req.URL.String()
|
|
|
|
ctx, cancel := context.WithTimeout(req.Context(), 1*time.Second)
|
|
ci := &callInfoImpl{call: call, req: req.WithContext(ctx)}
|
|
return ci, cancel
|
|
}
|
|
|
|
func TestJSONProtocolwriteJSONInputRequestBasicFields(t *testing.T) {
|
|
ci, cancel := setupRequest(nil)
|
|
defer cancel()
|
|
r, w := io.Pipe()
|
|
proto := JSONProtocol{w, r}
|
|
go func() {
|
|
err := proto.writeJSONToContainer(ci)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
w.Close()
|
|
}()
|
|
incomingReq := &jsonIn{}
|
|
bb := new(bytes.Buffer)
|
|
|
|
_, err := bb.ReadFrom(r)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
err = json.Unmarshal(bb.Bytes(), incomingReq)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
if incomingReq.CallID != ci.CallID() {
|
|
t.Errorf("Request CallID assertion mismatch: expected: %s, got %s",
|
|
ci.CallID(), incomingReq.CallID)
|
|
}
|
|
if incomingReq.ContentType != ci.ContentType() {
|
|
t.Errorf("Request ContentType assertion mismatch: expected: %s, got %s",
|
|
ci.ContentType(), incomingReq.ContentType)
|
|
}
|
|
if incomingReq.Deadline != ci.Deadline().String() {
|
|
t.Errorf("Request Deadline assertion mismatch: expected: %s, got %s",
|
|
ci.Deadline(), incomingReq.Deadline)
|
|
}
|
|
}
|
|
|
|
func TestJSONProtocolwriteJSONInputRequestWithData(t *testing.T) {
|
|
rDataBefore := RequestData{A: "a"}
|
|
ci, cancel := setupRequest(rDataBefore)
|
|
defer cancel()
|
|
r, w := io.Pipe()
|
|
proto := JSONProtocol{w, r}
|
|
go func() {
|
|
err := proto.writeJSONToContainer(ci)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
w.Close()
|
|
}()
|
|
incomingReq := &jsonIn{}
|
|
bb := new(bytes.Buffer)
|
|
|
|
_, err := bb.ReadFrom(r)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
err = json.Unmarshal(bb.Bytes(), incomingReq)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
rDataAfter := new(RequestData)
|
|
err = json.Unmarshal([]byte(incomingReq.Body), &rDataAfter)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
if rDataBefore.A != rDataAfter.A {
|
|
t.Errorf("Request data assertion mismatch: expected: %s, got %s",
|
|
rDataBefore.A, rDataAfter.A)
|
|
}
|
|
if incomingReq.Protocol.Type != ci.ProtocolType() {
|
|
t.Errorf("Call protocol type assertion mismatch: expected: %s, got %s",
|
|
ci.ProtocolType(), incomingReq.Protocol.Type)
|
|
}
|
|
if incomingReq.Protocol.Method != ci.Method() {
|
|
t.Errorf("Call protocol method assertion mismatch: expected: %s, got %s",
|
|
ci.Method(), incomingReq.Protocol.Method)
|
|
}
|
|
if incomingReq.Protocol.RequestURL != ci.RequestURL() {
|
|
t.Errorf("Call protocol request URL assertion mismatch: expected: %s, got %s",
|
|
ci.RequestURL(), incomingReq.Protocol.RequestURL)
|
|
}
|
|
}
|
|
|
|
func TestJSONProtocolwriteJSONInputRequestWithoutData(t *testing.T) {
|
|
ci, cancel := setupRequest(nil)
|
|
defer cancel()
|
|
r, w := io.Pipe()
|
|
proto := JSONProtocol{w, r}
|
|
go func() {
|
|
err := proto.writeJSONToContainer(ci)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
w.Close()
|
|
}()
|
|
incomingReq := &jsonIn{}
|
|
bb := new(bytes.Buffer)
|
|
|
|
_, err := bb.ReadFrom(r)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
err = json.Unmarshal(bb.Bytes(), incomingReq)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
if incomingReq.Body != "" {
|
|
t.Errorf("Request body assertion mismatch: expected: %s, got %s",
|
|
"<empty-string>", incomingReq.Body)
|
|
}
|
|
if !models.Headers(ci.req.Header).Equals(models.Headers(incomingReq.Protocol.Headers)) {
|
|
t.Errorf("Request headers assertion mismatch: expected: %s, got %s",
|
|
ci.req.Header, incomingReq.Protocol.Headers)
|
|
}
|
|
if incomingReq.Protocol.Type != ci.ProtocolType() {
|
|
t.Errorf("Call protocol type assertion mismatch: expected: %s, got %s",
|
|
ci.ProtocolType(), incomingReq.Protocol.Type)
|
|
}
|
|
if incomingReq.Protocol.Method != ci.Method() {
|
|
t.Errorf("Call protocol method assertion mismatch: expected: %s, got %s",
|
|
ci.Method(), incomingReq.Protocol.Method)
|
|
}
|
|
if incomingReq.Protocol.RequestURL != ci.RequestURL() {
|
|
t.Errorf("Call protocol request URL assertion mismatch: expected: %s, got %s",
|
|
ci.RequestURL(), incomingReq.Protocol.RequestURL)
|
|
}
|
|
}
|
|
|
|
func TestJSONProtocolwriteJSONInputRequestWithQuery(t *testing.T) {
|
|
ci, cancel := setupRequest(nil)
|
|
defer cancel()
|
|
r, w := io.Pipe()
|
|
proto := JSONProtocol{w, r}
|
|
go func() {
|
|
err := proto.writeJSONToContainer(ci)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
w.Close()
|
|
}()
|
|
incomingReq := &jsonIn{}
|
|
bb := new(bytes.Buffer)
|
|
|
|
_, err := bb.ReadFrom(r)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
err = json.Unmarshal(bb.Bytes(), incomingReq)
|
|
if err != nil {
|
|
t.Error(err.Error())
|
|
}
|
|
if incomingReq.Protocol.RequestURL != ci.call.URL {
|
|
t.Errorf("Request URL does not match protocol URL: expected: %s, got %s",
|
|
ci.call.URL, incomingReq.Protocol.RequestURL)
|
|
}
|
|
}
|