Isolate acceptance env vars

This commit is contained in:
William Martin 2024-10-11 16:25:36 +02:00
parent dc7c66c142
commit 9d569b3c11
2 changed files with 47 additions and 36 deletions

View file

@ -6,23 +6,28 @@ The acceptance tests are blackbox* tests that are expected to interact with reso
### Running the Acceptance Tests
The acceptance tests currently require three environment variables to be set:
* `GH_HOST`
* `GH_ACCEPTANCE_ORG`
* `GH_TOKEN`
While `GH_HOST` may not strictly be necessary because `gh` can choose a host, it is required to avoid ambiguity and unexpected results depending on the state of `gh`.
The `GH_ACCEPTANCE_ORG` is an organization that the tests can manage resources in.
The `GH_TOKEN` must already have the necessary scopes for each test, and must have permissions to act in the `GH_ACCEPTANCE_ORG`. See [Effective Test Authoring](#effective-test-authoring) for how tests must handle tokens without sufficient scopes.
The acceptance tests have a build constraint of `//go:build acceptance`, this means that `go test ./...` will continue to work without any modifications. The `acceptance` tag must therefore be provided when running `go test`.
The following environment variables are required:
#### `GH_ACCEPTANCE_HOST`
The GitHub host to target e.g. `github.com`
#### `GH_ACCEPTANCE_ORG`
The organization in which the acceptance tests can manage resources in.
#### `GH_ACCEPTANCE_TOKEN`
The token to use for authenticatin with the `GH_HOST`. This must already have the necessary scopes for each test, and must have permissions to act in the `GH_ACCEPTANCE_ORG`. See [Effective Test Authoring](#effective-test-authoring) for how tests must handle tokens without sufficient scopes.
---
A full example invocation can be found below:
```
GH_HOST=<host> GH_ACCEPTANCE_ORG=<org> GH_TOKEN=<token> test -tags=acceptance ./acceptance
GH_ACCEPTANCE_HOST=<host> GH_ACCEPTANCE_ORG=<org> GH_ACCEPTANCE_TOKEN=<token> test -tags=acceptance ./acceptance
```
### Writing Tests
@ -32,8 +37,9 @@ This section is to be expanded over time as we write more tests and learn more.
#### Environment Variables
The following custom environment variables are made available to the scripts:
* `GH_TOKEN`: Set to the value of the `GH_TOKEN` env var provided to `go test`
* `GH_HOST`: Set to value of the `GH_ACCEPTANCE_ORG` env var provided to `go test`
* `ORG`: Set to the value of the `GH_ACCEPTANCE_ORG` env var provided to `go test`
* `GH_TOKEN`: Set to the value of the `GH_ACCEPTANCE_TOKEN` env var provided to `go test`
* `RANDOM_STRING`: Set to a length 10 random string of letters to help isolate globally visible resources
* `SCRIPT_NAME`: Set to the name of the `testscript` currently running, without extension e.g. `pr-view`
* `HOME`: Set to the initial working directory. Required for `git` operations

View file

@ -32,38 +32,37 @@ func TestPullRequests(t *testing.T) {
os.Exit(1)
}
testscript.Run(t, testScriptParamsFor("pr"))
testscript.Run(t, testScriptParamsFor(tsEnv, "pr"))
}
func testScriptParamsFor(dir string) testscript.Params {
func testScriptParamsFor(tsEnv testScriptEnv, dir string) testscript.Params {
return testscript.Params{
Dir: path.Join("testdata", dir),
Files: []string{},
Setup: sharedSetup,
Setup: sharedSetup(tsEnv),
Cmds: sharedCmds,
RequireExplicitExec: true,
RequireUniqueNames: true,
}
}
var sharedSetup = func(ts *testscript.Env) error {
scriptName, ok := extractScriptName(ts.Vars)
if !ok {
ts.T().Fatal("script name not found")
func sharedSetup(tsEnv testScriptEnv) func(ts *testscript.Env) error {
return func(ts *testscript.Env) error {
scriptName, ok := extractScriptName(ts.Vars)
if !ok {
ts.T().Fatal("script name not found")
}
ts.Setenv("SCRIPT_NAME", scriptName)
ts.Setenv("HOME", ts.Cd)
ts.Setenv("GH_CONFIG_DIR", ts.Cd)
ts.Setenv("GH_HOST", tsEnv.host)
ts.Setenv("ORG", tsEnv.org)
ts.Setenv("GH_TOKEN", tsEnv.token)
ts.Setenv("RANDOM_STRING", randomString(10))
return nil
}
ts.Setenv("SCRIPT_NAME", scriptName)
ts.Setenv("HOME", ts.Cd)
ts.Setenv("GH_CONFIG_DIR", ts.Cd)
ts.Setenv("GH_TOKEN", os.Getenv("GH_TOKEN"))
ts.Setenv("GH_HOST", os.Getenv("GH_HOST"))
ts.Setenv("ORG", os.Getenv("GH_ACCEPTANCE_ORG"))
ts.Setenv("RANDOM_STRING", randomString(10))
return nil
}
var sharedCmds = map[string]func(ts *testscript.TestScript, neg bool, args []string){
@ -121,8 +120,14 @@ type testScriptEnv struct {
func (e *testScriptEnv) fromEnv() error {
envMap := map[string]string{}
requiredEnvVars := []string{
"GH_ACCEPTANCE_HOST",
"GH_ACCEPTANCE_ORG",
"GH_ACCEPTANCE_TOKEN",
}
var missingEnvs []string
for _, key := range []string{"GH_HOST", "GH_ACCEPTANCE_ORG", "GH_TOKEN"} {
for _, key := range requiredEnvVars {
val, ok := os.LookupEnv(key)
if !ok {
missingEnvs = append(missingEnvs, key)
@ -136,9 +141,9 @@ func (e *testScriptEnv) fromEnv() error {
return missingEnvError{missingEnvs: missingEnvs}
}
e.host = envMap["GH_HOST"]
e.host = envMap["GH_ACCEPTANCE_HOST"]
e.org = envMap["GH_ACCEPTANCE_ORG"]
e.token = envMap["GH_TOKEN"]
e.token = envMap["GH_ACCEPTANCE_TOKEN"]
return nil
}