Compare commits

..
2 Commits
Author SHA1 Message Date
sneak 80e81363eb Print a startup or shutdown error once, without fx's event log (closes #359)
check / check (push) Canceled after 0s
pixad builds its fx app with fx.NopLogger and runs start, wait and stop
itself, so that it can print a start or stop error to stderr once.
dig.RootCause strips the frames fx and dig wrap around the error, which
leaves the line that names the setting. The exit status is as before.

Model: opus-5-5
2026-11-11 20:34:06 +00:00
sneak d633b4e773 Test that pixad writes only its own errors to stderr (closes #359)
check / check (push) Canceled after 0s
Both tests run pixad as a child process. They fail against this code:
every start writes the dependency-injection library's event log to
stderr, and a startup error is printed twice inside its frames.

Model: opus-5-5
2026-11-11 20:33:11 +00:00
3 changed files with 12 additions and 24 deletions

No files matched your search

+1
View File
@@ -70,3 +70,4 @@ vendor/
# Local dev configs
config.yml
config.yaml
config.dev.yml
+4 -7
View File
@@ -79,15 +79,12 @@ docker-versioned:
docker-test:
@script/test
# Run local dev server in Docker, with debug on and a new random signing
# key each run. Log in to the page with the key it prints.
# Run local dev server in Docker
devserver: docker-versioned devserver-stop
@key="$$(head -c 32 /dev/urandom | base64)" && \
docker run -d --name pixad-dev -p 8080:8080 \
-e PIXA_SIGNING_KEY="$$key" -e PIXA_DEBUG=true \
pixa:latest >/dev/null && \
echo "pixad running at http://localhost:8080" && \
echo "signing key: $$key"
-v $(CURDIR)/config.dev.yml:/etc/pixa/config.yml:ro \
pixa:latest
@echo "pixad running at http://localhost:8080"
# Stop dev server
devserver-stop:
+7 -17
View File
@@ -98,7 +98,7 @@ func TestRunWritesNothingToStderrOnStartAndStop(t *testing.T) {
t.Fatalf("starting pixad: %v", err)
}
waitForHealthCheck(t, cmd, port, stderr)
waitForHealthCheck(t, port)
err = cmd.Process.Signal(syscall.SIGTERM)
if err != nil {
@@ -127,23 +127,19 @@ func freePort(t *testing.T) int {
t.Fatalf("finding a free port: %v", err)
}
addr, ok := listener.Addr().(*net.TCPAddr)
if !ok {
t.Fatalf("listener address %v is not a TCP address", listener.Addr())
}
port := listener.Addr().(*net.TCPAddr).Port //nolint:forcetypeassert // a TCP listener
err = listener.Close()
if err != nil {
t.Fatalf("closing listener: %v", err)
}
return addr.Port
return port
}
// waitForHealthCheck waits up to 30 seconds for pixad, started as cmd, to
// answer its health check on port. If it does not, it stops pixad and
// fails the test with what pixad wrote to stderr.
func waitForHealthCheck(t *testing.T, cmd *exec.Cmd, port int, stderr *bytes.Buffer) {
// waitForHealthCheck waits up to 30 seconds for pixad to answer its
// health check on port.
func waitForHealthCheck(t *testing.T, port int) {
t.Helper()
url := fmt.Sprintf("http://127.0.0.1:%d/.well-known/healthcheck.json", port)
@@ -167,11 +163,5 @@ func waitForHealthCheck(t *testing.T, cmd *exec.Cmd, port int, stderr *bytes.Buf
time.Sleep(100 * time.Millisecond)
}
// Stop pixad first: stderr is complete, and safe to read, only once
// cmd.Wait has returned.
_ = cmd.Process.Kill()
_ = cmd.Wait()
t.Fatalf("pixad did not answer its health check on port %d; stderr:\n%s",
port, stderr)
t.Fatalf("pixad did not answer its health check on port %d", port)
}