~bigbes/sr-ht-compare

1e111cf406ab94437137fd882c724cf25af2adaf — bigbes 9 days ago eb87ed5
cmd: ecoretest keys in the startup smoke test

The synthesized config.ini takes ecore's fixed keyset and origins rather
than generating a keypair per run; a constant cannot be malformed by
accident, which matters for a subprocess whose only way of complaining
is a log.Fatal. Also notes the three middlewares Register now installs
inside its own group, and why chi's Recoverer stays out here.
2 files changed, 26 insertions(+), 23 deletions(-)

M cmd/comparesrht/main.go
M cmd/comparesrht/main_test.go
M cmd/comparesrht/main.go => cmd/comparesrht/main.go +9 -2
@@ 30,12 30,12 @@ import (
	"strings"
	"time"

	"sourcecraft.dev/bigbes/sr-ht-core/config"
	coreserver "sourcecraft.dev/bigbes/sr-ht-core/server"
	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"github.com/sirupsen/logrus"
	"github.com/vaughan0/go-ini"
	"sourcecraft.dev/bigbes/sr-ht-core/config"
	coreserver "sourcecraft.dev/bigbes/sr-ht-core/server"

	"sourcecraft.dev/bigbes/sr-ht-compare/authz"
	"sourcecraft.dev/bigbes/sr-ht-compare/web"


@@ 81,6 81,13 @@ func main() {
	// registration (it built inline sub-routers during construction), so the
	// group + middleware + routes are installed together inside a Group, which
	// chi permits on a fresh inline mux sharing the same routing tree.
	//
	// Register installs three more of its own inside a nested group: the
	// private cache policy, panic recovery through the service's error page,
	// and the same-origin guard. chi's Recoverer stays here as the outer net
	// for a panic in the two middlewares above, which are outside that group —
	// it re-panics http.ErrAbortHandler, which is what the inner one raises for
	// a panic arriving after the response has already started.
	srv.AnonRouter().Group(func(r chi.Router) {
		r.Use(middleware.RealIP)
		r.Use(middleware.Recoverer)

M cmd/comparesrht/main_test.go => cmd/comparesrht/main_test.go +17 -21
@@ 1,8 1,6 @@
package main

import (
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"net"
	"net/http"


@@ 13,15 11,16 @@ import (
	"testing"
	"time"

	"github.com/fernet/fernet-go"
	"sourcecraft.dev/bigbes/sr-ht-ecore/ecoretest"
)

// TestStartupSmoke builds the daemon, runs it against a synthesized minimal
// config.ini (fresh crypto keys, an empty repos root), waits for /healthz to
// config.ini (ecore's test keyset, an empty repos root), waits for /healthz to
// answer 200, then sends SIGINT and asserts a clean (exit code 0) warm
// shutdown. It exercises the real startup path end to end: config validation,
// crypto init via server.New, web.New (which globs the embedded hashed CSS),
// the middleware chain, and core-go's signal-driven Run loop.
// crypto init via server.New, web.New (which resolves the embedded hashed
// artefacts and parses every page template), the middleware chain, and
// core-go's signal-driven Run loop.
//
// server.New's Run installs its warm-shutdown handler on SIGINT (the SourceHut
// fleet convention); the deployed systemd unit sets KillSignal=SIGINT so


@@ 42,36 41,33 @@ func TestStartupSmoke(t *testing.T) {
		t.Fatalf("go build: %v\n%s", err, out)
	}

	// Synthesize a config.ini with valid crypto keys and an empty repos root.
	var fk fernet.Key
	if err := fk.Generate(); err != nil {
		t.Fatalf("generate fernet key: %v", err)
	}
	seed := make([]byte, 32)
	if _, err := rand.Read(seed); err != nil {
		t.Fatalf("generate webhook seed: %v", err)
	}

	// Synthesize a config.ini around ecore's test keyset and an empty repos
	// root. The keys are constants rather than generated ones because they
	// secure nothing here — nothing outside this test ever sees them, and a
	// constant cannot be malformed by accident, which matters for a subprocess
	// whose only way of complaining is a log.Fatal on startup.
	confDir := t.TempDir() // becomes the process cwd; LoadConfig finds config.ini here
	reposDir := t.TempDir()
	confBody := fmt.Sprintf(`[sr.ht]
network-key=%s
site-name=sourcehut
site-name=%s
environment=development

[webhooks]
private-key=%s

[compare.sr.ht]
origin=http://compare.example
origin=%s

[meta.sr.ht]
origin=http://meta.example
origin=%s

[git.sr.ht]
origin=http://git.example
origin=%s
repos=%s
`, fk.Encode(), base64.StdEncoding.EncodeToString(seed), reposDir)
`, ecoretest.NetworkKey, ecoretest.SiteName, ecoretest.WebhookKey,
		ecoretest.Origin(service), ecoretest.Origin("meta.sr.ht"),
		ecoretest.Origin("git.sr.ht"), reposDir)
	if err := os.WriteFile(filepath.Join(confDir, "config.ini"), []byte(confBody), 0o644); err != nil {
		t.Fatalf("write config.ini: %v", err)
	}