Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

124 lines
4.1 KiB
Go

package hooks
import (
"context"
"encoding/json"
"net"
"os"
"path/filepath"
"testing"
"time"
"go.uber.org/zap"
"github.com/zzet/gortex/internal/daemon"
)
// fakeController implements daemon.Controller with stubbed SearchSymbols
// and no-op everything else. Lives in the hooks package so the e2e test
// can drive it through the real socket without dragging the hooks
// package into internal/daemon (which would create an import cycle).
type fakeController struct {
hits []daemon.SymbolHit
}
func (f *fakeController) Track(_ context.Context, _ daemon.TrackParams) (json.RawMessage, error) {
return json.RawMessage(`{}`), nil
}
func (f *fakeController) Untrack(_ context.Context, _ daemon.UntrackParams) (json.RawMessage, error) {
return json.RawMessage(`{}`), nil
}
func (f *fakeController) Reload(_ context.Context) (json.RawMessage, error) {
return json.RawMessage(`{}`), nil
}
func (f *fakeController) ReloadServers(_ context.Context) (json.RawMessage, error) {
return json.RawMessage(`{}`), nil
}
func (f *fakeController) Status(_ context.Context) (daemon.StatusResponse, error) {
return daemon.StatusResponse{}, nil
}
func (f *fakeController) Shutdown(_ context.Context) error { return nil }
func (f *fakeController) SearchSymbols(_ context.Context, _ daemon.SearchSymbolsParams) (daemon.SearchSymbolsResult, error) {
return daemon.SearchSymbolsResult{Hits: f.hits}, nil
}
func (f *fakeController) EnrichChurn(_ context.Context, _ daemon.EnrichChurnParams) (daemon.EnrichChurnResult, error) {
return daemon.EnrichChurnResult{}, nil
}
func (f *fakeController) EnrichReleases(_ context.Context, _ daemon.EnrichReleasesParams) (daemon.EnrichReleasesResult, error) {
return daemon.EnrichReleasesResult{}, nil
}
func (f *fakeController) EnrichBlame(_ context.Context, _ daemon.EnrichBlameParams) (daemon.EnrichBlameResult, error) {
return daemon.EnrichBlameResult{}, nil
}
func (f *fakeController) EnrichCoverage(_ context.Context, _ daemon.EnrichCoverageParams) (daemon.EnrichCoverageResult, error) {
return daemon.EnrichCoverageResult{}, nil
}
func (f *fakeController) EnrichCochange(_ context.Context, _ daemon.EnrichCochangeParams) (daemon.EnrichCochangeResult, error) {
return daemon.EnrichCochangeResult{}, nil
}
// startTestDaemon spins up a real daemon on a short-path unix socket and
// points GORTEX_DAEMON_SOCKET at it so daemon.Dial finds it.
func startTestDaemon(t *testing.T, ctrl daemon.Controller) {
t.Helper()
dir, err := os.MkdirTemp("/tmp", "gx-hook-e2e")
if err != nil {
t.Fatalf("mktemp: %v", err)
}
t.Cleanup(func() { _ = os.RemoveAll(dir) })
socket := filepath.Join(dir, "s")
t.Setenv("GORTEX_DAEMON_SOCKET", socket)
t.Setenv("GORTEX_DAEMON_PIDFILE", filepath.Join(dir, "p"))
srv := daemon.New(socket, "test-0.0.0", zap.NewNop())
srv.Controller = ctrl
if err := srv.Listen(); err != nil {
t.Fatalf("listen: %v", err)
}
go func() { _ = srv.Serve() }()
t.Cleanup(func() { _ = srv.Shutdown() })
// Wait for the socket to actually accept.
deadline := time.Now().Add(2 * time.Second)
for time.Now().Before(deadline) {
c, err := net.DialTimeout("unix", socket, 100*time.Millisecond)
if err == nil {
_ = c.Close()
return
}
time.Sleep(20 * time.Millisecond)
}
t.Fatal("daemon socket never accepted")
}
func TestProbeViaDaemon_Hit_E2E(t *testing.T) {
startTestDaemon(t, &fakeController{
hits: []daemon.SymbolHit{
{Name: "handleFoo", Kind: "function", FilePath: "x.go", Line: 7},
},
})
hits, err := probeViaDaemon("handleFoo", 2*time.Second)
if err != nil {
t.Fatalf("probe error: %v", err)
}
if len(hits) != 1 || hits[0].Name != "handleFoo" || hits[0].FilePath != "x.go" || hits[0].Line != 7 {
t.Errorf("unexpected hits: %+v", hits)
}
}
func TestProbeViaDaemon_NoDaemon_ReturnsUnreachable(t *testing.T) {
// Point at a path that has no listener.
dir, err := os.MkdirTemp("/tmp", "gx-hook-empty")
if err != nil {
t.Fatalf("mktemp: %v", err)
}
t.Cleanup(func() { _ = os.RemoveAll(dir) })
t.Setenv("GORTEX_DAEMON_SOCKET", filepath.Join(dir, "missing"))
_, err = probeViaDaemon("handleFoo", 500*time.Millisecond)
if err != errDaemonUnreachable {
t.Errorf("expected errDaemonUnreachable, got %v", err)
}
}