Documentation
¶
Overview ¶
Package testutil provides utilities for end-to-end CLI testing.
Index ¶
- Constants
- func APIKeyListFixture() []map[string]interface{}
- func AlertFixture(id string) map[string]interface{}
- func AlertHistoryFixture() []map[string]interface{}
- func AlertListFixture() []map[string]interface{}
- func AlertMuteListFixture() []map[string]interface{}
- func AlertStatsFixture() map[string]interface{}
- func BillingInfoFixture() map[string]interface{}
- func BillingStatusFixture() map[string]interface{}
- func BillingUsageFixture() map[string]interface{}
- func CLIVerifyFixture() map[string]interface{}
- func ChannelFixture(id string) map[string]interface{}
- func ChannelListFixture() []map[string]interface{}
- func DashboardStatsFixture() map[string]interface{}
- func DependencyTreeFixture() []map[string]interface{}
- func GetLiveAPIURL() string
- func IsLiveTestEnabled() bool
- func LabelKeyListFixture() []map[string]interface{}
- func LabelListFixture() []map[string]interface{}
- func NewAPIKeyFixture() map[string]interface{}
- func NewAlertMuteFixture() map[string]interface{}
- func NewChannelFixture() map[string]interface{}
- func NewLabelFixture() map[string]interface{}
- func NewLabelKeyFixture() map[string]interface{}
- func NewProbeDependencyFixture() map[string]interface{}
- func NewProbeFixture() map[string]interface{}
- func NewStatusPageFixture() map[string]interface{}
- func NewStatusPageIncidentFixture() map[string]interface{}
- func NewTeamMemberFixture() map[string]interface{}
- func ProbeDependencyListFixture() []map[string]interface{}
- func ProbeFixture(id string) map[string]interface{}
- func ProbeHistoryFixture() []map[string]interface{}
- func ProbeListFixture() []map[string]interface{}
- func ProbeStatsFixture() map[string]interface{}
- func ProbeTestResultFixture() map[string]interface{}
- func RegionListByContinent() map[string][]map[string]interface{}
- func RegionListFixture() []map[string]interface{}
- func RespondWithError(w http.ResponseWriter, status int, message string)
- func RespondWithJSON(w http.ResponseWriter, status int, data interface{})
- func StatusPageFixture(id string) map[string]interface{}
- func StatusPageIncidentListFixture() []map[string]interface{}
- func StatusPageListFixture() []map[string]interface{}
- func TeamInvitationListFixture() []map[string]interface{}
- func TeamMemberListFixture() []map[string]interface{}
- func UserOrganizationListFixture() []map[string]interface{}
- func UserProfileFixture() map[string]interface{}
- type APIMeta
- type APIResponse
- type CLIRunner
- type ErrorConfig
- type MockServer
- func (ms *MockServer) CallCount(method, pathPrefix string) int
- func (ms *MockServer) ClearAllDynamicResponses()
- func (ms *MockServer) ClearAllErrors()
- func (ms *MockServer) ClearCalls()
- func (ms *MockServer) ClearDynamicResponse(method, path string)
- func (ms *MockServer) ClearError(method, path string)
- func (ms *MockServer) Close()
- func (ms *MockServer) GetCalls() []RecordedCall
- func (ms *MockServer) GetCallsForPath(method, pathPrefix string) []RecordedCall
- func (ms *MockServer) HasCall(method, pathPrefix string) bool
- func (ms *MockServer) Register(method, pattern string, handler RouteHandler)
- func (ms *MockServer) RegisterAllRoutes()
- func (ms *MockServer) RegisterDefaultRoutes()
- func (ms *MockServer) SetDynamicResponse(method, path string, data interface{})
- func (ms *MockServer) WithError(method, path string, statusCode int, message string)
- func (ms *MockServer) WithLatency(d time.Duration)
- func (ms *MockServer) WithRouteLatency(method, path string, d time.Duration)
- type RecordedCall
- type Route
- type RouteHandler
- type RunResult
- func (r *RunResult) CombinedOutput() string
- func (r *RunResult) Contains(substr string) bool
- func (r *RunResult) Failed() bool
- func (r *RunResult) Lines() []string
- func (r *RunResult) StderrContains(substr string) bool
- func (r *RunResult) StderrLines() []string
- func (r *RunResult) String() string
- func (r *RunResult) Success() bool
- type TestConfig
- type TestEnv
- func (e *TestEnv) AssertAPICall(method, pathPrefix string)
- func (e *TestEnv) AssertContains(result *RunResult, substr string)
- func (e *TestEnv) AssertJSONOutput(result *RunResult, v any)
- func (e *TestEnv) AssertNoAPICall(method, pathPrefix string)
- func (e *TestEnv) AssertNotContains(result *RunResult, substr string)
- func (e *TestEnv) AssertStderrContains(result *RunResult, substr string)
- func (e *TestEnv) AssertTableHasRows(result *RunResult, minRows int)
- func (e *TestEnv) Cleanup()
- func (e *TestEnv) ClearAPICalls()
- func (e *TestEnv) GetAPICalls() []RecordedCall
- func (e *TestEnv) IsLiveMode() bool
- func (e *TestEnv) Run(args ...string) *RunResult
- func (e *TestEnv) RunError(args ...string) *RunResult
- func (e *TestEnv) RunSuccess(args ...string) *RunResult
Constants ¶
const ( // EnvLiveTest enables live API testing when set to "true" or "1". EnvLiveTest = "STACKEYE_E2E_LIVE" // EnvLiveAPIURL overrides the API URL for live testing. EnvLiveAPIURL = "STACKEYE_E2E_API_URL" // DefaultLiveAPIURL is the default API URL for live testing. DefaultLiveAPIURL = "https://api-dev.stackeye.io" )
Environment variables for live testing.
const ( ProbeID1 = "11111111-1111-1111-1111-111111111111" ProbeID2 = "22222222-2222-2222-2222-222222222222" AlertID1 = "aaaaaaaa-1111-1111-1111-111111111111" ChannelID1 = "cccccccc-1111-1111-1111-111111111111" ChannelID2 = "cccccccc-2222-2222-2222-222222222222" OrganizationID = "00000000-0000-0000-0000-000000000001" MuteID1 = "eeeeeeee-1111-1111-1111-111111111111" StatusPageID1 = "55555555-1111-1111-1111-111111111111" IncidentID1 = "66666666-1111-1111-1111-111111111111" TeamMemberID1 = "77777777-1111-1111-1111-111111111111" TeamMemberID2 = "77777777-2222-2222-2222-222222222222" InvitationID1 = "88888888-1111-1111-1111-111111111111" APIKeyID1 = "99999999-1111-1111-1111-111111111111" LabelID1 = "bbbbbbbb-1111-1111-1111-111111111111" LabelKeyID1 = "dddddddd-1111-1111-1111-111111111111" DependencyID1 = "ffffffff-1111-1111-1111-111111111111" UserID1 = "44444444-1111-1111-1111-111111111111" )
Known fixture IDs for consistent testing Note: All IDs must be valid UUIDs (36 chars, proper hex format)
const TestAPIKey = "se_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
TestAPIKey is a fixed API key for testing.
const TestContextName = "test"
TestContextName is the default test context name.
Variables ¶
This section is empty.
Functions ¶
func APIKeyListFixture ¶
func APIKeyListFixture() []map[string]interface{}
APIKeyListFixture returns a list of API keys.
func AlertFixture ¶
AlertFixture returns an alert fixture by ID.
func AlertHistoryFixture ¶
func AlertHistoryFixture() []map[string]interface{}
AlertHistoryFixture returns alert history entries.
func AlertListFixture ¶
func AlertListFixture() []map[string]interface{}
AlertListFixture returns a list of alerts for testing. Note: Field names MUST match SDK's Alert struct JSON tags exactly.
func AlertMuteListFixture ¶
func AlertMuteListFixture() []map[string]interface{}
AlertMuteListFixture returns a list of alert mutes for testing.
func AlertStatsFixture ¶
func AlertStatsFixture() map[string]interface{}
AlertStatsFixture returns alert statistics fixture.
func BillingInfoFixture ¶
func BillingInfoFixture() map[string]interface{}
BillingInfoFixture returns billing info.
func BillingStatusFixture ¶
func BillingStatusFixture() map[string]interface{}
BillingStatusFixture returns billing/subscription status.
func BillingUsageFixture ¶
func BillingUsageFixture() map[string]interface{}
BillingUsageFixture returns current billing usage.
func CLIVerifyFixture ¶
func CLIVerifyFixture() map[string]interface{}
CLIVerifyFixture returns a CLI credential verification response. Matches the CLIVerifyResponse struct in stackeye-go-sdk/client/cli_auth.go.
func ChannelFixture ¶
ChannelFixture returns a channel fixture by ID.
func ChannelListFixture ¶
func ChannelListFixture() []map[string]interface{}
ChannelListFixture returns a list of notification channels for testing. Note: Field names MUST match SDK's Channel struct JSON tags exactly.
func DashboardStatsFixture ¶
func DashboardStatsFixture() map[string]interface{}
DashboardStatsFixture returns dashboard statistics.
func DependencyTreeFixture ¶
func DependencyTreeFixture() []map[string]interface{}
DependencyTreeFixture returns a dependency tree for an organization.
func GetLiveAPIURL ¶
func GetLiveAPIURL() string
GetLiveAPIURL returns the API URL for live testing.
func IsLiveTestEnabled ¶
func IsLiveTestEnabled() bool
IsLiveTestEnabled returns true if live testing is enabled via environment.
func LabelKeyListFixture ¶
func LabelKeyListFixture() []map[string]interface{}
LabelKeyListFixture returns a list of label keys for an organization.
func LabelListFixture ¶
func LabelListFixture() []map[string]interface{}
LabelListFixture returns a list of labels for a probe.
func NewAPIKeyFixture ¶
func NewAPIKeyFixture() map[string]interface{}
NewAPIKeyFixture returns a newly created API key fixture.
func NewAlertMuteFixture ¶
func NewAlertMuteFixture() map[string]interface{}
NewAlertMuteFixture returns a newly created alert mute fixture.
func NewChannelFixture ¶
func NewChannelFixture() map[string]interface{}
NewChannelFixture returns a newly created channel fixture.
func NewLabelFixture ¶
func NewLabelFixture() map[string]interface{}
NewLabelFixture returns a newly created label fixture.
func NewLabelKeyFixture ¶
func NewLabelKeyFixture() map[string]interface{}
NewLabelKeyFixture returns a newly created label key fixture.
func NewProbeDependencyFixture ¶
func NewProbeDependencyFixture() map[string]interface{}
NewProbeDependencyFixture returns a newly created dependency fixture.
func NewProbeFixture ¶
func NewProbeFixture() map[string]interface{}
NewProbeFixture returns a newly created probe fixture.
func NewStatusPageFixture ¶
func NewStatusPageFixture() map[string]interface{}
NewStatusPageFixture returns a newly created status page fixture.
func NewStatusPageIncidentFixture ¶
func NewStatusPageIncidentFixture() map[string]interface{}
NewStatusPageIncidentFixture returns a newly created incident fixture.
func NewTeamMemberFixture ¶
func NewTeamMemberFixture() map[string]interface{}
NewTeamMemberFixture returns a newly invited team member fixture.
func ProbeDependencyListFixture ¶
func ProbeDependencyListFixture() []map[string]interface{}
ProbeDependencyListFixture returns a list of probe dependencies.
func ProbeFixture ¶
ProbeFixture returns a probe fixture by ID.
func ProbeHistoryFixture ¶
func ProbeHistoryFixture() []map[string]interface{}
ProbeHistoryFixture returns probe history entries.
func ProbeListFixture ¶
func ProbeListFixture() []map[string]interface{}
ProbeListFixture returns a list of probes for testing. Note: Field names MUST match SDK's Probe struct JSON tags exactly.
func ProbeStatsFixture ¶
func ProbeStatsFixture() map[string]interface{}
ProbeStatsFixture returns probe statistics fixture.
func ProbeTestResultFixture ¶
func ProbeTestResultFixture() map[string]interface{}
ProbeTestResultFixture returns a probe test result fixture. Note: Field names MUST match SDK's ProbeTestResponse struct JSON tags exactly.
func RegionListByContinent ¶
RegionListByContinent returns regions grouped by continent, matching SDK's RegionListResponse.Data format. SDK expects: map[string][]Region where key is continent slug like "north_america", "europe".
func RegionListFixture ¶
func RegionListFixture() []map[string]interface{}
RegionListFixture returns a flat list of available regions (legacy format).
func RespondWithError ¶
func RespondWithError(w http.ResponseWriter, status int, message string)
RespondWithError writes an error response.
func RespondWithJSON ¶
func RespondWithJSON(w http.ResponseWriter, status int, data interface{})
RespondWithJSON writes a JSON response.
func StatusPageFixture ¶
StatusPageFixture returns a status page by ID.
func StatusPageIncidentListFixture ¶
func StatusPageIncidentListFixture() []map[string]interface{}
StatusPageIncidentListFixture returns a list of incidents for a status page.
func StatusPageListFixture ¶
func StatusPageListFixture() []map[string]interface{}
StatusPageListFixture returns a list of status pages.
func TeamInvitationListFixture ¶
func TeamInvitationListFixture() []map[string]interface{}
TeamInvitationListFixture returns a list of pending invitations.
func TeamMemberListFixture ¶
func TeamMemberListFixture() []map[string]interface{}
TeamMemberListFixture returns a list of team members.
func UserOrganizationListFixture ¶
func UserOrganizationListFixture() []map[string]interface{}
UserOrganizationListFixture returns a list of organizations the user belongs to.
func UserProfileFixture ¶
func UserProfileFixture() map[string]interface{}
UserProfileFixture returns a user profile.
Types ¶
type APIMeta ¶
type APIMeta struct {
Page int `json:"page"`
Limit int `json:"limit"`
Total int `json:"total"`
Pages int `json:"pages"`
HasNext bool `json:"has_next"`
}
APIMeta contains pagination metadata.
type APIResponse ¶
type APIResponse struct {
Status string `json:"status"`
Data interface{} `json:"data,omitempty"`
Error string `json:"error,omitempty"`
Meta *APIMeta `json:"meta,omitempty"`
}
APIResponse represents a standardized API response.
type CLIRunner ¶
type CLIRunner struct {
// BinaryPath is the path to the CLI binary.
BinaryPath string
// ConfigPath is the path to the config file.
ConfigPath string
// XDGConfigHome is the XDG_CONFIG_HOME value to use.
// This ensures the CLI's Save() function writes to the correct location.
XDGConfigHome string
// Env contains additional environment variables.
Env map[string]string
}
CLIRunner executes CLI commands for E2E testing.
func NewCLIRunner ¶
NewCLIRunner creates a new CLI runner with the given config path and XDG config home. It expects the binary to be built and available in the project root or path. The xdgConfigHome parameter is set as XDG_CONFIG_HOME environment variable so that the CLI's Save() function writes to the correct location (not the user's actual config).
func (*CLIRunner) RunExpectError ¶
RunExpectError executes and expects a non-zero exit code.
type ErrorConfig ¶
ErrorConfig configures an error response for a specific route.
type MockServer ¶
type MockServer struct {
Server *httptest.Server
BaseURL string
// contains filtered or unexported fields
}
MockServer provides a mock HTTP server for E2E testing.
func NewMockServer ¶
func NewMockServer() *MockServer
NewMockServer creates a new mock API server with default routes.
func (*MockServer) CallCount ¶
func (ms *MockServer) CallCount(method, pathPrefix string) int
CallCount returns the number of calls matching the given method and path prefix.
func (*MockServer) ClearAllDynamicResponses ¶
func (ms *MockServer) ClearAllDynamicResponses()
ClearAllDynamicResponses removes all dynamic response overrides.
func (*MockServer) ClearAllErrors ¶
func (ms *MockServer) ClearAllErrors()
ClearAllErrors removes all forced errors.
func (*MockServer) ClearCalls ¶
func (ms *MockServer) ClearCalls()
ClearCalls clears the recorded API calls.
func (*MockServer) ClearDynamicResponse ¶
func (ms *MockServer) ClearDynamicResponse(method, path string)
ClearDynamicResponse removes a dynamic response override.
func (*MockServer) ClearError ¶
func (ms *MockServer) ClearError(method, path string)
ClearError removes a forced error for a specific route.
func (*MockServer) GetCalls ¶
func (ms *MockServer) GetCalls() []RecordedCall
GetCalls returns all recorded API calls.
func (*MockServer) GetCallsForPath ¶
func (ms *MockServer) GetCallsForPath(method, pathPrefix string) []RecordedCall
GetCallsForPath returns recorded calls matching a path prefix.
func (*MockServer) HasCall ¶
func (ms *MockServer) HasCall(method, pathPrefix string) bool
HasCall checks if a specific API call was made.
func (*MockServer) Register ¶
func (ms *MockServer) Register(method, pattern string, handler RouteHandler)
Register adds a new route handler to the mock server.
Route Pattern Behavior (Task #8216) ¶
Routes use regex patterns to match URL paths. The common pattern `[a-f0-9-]+` is used to match UUIDs (e.g., "550e8400-e29b-41d4-a716-446655440000").
WARNING: This pattern can match unintended paths that contain only hex characters and hyphens. English words that would falsely match include:
- "feed", "dead", "cafe", "bead", "beef", "face", "fade", "deaf"
- "decade", "facade", "effaced", "defaced"
If you add a route like "/v1/probes/feed" (hypothetical probe aggregation feed endpoint), it could be matched by `/v1/probes/([a-f0-9-]+)` instead.
MITIGATION: When adding new routes with potential hex-only names:
- Register specific literal routes BEFORE wildcard UUID routes, as the mock server uses first-match semantics
- Or use more restrictive patterns that require the full UUID structure: `[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}`
func (*MockServer) RegisterAllRoutes ¶
func (ms *MockServer) RegisterAllRoutes()
RegisterAllRoutes registers all API routes including extended endpoints for team, billing, status pages, alert stats/history, probe history/stats, API keys, dashboard, alert mutes, labels, and probe dependencies.
func (*MockServer) RegisterDefaultRoutes ¶
func (ms *MockServer) RegisterDefaultRoutes()
RegisterDefaultRoutes registers common API routes with fixture responses. Note: SDK uses paths like "/v1/probes" (without /api prefix). SDK directly unmarshals responses into typed structs, not wrapped APIResponse.
func (*MockServer) SetDynamicResponse ¶
func (ms *MockServer) SetDynamicResponse(method, path string, data interface{})
SetDynamicResponse overrides the response for a specific route with custom data.
func (*MockServer) WithError ¶
func (ms *MockServer) WithError(method, path string, statusCode int, message string)
WithError forces a specific route to return an error response.
func (*MockServer) WithLatency ¶
func (ms *MockServer) WithLatency(d time.Duration)
WithLatency sets a global latency for all responses.
func (*MockServer) WithRouteLatency ¶
func (ms *MockServer) WithRouteLatency(method, path string, d time.Duration)
WithRouteLatency sets latency for a specific route (e.g., "GET /v1/probes").
type RecordedCall ¶
RecordedCall records details of an API call made to the mock server.
type Route ¶
type Route struct {
Method string
Pattern *regexp.Regexp
Handler RouteHandler
}
Route represents a registered API route.
type RouteHandler ¶
type RouteHandler func(w http.ResponseWriter, r *http.Request, matches []string)
RouteHandler is a function that handles an API route.
type RunResult ¶
type RunResult struct {
// Stdout contains the standard output.
Stdout string
// Stderr contains the standard error.
Stderr string
// ExitCode is the exit code of the command.
ExitCode int
// Err is any error that occurred during execution.
Err error
}
RunResult contains the result of running a CLI command.
func (*RunResult) CombinedOutput ¶
CombinedOutput returns stdout and stderr combined.
func (*RunResult) StderrContains ¶
StderrContains returns true if stderr contains the given substring.
func (*RunResult) StderrLines ¶
StderrLines returns stderr split into lines.
type TestConfig ¶
type TestConfig struct {
// Dir is the temporary config directory.
Dir string
// ConfigPath is the path to the config file.
ConfigPath string
// Config is the configuration object.
Config *config.Config
}
TestConfig manages temporary configuration for E2E tests.
func NewTestConfig ¶
func NewTestConfig(apiURL string) (*TestConfig, error)
NewTestConfig creates a new test configuration with a temporary directory. The returned TestConfig must be cleaned up with Cleanup().
The directory structure matches XDG_CONFIG_HOME expectations: - Dir (XDG_CONFIG_HOME): /tmp/stackeye-e2e-xxx/ - ConfigPath: /tmp/stackeye-e2e-xxx/stackeye/config.yaml
This allows the CLI's Save() function to work correctly when XDG_CONFIG_HOME is set to Dir.
func NewTestConfigWithMultipleContexts ¶
func NewTestConfigWithMultipleContexts(apiURL string) (*TestConfig, error)
NewTestConfigWithMultipleContexts creates a test config with multiple contexts.
func (*TestConfig) AddContext ¶
func (tc *TestConfig) AddContext(name string, ctx *config.Context) error
AddContext adds a new context and saves the config.
func (*TestConfig) Cleanup ¶
func (tc *TestConfig) Cleanup()
Cleanup removes the temporary configuration directory.
func (*TestConfig) Reload ¶
func (tc *TestConfig) Reload() error
Reload reloads the config from disk.
func (*TestConfig) RemoveContext ¶
func (tc *TestConfig) RemoveContext(name string) error
RemoveContext removes a context and saves the config.
func (*TestConfig) SetCurrentContext ¶
func (tc *TestConfig) SetCurrentContext(name string) error
SetCurrentContext changes the current context and saves the config.
type TestEnv ¶
type TestEnv struct {
// T is the testing context.
T *testing.T
// Server is the mock API server.
Server *MockServer
// Config is the test configuration.
Config *TestConfig
// CLI is the command runner.
CLI *CLIRunner
}
TestEnv encapsulates all test dependencies.
func NewLiveTestEnv ¶
NewLiveTestEnv creates a test environment using the user's real CLI config. This connects to the live API instead of a mock server. Requires: User must be authenticated (run `stackeye login` first).
func NewTestEnv ¶
NewTestEnv creates a complete test environment with mock server, config, and CLI runner. Call Cleanup() when done to release resources.
func NewTestEnvWithMultipleContexts ¶
NewTestEnvWithMultipleContexts creates a test environment with multiple contexts.
func (*TestEnv) AssertAPICall ¶
AssertAPICall asserts that a specific API call was made. In live mode, this is a no-op (we can't inspect real API calls).
func (*TestEnv) AssertContains ¶
AssertContains asserts that stdout contains the substring.
func (*TestEnv) AssertJSONOutput ¶
AssertJSONOutput asserts that stdout is valid JSON and unmarshals it.
func (*TestEnv) AssertNoAPICall ¶
AssertNoAPICall asserts that no API call matching the pattern was made. In live mode, this is a no-op (we can't inspect real API calls).
func (*TestEnv) AssertNotContains ¶
AssertNotContains asserts that stdout does not contain the substring.
func (*TestEnv) AssertStderrContains ¶
AssertStderrContains asserts that stderr contains the substring.
func (*TestEnv) AssertTableHasRows ¶
AssertTableHasRows asserts that table output has at least the expected number of rows. This accounts for header row(s).
func (*TestEnv) ClearAPICalls ¶
func (e *TestEnv) ClearAPICalls()
ClearAPICalls clears the recorded API calls. In live mode, this is a no-op.
func (*TestEnv) GetAPICalls ¶
func (e *TestEnv) GetAPICalls() []RecordedCall
GetAPICalls returns all recorded API calls. In live mode, returns an empty slice (we can't intercept real API calls).
func (*TestEnv) IsLiveMode ¶
IsLiveMode returns true if running against live API (Server is nil).
func (*TestEnv) RunSuccess ¶
RunSuccess executes and asserts success.