Documentation
¶
Overview ¶
Package test provides utilities for testing unstructured Kubernetes objects.
The primary functionality is JSONPath-like field access for unstructured.Unstructured objects, making test assertions more readable and maintainable.
Index ¶
- func Field(obj interface{}, path string) (interface{}, bool)
- func FieldExists(obj *unstructured.Unstructured, path string) bool
- func FieldInt(obj *unstructured.Unstructured, path string) int64
- func FieldString(obj *unstructured.Unstructured, path string) string
- func FieldValue(obj *unstructured.Unstructured, path string) interface{}
- func KubeConfigFake() *clientcmdapi.Config
- func KubeconfigFile(t *testing.T, kubeconfig *api.Config) string
- func McpRawPost(t *testing.T, endpoint, sessionID, jsonBody string) *http.Response
- func Must[T any](v T, err error) T
- func RandomPortAddress() (*net.TCPAddr, error)
- func ReadFile(path ...string) string
- func RestoreEnv(originalEnv []string)
- func WaitForHealthz(tcpAddr *net.TCPAddr) error
- func WaitForServer(tcpAddr *net.TCPAddr) error
- func WriteObject(w http.ResponseWriter, obj runtime.Object)
- type CapturedNotification
- type DiscoveryClientHandler
- type LogNotification
- type McpClient
- func (m *McpClient) CallTool(name string, args map[string]any) (*mcp.CallToolResult, error)
- func (m *McpClient) CallToolRaw(t *testing.T, jsonParams string) *http.Response
- func (m *McpClient) Close()
- func (m *McpClient) GetPrompt(name string, arguments map[string]string) (*mcp.GetPromptResult, error)
- func (m *McpClient) ListPrompts() (*mcp.ListPromptsResult, error)
- func (m *McpClient) ListTools() (*mcp.ListToolsResult, error)
- func (m *McpClient) SetLoggingLevel(level mcp.LoggingLevel) error
- func (m *McpClient) StartCapturingNotifications() *NotificationCapture
- type McpClientOption
- func WithAllowConnectionError() McpClientOption
- func WithClientCapabilities(capabilities *mcp.ClientCapabilities) McpClientOption
- func WithClientInfo(name, version string) McpClientOption
- func WithElicitationHandler(handler func(context.Context, *mcp.ElicitRequest) (*mcp.ElicitResult, error)) McpClientOption
- func WithEmptyClientInfo() McpClientOption
- func WithEndpoint(endpoint string) McpClientOption
- func WithHTTPHeaders(headers map[string]string) McpClientOption
- type MockServer
- type NotificationCapture
- func (c *NotificationCapture) RequireLogNotification(t *testing.T, timeout time.Duration) *LogNotification
- func (c *NotificationCapture) RequireNoLogNotification(t *testing.T, timeout time.Duration)
- func (c *NotificationCapture) RequireNotification(t *testing.T, timeout time.Duration, method string) *CapturedNotification
- type StreamContext
- type StreamOptions
- type SyncBuffer
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Field ¶ added in v0.0.55
Field is the core helper that traverses an unstructured object using JSONPath-like notation. It supports both dot notation (foo.bar) and array indexing (foo[0].bar). Returns (nil, false) if any intermediate field is nil, as we cannot traverse through nil.
func FieldExists ¶ added in v0.0.55
func FieldExists(obj *unstructured.Unstructured, path string) bool
FieldExists checks if a field exists at the given JSONPath-like path.
func FieldInt ¶ added in v0.0.55
func FieldInt(obj *unstructured.Unstructured, path string) int64
FieldInt retrieves an integer field from an unstructured object using JSONPath-like notation. Returns the integer value (int64), or 0 if not found or not an integer type (int, int64, int32).
IMPORTANT: This function cannot distinguish between "field doesn't exist", "field is nil", and "field exists with value 0". When asserting zero values (0), you should also verify the field exists using FieldExists:
s.True(test.FieldExists(obj, "spec.zeroValue"), "field should exist") s.Equal(int64(0), test.FieldInt(obj, "spec.zeroValue"), "field should be 0")
Examples:
- "spec.replicas"
- "spec.ports[0].containerPort"
func FieldString ¶ added in v0.0.55
func FieldString(obj *unstructured.Unstructured, path string) string
FieldString retrieves a string field from an unstructured object using JSONPath-like notation. Returns the string value, or empty string if not found or not a string.
IMPORTANT: This function cannot distinguish between "field doesn't exist", "field is nil", and "field exists with empty string value". When asserting empty string values (""), you should also verify the field exists using FieldExists:
s.True(test.FieldExists(obj, "spec.emptyField"), "field should exist")
s.Equal("", test.FieldString(obj, "spec.emptyField"), "field should be empty string")
Examples:
- "spec.runStrategy"
- "spec.template.spec.volumes[0].containerDisk.image"
- "spec.dataVolumeTemplates[0].spec.sourceRef.kind"
func FieldValue ¶ added in v0.0.55
func FieldValue(obj *unstructured.Unstructured, path string) interface{}
FieldValue retrieves any field value from an unstructured object using JSONPath-like notation. Returns nil if the field is not found. This is useful when you need the raw value without type conversion. Examples:
- "spec.template.spec.containers[0]" - returns map[string]interface{}
- "metadata.labels" - returns map[string]interface{}
func KubeConfigFake ¶ added in v0.0.51
func KubeConfigFake() *clientcmdapi.Config
func KubeconfigFile ¶ added in v0.0.53
func McpRawPost ¶ added in v0.0.59
McpRawPost sends a raw JSON-RPC request to an MCP HTTP endpoint. This is useful for testing MCP protocol edge cases that can't be reproduced through the go-sdk client due to its automatic normalization (e.g., always adding "arguments": {}, always setting clientInfo). The jsonBody should be a complete JSON-RPC message.
func RandomPortAddress ¶ added in v0.0.54
func RestoreEnv ¶ added in v0.0.54
func RestoreEnv(originalEnv []string)
func WaitForHealthz ¶ added in v0.0.55
WaitForHealthz waits for the /healthz endpoint to return a non-404 response
func WaitForServer ¶ added in v0.0.54
func WriteObject ¶
func WriteObject(w http.ResponseWriter, obj runtime.Object)
Types ¶
type CapturedNotification ¶ added in v0.0.58
CapturedNotification represents a captured MCP notification for testing
type DiscoveryClientHandler ¶ added in v0.0.55
type DiscoveryClientHandler struct {
// APIResourceLists defines all API groups and their resources.
// The handler automatically generates /api, /apis, and /apis/<group>/<version> endpoints.
APIResourceLists []metav1.APIResourceList
// contains filtered or unexported fields
}
func NewDiscoveryClientHandler ¶ added in v0.0.57
func NewDiscoveryClientHandler(additionalResources ...metav1.APIResourceList) *DiscoveryClientHandler
NewDiscoveryClientHandler creates a DiscoveryClientHandler with default Kubernetes resources.
func NewInOpenShiftHandler ¶ added in v0.0.57
func NewInOpenShiftHandler(additionalResources ...metav1.APIResourceList) *DiscoveryClientHandler
NewInOpenShiftHandler creates a DiscoveryClientHandler configured for OpenShift clusters. It includes the OpenShift project.openshift.io API group by default. Additional API resource lists can be passed to extend the handler.
func (*DiscoveryClientHandler) AddAPIResourceList ¶ added in v0.0.57
func (h *DiscoveryClientHandler) AddAPIResourceList(resourceList metav1.APIResourceList)
AddAPIResourceList adds an API resource list to the handler. This is useful for dynamically modifying the handler during tests.
func (*DiscoveryClientHandler) ServeHTTP ¶ added in v0.0.55
func (h *DiscoveryClientHandler) ServeHTTP(w http.ResponseWriter, req *http.Request)
type LogNotification ¶ added in v0.0.57
type LogNotification struct {
// Level is the log severity level (debug, info, notice, warning, error, critical, alert, emergency)
Level string
// Logger is the name of the logger that generated the message
Logger string
// Data contains the log message content
Data string
}
LogNotification represents a parsed MCP logging notification. Used for asserting log messages sent to MCP clients during error handling.
type McpClient ¶ added in v0.0.51
type McpClient struct {
Session *mcp.ClientSession
InitializeResult *mcp.InitializeResult
// contains filtered or unexported fields
}
func NewMcpClient ¶ added in v0.0.51
NewMcpClient creates a new MCP test client.
When an http.Handler is provided, an httptest.Server is created automatically. Alternatively, use WithEndpoint() option to connect to an existing server URL.
Example with handler:
client := test.NewMcpClient(t, myHandler)
Example with endpoint:
client := test.NewMcpClient(t, nil, test.WithEndpoint("http://localhost:8080/mcp"))
func (*McpClient) CallTool ¶ added in v0.0.51
CallTool helper function to call a tool by name with arguments
func (*McpClient) CallToolRaw ¶ added in v0.0.59
CallToolRaw sends a raw JSON-RPC tools/call request bypassing the go-sdk client. This allows sending requests exactly as a non-go-sdk MCP client would, without the go-sdk's automatic normalization (e.g., the go-sdk always adds "arguments": {} even when nil). The jsonParams is the raw JSON for the "params" field of the JSON-RPC request.
func (*McpClient) GetPrompt ¶ added in v0.0.58
func (m *McpClient) GetPrompt(name string, arguments map[string]string) (*mcp.GetPromptResult, error)
GetPrompt helper function to get a prompt by name
func (*McpClient) ListPrompts ¶ added in v0.0.58
func (m *McpClient) ListPrompts() (*mcp.ListPromptsResult, error)
ListPrompts helper function to list available prompts
func (*McpClient) ListTools ¶ added in v0.0.58
func (m *McpClient) ListTools() (*mcp.ListToolsResult, error)
ListTools helper function to list available tools
func (*McpClient) SetLoggingLevel ¶ added in v0.0.58
func (m *McpClient) SetLoggingLevel(level mcp.LoggingLevel) error
SetLoggingLevel sets the logging level on the server
func (*McpClient) StartCapturingNotifications ¶ added in v0.0.57
func (m *McpClient) StartCapturingNotifications() *NotificationCapture
StartCapturingNotifications returns the notification capture for waiting on notifications. The notifications are always being captured; this just returns the capture object.
type McpClientOption ¶ added in v0.0.58
type McpClientOption interface {
// contains filtered or unexported methods
}
McpClientOption configures McpClient creation
func WithAllowConnectionError ¶ added in v0.0.58
func WithAllowConnectionError() McpClientOption
WithAllowConnectionError allows connection errors without failing the test. When set, connection failures will result in a nil Session instead of a test failure. Useful for testing authentication/authorization scenarios where connection rejection is expected.
func WithClientCapabilities ¶ added in v0.0.59
func WithClientCapabilities(capabilities *mcp.ClientCapabilities) McpClientOption
WithClientCapabilities sets explicit client capabilities on the MCP client. This overrides capabilities inferred from handlers (e.g., elicitation mode support).
func WithClientInfo ¶ added in v0.0.58
func WithClientInfo(name, version string) McpClientOption
WithClientInfo sets custom MCP client info for initialization
func WithElicitationHandler ¶ added in v0.0.59
func WithElicitationHandler(handler func(context.Context, *mcp.ElicitRequest) (*mcp.ElicitResult, error)) McpClientOption
WithElicitationHandler sets an elicitation handler on the MCP client. When set, the client advertises elicitation support and the handler is invoked when the server sends an elicitation request during tool execution.
func WithEmptyClientInfo ¶ added in v0.0.58
func WithEmptyClientInfo() McpClientOption
WithEmptyClientInfo sets empty MCP client info for initialization
func WithEndpoint ¶ added in v0.0.58
func WithEndpoint(endpoint string) McpClientOption
WithEndpoint sets a custom endpoint URL for the MCP client. When set, no httptest.Server will be created and the provided URL will be used directly. The URL should include the full path (e.g., "http://localhost:8080/mcp").
func WithHTTPHeaders ¶ added in v0.0.58
func WithHTTPHeaders(headers map[string]string) McpClientOption
WithHTTPHeaders sets custom HTTP headers for the MCP client transport
type MockServer ¶
type MockServer struct {
// contains filtered or unexported fields
}
func NewMockServer ¶
func NewMockServer() *MockServer
func (*MockServer) Close ¶
func (m *MockServer) Close()
func (*MockServer) Config ¶
func (m *MockServer) Config() *rest.Config
func (*MockServer) Handle ¶
func (m *MockServer) Handle(handler http.Handler)
func (*MockServer) Kubeconfig ¶ added in v0.0.51
func (m *MockServer) Kubeconfig() *api.Config
func (*MockServer) KubeconfigFile ¶ added in v0.0.51
func (m *MockServer) KubeconfigFile(t *testing.T) string
func (*MockServer) ResetHandlers ¶ added in v0.0.54
func (m *MockServer) ResetHandlers()
type NotificationCapture ¶ added in v0.0.57
type NotificationCapture struct {
// contains filtered or unexported fields
}
NotificationCapture captures MCP notifications for testing. Use StartCapturingNotifications to begin capturing, then RequireNotification to retrieve.
func (*NotificationCapture) RequireLogNotification ¶ added in v0.0.57
func (c *NotificationCapture) RequireLogNotification(t *testing.T, timeout time.Duration) *LogNotification
RequireLogNotification waits for a logging notification and returns it parsed. Filters for "notifications/message" method and fails the test if not received within timeout.
Timeout recommendations:
- 2 seconds: Standard timeout for log notifications after tool calls (recommended default)
func (*NotificationCapture) RequireNoLogNotification ¶ added in v0.0.58
func (c *NotificationCapture) RequireNoLogNotification(t *testing.T, timeout time.Duration)
RequireNoLogNotification asserts that no logging notification is received within the given timeout. Use this to verify that non-Kubernetes errors do not produce MCP log notifications.
func (*NotificationCapture) RequireNotification ¶ added in v0.0.57
func (c *NotificationCapture) RequireNotification(t *testing.T, timeout time.Duration, method string) *CapturedNotification
RequireNotification waits for a notification matching the specified method and fails the test if not received. Iterates through all captured notifications looking for a match, waiting for new ones if needed. The method parameter specifies which notification method to wait for (e.g., "notifications/tools/list_changed").
Timeout recommendations:
- 2 seconds: For immediate notifications like log messages after tool calls
- 5 seconds: For notifications involving file system or cluster state changes (kubeconfig, API groups)
type StreamContext ¶
type StreamContext struct {
Closer io.Closer
StdinStream io.ReadCloser
StdoutStream io.WriteCloser
StderrStream io.WriteCloser
// contains filtered or unexported fields
}
func CreateHTTPStreams ¶
func CreateHTTPStreams(w http.ResponseWriter, req *http.Request, opts *StreamOptions) (*StreamContext, error)
type StreamOptions ¶
type SyncBuffer ¶ added in v0.0.58
type SyncBuffer struct {
// contains filtered or unexported fields
}
SyncBuffer is a thread-safe wrapper around bytes.Buffer. Use this for test log buffers to avoid race conditions when multiple goroutines write to the logger concurrently.
func (*SyncBuffer) Reset ¶ added in v0.0.58
func (b *SyncBuffer) Reset()
func (*SyncBuffer) String ¶ added in v0.0.58
func (b *SyncBuffer) String() string