diff --git a/app/proxy/proxy_test.go b/app/proxy/proxy_test.go index 0154432f..4d916b18 100644 --- a/app/proxy/proxy_test.go +++ b/app/proxy/proxy_test.go @@ -34,6 +34,7 @@ func TestHttp_Do(t *testing.T) { t.Logf("req: %v", r) w.Header().Add("h1", "v1") require.Equal(t, "127.0.0.1", r.Header.Get("X-Real-IP")) + require.Equal(t, "127.0.0.1", r.Header.Get("X-Forwarded-For")) fmt.Fprintf(w, "response %s", r.URL.String()) })) @@ -59,7 +60,7 @@ func TestHttp_Do(t *testing.T) { client := http.Client{} - { + t.Run("to 127.0.0.1, good", func(t *testing.T) { req, err := http.NewRequest("GET", "http://127.0.0.1:"+strconv.Itoa(port)+"/api/something", http.NoBody) require.NoError(t, err) resp, err := client.Do(req) @@ -75,9 +76,9 @@ func TestHttp_Do(t *testing.T) { assert.Equal(t, "v1", resp.Header.Get("h1")) assert.Equal(t, "vv1", resp.Header.Get("hh1")) assert.Equal(t, "vv2", resp.Header.Get("hh2")) - } + }) - { + t.Run("to localhost, good", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/api/something") require.NoError(t, err) defer resp.Body.Close() @@ -89,9 +90,9 @@ func TestHttp_Do(t *testing.T) { assert.Equal(t, "response /123/something", string(body)) assert.Equal(t, "reproxy", resp.Header.Get("App-Name")) assert.Equal(t, "v1", resp.Header.Get("h1")) - } + }) - { + t.Run("bad gateway", func(t *testing.T) { resp, err := client.Get("http://127.0.0.1:" + strconv.Itoa(port) + "/bad/something") require.NoError(t, err) defer resp.Body.Close() @@ -100,9 +101,9 @@ func TestHttp_Do(t *testing.T) { require.NoError(t, err) assert.Contains(t, string(b), "Sorry for the inconvenience") assert.Equal(t, "text/html; charset=utf-8", resp.Header.Get("Content-Type")) - } + }) - { + t.Run("url encode", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/api/test%20%25%20and%20&,%20and%20other%20characters%20@%28%29%5E%21") require.NoError(t, err) defer resp.Body.Close() @@ -114,7 +115,7 @@ func TestHttp_Do(t *testing.T) { assert.Equal(t, "response /123/test%20%25%20and%20&,%20and%20other%20characters%20@%28%29%5E%21", string(body)) assert.Equal(t, "reproxy", resp.Header.Get("App-Name")) assert.Equal(t, "v1", resp.Header.Get("h1")) - } + }) } func TestHttp_DoWithAssets(t *testing.T) { @@ -153,7 +154,7 @@ func TestHttp_DoWithAssets(t *testing.T) { client := http.Client{} - { + t.Run("api call", func(t *testing.T) { req, err := http.NewRequest("GET", "http://127.0.0.1:"+strconv.Itoa(port)+"/api/something", http.NoBody) require.NoError(t, err) resp, err := client.Do(req) @@ -167,9 +168,9 @@ func TestHttp_DoWithAssets(t *testing.T) { assert.Equal(t, "response /567/something", string(body)) assert.Equal(t, "", resp.Header.Get("App-Method")) assert.Equal(t, "v1", resp.Header.Get("h1")) - } + }) - { + t.Run("static call, good", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/static/1.html") require.NoError(t, err) defer resp.Body.Close() @@ -182,9 +183,9 @@ func TestHttp_DoWithAssets(t *testing.T) { assert.Equal(t, "", resp.Header.Get("App-Method")) assert.Equal(t, "", resp.Header.Get("h1")) assert.Equal(t, "public, max-age=43200", resp.Header.Get("Cache-Control")) - } + }) - { + t.Run("static call, bad", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/static/bad.html") require.NoError(t, err) defer resp.Body.Close() @@ -192,9 +193,9 @@ func TestHttp_DoWithAssets(t *testing.T) { body, err := io.ReadAll(resp.Body) require.NoError(t, err) assert.Equal(t, "404 page not found\n", string(body)) - } + }) - { + t.Run("bad url", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/svcbad") require.NoError(t, err) defer resp.Body.Close() @@ -203,7 +204,7 @@ func TestHttp_DoWithAssets(t *testing.T) { require.NoError(t, err) assert.Contains(t, string(body), "Server error") assert.Equal(t, "text/plain; charset=utf-8", resp.Header.Get("Content-Type")) - } + }) } func TestHttp_DoWithAssetsCustom404(t *testing.T) { @@ -243,7 +244,7 @@ func TestHttp_DoWithAssetsCustom404(t *testing.T) { client := http.Client{} - { + t.Run("api call, found", func(t *testing.T) { req, err := http.NewRequest("GET", "http://127.0.0.1:"+strconv.Itoa(port)+"/api/something", http.NoBody) require.NoError(t, err) resp, err := client.Do(req) @@ -257,9 +258,9 @@ func TestHttp_DoWithAssetsCustom404(t *testing.T) { assert.Equal(t, "response /567/something", string(body)) assert.Equal(t, "", resp.Header.Get("App-Method")) assert.Equal(t, "v1", resp.Header.Get("h1")) - } + }) - { + t.Run("static call, found", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/static/1.html") require.NoError(t, err) defer resp.Body.Close() @@ -272,9 +273,9 @@ func TestHttp_DoWithAssetsCustom404(t *testing.T) { assert.Equal(t, "", resp.Header.Get("App-Method")) assert.Equal(t, "", resp.Header.Get("h1")) assert.Equal(t, "public, max-age=43200", resp.Header.Get("Cache-Control")) - } + }) - { + t.Run("static call, not found", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/static/bad.html") require.NoError(t, err) defer resp.Body.Close() @@ -284,9 +285,9 @@ func TestHttp_DoWithAssetsCustom404(t *testing.T) { assert.Equal(t, "not found! blah blah blah\nthere is no spoon", string(body)) t.Logf("%+v", resp.Header) assert.Equal(t, "text/html; charset=utf-8", resp.Header.Get("Content-Type")) - } + }) - { + t.Run("another static call, not found", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/static/bad2.html") require.NoError(t, err) defer resp.Body.Close() @@ -296,7 +297,7 @@ func TestHttp_DoWithAssetsCustom404(t *testing.T) { assert.Equal(t, "not found! blah blah blah\nthere is no spoon", string(body)) t.Logf("%+v", resp.Header) assert.Equal(t, "text/html; charset=utf-8", resp.Header.Get("Content-Type")) - } + }) } func TestHttp_DoWithSpaAssets(t *testing.T) { @@ -336,7 +337,7 @@ func TestHttp_DoWithSpaAssets(t *testing.T) { client := http.Client{} - { + t.Run("api call, good", func(t *testing.T) { req, err := http.NewRequest("GET", "http://127.0.0.1:"+strconv.Itoa(port)+"/api/something", http.NoBody) require.NoError(t, err) resp, err := client.Do(req) @@ -350,9 +351,9 @@ func TestHttp_DoWithSpaAssets(t *testing.T) { assert.Equal(t, "response /567/something", string(body)) assert.Equal(t, "", resp.Header.Get("App-Method")) assert.Equal(t, "v1", resp.Header.Get("h1")) - } + }) - { + t.Run("static call, good", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/static/1.html") require.NoError(t, err) defer resp.Body.Close() @@ -365,9 +366,9 @@ func TestHttp_DoWithSpaAssets(t *testing.T) { assert.Equal(t, "", resp.Header.Get("App-Method")) assert.Equal(t, "", resp.Header.Get("h1")) assert.Equal(t, "public, max-age=43200", resp.Header.Get("Cache-Control")) - } + }) - { + t.Run("static call, not found server index", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/static/bad.html") require.NoError(t, err) defer resp.Body.Close() @@ -380,9 +381,9 @@ func TestHttp_DoWithSpaAssets(t *testing.T) { assert.Equal(t, "", resp.Header.Get("App-Method")) assert.Equal(t, "", resp.Header.Get("h1")) assert.Equal(t, "public, max-age=43200", resp.Header.Get("Cache-Control")) - } + }) - { + t.Run("static call, bad url", func(t *testing.T) { resp, err := client.Get("http://localhost:" + strconv.Itoa(port) + "/svcbad") require.NoError(t, err) defer resp.Body.Close() @@ -391,7 +392,7 @@ func TestHttp_DoWithSpaAssets(t *testing.T) { require.NoError(t, err) assert.Contains(t, string(body), "Server error") assert.Equal(t, "text/plain; charset=utf-8", resp.Header.Get("Content-Type")) - } + }) } func TestHttp_DoWithAssetRules(t *testing.T) { @@ -715,16 +716,16 @@ func TestHttp_withBasicAuth(t *testing.T) { client := http.Client{} - { + t.Run("no auth", func(t *testing.T) { req, err := http.NewRequest("POST", "http://127.0.0.1:"+strconv.Itoa(port)+"/api/something", bytes.NewBufferString("abcdefg")) require.NoError(t, err) resp, err := client.Do(req) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusUnauthorized, resp.StatusCode) - } + }) - { + t.Run("bad auth", func(t *testing.T) { req, err := http.NewRequest("POST", "http://127.0.0.1:"+strconv.Itoa(port)+"/api/something", bytes.NewBufferString("abcdefg")) req.SetBasicAuth("test", "badpasswd") require.NoError(t, err) @@ -732,8 +733,9 @@ func TestHttp_withBasicAuth(t *testing.T) { require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusUnauthorized, resp.StatusCode) - } - { + }) + + t.Run("good auth", func(t *testing.T) { req, err := http.NewRequest("POST", "http://127.0.0.1:"+strconv.Itoa(port)+"/api/something", bytes.NewBufferString("abcdefg")) req.SetBasicAuth("test", "passwd") require.NoError(t, err) @@ -741,8 +743,9 @@ func TestHttp_withBasicAuth(t *testing.T) { require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) - } - { + }) + + t.Run("good auth 2", func(t *testing.T) { req, err := http.NewRequest("POST", "http://127.0.0.1:"+strconv.Itoa(port)+"/api/something", bytes.NewBufferString("abcdefg")) req.SetBasicAuth("test2", "passwd2") require.NoError(t, err) @@ -750,7 +753,7 @@ func TestHttp_withBasicAuth(t *testing.T) { require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) - } + }) } func TestHttp_toHttp(t *testing.T) { @@ -766,9 +769,9 @@ func TestHttp_toHttp(t *testing.T) { } h := Http{} - for i, tt := range tbl { + for _, tt := range tbl { tt := tt - t.Run(strconv.Itoa(i), func(t *testing.T) { + t.Run(tt.addr, func(t *testing.T) { assert.Equal(t, tt.res, h.toHTTP(tt.addr, tt.port)) }) } @@ -791,8 +794,8 @@ func TestHttp_isAssetRequest(t *testing.T) { {"/static/", "/tmp", "", false}, } - for i, tt := range tbl { - t.Run(strconv.Itoa(i), func(t *testing.T) { + for _, tt := range tbl { + t.Run(tt.req, func(t *testing.T) { h := Http{AssetsLocation: tt.assetsLocation, AssetsWebRoot: tt.assetsWebRoot} r, err := http.NewRequest("GET", tt.req, http.NoBody) require.NoError(t, err) @@ -803,56 +806,61 @@ func TestHttp_isAssetRequest(t *testing.T) { } func TestHttp_matchHandler(t *testing.T) { - tbl := []struct { + name string matches discovery.Matches res string ok bool }{ - { - discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{ + name: "all alive destinations", + matches: discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{ {Destination: "dest1", Alive: true}, {Destination: "dest2", Alive: true}, {Destination: "dest3", Alive: true}, }}, - "dest1", true, + res: "dest1", ok: true, }, { - discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{ + name: "second alive destination", + matches: discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{ {Destination: "dest1", Alive: false}, {Destination: "dest2", Alive: true}, {Destination: "dest3", Alive: false}, }}, - "dest2", true, + res: "dest2", ok: true, }, { - discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{ + name: "one dead destination", + matches: discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{ {Destination: "dest1", Alive: false}, {Destination: "dest2", Alive: true}, {Destination: "dest3", Alive: true}, }}, - "dest2", true, + res: "dest2", ok: true, }, { - discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{ + name: "last alive destination", + matches: discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{ {Destination: "dest1", Alive: false}, {Destination: "dest2", Alive: false}, {Destination: "dest3", Alive: true}, }}, - "dest3", true, + res: "dest3", ok: true, }, { - discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{ + name: "all dead destinations", + matches: discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{ {Destination: "dest1", Alive: false}, {Destination: "dest2", Alive: false}, {Destination: "dest3", Alive: false}, }}, - "", false, + res: "", ok: false, }, { - discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{}}, "", false, + name: "no destinations", + matches: discovery.Matches{MatchType: discovery.MTProxy, Routes: []discovery.MatchedRoute{}}, res: "", ok: false, }, } @@ -864,9 +872,8 @@ func TestHttp_matchHandler(t *testing.T) { } client := http.Client{} - for i, tt := range tbl { - t.Run(strconv.Itoa(i), func(t *testing.T) { - + for _, tt := range tbl { + t.Run(tt.name, func(t *testing.T) { h := Http{Matcher: matcherMock, LBSelector: func(len int) int { return 0 }} handler := h.matchHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { t.Logf("req: %+v", r) @@ -893,7 +900,6 @@ func TestHttp_matchHandler(t *testing.T) { } func TestHttp_discoveredServers(t *testing.T) { - calls := 0 m := &MatcherMock{ServersFunc: func() []string { defer func() { calls++ }()