mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2024-12-12 11:15:02 +02:00
c7bfbdecef
* feature: Implement graceful shutdown Propagate the request context to the Redis client. It is possible to propagate a context cancel to Redis client if the connection is closed by the HTTP client. The redis.Cmdable cannot use WithContext, so added the Client interface to handle redis.Client and redis.ClusterClient transparently. Added handling of Unix signals to http server. Upgrade go-redis/redis to v7. * Update dependencies - Upgrade golang/x/* and google-api-go - Migrate fsnotify import from gopkg.in to github.com - Replace bmizerany/assert with stretchr/testify/assert * add doc for wrapper interface * Update CHANGELOG.md * fix: upgrade fsnotify to v1.4.9 * fix: remove unnessary logging * fix: wait until all connections have been closed * refactor: move chan to main for testing * add assert to check if stop chan is empty * add an idiomatic for sync.WaitGroup with timeout
189 lines
4.7 KiB
Go
189 lines
4.7 KiB
Go
package main
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
const localhost = "127.0.0.1"
|
|
const host = "test-server"
|
|
|
|
func TestGCPHealthcheckLiveness(t *testing.T) {
|
|
handler := func(w http.ResponseWriter, req *http.Request) {
|
|
w.Write([]byte("test"))
|
|
}
|
|
|
|
h := gcpHealthcheck(http.HandlerFunc(handler))
|
|
rw := httptest.NewRecorder()
|
|
r, _ := http.NewRequest("GET", "/liveness_check", nil)
|
|
r.RemoteAddr = localhost
|
|
r.Host = host
|
|
h.ServeHTTP(rw, r)
|
|
|
|
assert.Equal(t, 200, rw.Code)
|
|
assert.Equal(t, "OK", rw.Body.String())
|
|
}
|
|
|
|
func TestGCPHealthcheckReadiness(t *testing.T) {
|
|
handler := func(w http.ResponseWriter, req *http.Request) {
|
|
w.Write([]byte("test"))
|
|
}
|
|
|
|
h := gcpHealthcheck(http.HandlerFunc(handler))
|
|
rw := httptest.NewRecorder()
|
|
r, _ := http.NewRequest("GET", "/readiness_check", nil)
|
|
r.RemoteAddr = localhost
|
|
r.Host = host
|
|
h.ServeHTTP(rw, r)
|
|
|
|
assert.Equal(t, 200, rw.Code)
|
|
assert.Equal(t, "OK", rw.Body.String())
|
|
}
|
|
|
|
func TestGCPHealthcheckNotHealthcheck(t *testing.T) {
|
|
handler := func(w http.ResponseWriter, req *http.Request) {
|
|
w.Write([]byte("test"))
|
|
}
|
|
|
|
h := gcpHealthcheck(http.HandlerFunc(handler))
|
|
rw := httptest.NewRecorder()
|
|
r, _ := http.NewRequest("GET", "/not_any_check", nil)
|
|
r.RemoteAddr = localhost
|
|
r.Host = host
|
|
h.ServeHTTP(rw, r)
|
|
|
|
assert.Equal(t, "test", rw.Body.String())
|
|
}
|
|
|
|
func TestGCPHealthcheckIngress(t *testing.T) {
|
|
handler := func(w http.ResponseWriter, req *http.Request) {
|
|
w.Write([]byte("test"))
|
|
}
|
|
|
|
h := gcpHealthcheck(http.HandlerFunc(handler))
|
|
rw := httptest.NewRecorder()
|
|
r, _ := http.NewRequest("GET", "/", nil)
|
|
r.RemoteAddr = localhost
|
|
r.Host = host
|
|
r.Header.Set(userAgentHeader, googleHealthCheckUserAgent)
|
|
h.ServeHTTP(rw, r)
|
|
|
|
assert.Equal(t, 200, rw.Code)
|
|
assert.Equal(t, "", rw.Body.String())
|
|
}
|
|
|
|
func TestGCPHealthcheckNotIngress(t *testing.T) {
|
|
handler := func(w http.ResponseWriter, req *http.Request) {
|
|
w.Write([]byte("test"))
|
|
}
|
|
|
|
h := gcpHealthcheck(http.HandlerFunc(handler))
|
|
rw := httptest.NewRecorder()
|
|
r, _ := http.NewRequest("GET", "/foo", nil)
|
|
r.RemoteAddr = localhost
|
|
r.Host = host
|
|
r.Header.Set(userAgentHeader, googleHealthCheckUserAgent)
|
|
h.ServeHTTP(rw, r)
|
|
|
|
assert.Equal(t, "test", rw.Body.String())
|
|
}
|
|
|
|
func TestGCPHealthcheckNotIngressPut(t *testing.T) {
|
|
handler := func(w http.ResponseWriter, req *http.Request) {
|
|
w.Write([]byte("test"))
|
|
}
|
|
|
|
h := gcpHealthcheck(http.HandlerFunc(handler))
|
|
rw := httptest.NewRecorder()
|
|
r, _ := http.NewRequest("PUT", "/", nil)
|
|
r.RemoteAddr = localhost
|
|
r.Host = host
|
|
r.Header.Set(userAgentHeader, googleHealthCheckUserAgent)
|
|
h.ServeHTTP(rw, r)
|
|
|
|
assert.Equal(t, "test", rw.Body.String())
|
|
}
|
|
|
|
func TestRedirectToHTTPSTrue(t *testing.T) {
|
|
opts := NewOptions()
|
|
opts.ForceHTTPS = true
|
|
handler := func(w http.ResponseWriter, req *http.Request) {
|
|
w.Write([]byte("test"))
|
|
}
|
|
|
|
h := redirectToHTTPS(opts, http.HandlerFunc(handler))
|
|
rw := httptest.NewRecorder()
|
|
r, _ := http.NewRequest("GET", "/", nil)
|
|
h.ServeHTTP(rw, r)
|
|
|
|
assert.Equal(t, http.StatusPermanentRedirect, rw.Code, "status code should be %d, got: %d", http.StatusPermanentRedirect, rw.Code)
|
|
}
|
|
|
|
func TestRedirectToHTTPSFalse(t *testing.T) {
|
|
opts := NewOptions()
|
|
handler := func(w http.ResponseWriter, req *http.Request) {
|
|
w.Write([]byte("test"))
|
|
}
|
|
|
|
h := redirectToHTTPS(opts, http.HandlerFunc(handler))
|
|
rw := httptest.NewRecorder()
|
|
r, _ := http.NewRequest("GET", "/", nil)
|
|
h.ServeHTTP(rw, r)
|
|
|
|
assert.Equal(t, http.StatusOK, rw.Code, "status code should be %d, got: %d", http.StatusOK, rw.Code)
|
|
}
|
|
|
|
func TestRedirectNotWhenHTTPS(t *testing.T) {
|
|
opts := NewOptions()
|
|
opts.ForceHTTPS = true
|
|
handler := func(w http.ResponseWriter, req *http.Request) {
|
|
w.Write([]byte("test"))
|
|
}
|
|
|
|
h := redirectToHTTPS(opts, http.HandlerFunc(handler))
|
|
s := httptest.NewTLSServer(h)
|
|
defer s.Close()
|
|
|
|
opts.HTTPSAddress = s.URL
|
|
client := s.Client()
|
|
res, err := client.Get(s.URL)
|
|
if err != nil {
|
|
t.Fatalf("request to test server failed with error: %v", err)
|
|
}
|
|
|
|
assert.Equal(t, http.StatusOK, res.StatusCode, "status code should be %d, got: %d", http.StatusOK, res.StatusCode)
|
|
}
|
|
|
|
func TestGracefulShutdown(t *testing.T) {
|
|
opts := NewOptions()
|
|
stop := make(chan struct{}, 1)
|
|
srv := Server{Handler: http.DefaultServeMux, Opts: opts, stop: stop}
|
|
var wg sync.WaitGroup
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
srv.ServeHTTP()
|
|
}()
|
|
|
|
stop <- struct{}{} // emulate catching signals
|
|
|
|
// An idiomatic for sync.WaitGroup with timeout
|
|
c := make(chan struct{})
|
|
go func() {
|
|
defer close(c)
|
|
wg.Wait()
|
|
}()
|
|
select {
|
|
case <-c:
|
|
case <-time.After(1 * time.Second):
|
|
t.Fatal("Server should return gracefully but timeout has occurred")
|
|
}
|
|
|
|
assert.Len(t, stop, 0) // check if stop chan is empty
|
|
}
|