Documentation
¶
Overview ¶
Package gitforge stands up a real, hermetic git remote for tests.
Why this exists rather than a mock ¶
pkg/executor/gitprovision and pkg/executor/gitwriteback are the two halves of one circuit: a leased credential reaches a sandbox through the first, and the commits the sandbox produced travel back through the second. Neither half can be proven against a fake. The claims they make — the token is scoped to one origin, the environment handed to git is closed, a refusal happens before any byte reaches the remote — are claims about what the *git binary* does with the environment those packages build. A mock that returned canned output would agree with any of them.
So the remote here is a real bare repository served by real git-http-backend over real TLS, and every assertion about it is an assertion about a repository rather than about a recorded call. It is hermetic all the same: the listener is on loopback, the certificate is minted by httptest, and nothing outside the test's temporary directories is read or written.
Why TLS and not plain HTTP ¶
executor.Workspace refuses a repo URL that is not https, because a brokered token on cleartext http is a published token. A test forge on http would therefore be testing a configuration production cannot express. TLS also makes the transport allowlist observable: the only way a client can trust this forge's certificate is GIT_SSL_CAINFO, which is on gitprovision's allowlist, while GIT_SSL_NO_VERIFY — the shortcut — is deliberately not. A fetch that succeeds here is therefore evidence that the allowlist works, and one that fails without CAINFO is evidence that the shortcut really is absent.
Why it lives under internal/ ¶
It imports "testing", so it must never be reachable from a shipped binary. internal/ enforces that, and scopes it to the executor tree where both callers live.
Index ¶
- Constants
- func FixtureEnv(home string) []string
- func Git(tb testing.TB, tools Tools, home, dir string, args ...string) string
- func NoSecretIn(tb testing.TB, set *redact.Set, what, text string)
- func NoSecretUnder(tb testing.TB, set *redact.Set, root string) int
- func TryGit(tb testing.TB, tools Tools, home, dir string, args ...string) (string, error)
- func WriteFile(tb testing.TB, dir, rel, content string) string
- type Forge
- func (f *Forge) AddFile(tb testing.TB, owner, name, branch, path, content, msg string) string
- func (f *Forge) CAFile() string
- func (f *Forge) Count() int
- func (f *Forge) Create(tb testing.TB, owner, name string) string
- func (f *Forge) Git(tb testing.TB, dir string, args ...string) string
- func (f *Forge) Log() string
- func (f *Forge) Path(owner, name string) string
- func (f *Forge) RepoURL(owner, name string) string
- func (f *Forge) Requests() []Request
- func (f *Forge) SHA(tb testing.TB, owner, name, branch string) string
- func (f *Forge) Trust(tb testing.TB)
- func (f *Forge) URL() string
- type Options
- type Request
- type Tools
Constants ¶
const DefaultBranch = "main"
DefaultBranch is the branch a seeded repository puts its first commit on. It is named explicitly everywhere rather than inherited from the git version's default, which has changed.
Variables ¶
This section is empty.
Functions ¶
func FixtureEnv ¶
FixtureEnv is the environment every fixture git command runs in.
It is closed for the same reason the code under test closes its own: a developer's ~/.gitconfig holding a credential helper, an insteadOf rewrite or a commit.gpgsign would otherwise decide the outcome of a test about something else. home isolates anything that still reaches for it.
func Git ¶
Git runs a fixture git command outside any forge, for tests that only need a local repository. home is the isolated HOME to run it under.
func NoSecretIn ¶
NoSecretIn fails tb when text contains any value in set.
what names the channel — "the returned error", "the emitted log" — because the first question on a failure is which surface leaked, not what the value was. The value itself is never printed; a test that leaked the credential into the test log would have reproduced the bug it was written to catch.
func NoSecretUnder ¶
NoSecretUnder walks root and fails tb for any file whose name or contents contain a value in set.
This is the assertion that a credential never reached the disk, and it is deliberately blunt: it does not know whether the leak would be an askpass script, a credential-helper file, a .git/config entry or a stray temporary, and it does not need to. Anything a future change writes lands in one of these files or it does not exist.
It returns the number of files scanned so a caller can refuse a vacuous pass: an assertion over an empty tree succeeds for the wrong reason.
Types ¶
type Forge ¶
type Forge struct {
// contains filtered or unexported fields
}
Forge is a bare-repository host served over TLS.
func (*Forge) AddFile ¶
AddFile commits one file onto a branch of an existing repository and returns the new tip.
func (*Forge) Count ¶
Count is how many requests the forge has received. Zero is the assertion that matters for every refusal that is supposed to happen before the network.
func (*Forge) Create ¶
Create makes a bare repository and seeds it with one commit on DefaultBranch, returning that commit's SHA.
The seed travels over the filesystem rather than over HTTP: fixture setup must not depend on the path under test, or a broken fetch would show up as a broken fixture.
func (*Forge) Path ¶
Path is the bare repository's directory, for fixture work that must not go through the path under test.
func (*Forge) SHA ¶
SHA resolves a branch on the forge, returning "" when the ref does not exist. The empty string is the useful answer for "the push was refused": a test can assert the ref was never created without special-casing an error.
type Options ¶
type Options struct {
// User and Password are the basic credential the forge demands. When
// Password is empty the forge serves anonymously, which is how a test
// distinguishes "the client sent no credential" from "the credential was
// wrong".
User, Password string
// Intercept, when non-nil, runs for every request after it is recorded and
// before it is authenticated. Returning true means it wrote the response
// itself and git must not be invoked — used to model a redirect, a hang, or
// a forge that is down.
Intercept func(w http.ResponseWriter, r *http.Request) bool
}
Options configure a forge.
type Request ¶
type Request struct {
Method string
Path string
Authorization string
User string
Password string
Authorized bool
}
Request is one HTTP request the forge received.
Authorization is recorded verbatim, which is what lets a test assert the negative that matters most: that a host the grant does not cover never saw the header at all.
type Tools ¶
type Tools struct {
// Git is the client and fixture binary.
Git string
// Backend is git-http-backend, which serves the smart-HTTP protocol as CGI.
Backend string
}
Tools are the binaries a forge needs.
func RequireGit ¶
RequireGit locates git and git-http-backend, or ends the test.
The interesting decision is what "or ends the test" means, and it is not always a skip. A skipped test is reported as a pass by every summary anyone actually reads, so a suite that skips itself into silence is worse than one that was never written: it occupies the place where coverage is supposed to be. These tests are the only executable proof that a leased credential does not leak, which makes them precisely the ones that must not disappear quietly.
So the rule is conditional on whether the environment is one where git is guaranteed. In CI it is: this repository cannot be checked out without git, so a runner that cannot find it is misconfigured and the suite says so with a failure. On a developer machine — where git-http-backend genuinely may not be installed, since several distributions package it separately — the skip stands, and it names the package to install rather than leaving the reader to guess.
CLOOP_REQUIRE_GIT_E2E=1 forces the failing behaviour anywhere, so an operator debugging a suspiciously green run can prove the tests really ran.