Documentation
¶
Overview ¶
Package cicd provides support for working with CI environments.
Index ¶
- Constants
- func IsGitHubActions() bool
- func IsGitHubHostedRunner() bool
- func IsSelfHostedRunner() bool
- func LongRunningTest(t TestingT, level int)
- func ParseLongRunningTestsEnv() (enabled bool, level int, regex *regexp.Regexp, err error)
- func SkipIf(t TestingTSkip, msg string, skipping bool)
- func SkipLinux(t TestingTSkip)
- func SkipMacOS(t TestingTSkip)
- func SkipWindows(t TestingTSkip)
- func TestMain[T TestingT](ctx context.Context, verbose bool, regex *regexp.Regexp, wr io.Writer, ...) error
- type ConfigManager
- type Testing
- func (t *Testing) Cleanup(f func())
- func (t *Testing) Context() context.Context
- func (t *Testing) Error(args ...any)
- func (t *Testing) Errorf(format string, args ...any)
- func (t *Testing) Fail()
- func (t *Testing) FailNow()
- func (t *Testing) Failed() bool
- func (t *Testing) Fatal(args ...any)
- func (t *Testing) Fatalf(format string, args ...any)
- func (t *Testing) Helper()
- func (t *Testing) Log(args ...any)
- func (t *Testing) Logf(format string, args ...any)
- func (t *Testing) Name() string
- func (t *Testing) Run(name string, f func(*Testing)) bool
- func (t *Testing) RunCleanups()
- func (t *Testing) Skip(args ...any)
- func (t *Testing) SkipNow()
- func (t *Testing) Skipf(format string, args ...any)
- func (t *Testing) Skipped() bool
- type TestingT
- type TestingTSkip
Examples ¶
Constants ¶
const LongRunningTestsEnv = "CLOUDENG_LONG_RUNNING_TESTS"
LongRunningTestsEnv, is used to control whether and which long running tests are to be run. No long running tests are run if this variable is not set. If set, it may refer to either a numeric level (ie. 1, 2, etc) or a regular expression as per go test '-run'. The numeric level is used to control ever longer running tests, level 1 for < 10 minutes, level 2 for < 30 minutes, etc. The regular expression is used to control which tests are run based on their name, for example setting it to "Lifecycle" would run only tests with "Lifecycle" in their name.
Variables ¶
This section is empty.
Functions ¶
func IsGitHubActions ¶
func IsGitHubActions() bool
IsGitHubActions returns true when running inside any GitHub Actions workflow, regardless of whether the runner is hosted or self-hosted.
func IsGitHubHostedRunner ¶
func IsGitHubHostedRunner() bool
IsGitHubHostedRunner returns true when running on a GitHub-hosted runner.
func IsSelfHostedRunner ¶
func IsSelfHostedRunner() bool
IsSelfHostedRunner returns true when running on a self-hosted GitHub Actions runner.
func LongRunningTest ¶
LongRunningTest declares the calling test as a long-running one of a given level that should only be run if requested via the CLOUDENG_LONG_RUNNING_TESTS environment variable. See the documentation for CLOUDENG_LONG_RUNNING_TESTS for details on how to control which long-running tests are run. In short, if not set, no long running tests are run; if set to a number, only long-running tests with that level and below are run; if set to a non-number, only long-running tests with names matching that regular expression are run.
func ParseLongRunningTestsEnv ¶
ParseLongRunningTestsEnv parses the CLOUDENG_LONG_RUNNING_TESTS environment variable and returns whether long-running tests are enabled, the numeric level if it is a number, and the regular expression if it is not a number. The results are cached after the first call.
func SkipIf ¶
func SkipIf(t TestingTSkip, msg string, skipping bool)
SkipIf skips t if skipping is true, using msg as the skip message.
func TestMain ¶
func TestMain[T TestingT](ctx context.Context, verbose bool, regex *regexp.Regexp, wr io.Writer, tests []func(T)) error
TestMain runs each test in tests with its own fresh *Testing. T must be compatible with *Testing (i.e. *Testing or an interface it implements, such as TestingT). Each test's name is derived from its function name via reflection. Tests run in slice order. Output goes to w (nil → os.Stderr).
Types ¶
type ConfigManager ¶
type ConfigManager[T any] struct { // contains filtered or unexported fields }
ConfigManager provides a means to manage configurations based on regex patterns that can be matched against test names. It is useful for centralizing the configuration of tests, especially those that are externalized by a one package for use by multiple others. For example, when an interface has multiple implementations for which tests can be shared.
Example ¶
ExampleConfigManager demonstrates centralizing per-implementation test configuration. A shared test suite calls Get with the running test name to obtain the parameters that match that implementation; names that match no regex fall back to the default.
package main
import (
"fmt"
"regexp"
"time"
"cloudeng.io/cicd"
)
func main() {
type VMConfig struct {
Image string
Timeout time.Duration
}
var mgr cicd.ConfigManager[VMConfig]
mgr.SetDefault(VMConfig{Image: "linux:latest", Timeout: 5 * time.Minute})
mgr.Set(regexp.MustCompile(`MacOS`), VMConfig{Image: "macos:latest", Timeout: 15 * time.Minute})
mgr.Set(regexp.MustCompile(`Windows`), VMConfig{Image: "windows:latest", Timeout: 20 * time.Minute})
for _, testName := range []string{
"TestProvisionMacOS",
"TestProvisionWindows",
"TestProvisionLinux",
} {
cfg := mgr.Get(testName)
fmt.Printf("%-26s image=%-18s timeout=%v\n", testName, cfg.Image, cfg.Timeout)
}
}
Output: TestProvisionMacOS image=macos:latest timeout=15m0s TestProvisionWindows image=windows:latest timeout=20m0s TestProvisionLinux image=linux:latest timeout=5m0s
func (*ConfigManager[T]) Get ¶
func (c *ConfigManager[T]) Get(s string) T
Get returns the configuration associated with the first regex that matches the input string. The regexes are evaluated in the order they were added via Set. If no regex matches, the default configuration is returned, hence there is no need to use a regex that matches all strings as the default case.
func (*ConfigManager[T]) Set ¶
func (c *ConfigManager[T]) Set(re *regexp.Regexp, config T)
Set associates a regex pattern with a specific configuration. It panics if a nil regex is provided. The regexes are evaluated in the order they were added via Set, so the first matching regex will determine the configuration returned by Get.
func (*ConfigManager[T]) SetDefault ¶
func (c *ConfigManager[T]) SetDefault(config T)
SetDefault sets the default configuration to be returned when no regex matches.
type Testing ¶
type Testing struct {
// contains filtered or unexported fields
}
Testing is a concrete implementation of TestingT for use outside the test harness (e.g. integration tests run as binaries). Fatal/Fatalf and Skip/Skipf terminate the current goroutine via runtime.Goexit, which runs deferred functions before exiting — matching the behaviour of *testing.T. Note that RunCleanups must be called to run registered cleanup functions after the test body completes, matching *testing.T semantics.
func NewTesting ¶
NewTesting creates a Testing with the given name. Output goes to w; pass nil to use os.Stderr.
func (*Testing) Cleanup ¶
func (t *Testing) Cleanup(f func())
Cleanup registers a function to be called when RunCleanups is invoked. Functions are called in last-in-first-out order, matching *testing.T.
func (*Testing) Context ¶
Context returns the context for this test. The context is cancelled just before RunCleanups is called, matching testing.T.Context() semantics.
func (*Testing) Fail ¶
func (t *Testing) Fail()
Fail marks the function as having failed but continues execution. It mirrors testing.T.Fail.
func (*Testing) FailNow ¶
func (t *Testing) FailNow()
FailNow marks the function as having failed and stops its execution by calling runtime.Goexit (which runs all deferred calls in the current goroutine). It mirrors testing.T.FailNow.
func (*Testing) Fatal ¶
Fatal marks the test as failed, writes a message, then terminates the current goroutine via runtime.Goexit.
func (*Testing) Fatalf ¶
Fatalf marks the test as failed, writes a formatted message, then terminates the current goroutine via runtime.Goexit.
func (*Testing) Helper ¶
func (t *Testing) Helper()
Helper marks the calling function as a test helper function. When printing file and line information, that function will be skipped.
func (*Testing) Run ¶
Run mirrors testing.T.Run: it creates a child Testing named "parent/name", runs f in a new goroutine (so Fatal/Skip only exit the child), waits for completion. If the child fails, the parent is also marked as failed, matching testing.T.Run semantics. Returns true if the child did not fail.
func (*Testing) RunCleanups ¶
func (t *Testing) RunCleanups()
RunCleanups runs all registered cleanup functions in LIFO order and clears the cleanup list.
func (*Testing) Skip ¶
Skip marks the test as skipped, writes a message, then terminates the current goroutine via runtime.Goexit.
func (*Testing) SkipNow ¶
func (t *Testing) SkipNow()
SkipNow marks the test as skipped and stops its execution by calling runtime.Goexit. It mirrors testing.T.SkipNow.
type TestingT ¶
type TestingT interface {
Helper()
Context() context.Context
Skipf(format string, args ...any)
Fatalf(format string, args ...any)
Name() string
Failed() bool
Skipped() bool
Log(args ...any)
Logf(format string, args ...any)
Error(args ...any)
Errorf(format string, args ...any)
Fatal(args ...any)
Skip(args ...any)
Cleanup(f func())
Fail()
FailNow()
SkipNow()
}
TestingT mirrors testing.T and is implemented by cicd.Testing.