Skip to content

Commit

Permalink
Expand docs with test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
enocom committed Oct 26, 2022
1 parent c7374d3 commit e11d226
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 11 deletions.
25 changes: 24 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,27 @@ Instance Level Configuration
my-project:us-central1:my-db-server \
'my-project:us-central1:my-other-server?address=0.0.0.0&port=7000'
Health checks
When enabling the --health-checks flag, the proxy will start an HTTP server
on localhost with three endpoints:
- /startup: Returns 200 status when the proxy has finished starting up.
Otherwise returns 503 status.
- /readiness: Returns 200 status when the proxy has started, has available
connections if max connections have been set with the --max-connections
flag, and when the proxy can connect to all registered instances. Otherwise,
returns a 503 status. Optionally supports a min-ready query param (e.g.,
/readiness?min-ready=3) where the proxy will return a 200 status if the
proxy can connect successfully to at least min-ready number of instances. If
min-ready exceeds the number of registered instances, returns a 400.
- /liveness: Always returns 200 status. If this endpoint is not responding,
the proxy is in a bad state and should be restarted.
To configure the address, use --http-server.
Service Account Impersonation
The proxy supports service account impersonation with the
Expand Down Expand Up @@ -620,6 +641,8 @@ func runSignalWrapper(cmd *Command) error {
notify := func() {}
if cmd.healthCheck {
needsHTTPServer = true
cmd.logger.Infof("Starting health check server at %s",
net.JoinHostPort(cmd.httpAddress, cmd.httpPort))
hc := healthcheck.NewCheck(p, cmd.logger)
mux.HandleFunc("/startup", hc.HandleStartup)
mux.HandleFunc("/readiness", hc.HandleReadiness)
Expand All @@ -630,7 +653,7 @@ func runSignalWrapper(cmd *Command) error {
// Start the HTTP server if anything requiring HTTP is specified.
if needsHTTPServer {
server := &http.Server{
Addr: fmt.Sprintf("%s:%s", cmd.httpAddress, cmd.httpPort),
Addr: net.JoinHostPort(cmd.httpAddress, cmd.httpPort),
Handler: mux,
}
// Start the HTTP server.
Expand Down
5 changes: 5 additions & 0 deletions internal/healthcheck/healthcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ func (c *Check) HandleReadiness(w http.ResponseWriter, req *http.Request) {
}

n, err := c.proxy.CheckConnections(ctx)
if minReady > n {
c.logger.Errorf("[Health Check] min-ready was greater than registered instances")
w.WriteHeader(http.StatusBadRequest)
return
}
if err != nil && !ready(err, minReady, n) {
c.logger.Errorf("[Health Check] Readiness failed: %v", err)
w.WriteHeader(http.StatusServiceUnavailable)
Expand Down
25 changes: 15 additions & 10 deletions internal/healthcheck/healthcheck_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func TestHandleStartupWhenNotNotified(t *testing.T) {
check := healthcheck.NewCheck(p, logger)

rec := httptest.NewRecorder()
check.HandleStartup(rec, &http.Request{})
check.HandleStartup(rec, &http.Request{URL: &url.URL{}})

// Startup is not complete because the Check has not been notified of the
// proxy's startup.
Expand All @@ -156,7 +156,7 @@ func TestHandleStartupWhenNotified(t *testing.T) {
check.NotifyStarted()

rec := httptest.NewRecorder()
check.HandleStartup(rec, &http.Request{})
check.HandleStartup(rec, &http.Request{URL: &url.URL{}})

resp := rec.Result()
if got, want := resp.StatusCode, http.StatusOK; got != want {
Expand All @@ -174,7 +174,7 @@ func TestHandleReadinessWhenNotNotified(t *testing.T) {
check := healthcheck.NewCheck(p, logger)

rec := httptest.NewRecorder()
check.HandleReadiness(rec, &http.Request{})
check.HandleReadiness(rec, &http.Request{URL: &url.URL{}})

resp := rec.Result()
if got, want := resp.StatusCode, http.StatusServiceUnavailable; got != want {
Expand Down Expand Up @@ -210,7 +210,7 @@ func TestHandleReadinessForMaxConns(t *testing.T) {
waitForConnect := func(t *testing.T, wantCode int) *http.Response {
for i := 0; i < 10; i++ {
rec := httptest.NewRecorder()
check.HandleReadiness(rec, &http.Request{})
check.HandleReadiness(rec, &http.Request{URL: &url.URL{}})
resp := rec.Result()
if resp.StatusCode == wantCode {
return resp
Expand Down Expand Up @@ -242,7 +242,7 @@ func TestHandleReadinessWithConnectionProblems(t *testing.T) {
check.NotifyStarted()

rec := httptest.NewRecorder()
check.HandleReadiness(rec, &http.Request{})
check.HandleReadiness(rec, &http.Request{URL: &url.URL{}})

resp := rec.Result()
if got, want := resp.StatusCode, http.StatusServiceUnavailable; got != want {
Expand All @@ -264,16 +264,16 @@ func TestReadinessWithMinReady(t *testing.T) {
minReady string
wantStatus int
}{
{
desc: "when all instances must be ready",
minReady: "2",
wantStatus: http.StatusServiceUnavailable,
},
{
desc: "when only one instance must be ready",
minReady: "1",
wantStatus: http.StatusOK,
},
{
desc: "when all instances must be ready",
minReady: "2",
wantStatus: http.StatusServiceUnavailable,
},
{
desc: "when min ready is not configured",
minReady: "0",
Expand All @@ -284,6 +284,11 @@ func TestReadinessWithMinReady(t *testing.T) {
minReady: "bogus",
wantStatus: http.StatusServiceUnavailable,
},
{
desc: "when min ready is greater than registered instances",
minReady: "100",
wantStatus: http.StatusBadRequest,
},
}
p := newProxyWithParams(t, 0,
// for every two calls, flaky dialer fails for the first, succeeds for
Expand Down

0 comments on commit e11d226

Please sign in to comment.