Skip to content
Snippets Groups Projects
Commit 4367fc4e authored by Alex Ellis (VMware)'s avatar Alex Ellis (VMware) Committed by Alex Ellis
Browse files

Add test coverage for buildUpstreamRequest

parent 2f98ca88
No related branches found
No related tags found
No related merge requests found
...@@ -19,7 +19,7 @@ if [ "$1" ] ; then ...@@ -19,7 +19,7 @@ if [ "$1" ] ; then
fi fi
fi fi
NS=openfaas NS=alexellis
echo Building $NS/gateway:$eTAG echo Building $NS/gateway:$eTAG
......
...@@ -16,15 +16,15 @@ import ( ...@@ -16,15 +16,15 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
// Parse out the service name (group 1) and rest of path (group 2). // functionMatcher parses out the service name (group 1) and rest of path (group 2).
var functionMatcher = regexp.MustCompile("^/?(?:async-)?function/([^/?]+)([^?]*)") var functionMatcher = regexp.MustCompile("^/?(?:async-)?function/([^/?]+)([^?]*)")
// Indicies and meta-data for functionMatcher regex parts // Indicies and meta-data for functionMatcher regex parts
const ( const (
hasPathCount = 3 hasPathCount = 3
routeIndex = 0 routeIndex = 0 // routeIndex corresponds to /function/ or /async-function/
nameIndex = 1 nameIndex = 1 // nameIndex is the function name
pathIndex = 2 pathIndex = 2 // pathIndex is the path i.e. /employee/:id/
) )
// HTTPNotifier notify about HTTP request/response // HTTPNotifier notify about HTTP request/response
...@@ -218,28 +218,6 @@ func (f TransparentURLPathTransformer) Transform(r *http.Request) string { ...@@ -218,28 +218,6 @@ func (f TransparentURLPathTransformer) Transform(r *http.Request) string {
return r.URL.Path return r.URL.Path
} }
// FunctionPathTruncatingURLPathTransformer always truncated the path to "/".
type FunctionPathTruncatingURLPathTransformer struct {
}
// Transform always return a path of "/".
func (f FunctionPathTruncatingURLPathTransformer) Transform(r *http.Request) string {
ret := r.URL.Path
if ret != "" {
matcher := functionMatcher.Copy()
parts := matcher.FindStringSubmatch(ret)
// In the following regex, in the case of a match the r.URL.Path will be at `0`,
// the function name at `1` and the rest of the path (the part we are interested in)
// at `2`. For this transformer, all we need to do is confirm it is a function.
if len(parts) == hasPathCount {
ret = "/"
}
}
return ret
}
// FunctionPrefixTrimmingURLPathTransformer removes the "/function/servicename/" prefix from the URL path. // FunctionPrefixTrimmingURLPathTransformer removes the "/function/servicename/" prefix from the URL path.
type FunctionPrefixTrimmingURLPathTransformer struct { type FunctionPrefixTrimmingURLPathTransformer struct {
} }
......
...@@ -2,6 +2,7 @@ package handlers ...@@ -2,6 +2,7 @@ package handlers
import ( import (
"bytes" "bytes"
"fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
...@@ -151,12 +152,126 @@ func Test_getServiceName(t *testing.T) { ...@@ -151,12 +152,126 @@ func Test_getServiceName(t *testing.T) {
} }
} }
func Test_buildUpstreamRequest_Body_Method_Query_Path(t *testing.T) { func Test_buildUpstreamRequest_WithPathNoQuery(t *testing.T) {
srcBytes := []byte("hello world") srcBytes := []byte("hello world")
path := "/my/deep/path" functionPath := "/employee/info/300"
requestPath := fmt.Sprintf("/function/xyz%s", functionPath)
reader := bytes.NewReader(srcBytes)
request, _ := http.NewRequest(http.MethodPost, requestPath, reader)
request.Header.Set("X-Source", "unit-test")
queryWant := ""
if request.URL.RawQuery != queryWant {
t.Errorf("Query - want: %s, got: %s", queryWant, request.URL.RawQuery)
t.Fail()
}
transformer := FunctionPrefixTrimmingURLPathTransformer{}
transformedPath := transformer.Transform(request)
wantTransformedPath := functionPath
if transformedPath != wantTransformedPath {
t.Errorf("transformedPath want: %s, got %s", wantTransformedPath, transformedPath)
}
upstream := buildUpstreamRequest(request, "http://xyz:8080", transformedPath)
if request.Method != upstream.Method {
t.Errorf("Method - want: %s, got: %s", request.Method, upstream.Method)
t.Fail()
}
upstreamBytes, _ := ioutil.ReadAll(upstream.Body)
if string(upstreamBytes) != string(srcBytes) {
t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes))
t.Fail()
}
if request.Header.Get("X-Source") != upstream.Header.Get("X-Source") {
t.Errorf("Header X-Source - want: %s, got: %s", request.Header.Get("X-Source"), upstream.Header.Get("X-Source"))
t.Fail()
}
if request.URL.RawQuery != upstream.URL.RawQuery {
t.Errorf("URL.RawQuery - want: %s, got: %s", request.URL.RawQuery, upstream.URL.RawQuery)
t.Fail()
}
if functionPath != upstream.URL.Path {
t.Errorf("URL.Path - want: %s, got: %s", functionPath, upstream.URL.Path)
t.Fail()
}
}
func Test_buildUpstreamRequest_WithNoPathNoQuery(t *testing.T) {
srcBytes := []byte("hello world")
functionPath := "/"
requestPath := fmt.Sprintf("/function/xyz%s", functionPath)
reader := bytes.NewReader(srcBytes) reader := bytes.NewReader(srcBytes)
request, _ := http.NewRequest(http.MethodPost, "/function/xyz"+path+"?code=1", reader) request, _ := http.NewRequest(http.MethodPost, requestPath, reader)
request.Header.Set("X-Source", "unit-test")
queryWant := ""
if request.URL.RawQuery != queryWant {
t.Errorf("Query - want: %s, got: %s", queryWant, request.URL.RawQuery)
t.Fail()
}
transformer := FunctionPrefixTrimmingURLPathTransformer{}
transformedPath := transformer.Transform(request)
wantTransformedPath := "/"
if transformedPath != wantTransformedPath {
t.Errorf("transformedPath want: %s, got %s", wantTransformedPath, transformedPath)
}
upstream := buildUpstreamRequest(request, "http://xyz:8080", transformedPath)
if request.Method != upstream.Method {
t.Errorf("Method - want: %s, got: %s", request.Method, upstream.Method)
t.Fail()
}
upstreamBytes, _ := ioutil.ReadAll(upstream.Body)
if string(upstreamBytes) != string(srcBytes) {
t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes))
t.Fail()
}
if request.Header.Get("X-Source") != upstream.Header.Get("X-Source") {
t.Errorf("Header X-Source - want: %s, got: %s", request.Header.Get("X-Source"), upstream.Header.Get("X-Source"))
t.Fail()
}
if request.URL.RawQuery != upstream.URL.RawQuery {
t.Errorf("URL.RawQuery - want: %s, got: %s", request.URL.RawQuery, upstream.URL.RawQuery)
t.Fail()
}
if functionPath != upstream.URL.Path {
t.Errorf("URL.Path - want: %s, got: %s", functionPath, upstream.URL.Path)
t.Fail()
}
}
func Test_buildUpstreamRequest_WithPathAndQuery(t *testing.T) {
srcBytes := []byte("hello world")
functionPath := "/employee/info/300"
requestPath := fmt.Sprintf("/function/xyz%s?code=1", functionPath)
reader := bytes.NewReader(srcBytes)
request, _ := http.NewRequest(http.MethodPost, requestPath, reader)
request.Header.Set("X-Source", "unit-test") request.Header.Set("X-Source", "unit-test")
if request.URL.RawQuery != "code=1" { if request.URL.RawQuery != "code=1" {
...@@ -167,6 +282,11 @@ func Test_buildUpstreamRequest_Body_Method_Query_Path(t *testing.T) { ...@@ -167,6 +282,11 @@ func Test_buildUpstreamRequest_Body_Method_Query_Path(t *testing.T) {
transformer := FunctionPrefixTrimmingURLPathTransformer{} transformer := FunctionPrefixTrimmingURLPathTransformer{}
transformedPath := transformer.Transform(request) transformedPath := transformer.Transform(request)
wantTransformedPath := functionPath
if transformedPath != wantTransformedPath {
t.Errorf("transformedPath want: %s, got %s", wantTransformedPath, transformedPath)
}
upstream := buildUpstreamRequest(request, "http://xyz:8080", transformedPath) upstream := buildUpstreamRequest(request, "http://xyz:8080", transformedPath)
if request.Method != upstream.Method { if request.Method != upstream.Method {
...@@ -191,8 +311,8 @@ func Test_buildUpstreamRequest_Body_Method_Query_Path(t *testing.T) { ...@@ -191,8 +311,8 @@ func Test_buildUpstreamRequest_Body_Method_Query_Path(t *testing.T) {
t.Fail() t.Fail()
} }
if path != upstream.URL.Path { if functionPath != upstream.URL.Path {
t.Errorf("URL.Path - want: %s, got: %s", path, upstream.URL.Path) t.Errorf("URL.Path - want: %s, got: %s", functionPath, upstream.URL.Path)
t.Fail() t.Fail()
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment