Skip to content

Commit

Permalink
add test case for http handler
Browse files Browse the repository at this point in the history
  • Loading branch information
karupanerura committed Jul 7, 2019
1 parent 35f853e commit fb90241
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 13 deletions.
21 changes: 21 additions & 0 deletions common_test.go
@@ -0,0 +1,21 @@
package gaedispemu

import "net/url"

func mustParseURL(s string) *url.URL {
u, err := url.Parse(s)
if err != nil {
panic(err)
}

return u
}

func mustCompileHostPathMatcher(pattern string) HostPathMatcher {
m, err := CompileHostPathMatcher(pattern)
if err != nil {
panic(err)
}

return m
}
10 changes: 0 additions & 10 deletions dispatcher_test.go
@@ -1,7 +1,6 @@
package gaedispemu

import (
"net/url"
"testing"

"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -100,12 +99,3 @@ func TestDispatcher(t *testing.T) {
}
}
}

func mustParseURL(s string) *url.URL {
u, err := url.Parse(s)
if err != nil {
panic(err)
}

return u
}
6 changes: 3 additions & 3 deletions http_handler.go
Expand Up @@ -149,9 +149,9 @@ func getNewForwardedIPs(r *http.Request) string {
func getRemoteIP(r *http.Request) string {
// remove port
index := strings.Index(r.RemoteAddr, ":")
if index != -1 {
return r.RemoteAddr[:index]
if index == -1 {
return r.RemoteAddr
}

return r.RemoteAddr
return r.RemoteAddr[:index]
}
183 changes: 183 additions & 0 deletions http_handler_test.go
@@ -0,0 +1,183 @@
package gaedispemu

import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"strconv"
"strings"
"testing"

"github.com/MakeNowJust/heredoc"
)

func TestProxyHandler(t *testing.T) {
defaultBackend := httptest.NewServer(getBackendHandler("default"))
defer defaultBackend.Close()

fooBackend := httptest.NewServer(getBackendHandler("foo"))
defer fooBackend.Close()

dispatcher, err := NewDispatcher(
map[string]*Service{
"default": &Service{
Name: "default",
Origin: mustParseURL(defaultBackend.URL),
},
"foo": &Service{
Name: "foo",
Origin: mustParseURL(fooBackend.URL),
},
},
&Config{
Rules: []ConfigRule{
{
ServiceName: "default",
HostPathMatcher: mustCompileHostPathMatcher("*/default/*"),
},
{
ServiceName: "foo",
HostPathMatcher: mustCompileHostPathMatcher("*/foo/*"),
},
},
},
)
if err != nil {
t.Error(err)
}

proxy := httptest.NewServer(NewProxyHandler(dispatcher))
defer proxy.Close()

reqGet := func(service, path string, status int) (*http.Response, error) {
u := fmt.Sprintf("%s/%s%s", proxy.URL, service, path)
req, err := http.NewRequest(http.MethodGet, u, nil)
if err != nil {
return nil, err
}

req.Header.Set("User-Agent", "testing")
req.Header.Set("Status", strconv.Itoa(status))
return http.DefaultClient.Do(req)
}
reqPost := func(service, path, body string, status int) (*http.Response, error) {
u := fmt.Sprintf("%s/%s%s", proxy.URL, service, path)
req, err := http.NewRequest(http.MethodPost, u, strings.NewReader(body))
if err != nil {
return nil, err
}

req.Header.Set("User-Agent", "testing")
req.Header.Set("Status", strconv.Itoa(status))
return http.DefaultClient.Do(req)
}

for _, service := range []string{"default", "foo"} {
t.Run(service, func(t *testing.T) {
t.Run("GET", func(t *testing.T) {
res, err := reqGet(service, "/foo", 200)
if err != nil {
t.Error(err)
}
defer res.Body.Close()

if res.StatusCode != 200 {
t.Errorf("proxy status code should be 200 but got %d", res.StatusCode)
}
if s := res.Header.Get("Service"); s != service {
t.Errorf("should proxy to %s, but got %s", service, s)
}

body, err := ioutil.ReadAll(res.Body)
if err != nil {
t.Error(err)
}

got := string(body)
expected := fmt.Sprintf(heredoc.Doc(`
GET /%s/foo
Accept-Encoding: gzip
Status: 200
User-Agent: testing
X-Forwarded-For: 127.0.0.1
`), service)
if got != expected {
t.Errorf("Unexpected response body: %s", got)
}
})

t.Run("POST", func(t *testing.T) {
res, err := reqPost(service, "/", "this is a body\n", 201)
if err != nil {
t.Error(err)
}
defer res.Body.Close()

if res.StatusCode != 201 {
t.Errorf("proxy status code should be 201 but got %d", res.StatusCode)
}
if s := res.Header.Get("Service"); s != service {
t.Errorf("should proxy to default, but got %s", s)
}

body, err := ioutil.ReadAll(res.Body)
if err != nil {
t.Error(err)
}

got := string(body)
expected := fmt.Sprintf(heredoc.Doc(`
POST /%s/
Accept-Encoding: gzip
Status: 201
User-Agent: testing
X-Forwarded-For: 127.0.0.1
this is a body
`), service)
if got != expected {
t.Errorf("Unexpected response body: %s", got)
}
})
})
}

t.Run("NoBackend", func(t *testing.T) {
res, err := http.Get(proxy.URL)
if err != nil {
t.Error(err)
}
defer res.Body.Close()

if res.StatusCode != 404 {
t.Errorf("proxy status code should be 404 but got %d", res.StatusCode)
}
})
}

func getBackendHandler(service string) http.Handler {
replacer := strings.NewReplacer("\r\n", "\n")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Service", service)

status := r.Header.Get("Status")
if status != "" {
s, err := strconv.Atoi(status)
if err != nil {
panic(err)
}

w.WriteHeader(s)
}

var buf bytes.Buffer
r.Header.Write(&buf)
headers := replacer.Replace(buf.String())

io.WriteString(w, r.Method+" "+r.URL.RequestURI()+"\n")
io.WriteString(w, headers)
io.Copy(w, r.Body)
})
}

0 comments on commit fb90241

Please sign in to comment.