servertest

package
v1.47.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 14, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package servertest starts a Packhorse with a fake upstream behind it, so tests can run real git fetches against it.

Index

Constants

View Source
const (
	// RepoPath is the path the upstream repository is served from.
	RepoPath = "/test/repo.git"

	// RepoName is RepoPath as the allowlist sees it.
	RepoName = "test/repo"
)

Variables

This section is empty.

Functions

func Fsck

func Fsck(ctx context.Context, t *testing.T, dir string)

Fsck checks every object in dir is well-formed. fsck re-hashes each object, so a truncated or corrupt pack fails here.

--no-dangling is needed because fetching a bare SHA leaves the new objects reachable only from FETCH_HEAD.

func GitErr

func GitErr(ctx context.Context, dir string, args ...string) error

GitErr is RunGit for goroutines, where require would be invalid. It reports the failure instead of ending the test.

func InitClientRepo

func InitClientRepo(ctx context.Context, repoDir, remoteURL string) error

InitClientRepo points a new repository at remoteURL. It returns an error instead of failing the test so the parallel tests can call it from a goroutine, where require would be invalid.

func RequireCommit

func RequireCommit(ctx context.Context, t *testing.T, dir, commit string)

RequireCommit checks commit arrived in dir as a commit object.

func RunGit

func RunGit(ctx context.Context, t *testing.T, dir string, args ...string) string

RunGit runs a git command in dir and returns stdout, failing the test with stderr attached if git exits non-zero. It goes through testgitserver.GitCommand so the local git config can't move the request off the path under test.

func RunGitCombined

func RunGitCombined(ctx context.Context, t *testing.T, dir string, args ...string) string

RunGitCombined is RunGit but returns stdout and stderr interleaved, for tests that assert on what git printed rather than only on its exit status.

func SkipIfShort

func SkipIfShort(t *testing.T)

SkipIfShort skips a test that shells out to git and starts a server.

Types

type LogCapture added in v1.47.0

type LogCapture struct {
	// contains filtered or unexported fields
}

LogCapture collects what Packhorse logged, as decoded JSON records.

func CaptureLogs added in v1.47.0

func CaptureLogs(t *testing.T) *LogCapture

CaptureLogs redirects the process-wide logger into a LogCapture as JSON for the rest of the test, restoring the previous logger afterwards.

Call it before NewTestPackhorse: every component captures the logger when it is built, so a swap afterwards would not reach them. It also stands in for the harness's own logging setup, which would otherwise replace the capture the first time NewTestPackhorse runs in a binary.

A test using it must not call t.Parallel(), since the logger it swaps is shared by the whole process.

func (*LogCapture) Records added in v1.47.0

func (c *LogCapture) Records(t *testing.T) []map[string]any

Records returns every line logged so far, decoded.

func (*LogCapture) Write added in v1.47.0

func (c *LogCapture) Write(p []byte) (int, error)

Write implements io.Writer for the slog handler. slog serialises its own writes, but a server built while the capture is installed can keep logging from a background goroutine after the test starts reading, so the lock guards the buffer rather than trusting that.

type Option

type Option func(*settings)

Option changes how NewTestPackhorse builds the Packhorse.

func WithAllowlist

func WithAllowlist(allowed *allowlist.Allowlist) Option

WithAllowlist replaces the default allowlist, which holds only the test repository. Pass one that excludes it to exercise the bypass path.

func WithBlobBucket added in v1.47.0

func WithBlobBucket(bucket *blob.Bucket) Option

WithBlobBucket turns on the object-storage cache, which is what makes the packfile-uri path reachable: without a bucket the URI handler hands every request straight back to the local cache. Pair it with NewSignedFileBucket, whose signed URLs a real git client can download from.

func WithCommits

func WithCommits(n int) Option

WithCommits sets how many commits the upstream repository holds.

func WithDryRun added in v1.41.0

func WithDryRun(list *allowlist.Allowlist) Option

WithDryRun turns on dry-run observation for the given list. The caching allowlist wins over dry-run: repos in both are served by the cache path.

func WithIdleAge

func WithIdleAge(idleAge time.Duration) Option

WithIdleAge turns on the sliding TTL.

type SignedFileBucket added in v1.47.0

type SignedFileBucket struct {
	// Bucket is what Packhorse writes packs to and signs URLs for.
	Bucket *blob.Bucket
	// contains filtered or unexported fields
}

SignedFileBucket is a local file-backed bucket whose signed URLs can actually be downloaded, standing in for GCS on the packfile-uri path.

func NewSignedFileBucket added in v1.47.0

func NewSignedFileBucket(t *testing.T) *SignedFileBucket

NewSignedFileBucket opens a fileblob bucket and starts an HTTP server that serves its signed URLs.

Both halves are needed to exercise a packfile-uri fetch end to end. memblob has no SignedURL at all, and fileblob signs a URL without serving anything behind it, so a client handed one would have nowhere to download the pack from. The server here validates the signature with the same HMAC key and streams the object back, which is the role GCS plays in production.

func (*SignedFileBucket) Downloads added in v1.47.0

func (b *SignedFileBucket) Downloads() int64

Downloads is how many objects have been served through a signed URL. It is what separates a client that really fetched the pack from the bucket from one that ignored the URI and was served by Packhorse.

type TestPackhorse

type TestPackhorse struct {
	Packhorse *server.Server
	Upstream  *testgitserver.Server
	Repo      *testgitserver.TestRepo
	Metrics   *observability.MockAppMetrics
}

TestPackhorse is a running Packhorse, the upstream Git server it proxies to, and the repository they both serve. NewTestPackhorse shuts all of it down when the test ends.

func NewTestPackhorse

func NewTestPackhorse(t *testing.T, opts ...Option) *TestPackhorse

NewTestPackhorse starts an upstream Git server holding a repository, and a Packhorse pointed at it. Both listen on random ports.

The allowlist holds only that repository, which is how production runs. It also makes Packhorse label cache metrics by repository rather than collapsing them onto a sentinel, so tests can assert against RepoName.

func (*TestPackhorse) ClientRepo

func (p *TestPackhorse) ClientRepo(ctx context.Context, t *testing.T) string

ClientRepo returns a fresh empty repository pointed at Packhorse.

func (*TestPackhorse) CommitContent

func (p *TestPackhorse) CommitContent(t *testing.T, commit string) string

CommitContent returns the content of test.txt at commit. CreateTestRepo writes "Commit <n>\n" on its nth commit.

func (*TestPackhorse) Fetch

func (p *TestPackhorse) Fetch(ctx context.Context, t *testing.T, repoDir string, args ...string)

Fetch runs git fetch in repoDir. args are passed straight through.

func (*TestPackhorse) FetchInNewRepo

func (p *TestPackhorse) FetchInNewRepo(ctx context.Context, t *testing.T, args ...string) string

FetchInNewRepo fetches into a fresh client repository and returns its path. Calling it twice for the same commit gives the miss-then-hit pattern the cache tests need.

func (*TestPackhorse) RemoteURL

func (p *TestPackhorse) RemoteURL() string

RemoteURL is the repository's URL through Packhorse.

func (*TestPackhorse) RequireCommitContent

func (p *TestPackhorse) RequireCommitContent(ctx context.Context, t *testing.T, repoDir, commit string)

RequireCommitContent checks commit arrived in repoDir and its blob matches upstream. The blob check catches a pack that has the commit but not the objects under it.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL