Gitfed
bastien-mrq/gitfed / internal / adminrpc / adminrpc_test.go
package adminrpc

import (
	"path/filepath"
	"testing"
	"time"

	"git.neuromancer.ovh/bastien-mrq/gitfed/internal/admin"
	"git.neuromancer.ovh/bastien-mrq/gitfed/internal/ca"
	"git.neuromancer.ovh/bastien-mrq/gitfed/internal/federation"
	"git.neuromancer.ovh/bastien-mrq/gitfed/internal/store"
)

// TestErrNotFoundSurvivesRPC reproduces a real bug: the wire only carries
// error strings, so a naive client just wrapping resp.Error in a fresh
// errors.New produces a value that will never compare equal to
// store.ErrNotFound — breaking every `err == store.ErrNotFound` check
// downstream (this exact thing 500'd gitfed-web's repo settings page,
// since GetACL on a repo with no collaborators yet returns ErrNotFound).
func TestErrNotFoundSurvivesRPC(t *testing.T) {
	dir := t.TempDir()
	st, err := store.Open(filepath.Join(dir, "gitfed.db"))
	if err != nil {
		t.Fatalf("open store: %v", err)
	}
	defer st.Close()

	localCA, err := ca.LoadOrCreate(filepath.Join(dir, "ca"))
	if err != nil {
		t.Fatalf("load CA: %v", err)
	}
	a := admin.New(st, federation.NewResolver(st, "local.test", true), "local.test", dir, localCA)
	if err := a.CreateRepo("alice/demo", "alice"); err != nil {
		t.Fatalf("create repo: %v", err)
	}
	// No collaborators granted, so the ACL bucket has no entry for this
	// repo — GetACL is expected to return store.ErrNotFound.

	socketPath := filepath.Join(dir, "admin.sock")
	srv := NewServer(a, socketPath)
	go func() { _ = srv.ListenAndServe() }()

	client := NewClient(socketPath)
	deadline := time.Now().Add(2 * time.Second)
	for {
		if client.Ping() == nil {
			break
		}
		if time.Now().After(deadline) {
			t.Fatal("server never came up")
		}
		time.Sleep(10 * time.Millisecond)
	}

	_, err = client.GetACL("alice/demo")
	if err == nil {
		t.Fatal("expected store.ErrNotFound, got nil")
	}
	if err != store.ErrNotFound {
		t.Fatalf("got error %q (%T), want the exact store.ErrNotFound sentinel — identity was lost crossing the RPC boundary", err, err)
	}
}