summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-14 10:37:18 +0300
committerPaul Buetow <paul@buetow.org>2026-04-14 10:37:18 +0300
commitb0ac28f90ddf85e85b0308229569292fd6f7f9a2 (patch)
treea0598fdb2f598f9f333ae078fb44ab84d5b2f010
parent28b49a9e8bd0190679b8f60019676a1dab2bcfcc (diff)
daemon: NewHandler returns error instead of panicking (l3)
Replace Handler with NewHandler(statsDir) (http.Handler, error) when the auth store cannot be opened, matching Run's error wrapping. Tests use a small helper; add coverage for open failure on a read-only stats dir. Made-with: Cursor
-rw-r--r--internal/daemon/daemon.go18
-rw-r--r--internal/daemon/daemon_test.go43
-rw-r--r--internal/daemon/upload_test.go2
3 files changed, 43 insertions, 20 deletions
diff --git a/internal/daemon/daemon.go b/internal/daemon/daemon.go
index 22d9f1a..b913c43 100644
--- a/internal/daemon/daemon.go
+++ b/internal/daemon/daemon.go
@@ -30,6 +30,16 @@ type Config struct {
LogOutput io.Writer
}
+// NewHandler returns HTTP handlers for daemon routes using the default auth DB
+// under statsDir. It returns an error if the auth store cannot be opened.
+func NewHandler(statsDir string) (http.Handler, error) {
+ store, err := openAuthStore(context.Background(), statsDir, "")
+ if err != nil {
+ return nil, fmt.Errorf("auth db: %w", err)
+ }
+ return routes(statsDir, "", store), nil
+}
+
func routes(statsDir, authDB string, store *authkeys.Store) http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/health", health)
@@ -40,14 +50,6 @@ func routes(statsDir, authDB string, store *authkeys.Store) http.Handler {
return mux
}
-func Handler(statsDir string) http.Handler {
- store, err := openAuthStore(context.Background(), statsDir, "")
- if err != nil {
- panic(err)
- }
- return routes(statsDir, "", store)
-}
-
func logWriter(cfg Config) io.Writer {
if cfg.LogOutput != nil {
return cfg.LogOutput
diff --git a/internal/daemon/daemon_test.go b/internal/daemon/daemon_test.go
index ccc186e..a3ff0a6 100644
--- a/internal/daemon/daemon_test.go
+++ b/internal/daemon/daemon_test.go
@@ -32,8 +32,29 @@ func (s *syncBuffer) String() string {
return s.b.String()
}
+func testHandler(t *testing.T, statsDir string) http.Handler {
+ t.Helper()
+ h, err := NewHandler(statsDir)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return h
+}
+
+func TestNewHandlerOpenAuthStoreFails(t *testing.T) {
+ dir := t.TempDir()
+ if err := os.Chmod(dir, 0o555); err != nil {
+ t.Fatal(err)
+ }
+ defer func() { _ = os.Chmod(dir, 0o755) }()
+ _, err := NewHandler(dir)
+ if err == nil {
+ t.Fatal("expected error when auth db cannot be created")
+ }
+}
+
func TestHealth(t *testing.T) {
- srv := httptest.NewServer(Handler(t.TempDir()))
+ srv := httptest.NewServer(testHandler(t, t.TempDir()))
defer srv.Close()
res, err := http.Get(srv.URL + "/health")
if err != nil {
@@ -50,7 +71,7 @@ func TestHealth(t *testing.T) {
}
func TestHealthMethodNotAllowed(t *testing.T) {
- srv := httptest.NewServer(Handler(t.TempDir()))
+ srv := httptest.NewServer(testHandler(t, t.TempDir()))
defer srv.Close()
req, _ := http.NewRequest(http.MethodPost, srv.URL+"/health", nil)
res, err := http.DefaultClient.Do(req)
@@ -64,7 +85,7 @@ func TestHealthMethodNotAllowed(t *testing.T) {
}
func TestLivez(t *testing.T) {
- srv := httptest.NewServer(Handler(t.TempDir()))
+ srv := httptest.NewServer(testHandler(t, t.TempDir()))
defer srv.Close()
res, err := http.Get(srv.URL + "/livez")
if err != nil {
@@ -81,7 +102,7 @@ func TestLivez(t *testing.T) {
}
func TestReadyzOK(t *testing.T) {
- srv := httptest.NewServer(Handler(t.TempDir()))
+ srv := httptest.NewServer(testHandler(t, t.TempDir()))
defer srv.Close()
res, err := http.Get(srv.URL + "/readyz")
if err != nil {
@@ -98,7 +119,7 @@ func TestReadyzOK(t *testing.T) {
}
func TestReadyzMethodNotAllowed(t *testing.T) {
- srv := httptest.NewServer(Handler(t.TempDir()))
+ srv := httptest.NewServer(testHandler(t, t.TempDir()))
defer srv.Close()
req, _ := http.NewRequest(http.MethodPost, srv.URL+"/readyz", nil)
res, err := http.DefaultClient.Do(req)
@@ -182,7 +203,7 @@ func TestReadyzAuthDBDirNotWritable(t *testing.T) {
func TestReportHTTPTable(t *testing.T) {
fixtures := filepath.Join("..", "..", "fixtures")
- srv := httptest.NewServer(Handler(fixtures))
+ srv := httptest.NewServer(testHandler(t, fixtures))
defer srv.Close()
tests := []struct {
name string
@@ -268,7 +289,7 @@ func TestReportHTTPTable(t *testing.T) {
func TestReportMethodNotAllowed(t *testing.T) {
fixtures := filepath.Join("..", "..", "fixtures")
- srv := httptest.NewServer(Handler(fixtures))
+ srv := httptest.NewServer(testHandler(t, fixtures))
defer srv.Close()
req, _ := http.NewRequest(http.MethodPost, srv.URL+"/report?limit=2", nil)
res, err := http.DefaultClient.Do(req)
@@ -290,7 +311,7 @@ func TestReportAggregateFailure(t *testing.T) {
if err := os.WriteFile(filepath.Join(dir, "dup.y.records"), []byte(line), 0o644); err != nil {
t.Fatal(err)
}
- srv := httptest.NewServer(Handler(dir))
+ srv := httptest.NewServer(testHandler(t, dir))
defer srv.Close()
res, err := http.Get(srv.URL + "/report?limit=2")
if err != nil {
@@ -458,7 +479,7 @@ func TestAccessLogLineToWriter(t *testing.T) {
func TestUploadOpenWhenNoKeys(t *testing.T) {
statsDir := t.TempDir()
- srv := httptest.NewServer(Handler(statsDir))
+ srv := httptest.NewServer(testHandler(t, statsDir))
defer srv.Close()
req, _ := http.NewRequest(http.MethodPut, srv.URL+"/upload/myhost/txt", strings.NewReader("hello"))
res, err := http.DefaultClient.Do(req)
@@ -556,7 +577,7 @@ func TestUploadWrongHostForbidden(t *testing.T) {
func TestUploadBadKind(t *testing.T) {
statsDir := t.TempDir()
- srv := httptest.NewServer(Handler(statsDir))
+ srv := httptest.NewServer(testHandler(t, statsDir))
defer srv.Close()
req, _ := http.NewRequest(http.MethodPut, srv.URL+"/upload/myhost/nope", strings.NewReader("x"))
res, err := http.DefaultClient.Do(req)
@@ -571,7 +592,7 @@ func TestUploadBadKind(t *testing.T) {
func TestUploadAllKindsWriteExpectedFiles(t *testing.T) {
statsDir := t.TempDir()
- srv := httptest.NewServer(Handler(statsDir))
+ srv := httptest.NewServer(testHandler(t, statsDir))
defer srv.Close()
cases := []struct {
kind string
diff --git a/internal/daemon/upload_test.go b/internal/daemon/upload_test.go
index 5a3755f..2cc52f3 100644
--- a/internal/daemon/upload_test.go
+++ b/internal/daemon/upload_test.go
@@ -179,7 +179,7 @@ func TestOpenAuthStoreBadPath(t *testing.T) {
func TestUploadMethodNotAllowedTable(t *testing.T) {
statsDir := t.TempDir()
- srv := httptest.NewServer(Handler(statsDir))
+ srv := httptest.NewServer(testHandler(t, statsDir))
defer srv.Close()
for _, method := range []string{http.MethodGet, http.MethodPost, http.MethodDelete} {
t.Run(method, func(t *testing.T) {